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
69f2bf66
Commit
69f2bf66
authored
Nov 10, 2016
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finish user permission revoke
parent
dde9ffb2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
186 additions
and
140 deletions
+186
-140
admin_user_list.html
apps/assets/templates/assets/admin_user_list.html
+1
-1
utils.py
apps/common/utils.py
+8
-0
api.py
apps/perms/api.py
+36
-4
serializers.py
apps/perms/serializers.py
+16
-24
urls.py
apps/perms/urls.py
+4
-4
utils.py
apps/perms/utils.py
+18
-4
jumpserver.js
apps/static/js/jumpserver.js
+6
-7
forms.py
apps/users/forms.py
+2
-2
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
+0
-1
user_list.html
apps/users/templates/users/user_list.html
+1
-1
urls.py
apps/users/urls.py
+3
-3
utils.py
apps/users/utils.py
+54
-54
views.py
apps/users/views.py
+35
-33
No files found.
apps/assets/templates/assets/admin_user_list.html
View file @
69f2bf66
...
...
@@ -32,7 +32,7 @@ $(document).ready(function(){
ele
:
$
(
'#admin_user_list_table'
),
columnDefs
:
[
{
targets
:
1
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
detail_btn
=
'<a href="{% url "assets:a
pi-a
dmin-user-detail" pk=99991937 %}">'
+
cellData
+
'</a>'
;
var
detail_btn
=
'<a href="{% url "assets:admin-user-detail" pk=99991937 %}">'
+
cellData
+
'</a>'
;
$
(
td
).
html
(
detail_btn
.
replace
(
'99991937'
,
rowData
.
id
));
}},
{
targets
:
5
,
createdCell
:
function
(
td
,
cellData
)
{
...
...
apps/common/utils.py
View file @
69f2bf66
...
...
@@ -248,4 +248,11 @@ def validate_ssh_public_key(text):
return
True
def
setattr_bulk
(
seq
,
key
,
value
):
def
set_attr
(
obj
):
setattr
(
obj
,
key
,
value
)
return
obj
return
map
(
set_attr
,
seq
)
signer
=
Signer
()
\ No newline at end of file
apps/perms/api.py
View file @
69f2bf66
...
...
@@ -5,8 +5,10 @@ from rest_framework.views import APIView, Response
from
rest_framework.generics
import
ListCreateAPIView
from
rest_framework
import
viewsets
from
users.backends
import
IsValidUser
,
IsSuperUser
from
.utils
import
get_user_granted_assets
,
get_user_granted_asset_groups
from
common.utils
import
get_object_or_none
from
.utils
import
get_user_granted_assets
,
get_user_granted_asset_groups
,
get_user_asset_permissions
from
.models
import
AssetPermission
from
.hands
import
User
from
.
import
serializers
...
...
@@ -18,11 +20,41 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
def
get_queryset
(
self
):
queryset
=
super
(
AssetPermissionViewSet
,
self
)
.
get_queryset
()
user_id
=
self
.
request
.
query_params
.
get
(
'user'
,
''
)
if
user_id
:
queryset
=
queryset
.
filter
(
users__id
=
user_id
)
if
user_id
and
user_id
.
isdigit
():
from
users.models
import
User
self
.
user_id
=
user_id
user
=
get_object_or_none
(
User
,
id
=
int
(
user_id
))
if
user
:
queryset
=
get_user_asset_permissions
(
user
)
print
(
queryset
)
return
queryset
def
get_serializer_class
(
self
):
if
getattr
(
self
,
'user_id'
,
''
):
return
serializers
.
UserAssetPermissionSerializer
return
serializers
.
AssetPermissionSerializer
class
RevokeUserAssetPermission
(
APIView
):
permission_classes
=
(
IsSuperUser
,)
def
put
(
self
,
request
,
*
args
,
**
kwargs
):
permission_id
=
str
(
request
.
data
.
get
(
'id'
,
''
))
user_id
=
str
(
request
.
data
.
get
(
'user_id'
,
''
))
if
permission_id
and
user_id
and
permission_id
.
isdigit
()
and
user_id
.
isdigit
():
permission_id
=
int
(
permission_id
)
user_id
=
int
(
user_id
)
asset_permission
=
get_object_or_none
(
AssetPermission
,
id
=
permission_id
)
user
=
get_object_or_none
(
User
,
id
=
user_id
)
print
(
asset_permission
)
print
(
user
)
if
asset_permission
and
user
:
asset_permission
.
users
.
remove
(
user
)
return
Response
({
'msg'
:
'success'
})
return
Response
({
'msg'
:
'failed'
},
status
=
404
)
class
UserAssetsApi
(
APIView
):
permission_classes
=
(
IsValidUser
,)
...
...
apps/perms/serializers.py
View file @
69f2bf66
# -*- coding: utf-8 -*-
#
from
rest_framework
import
serializers
from
django.utils.translation
import
ugettext_lazy
as
_
from
rest_framework
import
serializers
from
common.utils
import
get_object_or_none
from
.models
import
AssetPermission
from
.hands
import
User
class
AssetPermissionSerializer
(
serializers
.
ModelSerializer
):
# users_amount = serializers.SerializerMethodField()
# user_groups_amount = serializers.SerializerMethodField()
# assets_amount = serializers.SerializerMethodField()
# asset_groups_amount = serializers.SerializerMethodField()
class
Meta
:
model
=
AssetPermission
fields
=
[
'id'
,
'name'
,
'users'
,
'user_groups'
,
'assets'
,
'asset_groups'
,
'system_users'
,
'is_active'
,
'comment'
,
'date_expired'
]
# @staticmethod
# def get_users_amount(obj):
# return obj.users.count()
#
# @staticmethod
# def get_user_groups_amount(obj):
# return obj.user_groups.count()
#
# @staticmethod
# def get_assets_amount(obj):
# return obj.assets.count()
#
# @staticmethod
# def get_asset_groups_amount(obj):
# return obj.asset_groups.count()
class
UserAssetPermissionSerializer
(
AssetPermissionSerializer
):
is_inherited
=
serializers
.
SerializerMethodField
()
@staticmethod
def
get_is_inherited
(
obj
):
if
getattr
(
obj
,
'inherited'
,
''
):
return
True
else
:
return
False
apps/perms/urls.py
View file @
69f2bf66
...
...
@@ -26,10 +26,10 @@ router = routers.DefaultRouter()
router
.
register
(
'v1/asset-permissions'
,
api
.
AssetPermissionViewSet
,
'api-asset-permission'
)
urlpatterns
+=
[
url
(
r'^v1/user/assets/$'
,
api
.
UserAssetsApi
.
as_view
(),
name
=
'user-assets'
),
url
(
r'^v1/user/asset-groups/$'
,
api
.
UserAssetsGroupsApi
.
as_view
(
),
name
=
'user-asset-groups'
),
url
(
r'^v1/user/assets/$'
,
api
.
UserAssetsApi
.
as_view
(),
name
=
'user-assets'
),
url
(
r'^v1/asset-permissions/user/revoke/'
,
api
.
RevokeUserAssetPermission
.
as_view
(
),
name
=
'revoke-user-asset-permission'
),
url
(
r'^v1/user/asset-groups/$'
,
api
.
UserAssetsGroupsApi
.
as_view
(),
name
=
'user-asset-groups'
),
url
(
r'^v1/user/asset-groups/(?P<pk>[0-9]+)/assets/$'
,
api
.
UserAssetsGroupAssetsApi
.
as_view
(),
name
=
'user-asset-groups-assets'
),
]
...
...
apps/perms/utils.py
View file @
69f2bf66
from
__future__
import
absolute_import
,
unicode_literals
from
common.utils
import
setattr_bulk
from
.hands
import
User
,
UserGroup
,
Asset
,
AssetGroup
,
SystemUser
...
...
@@ -7,7 +8,7 @@ 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: {asset
1: {system_user1, }, asset1
: {system_user1, system_user2]}
:return: {asset
_group1: {system_user1, }, asset_group2
: {system_user1, system_user2]}
"""
asset_groups
=
{}
asset_permissions
=
user_group
.
asset_permissions
.
all
()
...
...
@@ -41,7 +42,6 @@ def get_user_group_granted_assets(user_group):
assets
[
asset
]
|=
set
(
asset_permission
.
system_users
.
all
())
else
:
assets
[
asset
]
=
set
(
asset_permission
.
system_users
.
all
())
return
assets
...
...
@@ -112,7 +112,6 @@ def get_user_granted_asset_groups(user):
asset_groups
[
asset_group
]
|=
asset_groups_direct
[
asset_group
]
else
:
asset_groups
[
asset_group
]
=
asset_groups_direct
[
asset_group
]
return
asset_groups
...
...
@@ -175,10 +174,25 @@ def get_user_granted_assets(user):
assets
[
asset
]
|=
assets_direct
[
asset
]
else
:
assets
[
asset
]
=
assets_direct
[
asset
]
return
assets
def
get_user_group_asset_permissions
(
user_group
):
permissions
=
user_group
.
asset_permissions
.
all
()
return
permissions
def
get_user_asset_permissions
(
user
):
user_group_permissions
=
set
()
direct_permissions
=
set
(
setattr_bulk
(
user
.
asset_permissions
.
all
(),
'inherited'
,
0
))
for
user_group
in
user
.
groups
.
all
():
permissions
=
get_user_group_asset_permissions
(
user_group
)
user_group_permissions
|=
set
(
permissions
)
user_group_permissions
=
set
(
setattr_bulk
(
user_group_permissions
,
'inherited'
,
1
))
return
direct_permissions
|
user_group_permissions
def
get_user_groups_granted_in_asset
(
asset
):
pass
...
...
apps/static/js/jumpserver.js
View file @
69f2bf66
...
...
@@ -198,19 +198,18 @@ function APIUpdateAttr(props) {
contentType
:
props
.
content_type
||
"application/json; charset=utf-8"
,
dataType
:
props
.
data_type
||
"json"
}).
done
(
function
(
data
,
textStatue
,
jqXHR
)
{
toastr
.
success
(
success_message
);
if
(
typeof
props
.
success
===
'function'
)
{
return
props
.
success
(
data
);
}
else
{
toastr
.
success
(
success_message
);
}
}
}).
fail
(
function
(
jqXHR
,
textStatue
,
errorThrown
)
{
toastr
.
error
(
fail_message
);
if
(
typeof
props
.
error
===
'function'
)
{
return
props
.
error
(
errorThrown
);
}
else
{
toastr
.
error
(
textStatue
);
}
}
});
return
true
;
//
return true;
}
// Sweet Alert for Delete
...
...
apps/users/forms.py
View file @
69f2bf66
...
...
@@ -6,8 +6,8 @@ from django.utils.translation import gettext_lazy as _
from
captcha.fields
import
CaptchaField
from
common.utils
import
validate_ssh_public_key
from
perms.models
import
AssetPermission
from
.models
import
User
,
UserGroup
from
.hands
import
AssetPermission
class
UserLoginForm
(
AuthenticationForm
):
...
...
@@ -101,7 +101,7 @@ class UserPrivateAssetPermissionForm(forms.ModelForm):
def
save
(
self
,
commit
=
True
):
self
.
instance
=
super
(
UserPrivateAssetPermissionForm
,
self
)
.
save
(
commit
=
commit
)
#
self.instance.private_for = 'U'
self
.
instance
.
private_for
=
'U'
self
.
instance
.
users
=
[
self
.
user
]
self
.
instance
.
save
()
return
self
.
instance
...
...
apps/users/hands.py
View file @
69f2bf66
...
...
@@ -11,5 +11,5 @@
"""
from
terminal.models
import
Terminal
from
perms.models
import
AssetPermission
from
perms.utils
import
get_user_granted_assets
,
get_user_granted_asset_groups
#
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
View file @
69f2bf66
This diff is collapsed.
Click to expand it.
apps/users/templates/users/user_detail.html
View file @
69f2bf66
...
...
@@ -313,7 +313,6 @@ $(document).ready(function() {
var
user_groups
=
$
(
'.bdg_user_group'
).
map
(
function
()
{
return
$
(
this
).
data
(
'gid'
);
}).
get
();
console
.
log
(
user_groups
);
updateUserGroups
(
user_groups
)
}).
on
(
'click'
,
'#btn_reset_password'
,
function
()
{
function
doReset
()
{
...
...
apps/users/templates/users/user_list.html
View file @
69f2bf66
...
...
@@ -53,7 +53,7 @@ $(document).ready(function(){
$
(
td
).
html
(
detail_btn
.
replace
(
'99991937'
,
rowData
.
id
));
}},
{
targets
:
4
,
createdCell
:
function
(
td
,
cellData
)
{
var
innerHtml
=
cellData
.
length
>
8
?
cellData
.
substring
(
0
,
8
)
+
'...'
:
cellData
;
var
innerHtml
=
cellData
.
length
>
20
?
cellData
.
substring
(
0
,
20
)
+
'...'
:
cellData
;
$
(
td
).
html
(
'<a href="javascript:void(0);" data-toggle="tooltip" title="'
+
cellData
+
'">'
+
innerHtml
+
'</a>'
);
}},
{
targets
:
6
,
createdCell
:
function
(
td
,
cellData
)
{
...
...
apps/users/urls.py
View file @
69f2bf66
...
...
@@ -19,13 +19,13 @@ urlpatterns = [
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]+)/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'^import/$'
,
views
.
BulkImportUserView
.
as_view
(),
name
=
'user-import'
),
url
(
r'^user/(?P<pk>[0-9]+)/assets-perm$'
,
views
.
UserDetailView
.
as_view
(),
name
=
'user-detail'
),
#
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'
),
url
(
r'^user/(?P<pk>[0-9]+)/update$'
,
views
.
UserUpdateView
.
as_view
(),
name
=
'user-update'
),
...
...
apps/users/utils.py
View file @
69f2bf66
...
...
@@ -120,60 +120,60 @@ def send_reset_ssh_key_mail(user):
send_mail_async
.
delay
(
subject
,
message
,
recipient_list
,
html_message
=
message
)
def
validate_ssh_pk
(
text
):
"""
Expects a SSH private key as string.
Returns a boolean and a error message.
If the text is parsed as private key successfully,
(True,'') is returned. Otherwise,
(False, <message describing the error>) is returned.
from https://github.com/githubnemo/SSH-private-key-validator/blob/master/validate.py
"""
if
not
text
:
return
False
,
'No text given'
startPattern
=
re
.
compile
(
"^-----BEGIN [A-Z]+ PRIVATE KEY-----"
)
optionPattern
=
re
.
compile
(
"^.+: .+"
)
contentPattern
=
re
.
compile
(
"^([a-zA-Z0-9+/]{64}|[a-zA-Z0-9+/]{1,64}[=]{0,2})$"
)
endPattern
=
re
.
compile
(
"^-----END [A-Z]+ PRIVATE KEY-----"
)
def
contentState
(
text
):
for
i
in
range
(
0
,
len
(
text
)):
line
=
text
[
i
]
if
endPattern
.
match
(
line
):
if
i
==
len
(
text
)
-
1
or
len
(
text
[
i
+
1
])
==
0
:
return
True
,
''
else
:
return
False
,
'At end but content coming'
elif
not
contentPattern
.
match
(
line
):
return
False
,
'Wrong string in content section'
return
False
,
'No content or missing end line'
def
optionState
(
text
):
for
i
in
range
(
0
,
len
(
text
)):
line
=
text
[
i
]
if
line
[
-
1
:]
==
'
\\
'
:
return
optionState
(
text
[
i
+
2
:])
if
not
optionPattern
.
match
(
line
):
return
contentState
(
text
[
i
+
1
:])
return
False
,
'Expected option, found nothing'
def
startState
(
text
):
if
len
(
text
)
==
0
or
not
startPattern
.
match
(
text
[
0
]):
return
False
,
'Header is wrong'
return
optionState
(
text
[
1
:])
return
startState
([
n
.
strip
()
for
n
in
text
.
splitlines
()])
#
def validate_ssh_pk(text):
#
"""
#
Expects a SSH private key as string.
#
Returns a boolean and a error message.
#
If the text is parsed as private key successfully,
#
(True,'') is returned. Otherwise,
#
(False, <message describing the error>) is returned.
#
#
from https://github.com/githubnemo/SSH-private-key-validator/blob/master/validate.py
#
#
"""
#
#
if not text:
#
return False, 'No text given'
#
#
startPattern = re.compile("^-----BEGIN [A-Z]+ PRIVATE KEY-----")
#
optionPattern = re.compile("^.+: .+")
#
contentPattern = re.compile("^([a-zA-Z0-9+/]{64}|[a-zA-Z0-9+/]{1,64}[=]{0,2})$")
#
endPattern = re.compile("^-----END [A-Z]+ PRIVATE KEY-----")
#
#
def contentState(text):
#
for i in range(0, len(text)):
#
line = text[i]
#
#
if endPattern.match(line):
#
if i == len(text) - 1 or len(text[i + 1]) == 0:
#
return True, ''
#
else:
#
return False, 'At end but content coming'
#
#
elif not contentPattern.match(line):
#
return False, 'Wrong string in content section'
#
#
return False, 'No content or missing end line'
#
#
def optionState(text):
#
for i in range(0, len(text)):
#
line = text[i]
#
#
if line[-1:] == '\\':
#
return optionState(text[i + 2:])
#
#
if not optionPattern.match(line):
#
return contentState(text[i + 1:])
#
#
return False, 'Expected option, found nothing'
#
def startState(text):
#
if len(text) == 0 or not startPattern.match(text[0]):
#
return False, 'Header is wrong'
#
return optionState(text[1:])
#
#
return startState([n.strip() for n in text.splitlines()])
#
def
check_user_valid
(
**
kwargs
):
password
=
kwargs
.
pop
(
'password'
,
None
)
...
...
apps/users/views.py
View file @
69f2bf66
...
...
@@ -21,14 +21,14 @@ from django.views.generic.list import ListView
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
from
common.mixins
import
JSONResponseMixin
from
common.utils
import
get_object_or_none
,
get_logger
from
perms.models
import
AssetPermission
from
.models
import
User
,
UserGroup
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
#
from .hands import AssetPermission, get_user_granted_asset_groups, get_user_granted_assets
from
.
import
forms
...
...
@@ -341,32 +341,33 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
return
form
class
UserAssetPermissionView
(
AdminUserRequiredMixin
,
FormMixin
,
SingleObjectMixin
,
List
View
):
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
class
UserAssetPermissionView
(
AdminUserRequiredMixin
,
Detail
View
):
model
=
User
template_name
=
'users/user_asset_permission.html'
context_object_name
=
'user_object'
form_class
=
forms
.
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
)
context_object_name
=
'user'
# form_class = forms.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
=
{
...
...
@@ -414,18 +415,19 @@ class UserGrantedAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
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
()]
#
assets_granted = [(asset, system_users) for asset, system_users in
#
get_user_granted_assets(self.object).items()]
return
assets_granted
# return assets_granted
return
[]
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
()]
#
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
,
#
'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