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
7fd224e6
Commit
7fd224e6
authored
Sep 17, 2016
by
ibuler
Browse files
Options
Browse Files
Download
Plain Diff
Merge with user-perm
parents
343f1399
dc4d388d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
531 additions
and
205 deletions
+531
-205
forms.py
apps/assets/forms.py
+1
-1
models.py
apps/assets/models.py
+24
-6
admin_user_detail.html
apps/assets/templates/assets/admin_user_detail.html
+31
-11
system_user_asset.html
apps/assets/templates/assets/system_user_asset.html
+50
-10
system_user_detail.html
apps/assets/templates/assets/system_user_detail.html
+1
-5
system_user_list.html
apps/assets/templates/assets/system_user_list.html
+2
-2
urls.py
apps/assets/urls.py
+2
-2
views.py
apps/assets/views.py
+32
-25
common_tags.py
apps/common/templatetags/common_tags.py
+11
-2
forms.py
apps/perms/forms.py
+1
-1
models.py
apps/perms/models.py
+26
-26
asset_permission_asset.html
apps/perms/templates/perms/asset_permission_asset.html
+2
-2
asset_permission_create_update.html
...perms/templates/perms/asset_permission_create_update.html
+0
-2
asset_permission_detail.html
apps/perms/templates/perms/asset_permission_detail.html
+1
-9
asset_permission_user.html
apps/perms/templates/perms/asset_permission_user.html
+2
-2
perm_user_asset_list.html
apps/perms/templates/perms/perm_user_asset_list.html
+0
-66
urls.py
apps/perms/urls.py
+2
-2
utils.py
apps/perms/utils.py
+195
-2
views.py
apps/perms/views.py
+8
-8
jumpserver.css
apps/static/css/jumpserver.css
+2
-0
style.css
apps/static/css/style.css
+2
-4
forms.py
apps/users/forms.py
+25
-7
hands.py
apps/users/hands.py
+2
-2
user_asset_permission.html
apps/users/templates/users/user_asset_permission.html
+0
-0
user_detail.html
apps/users/templates/users/user_detail.html
+8
-4
user_granted_asset.html
apps/users/templates/users/user_granted_asset.html
+0
-0
urls.py
apps/users/urls.py
+6
-0
views.py
apps/users/views.py
+95
-4
No files found.
apps/assets/forms.py
View file @
7fd224e6
...
...
@@ -12,7 +12,7 @@ class AssetForm(forms.ModelForm):
fields
=
[
"ip"
,
"other_ip"
,
"remote_card_ip"
,
"hostname"
,
"port"
,
"groups"
,
"username"
,
"password"
,
"idc"
,
"mac_address"
,
"brand"
,
"cpu"
,
"memory"
,
"disk"
,
"os"
,
"cabinet_no"
,
"cabinet_pos"
,
"number"
,
"status"
,
"type"
,
"env"
,
"sn"
,
"is_active"
,
"comment"
,
"admin_user"
,
"system_user"
"number"
,
"status"
,
"type"
,
"env"
,
"sn"
,
"is_active"
,
"comment"
,
"admin_user"
,
"system_user
s
"
]
widgets
=
{
...
...
apps/assets/models.py
View file @
7fd224e6
...
...
@@ -194,6 +194,21 @@ class SystemUser(models.Model):
def
public_key
(
self
,
public_key_raw
):
self
.
_public_key
=
encrypt
(
public_key_raw
)
def
get_assets_inherit_from_asset_groups
(
self
):
assets
=
set
()
asset_groups
=
self
.
asset_groups
.
all
()
for
asset_group
in
asset_groups
:
for
asset
in
asset_group
.
assets
.
all
():
setattr
(
asset
,
'is_inherit_from_asset_groups'
,
True
)
setattr
(
asset
,
'inherit_from_asset_groups'
,
getattr
(
asset
,
b
'inherit_from_asset_groups'
,
set
())
.
add
(
asset_group
))
assets
.
add
(
asset
)
return
assets
def
get_assets
(
self
):
assets
=
set
(
self
.
assets
.
all
())
|
self
.
get_assets_inherit_from_asset_groups
()
return
list
(
assets
)
class
Meta
:
db_table
=
'system_user'
...
...
@@ -266,8 +281,8 @@ class Asset(models.Model):
password
=
models
.
CharField
(
max_length
=
256
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
"Admin password"
))
admin_user
=
models
.
ForeignKey
(
AdminUser
,
null
=
True
,
blank
=
True
,
related_name
=
'assets'
,
on_delete
=
models
.
SET_NULL
,
verbose_name
=
_
(
"Admin user"
))
system_user
=
models
.
ManyToManyField
(
SystemUser
,
blank
=
True
,
related_name
=
'assets'
,
verbose_name
=
_
(
"System User"
))
idc
=
models
.
ForeignKey
(
IDC
,
null
=
True
,
blank
=
True
,
related_name
=
'assets'
,
on_delete
=
models
.
SET_NULL
,
verbose_name
=
_
(
'IDC'
))
system_user
s
=
models
.
ManyToManyField
(
SystemUser
,
blank
=
True
,
related_name
=
'assets'
,
verbose_name
=
_
(
"System User"
))
idc
=
models
.
ForeignKey
(
IDC
,
null
=
True
,
related_name
=
'assets'
,
on_delete
=
models
.
SET_NULL
,
verbose_name
=
_
(
'IDC'
))
mac_address
=
models
.
CharField
(
max_length
=
20
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
"Mac address"
))
brand
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Brand'
))
cpu
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'CPU'
))
...
...
@@ -301,7 +316,7 @@ class Asset(models.Model):
@classmethod
def
generate_fake
(
cls
,
count
=
100
):
from
random
import
seed
from
random
import
seed
,
choice
import
forgery_py
from
django.db
import
IntegrityError
...
...
@@ -309,10 +324,14 @@ class Asset(models.Model):
for
i
in
range
(
count
):
asset
=
cls
(
ip
=
'
%
s.
%
s.
%
s.
%
s'
%
tuple
([
forgery_py
.
forgery
.
basic
.
text
(
length
=
3
,
digits
=
True
)
for
i
in
range
(
0
,
4
)]),
admin_user
=
choice
(
AdminUser
.
objects
.
all
()),
idc
=
choice
(
IDC
.
objects
.
all
()),
port
=
22
,
created_by
=
'Fake'
)
try
:
asset
.
save
()
asset
.
system_users
=
[
choice
(
SystemUser
.
objects
.
all
())
for
i
in
range
(
3
)]
asset
.
groups
=
[
choice
(
AssetGroup
.
objects
.
all
())
for
i
in
range
(
3
)]
logger
.
debug
(
'Generate fake asset :
%
s'
%
asset
.
ip
)
except
IntegrityError
:
print
(
'Error continue'
)
...
...
@@ -335,5 +354,5 @@ class Label(models.Model):
def
generate_fake
():
for
cls
in
(
Asset
,
AssetGroup
,
IDC
):
cls
.
generate_fake
()
\ No newline at end of file
for
cls
in
(
AssetGroup
,
IDC
,
AdminUser
,
SystemUser
,
Asset
):
cls
.
generate_fake
()
apps/assets/templates/assets/admin_user_detail.html
View file @
7fd224e6
...
...
@@ -15,9 +15,9 @@
<div
class=
"ibox float-e-margins"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li
class=
"active"
><a
href=
""
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Detail' %}
</a>
<li
class=
"active"
>
<a
href=
""
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Detail' %}
</a>
</li>
<li><a
href=
""
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Associate assets' %}
</a></li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
@@ -33,10 +33,6 @@
<i
class=
"fa fa-wrench"
></i>
</a>
<ul
class=
"dropdown-menu dropdown-user"
>
<li><a
href=
"#"
></a>
</li>
<li><a
href=
"#"
></a>
</li>
</ul>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
...
...
@@ -73,7 +69,7 @@
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
style=
"float: left"
>
{% trans 'Asset list of ' %}
<b>
{{ admin_user.name }}
</b></span>
<span
style=
"float: left"
>
{% trans 'Asset list of ' %}
<b>
{{ admin_user.name }}
</b>
<span
class=
"badge"
>
{{ paginator.count }}
</span>
</span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
...
...
@@ -82,10 +78,6 @@
<i
class=
"fa fa-wrench"
></i>
</a>
<ul
class=
"dropdown-menu dropdown-user"
>
<li><a
href=
"#"
></a>
</li>
<li><a
href=
"#"
></a>
</li>
</ul>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
...
...
@@ -185,6 +177,34 @@
</table>
</div>
</div>
<div
class=
"panel panel-warning"
>
<div
class=
"panel-heading"
>
<i
class=
"fa fa-info-circle"
></i>
{% trans 'Replace asset admin user with this admin user' %}
</div>
<div
class=
"panel-body"
>
<table
class=
"table"
>
<tbody>
<form>
<tr
class=
"no-borders-tr"
>
<td
colspan=
"2"
>
<select
data-placeholder=
"{% trans 'Select asset groups' %}"
class=
"select2"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
>
{% for group in groups %}
<option
value=
"{{ group.id }}"
>
{{ group.name }}
</option>
{% endfor %}
</select>
</td>
</tr>
<tr
class=
"no-borders-tr"
>
<td
colspan=
"2"
>
<button
type=
"button"
class=
"btn btn-warning btn-sm"
>
{% trans 'Replace' %}
</button>
</td>
</tr>
</form>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
...
...
apps/assets/templates/assets/system_user_asset.html
View file @
7fd224e6
...
...
@@ -19,10 +19,7 @@
<a
href=
"{% url 'assets:system-user-detail' pk=system_user.id %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Detail' %}
</a>
</li>
<li
class=
"active"
><a
href=
"{% url 'assets:system-user-asset' pk=system_user.id %}"
class=
"text-center"
>
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Associate assets' %}
</a>
</li>
<li><a
href=
"{% url 'assets:system-user-asset-group' pk=system_user.id %}"
class=
"text-center"
>
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Associate asset groups' %}
</a>
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Associate assets and asset groups' %}
</a>
</li>
</ul>
</div>
...
...
@@ -30,7 +27,7 @@
<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
list of ' %}
<b>
{{ admin_user.name }}
</b
></span>
<span
style=
"float: left"
>
{% trans 'Asset
s attached of ' %}
<b>
{{ system_user.name }}
</b><span
class=
"badge"
>
{{ paginator.count }}
</span
></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
...
...
@@ -52,7 +49,8 @@
<th>
{% trans 'Hostname' %}
</th>
<th>
{% trans 'IP' %}
</th>
<th>
{% trans 'Port' %}
</th>
<th>
{% trans 'Alive' %}
</th>
<th>
{% trans 'Reachable' %}
</th>
<th></th>
</tr>
</thead>
<tbody>
...
...
@@ -61,7 +59,12 @@
<td>
{{ asset.hostname }}
</td>
<td>
{{ asset.ip }}
</td>
<td>
{{ asset.port }}
</td>
<td>
Alive
</td>
<td>
<i
class=
"fa fa-check text-navy"
></i>
</td>
<td>
<button
class=
"btn btn-danger pull-right btn-xs {% if asset.is_inherit_from_asset_groups %} disabled {% endif %}"
type=
"button"
><i
class=
"fa fa-minus"
></i></button>
</td>
</tr>
{% endfor %}
</tbody>
...
...
@@ -75,7 +78,7 @@
<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 'A
dd asset to this system user
' %}
<i
class=
"fa fa-info-circle"
></i>
{% trans 'A
ttach to assets
' %}
</div>
<div
class=
"panel-body"
>
<table
class=
"table"
>
...
...
@@ -84,7 +87,7 @@
<tr
class=
"no-borders-tr"
>
<td
colspan=
"2"
>
<select
data-placeholder=
"{% trans 'Select asset' %}"
class=
"select2"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
>
{% for asset in assets %}
{% for asset in assets
_remain
%}
<option
value=
"{{ asset.id }}"
>
{{ asset.ip}}:{{ asset.port }}
</option>
{% endfor %}
</select>
...
...
@@ -92,7 +95,7 @@
</tr>
<tr
class=
"no-borders-tr"
>
<td
colspan=
"2"
>
<button
type=
"button"
class=
"btn btn-primary btn-sm"
>
{% trans 'A
dd
' %}
</button>
<button
type=
"button"
class=
"btn btn-primary btn-sm"
>
{% trans 'A
ttach
' %}
</button>
</td>
</tr>
</form>
...
...
@@ -100,6 +103,43 @@
</table>
</div>
</div>
<div
class=
"panel panel-info"
>
<div
class=
"panel-heading"
>
<i
class=
"fa fa-info-circle"
></i>
{% trans 'Attach to asset groups' %}
</div>
<div
class=
"panel-body"
>
<table
class=
"table group_edit"
>
<tbody>
<form>
<tr>
<td
colspan=
"2"
class=
"no-borders"
>
<select
data-placeholder=
"{% trans 'Add asset group' %}"
class=
"select2"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
>
{% for asset_group in asset_groups_remain %}
<option
value=
"{{ asset_group.id }}"
>
{{ asset_group.name }}
</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td
colspan=
"2"
class=
"no-borders"
>
<button
type=
"button"
class=
"btn btn-info btn-sm"
id=
"btn_add_user_group"
>
{% trans 'Attach' %}
</button>
</td>
</tr>
</form>
{% for asset_group in asset_groups %}
<tr>
<td
><b
data-gid=
{{
asset_group
.
id
}}
>
{{ asset_group.name }}
</b></td>
<td>
<button
class=
"btn btn-danger pull-right btn-xs"
type=
"button"
><i
class=
"fa fa-minus"
></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
...
...
apps/assets/templates/assets/system_user_detail.html
View file @
7fd224e6
...
...
@@ -20,13 +20,9 @@
</li>
<li>
<a
href=
"{% url 'assets:system-user-asset' pk=system_user.id %}"
class=
"text-center"
>
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Associate assets' %}
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Associate assets
and asset groups
' %}
</a>
</li>
<li>
<a
href=
"{% url 'assets:system-user-asset-group' pk=system_user.id %}"
class=
"text-center"
>
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Associate asset groups' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
apps/assets/templates/assets/system_user_list.html
View file @
7fd224e6
...
...
@@ -11,7 +11,7 @@
<th
class=
"text-center"
><a
href=
"{% url 'assets:system-user-list' %}?sort=username"
>
{% trans 'Username' %}
</a></th>
<th
class=
"text-center"
>
{% trans 'Asset num' %}
</th>
<th
class=
"text-center"
>
{% trans 'Asset group num' %}
</th>
<th
class=
"text-center"
>
{% trans 'Un
avail
able' %}
</th>
<th
class=
"text-center"
>
{% trans 'Un
reach
able' %}
</th>
<th
class=
"text-center"
>
{% trans 'Comment' %}
</th>
<th
class=
"text-center"
></th>
{% endblock %}
...
...
@@ -26,7 +26,7 @@
</a>
</td>
<td
class=
"text-center"
>
{{ system_user.username }}
</td>
<td
class=
"text-center"
>
{{ system_user.
assets.count
}}
</td>
<td
class=
"text-center"
>
{{ system_user.
get_assets|length
}}
</td>
<td
class=
"text-center"
>
{{ system_user.asset_groups.count }}
</td>
<td
class=
"text-center"
>
{{ system_user.assets.count }}
</td>
<td
class=
"text-center"
>
{{ system_user.comment|truncatewords:4 }}
</td>
...
...
apps/assets/urls.py
View file @
7fd224e6
...
...
@@ -48,7 +48,7 @@ urlpatterns = [
url
(
r'^system-user/(?P<pk>[0-9]+)/update'
,
views
.
SystemUserUpdateView
.
as_view
(),
name
=
'system-user-update'
),
url
(
r'^system-user/(?P<pk>[0-9]+)/delete$'
,
views
.
SystemUserDeleteView
.
as_view
(),
name
=
'system-user-delete'
),
url
(
r'^system-user/(?P<pk>[0-9]+)/asset$'
,
views
.
SystemUserAssetView
.
as_view
(),
name
=
'system-user-asset'
),
url
(
r'^system-user/(?P<pk>[0-9]+)/asset-group$'
,
views
.
SystemUserAssetGroupView
.
as_view
(),
name
=
'system-user-asset-group'
),
#
url(r'^system-user/(?P<pk>[0-9]+)/asset-group$', views.SystemUserAssetGroupView.as_view(),
#
name='system-user-asset-group'),
# url(r'^api/v1.0/', include(router.urls)),
]
apps/assets/views.py
View file @
7fd224e6
...
...
@@ -368,14 +368,13 @@ class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVi
self
.
object
.
name
,
))
return
s
elf
.
s
uccess_message
return
success_message
class
SystemUserUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
SystemUser
form_class
=
SystemUserForm
template_name
=
'assets/system_user_create_update.html'
success_message
=
_
(
'Update system user <a href="
%
s">
%
s</a> successfully.'
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
...
...
@@ -386,7 +385,7 @@ class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView):
return
super
(
SystemUserUpdateView
,
self
)
.
get_context_data
(
**
kwargs
)
def
get_success_url
(
self
):
success_url
=
reverse_lazy
(
'assets:system-user-detail'
,
pk
=
self
.
object
.
pk
)
success_url
=
reverse_lazy
(
'assets:system-user-detail'
,
kwargs
=
{
'pk'
:
self
.
object
.
pk
}
)
return
success_url
...
...
@@ -419,39 +418,47 @@ class SystemUserAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
self
.
object
=
self
.
get_object
(
queryset
=
SystemUser
.
objects
.
all
())
return
super
(
SystemUserAssetView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_asset_groups
(
self
):
return
self
.
object
.
asset_groups
.
all
()
# Todo: queryset default order by connectivity, need ops support
def
get_queryset
(
self
):
return
self
.
object
.
assets
.
all
(
)
return
list
(
self
.
object
.
get_assets
()
)
def
get_context_data
(
self
,
**
kwargs
):
asset_groups
=
self
.
get_asset_groups
()
assets
=
self
.
get_queryset
()
context
=
{
'app'
:
'assets'
,
'action'
:
'System user asset'
,
'assets'
:
self
.
get_queryset
(),
'assets_remain'
:
[
asset
for
asset
in
Asset
.
objects
.
all
()
if
asset
not
in
assets
],
'asset_groups'
:
asset_groups
,
'asset_groups_remain'
:
[
asset_group
for
asset_group
in
AssetGroup
.
objects
.
all
()
if
asset_group
not
in
asset_groups
]
}
kwargs
.
update
(
context
)
return
super
(
SystemUserAssetView
,
self
)
.
get_context_data
(
**
kwargs
)
class
SystemUserAssetGroupView
(
AdminUserRequiredMixin
,
SingleObjectMixin
,
ListView
):
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
template_name
=
'assets/system_user_asset_group.html'
context_object_name
=
'system_user'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
(
queryset
=
SystemUser
.
objects
.
all
())
return
super
(
SystemUserAssetGroupView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
#
class SystemUserAssetGroupView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
#
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
#
template_name = 'assets/system_user_asset_group.html'
#
context_object_name = 'system_user'
#
#
def get(self, request, *args, **kwargs):
#
self.object = self.get_object(queryset=SystemUser.objects.all())
#
return super(SystemUserAssetGroupView, self).get(request, *args, **kwargs)
#
# Todo: queryset default order by connectivity, need ops support
def
get_queryset
(
self
):
return
self
.
object
.
asset_groups
.
all
()
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'assets'
,
'action'
:
'System user asset group'
,
'asset_groups'
:
self
.
get_queryset
(),
}
kwargs
.
update
(
context
)
return
super
(
SystemUserAssetGroupView
,
self
)
.
get_context_data
(
**
kwargs
)
#
def get_queryset(self):
#
return self.object.asset_groups.all()
#
#
def get_context_data(self, **kwargs):
#
context = {
#
'app': 'assets',
#
'action': 'System user asset group',
#
'asset_groups': self.get_queryset(),
#
}
#
kwargs.update(context)
#
return super(SystemUserAssetGroupView, self).get_context_data(**kwargs)
apps/common/templatetags/common_tags.py
View file @
7fd224e6
...
...
@@ -32,4 +32,14 @@ def pagination_range(total_page, current_num=1, display=5):
start
=
current_num
-
display
/
2
if
current_num
>
display
/
2
else
1
end
=
start
+
display
if
start
+
display
<=
total_page
else
total_page
+
1
return
range
(
start
,
end
)
\ No newline at end of file
return
range
(
start
,
end
)
@register.filter
def
join_attr
(
seq
,
attr
=
None
,
sep
=
None
):
if
sep
is
None
:
sep
=
', '
if
attr
is
not
None
:
seq
=
[
getattr
(
obj
,
attr
)
for
obj
in
seq
]
print
(
seq
)
return
sep
.
join
(
seq
)
apps/perms/forms.py
View file @
7fd224e6
...
...
@@ -14,7 +14,7 @@ class AssetPermissionForm(forms.ModelForm):
model
=
AssetPermission
fields
=
[
'name'
,
'users'
,
'user_groups'
,
'assets'
,
'asset_groups'
,
'system_users'
,
'
action'
,
'
is_active'
,
'date_expired'
,
'comment'
,
'system_users'
,
'is_active'
,
'date_expired'
,
'comment'
,
]
widgets
=
{
'users'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
...
...
apps/perms/models.py
View file @
7fd224e6
...
...
@@ -11,18 +11,19 @@ from common.utils import date_expired_default, combine_seq
class
AssetPermission
(
models
.
Model
):
ACTION_CHOICE
=
(
(
'1'
,
'Allow'
),
(
'0'
,
'Deny'
),
PRIVATE_FOR_CHOICE
=
(
(
'N'
,
'None'
),
(
'U'
,
'user'
),
(
'G'
,
'user group'
),
)
name
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Name'
))
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'
)
action
=
models
.
CharField
(
choices
=
ACTION_CHOICE
,
max_length
=
8
,
default
=
'1'
)
private_for
=
models
.
CharField
(
choices
=
PRIVATE_FOR_CHOICE
,
max_length
=
1
,
default
=
'N'
,
blank
=
True
,
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'
))
...
...
@@ -30,7 +31,7 @@ class AssetPermission(models.Model):
comment
=
models
.
TextField
(
verbose_name
=
_
(
'Comment'
),
blank
=
True
)
def
__unicode__
(
self
):
return
'
%(name)
s:
%(action)
s'
%
{
'name'
:
self
.
name
,
'action'
:
self
.
action
}
return
self
.
name
@property
def
is_valid
(
self
):
...
...
@@ -38,32 +39,31 @@ class AssetPermission(models.Model):
return
True
return
True
@staticmethod
def
set_inherit
(
obj
):
setattr
(
obj
,
'inherited'
,
True
)
return
obj
def
get_granted_users
(
self
):
return
list
(
set
(
self
.
users
.
all
()
or
[])
|
set
(
self
.
get_granted_user_groups_member
()
))
return
list
(
set
(
self
.
users
.
all
()
)
|
self
.
get_granted_user_groups_member
(
))
def
get_granted_user_groups_member
(
self
):
combine_users
=
functools
.
partial
(
combine_seq
,
callback
=
AssetPermission
.
set_inherit
)
try
:
return
functools
.
reduce
(
combine_users
,
[
user_group
.
users
.
all
()
for
user_group
in
self
.
user_groups
.
iterator
()])
except
TypeError
:
return
[]
users
=
set
()
for
user_group
in
self
.
user_groups
.
all
():
for
user
in
user_group
.
users
.
all
():
setattr
(
user
,
'is_inherit_from_user_groups'
,
True
)
setattr
(
user
,
'inherit_from_user_groups'
,
getattr
(
user
,
b
'inherit_from_user_groups'
,
set
())
.
add
(
user_group
))
users
.
add
(
user
)
return
users
def
get_granted_assets
(
self
):
return
list
(
set
(
self
.
assets
.
all
()
or
[])
|
set
(
self
.
get_granted_asset_groups_member
()
))
return
list
(
set
(
self
.
assets
.
all
()
)
|
self
.
get_granted_asset_groups_member
(
))
def
get_granted_asset_groups_member
(
self
):
combine_assets
=
functools
.
partial
(
combine_seq
,
callback
=
AssetPermission
.
set_inherit
)
try
:
return
functools
.
reduce
(
combine_assets
,
[
asset_group
.
users
.
all
()
for
asset_group
in
self
.
asset_groups
.
iterator
()])
except
TypeError
:
return
[]
assets
=
set
()
for
asset_group
in
self
.
asset_groups
.
all
():
for
asset
in
asset_group
.
assets
.
all
():
setattr
(
asset
,
'is_inherit_from_asset_groups'
,
True
)
setattr
(
asset
,
'inherit_from_asset_groups'
,
getattr
(
asset
,
b
'inherit_from_user_groups'
,
set
())
.
add
(
asset_group
))
assets
.
add
(
asset
)
return
assets
class
Meta
:
db_table
=
'asset_permission'
...
...
apps/perms/templates/perms/asset_permission_asset
_list
.html
→
apps/perms/templates/perms/asset_permission_asset.html
View file @
7fd224e6
...
...
@@ -26,7 +26,7 @@
</li>
<li
class=
"active"
>
<a
href=
"{% url 'perms:asset-permission-asset-list' pk=asset_permission.id %}"
class=
"text-center"
>
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Assets and asset gr
uo
ps' %}
</a>
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Assets and asset gr
ou
ps' %}
</a>
</li>
<form
id=
"search_form"
method=
"get"
action=
""
class=
"pull-right mail-search"
>
<div
class=
"input-group"
>
...
...
@@ -85,7 +85,7 @@
</td>
<td>
<button
class=
"btn btn-danger btn-xs btn_delete_user_group
"
type=
"button"
style=
"float: right;"
><i
class=
"fa fa-minus"
></i></button>
<button
title=
"{{ asset.inherit_from_asset_groups }}"
class=
"btn btn-danger btn-xs {% if asset.is_inherit_from_asset_groups %} disabled {% endif %}
"
type=
"button"
style=
"float: right;"
><i
class=
"fa fa-minus"
></i></button>
</td>
</tr>
{% endfor %}
...
...
apps/perms/templates/perms/asset_permission_create_update.html
View file @
7fd224e6
...
...
@@ -43,8 +43,6 @@
{{ form.system_users |bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Other' %}
</h3>
{{ form.action|bootstrap_horizontal }}
<div
class=
"form-group"
>
<label
for=
"{{ form.is_active.id_for_label }}"
class=
"col-sm-2 control-label"
>
{% trans 'Active' %}
</label>
<div
class=
"col-sm-8"
>
...
...
apps/perms/templates/perms/asset_permission_detail.html
View file @
7fd224e6
...
...
@@ -26,7 +26,7 @@
</li>
<li>
<a
href=
"{% url 'perms:asset-permission-asset-list' pk=asset_permission.id %}"
class=
"text-center"
>
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Assets and asset gr
uo
ps' %}
</a>
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Assets and asset gr
ou
ps' %}
</a>
</li>
</ul>
</div>
...
...
@@ -76,14 +76,6 @@
<td>
{% trans 'System user count' %}:
</td>
<td><b>
{{ asset_permission.system_users.count }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Action' %}:
</td>
<td><b>
{{ asset_permission.get_action_display }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Is active' %}:
</td>
<td><b>
{{ asset_permission.is_active|yesno:'Yes, No, Unkown' }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Date expired' %}:
</td>
<td><b>
{{ asset_permission.date_expired }}
</b></td>
...
...
apps/perms/templates/perms/asset_permission_user
_list
.html
→
apps/perms/templates/perms/asset_permission_user.html
View file @
7fd224e6
...
...
@@ -26,7 +26,7 @@
</li>
<li>
<a
href=
"{% url 'perms:asset-permission-asset-list' pk=asset_permission.id %}"
class=
"text-center"
>
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Assets and asset gr
uo
ps' %}
</a>
<i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Assets and asset gr
ou
ps' %}
</a>
</li>
<form
id=
"search_form"
method=
"get"
action=
""
class=
"pull-right mail-search"
>
<div
class=
"input-group"
>
...
...
@@ -85,7 +85,7 @@
</td>
<td>
<button
class=
"btn btn-danger btn-xs btn_delete_user_group {% if user.i
nherited
%} disabled {% endif %}"
type=
"button"
style=
"float: right;"
><i
class=
"fa fa-minus"
></i></button>
<button
class=
"btn btn-danger btn-xs btn_delete_user_group {% if user.i
s_inherit_from_user_groups
%} disabled {% endif %}"
type=
"button"
style=
"float: right;"
><i
class=
"fa fa-minus"
></i></button>
</td>
</tr>
{% endfor %}
...
...
apps/perms/templates/perms/perm_user_asset_list.html
deleted
100644 → 0
View file @
343f1399
{% extends '_list_base.html' %}
{% load i18n %}
{% load common_tags %}
{% block content_left_head %}
<a
href=
"{% url 'users:user-create' %}"
class=
"btn btn-sm btn-primary "
>
{% trans "Create perm " %}
</a>
{% endblock %}
{% block table_head %}
<th
class=
"text-center"
>
<input
type=
"checkbox"
id=
"check_all"
onclick=
"checkAll('check_all', 'checked')"
>
</th>
<th
class=
"text-center"
><a
href=
"{% url 'users:user-list' %}?sort=name"
>
{% trans 'Name' %}
</a></th>
<th
class=
"text-center"
><a
href=
"{% url 'users:user-list' %}?sort=username"
>
{% trans 'Username' %}
</a></th>
<th
class=
"text-center"
>
{% trans 'Role' %}
</th>
<th
class=
"text-center"
>
{% trans 'Asset num' %}
</th>
<th
class=
"text-center"
>
{% trans 'Asset group' %}
</th>
<th
class=
"text-center"
>
{% trans 'System user' %}
</th>
<th
class=
"text-center"
><a
href=
"{% url 'users:user-list' %}?sort=date_expired"
>
{% trans 'Active' %}
</a></th>
<th
class=
"text-center"
></th>
{% endblock %}
{% block table_body %}
{% for perm in page_obj %}
<tr
class=
"gradeX"
>
<td
class=
"text-center"
>
<input
type=
"checkbox"
name=
"checked"
value=
"{{ user.id }}"
>
</td>
<td
class=
"text-center"
>
<a
href=
"{% url 'users:user-detail' pk=user.id %}"
>
{{ user.name }}
</a>
</td>
<td
class=
"text-center"
>
{{ user.username }}
</td>
<td
class=
"text-center"
>
{{ user.get_role_display }}
</td>
<th
class=
"text-center"
>
35/40
</th>
<th
class=
"text-center"
>
20
</th>
<th
class=
"text-center"
>
3
</th>
<td
class=
"text-center"
>
<a
href=
"{% url 'perms:perm-user-asset-create' pk=user.id %}"
class=
"btn btn-xs btn-info"
>
{% trans 'Create perm' %}
</a>
<a
href=
"{% url 'users:user-delete' pk=user.id %}"
class=
"btn btn-xs btn-danger del {% if user.id == request.user.id or user.username == 'admin' %} disabled {% endif %}"
>
{% trans 'Flush' %}
</a>
</td>
</tr>
{% endfor %}
{% endblock %}
{% block content_bottom_left %}
<form
id=
""
method=
"get"
action=
""
class=
" mail-search"
>
<div
class=
"input-group"
>
<select
class=
"form-control m-b"
style=
"width: auto"
>
<option>
{% trans 'Delete selected' %}
</option>
<option>
{% trans 'Update selected' %}
</option>
<option>
{% trans 'Deactive selected' %}
</option>
<option>
{% trans 'Export selected' %}
</option>
</select>
<div
class=
"input-group-btn pull-left"
style=
"padding-left: 5px;"
>
<button
id=
'search_btn'
type=
"submit"
style=
"height: 32px;"
class=
"btn btn-sm btn-primary"
>
{% trans 'Submit' %}
</button>
</div>
</div>
</form>
{% endblock %}
apps/perms/urls.py
View file @
7fd224e6
...
...
@@ -14,9 +14,9 @@ urlpatterns = [
name
=
'asset-permission-detail'
),
url
(
r'^asset-permission/(?P<pk>[0-9]+)/delete$'
,
views
.
AssetPermissionDeleteView
.
as_view
(),
name
=
'asset-permission-delete'
),
url
(
r'^asset-permission/(?P<pk>[0-9]+)/user$'
,
views
.
AssetPermissionUser
List
View
.
as_view
(),
url
(
r'^asset-permission/(?P<pk>[0-9]+)/user$'
,
views
.
AssetPermissionUserView
.
as_view
(),
name
=
'asset-permission-user-list'
),
url
(
r'^asset-permission/(?P<pk>[0-9]+)/asset$'
,
views
.
AssetPermissionAsset
List
View
.
as_view
(),
url
(
r'^asset-permission/(?P<pk>[0-9]+)/asset$'
,
views
.
AssetPermissionAssetView
.
as_view
(),
name
=
'asset-permission-asset-list'
),
]
apps/perms/utils.py
View file @
7fd224e6
# ~*~ coding: utf-8 ~*~
#
from
__future__
import
absolute_import
,
unicode_literals
from
.hands
import
User
,
UserGroup
,
Asset
,
AssetGroup
,
SystemUser
def
get_user_group_granted_asset_groups
(
user_group
):
"""Return asset groups granted of the user group
:param user_group: Instance of :class: ``UserGroup``
:return: {asset1: {system_user1, }, asset1: {system_user1, system_user2]}
"""
asset_groups
=
{}
asset_permissions
=
user_group
.
asset_permissions
.
all
()
for
asset_permission
in
asset_permissions
:
if
not
asset_permission
.
is_valid
:
continue
for
asset_group
in
asset_permission
.
asset_groups
.
all
():
if
asset_group
in
asset_groups
:
asset_groups
[
asset_group
]
|=
set
(
asset_permission
.
system_users
.
all
())
else
:
asset_groups
[
asset_group
]
=
set
(
asset_permission
.
system_users
.
all
())
return
asset_groups
def
get_user_group_granted_assets
(
user_group
):
"""Return assets granted of the user group
:param user_group: Instance of :class: ``UserGroup``
:return: {asset1: {system_user1, }, asset1: {system_user1, system_user2]}
"""
assets
=
{}
asset_permissions
=
user_group
.
asset_permissions
.
all
()
for
asset_permission
in
asset_permissions
:
if
not
asset_permission
.
is_valid
:
continue
for
asset
in
asset_permission
.
get_granted_assets
():
if
asset
in
assets
:
assets
[
asset
]
|=
set
(
asset_permission
.
system_users
.
all
())
else
:
assets
[
asset
]
=
set
(
asset_permission
.
system_users
.
all
())
return
assets
def
get_user_granted_asset_groups_direct
(
user
):
"""Return asset groups granted of the user direct nor inherit from user group
:param user: Instance of :class: ``User``
:return: {asset_group: {system_user1, }, asset_group2: {system_user1, system_user2]}
"""
asset_groups
=
{}
asset_permissions_direct
=
user
.
asset_permissions
.
all
()
for
asset_permission
in
asset_permissions_direct
:
if
not
asset_permission
.
is_valid
:
continue
for
asset_group
in
asset_permission
.
asset_groups
.
all
():
if
asset_group
in
asset_groups
:
asset_groups
[
asset_group
]
|=
set
(
asset_permission
.
system_users
.
all
())
else
:
setattr
(
asset_group
,
'is_inherit_from_user_group'
,
False
)
asset_groups
[
asset_group
]
=
set
(
asset_permission
.
system_users
.
all
())
return
asset_groups
def
get_user_granted_asset_groups_inherit_from_user_groups
(
user
):
"""Return asset groups granted of the user and inherit from user group
:param user: Instance of :class: ``User``
:return: {asset_group: {system_user1, }, asset_group2: {system_user1, system_user2]}
"""
asset_groups
=
{}
user_groups
=
user
.
groups
.
all
()
asset_permissions
=
set
()
# Get asset permission list of user groups for this user
for
user_group
in
user_groups
:
asset_permissions
|=
set
(
user_group
.
asset_permissions
.
all
())
# Get asset groups granted from user groups
for
asset_permission
in
asset_permissions
:
if
not
asset_permission
.
is_valid
:
continue
for
asset_group
in
asset_permission
.
asset_groups
.
all
():
if
asset_group
in
asset_groups
:
asset_groups
[
asset_group
]
|=
set
(
asset_permission
.
system_users
.
all
())
else
:
setattr
(
asset_group
,
'is_inherit_from_user_group'
,
True
)
asset_groups
[
asset_group
]
=
set
(
asset_permission
.
system_users
.
all
())
return
asset_groups
def
get_user_granted_asset_groups
(
user
):
"""Get user granted asset groups all, include direct and inherit from user group
:param user: Instance of :class: ``User``
:return: {asset1: {system_user1, system_user2}, asset2: {...}}
"""
asset_groups_inherit_from_user_groups
=
get_user_granted_asset_groups_inherit_from_user_groups
(
user
)
asset_groups_direct
=
get_user_granted_asset_groups_direct
(
user
)
asset_groups
=
asset_groups_inherit_from_user_groups
# Merge direct granted and inherit from user group
for
asset_group
,
system_users
in
asset_groups_direct
.
items
():
if
asset_group
in
asset_groups
:
asset_groups
[
asset_group
]
|=
asset_groups_direct
[
asset_group
]
else
:
asset_groups
[
asset_group
]
=
asset_groups_direct
[
asset_group
]
return
asset_groups
def
get_user_granted_assets_direct
(
user
):
"""Return assets granted of the user directly
:param user: Instance of :class: ``User``
:return: {asset1: {system_user1, system_user2}, asset2: {...}}
"""
assets
=
{}
asset_permissions_direct
=
user
.
asset_permissions
.
all
()
for
asset_permission
in
asset_permissions_direct
:
if
not
asset_permission
.
is_valid
:
continue
for
asset
in
asset_permission
.
get_granted_assets
():
if
asset
in
assets
:
assets
[
asset
]
|=
set
(
asset_permission
.
system_users
.
all
())
else
:
setattr
(
asset
,
'is_inherit_from_user_groups'
,
False
)
setattr
(
asset
,
'is_inherit_from_user_groups'
,
False
)
assets
[
asset
]
=
set
(
asset_permission
.
system_users
.
all
())
return
assets
def
get_user_granted_assets_inherit_from_user_groups
(
user
):
"""Return assets granted of the user inherit from user groups
:param user: Instance of :class: ``User``
:return: {asset1: {system_user1, system_user2}, asset2: {...}}
"""
assets
=
{}
user_groups
=
user
.
groups
.
all
()
for
user_group
in
user_groups
:
assets_inherited
=
get_user_group_granted_assets
(
user_group
)
for
asset
in
assets_inherited
:
if
asset
in
assets
:
assets
[
asset
]
|=
assets_inherited
[
asset
]
else
:
setattr
(
asset
,
'is_inherit_from_user_groups'
,
True
)
assets
[
asset
]
=
assets_inherited
[
asset
]
return
assets
def
get_user_granted_assets
(
user
):
"""Return assets granted of the user inherit from user groups
:param user: Instance of :class: ``User``
:return: {asset1: {system_user1, system_user2}, asset2: {...}}
"""
assets_direct
=
get_user_granted_assets_direct
(
user
)
assets_inherited
=
get_user_granted_assets_inherit_from_user_groups
(
user
)
assets
=
assets_inherited
for
asset
in
assets_direct
:
if
asset
in
assets
:
assets
[
asset
]
|=
assets_direct
[
asset
]
else
:
assets
[
asset
]
=
assets_direct
[
asset
]
return
assets
def
get_user_groups_granted_in_asset
(
asset
):
pass
def
get_users_granted_in_asset
(
asset
):
pass
def
get_user_groups_granted_in_asset_group
(
asset
):
pass
def
get_users_granted_in_asset_group
(
asset
):
pass
apps/perms/views.py
View file @
7fd224e6
...
...
@@ -120,15 +120,15 @@ class AssetPermissionDeleteView(AdminUserRequiredMixin, DeleteView):
success_url
=
reverse_lazy
(
'perms:asset-permission-list'
)
class
AssetPermissionUser
List
View
(
AdminUserRequiredMixin
,
SingleObjectMixin
,
ListView
):
template_name
=
'perms/asset_permission_user
_list
.html'
class
AssetPermissionUserView
(
AdminUserRequiredMixin
,
SingleObjectMixin
,
ListView
):
template_name
=
'perms/asset_permission_user.html'
context_object_name
=
'asset_permission'
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
(
queryset
=
AssetPermission
.
objects
.
all
())
self
.
keyword
=
self
.
request
.
GET
.
get
(
'keyword'
,
''
)
return
super
(
AssetPermissionUser
List
View
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
return
super
(
AssetPermissionUserView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_queryset
(
self
):
queryset
=
self
.
object
.
get_granted_users
()
...
...
@@ -152,18 +152,18 @@ class AssetPermissionUserListView(AdminUserRequiredMixin, SingleObjectMixin, Lis
'keyword'
:
self
.
keyword
,
}
kwargs
.
update
(
context
)
return
super
(
AssetPermissionUser
List
View
,
self
)
.
get_context_data
(
**
kwargs
)
return
super
(
AssetPermissionUserView
,
self
)
.
get_context_data
(
**
kwargs
)
class
AssetPermissionAsset
List
View
(
AdminUserRequiredMixin
,
SingleObjectMixin
,
ListView
):
template_name
=
'perms/asset_permission_asset
_list
.html'
class
AssetPermissionAssetView
(
AdminUserRequiredMixin
,
SingleObjectMixin
,
ListView
):
template_name
=
'perms/asset_permission_asset.html'
context_object_name
=
'asset_permission'
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
(
queryset
=
AssetPermission
.
objects
.
all
())
self
.
keyword
=
self
.
request
.
GET
.
get
(
'keyword'
,
''
)
return
super
(
AssetPermissionAsset
List
View
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
return
super
(
AssetPermissionAssetView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_queryset
(
self
):
queryset
=
self
.
object
.
get_granted_assets
()
...
...
@@ -187,4 +187,4 @@ class AssetPermissionAssetListView(AdminUserRequiredMixin, SingleObjectMixin, Li
'keyword'
:
self
.
keyword
,
}
kwargs
.
update
(
context
)
return
super
(
AssetPermissionAsset
List
View
,
self
)
.
get_context_data
(
**
kwargs
)
return
super
(
AssetPermissionAssetView
,
self
)
.
get_context_data
(
**
kwargs
)
apps/static/css/jumpserver.css
View file @
7fd224e6
...
...
@@ -77,3 +77,5 @@ th a {
.no-borders-tr
td
{
border-top
:
none
!important
;
}
apps/static/css/style.css
View file @
7fd224e6
/*
@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
...
...
apps/users/forms.py
View file @
7fd224e6
...
...
@@ -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'
}
...
...
@@ -98,3 +92,27 @@ class UserKeyForm(forms.Form):
print
e
raise
forms
.
ValidationError
(
_
(
'Not a valid ssh public key'
))
return
public_key
class
UserPrivateAssetPermissionForm
(
forms
.
ModelForm
):
def
save
(
self
,
commit
=
True
):
self
.
instance
=
super
(
UserPrivateAssetPermissionForm
,
self
)
.
save
(
commit
=
commit
)
self
.
instance
.
private_for
=
'U'
self
.
instance
.
users
=
[
self
.
user
]
self
.
instance
.
save
()
return
self
.
instance
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'
)}),
}
apps/users/hands.py
View file @
7fd224e6
...
...
@@ -10,5 +10,5 @@
:license: GPL v2, see LICENSE for more details.
"""
from
perms.models
import
AssetPermission
from
perms.utils
import
get_user_granted_assets
,
get_user_granted_asset_groups
apps/users/templates/users/user_asset_permission.html
0 → 100644
View file @
7fd224e6
This diff is collapsed.
Click to expand it.
apps/users/templates/users/user_detail.html
View file @
7fd224e6
...
...
@@ -17,10 +17,14 @@
<div
class=
"ibox float-e-margins"
>
<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>
<li
class=
"active"
>
<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 'User assets' %}
</a></li>
<li><a
href=
""
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'User log' %}
</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' %}
</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"
>
...
...
@@ -189,7 +193,7 @@
<tr>
<td
><b
class=
"bdg_user_group"
data-gid=
{{
group
.
id
}}
>
{{ group.name }}
</b></td>
<td>
<button
class=
"btn btn-danger pull-right btn-
sm
btn_delete_user_group"
type=
"button"
><i
class=
"fa fa-minus"
></i></button>
<button
class=
"btn btn-danger pull-right btn-
xs
btn_delete_user_group"
type=
"button"
><i
class=
"fa fa-minus"
></i></button>
</td>
</tr>
{% endfor %}
...
...
apps/users/templates/users/user_granted_asset.html
0 → 100644
View file @
7fd224e6
This diff is collapsed.
Click to expand it.
apps/users/urls.py
View file @
7fd224e6
...
...
@@ -16,6 +16,12 @@ 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-permission/create$'
,
views
.
UserAssetPermissionCreateView
.
as_view
(),
name
=
'user-asset-permission-create'
),
url
(
r'^user/(?P<pk>[0-9]+)/granted-asset'
,
views
.
UserGrantedAssetView
.
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'
),
...
...
apps/users/views.py
View file @
7fd224e6
...
...
@@ -18,16 +18,17 @@ 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
,
ModelFormMixin
,
ProcessFormView
,
BaseCreateView
from
django.views.generic.detail
import
DetailView
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
from
.hands
import
AssetPermission
,
get_user_granted_asset_groups
,
get_user_granted_assets
logger
=
get_logger
(
__name__
)
...
...
@@ -349,3 +350,93 @@ 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
):
form_class
=
UserPrivateAssetPermissionForm
model
=
AssetPermission
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
user_object
=
self
.
get_object
(
queryset
=
User
.
objects
.
all
())
return
redirect
(
reverse
(
'users:user-asset-permission'
,
kwargs
=
{
'pk'
:
user_object
.
id
}))
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
user_object
=
self
.
get_object
(
queryset
=
User
.
objects
.
all
())
return
super
(
UserAssetPermissionCreateView
,
self
)
.
post
(
request
,
*
args
,
**
kwargs
)
def
get_form
(
self
,
form_class
=
None
):
form
=
super
(
UserAssetPermissionCreateView
,
self
)
.
get_form
(
form_class
=
form_class
)
form
.
user
=
self
.
user_object
return
form
def
form_invalid
(
self
,
form
):
print
(
form
.
errors
)
return
redirect
(
reverse
(
'users:user-asset-permission'
,
kwargs
=
{
'pk'
:
self
.
user_object
.
id
}))
def
get_success_url
(
self
):
return
reverse
(
'users:user-asset-permission'
,
kwargs
=
{
'pk'
:
self
.
user_object
.
id
})
class
UserGrantedAssetView
(
AdminUserRequiredMixin
,
SingleObjectMixin
,
ListView
):
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
template_name
=
'users/user_granted_asset.html'
context_object_name
=
'user_object'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
(
queryset
=
User
.
objects
.
all
())
return
super
(
UserGrantedAssetView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_queryset
(
self
):
# Convert format from {'asset': ['system_users'], ..} to
# [('asset', ['system_users']), ('asset', ['system_users']))
assets_granted
=
[(
asset
,
system_users
)
for
asset
,
system_users
in
get_user_granted_assets
(
self
.
object
)
.
items
()]
return
assets_granted
def
get_context_data
(
self
,
**
kwargs
):
asset_groups
=
[(
asset_group
,
system_users
)
for
asset_group
,
system_users
in
get_user_granted_asset_groups
(
self
.
object
)
.
items
()]
context
=
{
'app'
:
'User'
,
'action'
:
'User granted asset'
,
'asset_groups'
:
asset_groups
,
}
kwargs
.
update
(
context
)
return
super
(
UserGrantedAssetView
,
self
)
.
get_context_data
(
**
kwargs
)
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