Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
ab2eeb0d
Commit
ab2eeb0d
authored
8 years ago
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finish user asset form
parent
e2329626
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
277 additions
and
19 deletions
+277
-19
views.py
apps/assets/views.py
+1
-1
models.py
apps/perms/models.py
+7
-1
style.css
apps/static/css/style.css
+2
-2
forms.py
apps/users/forms.py
+31
-7
hands.py
apps/users/hands.py
+2
-0
user_asset_permission.html
apps/users/templates/users/user_asset_permission.html
+180
-0
user_detail.html
apps/users/templates/users/user_detail.html
+6
-4
urls.py
apps/users/urls.py
+4
-0
views.py
apps/users/views.py
+44
-4
No files found.
apps/assets/views.py
View file @
ab2eeb0d
...
...
@@ -358,7 +358,7 @@ class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVi
self
.
object
.
name
,
))
return
s
elf
.
s
uccess_message
return
success_message
class
SystemUserUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
...
...
This diff is collapsed.
Click to expand it.
apps/perms/models.py
View file @
ab2eeb0d
...
...
@@ -11,12 +11,18 @@ from common.utils import date_expired_default, combine_seq
class
AssetPermission
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Name'
))
PRIVATE_FOR_CHOICE
=
(
(
'N'
,
'None'
),
(
'U'
,
'user'
),
(
'G'
,
'user group'
),
)
name
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
'Name'
))
users
=
models
.
ManyToManyField
(
User
,
related_name
=
'asset_permissions'
,
blank
=
True
)
user_groups
=
models
.
ManyToManyField
(
UserGroup
,
related_name
=
'asset_permissions'
,
blank
=
True
)
assets
=
models
.
ManyToManyField
(
Asset
,
related_name
=
'granted_by_permissions'
,
blank
=
True
)
asset_groups
=
models
.
ManyToManyField
(
AssetGroup
,
related_name
=
'granted_by_permissions'
,
blank
=
True
)
system_users
=
models
.
ManyToManyField
(
SystemUser
,
related_name
=
'granted_by_permissions'
)
private_for
=
models
.
CharField
(
choices
=
PRIVATE_FOR_CHOICE
,
max_length
=
1
,
default
=
'N'
,
verbose_name
=
_
(
'Private for'
))
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Active'
))
date_expired
=
models
.
DateTimeField
(
default
=
date_expired_default
,
verbose_name
=
_
(
'Date expired'
))
created_by
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Created by'
))
...
...
This diff is collapsed.
Click to expand it.
apps/static/css/style.css
View file @
ab2eeb0d
@import
url("https://fonts.
googleapis
.com/css?family=Open+Sans:300,400,600,700")
;
@import
url("https://fonts.
googleapis
.com/css?family=Roboto:400,300,500,700")
;
@import
url("https://fonts.
useso
.com/css?family=Open+Sans:300,400,600,700")
;
@import
url("https://fonts.
useso
.com/css?family=Roboto:400,300,500,700")
;
/*
*
* INSPINIA - Responsive Admin Theme
...
...
This diff is collapsed.
Click to expand it.
apps/users/forms.py
View file @
ab2eeb0d
...
...
@@ -3,10 +3,10 @@
from
django
import
forms
from
django.contrib.auth.forms
import
AuthenticationForm
from
django.utils.translation
import
gettext_lazy
as
_
from
captcha.fields
import
CaptchaField
from
.models
import
User
,
UserGroup
from
.hands
import
AssetPermission
class
UserLoginForm
(
AuthenticationForm
):
...
...
@@ -25,12 +25,10 @@ class UserCreateForm(forms.ModelForm):
'username'
,
'name'
,
'email'
,
'groups'
,
'wechat'
,
'phone'
,
'enable_otp'
,
'role'
,
'date_expired'
,
'comment'
,
]
help_texts
=
{
'username'
:
'* required'
,
'email'
:
'* required'
,
}
widgets
=
{
'groups'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Join user groups'
)}),
}
...
...
@@ -44,13 +42,11 @@ class UserUpdateForm(forms.ModelForm):
'name'
,
'email'
,
'groups'
,
'wechat'
,
'phone'
,
'enable_otp'
,
'role'
,
'date_expired'
,
'comment'
,
]
help_texts
=
{
'username'
:
'* required'
,
'email'
:
'* required'
,
'groups'
:
'* required'
}
widgets
=
{
'groups'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Join user groups'
)}),
}
...
...
@@ -60,11 +56,9 @@ class UserGroupForm(forms.ModelForm):
class
Meta
:
model
=
UserGroup
fields
=
[
'name'
,
'comment'
,
]
help_texts
=
{
'name'
:
'* required'
}
...
...
@@ -88,3 +82,33 @@ class UserKeyForm(forms.Form):
if
not
checked
:
raise
forms
.
ValidationError
(
_
(
'Not a valid ssh private key.'
))
return
ssh_pk
class
UserPrivateAssetPermissionForm
(
forms
.
ModelForm
):
def
save
(
self
,
commit
=
True
):
self
.
instance
=
super
(
UserPrivateAssetPermissionForm
,
self
)
.
save
(
commit
=
commit
)
self
.
instance
.
users
=
[
self
.
user
]
self
.
instance
.
name
=
'_Private for
%
s
%
s'
%
(
self
.
user
.
username
,
)
self
.
instance
.
save
()
return
self
.
instance
def
clean_private_for
(
self
):
return
'U'
class
Meta
:
model
=
AssetPermission
fields
=
[
'assets'
,
'asset_groups'
,
'system_users'
,
'private_for'
,
'name'
,
]
widgets
=
{
'assets'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select assets'
)}),
'asset_groups'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select asset groups'
)}),
'system_users'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select system users'
)}),
}
This diff is collapsed.
Click to expand it.
apps/users/hands.py
View file @
ab2eeb0d
...
...
@@ -10,5 +10,7 @@
:license: GPL v2, see LICENSE for more details.
"""
from
perms.models
import
AssetPermission
This diff is collapsed.
Click to expand it.
apps/users/templates/users/user_asset_permission.html
0 → 100644
View file @
ab2eeb0d
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load bootstrap %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link
href=
"{% static "
css
/
plugins
/
select2
/
select2
.
min
.
css
"
%}"
rel=
"stylesheet"
>
<script
src=
"{% static "
js
/
plugins
/
select2
/
select2
.
full
.
min
.
js
"
%}"
></script>
{% endblock %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li>
<a
href=
"{% url 'users:user-detail' pk=user_object.id %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'User detail' %}
</a>
</li>
<li
class=
"active"
>
<a
href=
"{% url 'users:user-asset-permission' pk=user_object.id %}"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Asset permission list' %}
</a>
</li>
<li>
<a
href=
"{% url 'users:user-granted-asset' pk=user_object.id %}"
class=
"text-center"
><i
class=
"fa fa-cubes"
></i>
{% trans 'Asset granted' %}
</a>
</li>
<li>
<a
href=
"{% url 'users:user-login-history' pk=user_object.id %}"
class=
"text-center"
><i
class=
"fa fa-calculator-o"
></i>
{% trans 'Login history' %}
</a>
</li>
<form
id=
"search_form"
method=
"get"
action=
""
class=
"pull-right mail-search"
>
<div
class=
"input-group"
>
<input
type=
"text"
class=
"form-control input-sm"
name=
"keyword"
placeholder=
"Search"
value=
"{{ keyword }}"
>
<div
class=
"input-group-btn"
>
<button
id=
"search_btn"
type=
"submit"
class=
"btn btn-sm btn-primary"
>
搜索
</button>
</div>
</div>
</form>
</ul>
</div>
<div
class=
"tab-content"
>
<div
class=
"col-sm-7"
style=
"padding-left: 0;"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
style=
"float: left"
>
{% trans 'Asset permission of ' %}
<b>
{{ user.name }}
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
</a>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
</a>
<ul
class=
"dropdown-menu dropdown-user"
>
</ul>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content"
>
<table
class=
"table table-hover"
>
<thead>
<tr>
<th
class=
"text-center"
><a
href=
"{% url 'perms:asset-permission-list' %}?sort=name"
>
{% trans 'Name' %}
</a></th>
<th
class=
"text-center"
>
{% trans 'User ' %}
</th>
<th
class=
"text-center"
>
{% trans 'User group ' %}
</th>
<th
class=
"text-center"
>
{% trans 'Asset ' %}
</th>
<th
class=
"text-center"
>
{% trans 'Asset group ' %}
</th>
<th
class=
"text-center"
>
{% trans 'System user ' %}
</th>
<th
class=
"text-center"
>
<a
href=
"#"
>
{% trans 'Is valid' %}
</a>
</th>
<th></th>
</tr>
</thead>
<tbody>
{% for asset_permission in object_list %}
<tr
class=
"gradeX"
>
<td
class=
"text-center"
>
<a
href=
"{% url 'perms:asset-permission-detail' pk=asset_permission.id %}"
>
{{ asset_permission.name }}
</a>
</td>
<td
class=
"text-center"
>
{{ asset_permission.users.count}}
</td>
<td
class=
"text-center"
>
{{ asset_permission.user_groups.count}}
</td>
<td
class=
"text-center"
>
{{ asset_permission.assets.count }}
</td>
<td
class=
"text-center"
>
{{ asset_permission.asset_groups.count }}
</td>
<td
class=
"text-center"
>
{{ asset_permission.system_users.count }}
</td>
<td
class=
"text-center"
>
{% if asset_permission.is_valid %}
<i
class=
"fa fa-check text-navy"
></i>
{% else %}
<i
class=
"fa fa-times text-danger"
></i>
{% endif %}
</td>
<td>
<button
class=
"btn btn-danger btn-xs btn_delete_user_group {% if asset_permission.is_inherit_from_user_groups %} disabled {% endif %}"
type=
"button"
style=
"float: right;"
><i
class=
"fa fa-minus"
></i></button>
</td>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div
class=
"row"
>
{% include '_pagination.html' %}
</div>
</div>
</div>
</div>
<div
class=
"col-sm-5"
style=
"padding-left: 0;padding-right: 0"
>
<div
class=
"panel panel-primary"
>
<div
class=
"panel-heading"
>
<i
class=
"fa fa-info-circle"
></i>
{% trans 'Quick create permission for user' %}
</div>
<div
class=
"panel-body"
>
<form>
<table
class=
"table"
>
<tbody>
{% csrf_token %}
<tr
class=
"no-borders-tr"
>
<td
colspan=
"1"
style=
"padding-top: 0"
>
{{ form.assets|bootstrap }}
</td>
</tr>
<tr
class=
"no-borders-tr"
>
<td
colspan=
"1"
style=
"padding-top: 0"
>
{{ form.asset_groups|bootstrap }}
</td>
</tr>
<tr
class=
"no-borders-tr"
>
<td
colspan=
"1"
style=
"padding-top: 0"
>
{{ form.system_users|bootstrap }}
</td>
</tr>
<tr
class=
"no-borders-tr"
>
<td>
<button
type=
"button"
class=
"btn btn-primary btn-sm"
>
{% trans 'Submit' %}
</button>
</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
{
#
function
switch_user_status
(
obj
)
{
#
}
{
#
var
status
=
$
(
obj
).
prop
(
'checked'
);
#
}
{
##
}
{
#
$
.
ajax
({
#
}
{
#
url
:
"{% url 'users:user-active-api' pk=user_object.id %}"
,
#
}
{
#
type
:
"PUT"
,
#
}
{
#
data
:
{
#
}
{
#
'is_active'
:
status
#
}
{
#
},
#
}
{
#
success
:
function
(
data
,
status
)
{
#
}
{
#
console
.
log
(
data
)
#
}
{
#
},
#
}
{
#
error
:
function
()
{
#
}
{
#
console
.
log
(
'error'
)
#
}
{
#
}
#
}
{
#
})
#
}
{
#
}
#
}
$
(
document
).
ready
(
function
()
{
$
(
'.select2'
).
select2
();
});
</script>
{% endblock %}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
apps/users/templates/users/user_detail.html
View file @
ab2eeb0d
...
...
@@ -18,11 +18,13 @@
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li
class=
"active"
>
<a
href=
""
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'User detail' %}
</a>
<a
href=
"
{% url 'users:user-detail' pk=user_object.id %}
"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'User detail' %}
</a>
</li>
<li><a
href=
""
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Asset permission list' %}
</a></li>
<li><a
href=
""
class=
"text-center"
><i
class=
"fa fa-cubes"
></i>
{% trans 'Asset granted' %}
</a></li>
<li><a
href=
""
class=
"text-center"
><i
class=
"fa fa-calculator-o"
></i>
{% trans 'Login history' %}
</a></li>
<li>
<a
href=
"{% url 'users:user-asset-permission' pk=user_object.id %}"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Asset permission list' %}
</a>
</li>
<li><a
href=
"{% url 'users:user-granted-asset' pk=user_object.id %}"
class=
"text-center"
><i
class=
"fa fa-cubes"
></i>
{% trans 'Asset granted' %}
</a></li>
<li><a
href=
"{% url 'users:user-login-history' pk=user_object.id %}"
class=
"text-center"
><i
class=
"fa fa-calculator-o"
></i>
{% trans 'Login history' %}
</a></li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
This diff is collapsed.
Click to expand it.
apps/users/urls.py
View file @
ab2eeb0d
...
...
@@ -16,6 +16,10 @@ urlpatterns = [
name
=
'reset-password-success'
),
url
(
r'^user$'
,
views
.
UserListView
.
as_view
(),
name
=
'user-list'
),
url
(
r'^user/(?P<pk>[0-9]+)$'
,
views
.
UserDetailView
.
as_view
(),
name
=
'user-detail'
),
url
(
r'^user/(?P<pk>[0-9]+)/asset-permission$'
,
views
.
UserAssetPermissionView
.
as_view
(),
name
=
'user-asset-permission'
),
url
(
r'^user/(?P<pk>[0-9]+)/asset-granted'
,
views
.
UserDetailView
.
as_view
(),
name
=
'user-granted-asset'
),
url
(
r'^user/(?P<pk>[0-9]+)/login-history'
,
views
.
UserDetailView
.
as_view
(),
name
=
'user-login-history'
),
url
(
r'^first-login/$'
,
views
.
UserFirstLoginView
.
as_view
(),
name
=
'user-first-login'
),
url
(
r'^user/(?P<pk>[0-9]+)/assets-perm$'
,
views
.
UserDetailView
.
as_view
(),
name
=
'user-detail'
),
url
(
r'^user/create$'
,
views
.
UserCreateView
.
as_view
(),
name
=
'user-create'
),
...
...
This diff is collapsed.
Click to expand it.
apps/users/views.py
View file @
ab2eeb0d
...
...
@@ -2,8 +2,6 @@
from
__future__
import
unicode_literals
import
logging
from
django.conf
import
settings
from
django.contrib.auth
import
login
as
auth_login
,
logout
as
auth_logout
from
django.contrib.auth.mixins
import
LoginRequiredMixin
...
...
@@ -20,7 +18,7 @@ from django.views.decorators.csrf import csrf_protect
from
django.views.decorators.debug
import
sensitive_post_parameters
from
django.views.generic.base
import
TemplateView
from
django.views.generic.list
import
ListView
from
django.views.generic.edit
import
CreateView
,
DeleteView
,
UpdateView
,
FormView
from
django.views.generic.edit
import
CreateView
,
DeleteView
,
UpdateView
,
FormView
,
SingleObjectMixin
,
FormMixin
from
django.views.generic.detail
import
DetailView
from
formtools.wizard.views
import
SessionWizardView
...
...
@@ -28,10 +26,12 @@ from formtools.wizard.views import SessionWizardView
from
common.utils
import
get_object_or_none
,
get_logger
from
.models
import
User
,
UserGroup
from
.forms
import
UserCreateForm
,
UserUpdateForm
,
UserGroupForm
,
UserLoginForm
,
UserInfoForm
,
UserKeyForm
from
.forms
import
UserCreateForm
,
UserUpdateForm
,
UserGroupForm
,
UserLoginForm
,
UserInfoForm
,
UserKeyForm
,
\
UserPrivateAssetPermissionForm
from
.utils
import
AdminUserRequiredMixin
,
user_add_success_next
,
send_reset_password_mail
logger
=
get_logger
(
__name__
)
...
...
@@ -355,3 +355,43 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
'phone'
:
user
.
phone
or
''
}
return
super
(
UserFirstLoginView
,
self
)
.
get_form_initial
(
step
)
class
UserAssetPermissionView
(
AdminUserRequiredMixin
,
FormMixin
,
SingleObjectMixin
,
ListView
):
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
template_name
=
'users/user_asset_permission.html'
context_object_name
=
'user_object'
form_class
=
UserPrivateAssetPermissionForm
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
(
queryset
=
User
.
objects
.
all
())
return
super
(
UserAssetPermissionView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_asset_permission_inherit_from_user_group
(
self
):
asset_permissions
=
set
()
user_groups
=
self
.
object
.
groups
.
all
()
for
user_group
in
user_groups
:
for
asset_permission
in
user_group
.
asset_permissions
.
all
():
setattr
(
asset_permission
,
'is_inherit_from_user_groups'
,
True
)
setattr
(
asset_permission
,
'inherit_from_user_groups'
,
getattr
(
asset_permission
,
b
'inherit_from_user_groups'
,
set
())
.
add
(
user_group
))
asset_permissions
.
add
(
asset_permission
)
return
asset_permissions
def
get_queryset
(
self
):
asset_permissions
=
set
(
self
.
object
.
asset_permissions
.
all
())
\
|
self
.
get_asset_permission_inherit_from_user_group
()
return
list
(
asset_permissions
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'Users'
,
'action'
:
'User asset permissions'
,
}
kwargs
.
update
(
context
)
return
super
(
UserAssetPermissionView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserAssetPermissionCreateView
(
AdminUserRequiredMixin
,
CreateView
):
pass
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment