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
25cb47d2
Commit
25cb47d2
authored
Jan 17, 2017
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Change] 拆分user view为多个view
parent
87bbb6af
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
705 additions
and
518 deletions
+705
-518
serializers.py
apps/applications/serializers.py
+4
-2
serializers.py
apps/assets/serializers.py
+9
-3
models.py
apps/audits/models.py
+10
-5
serializers.py
apps/audits/serializers.py
+4
-2
command_log_list.html
apps/audits/templates/audits/command_log_list.html
+1
-1
proxy_log_detail.html
apps/audits/templates/audits/proxy_log_detail.html
+1
-25
views.py
apps/audits/views.py
+12
-7
celery.py
apps/common/celery.py
+2
-1
api.py
apps/perms/api.py
+45
-12
utils.py
apps/perms/utils.py
+8
-1
api.py
apps/users/api.py
+16
-11
authentication.py
apps/users/authentication.py
+39
-13
authentication.py
apps/users/models/authentication.py
+2
-1
api_urls.py
apps/users/urls/api_urls.py
+6
-3
views_urls.py
apps/users/urls/views_urls.py
+55
-22
__init__.py
apps/users/views/__init__.py
+5
-0
group.py
apps/users/views/group.py
+169
-0
login.py
apps/users/views/login.py
+200
-0
user.py
apps/users/views/user.py
+117
-409
No files found.
apps/applications/serializers.py
View file @
25cb47d2
...
@@ -14,8 +14,9 @@ class TerminalSerializer(serializers.ModelSerializer):
...
@@ -14,8 +14,9 @@ class TerminalSerializer(serializers.ModelSerializer):
class
Meta
:
class
Meta
:
model
=
Terminal
model
=
Terminal
fields
=
[
'id'
,
'name'
,
'remote_addr'
,
'type'
,
'url'
,
'comment'
,
'is_accepted'
,
fields
=
[
'id'
,
'name'
,
'remote_addr'
,
'type'
,
'url'
,
'comment'
,
'is_active'
,
'get_type_display'
,
'proxy_online'
,
'is_alive'
]
'is_accepted'
,
'is_active'
,
'get_type_display'
,
'proxy_online'
,
'is_alive'
]
@staticmethod
@staticmethod
def
get_proxy_online
(
obj
):
def
get_proxy_online
(
obj
):
...
@@ -31,6 +32,7 @@ class TerminalSerializer(serializers.ModelSerializer):
...
@@ -31,6 +32,7 @@ class TerminalSerializer(serializers.ModelSerializer):
class
TerminalHeatbeatSerializer
(
serializers
.
ModelSerializer
):
class
TerminalHeatbeatSerializer
(
serializers
.
ModelSerializer
):
date_start
=
serializers
.
DateTimeField
class
Meta
:
class
Meta
:
model
=
TerminalHeatbeat
model
=
TerminalHeatbeat
...
...
apps/assets/serializers.py
View file @
25cb47d2
...
@@ -99,6 +99,12 @@ class SystemUserSerializer(serializers.ModelSerializer):
...
@@ -99,6 +99,12 @@ class SystemUserSerializer(serializers.ModelSerializer):
return
fields
return
fields
class
AssetSystemUserSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
SystemUser
fields
=
(
'id'
,
'name'
,
'username'
,
'protocol'
,
'auth_method'
,
'comment'
)
class
SystemUserUpdateAssetsSerializer
(
serializers
.
ModelSerializer
):
class
SystemUserUpdateAssetsSerializer
(
serializers
.
ModelSerializer
):
assets
=
serializers
.
PrimaryKeyRelatedField
(
many
=
True
,
queryset
=
Asset
.
objects
.
all
())
assets
=
serializers
.
PrimaryKeyRelatedField
(
many
=
True
,
queryset
=
Asset
.
objects
.
all
())
...
@@ -145,13 +151,13 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
...
@@ -145,13 +151,13 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
class
AssetGrantedSerializer
(
serializers
.
ModelSerializer
):
class
AssetGrantedSerializer
(
serializers
.
ModelSerializer
):
system_users
=
SystemUserSerializer
(
many
=
True
,
read_only
=
True
)
system_users
_granted
=
Asset
SystemUserSerializer
(
many
=
True
,
read_only
=
True
)
is_inherited
=
serializers
.
SerializerMethodField
()
is_inherited
=
serializers
.
SerializerMethodField
()
system_users_join
=
serializers
.
SerializerMethodField
()
system_users_join
=
serializers
.
SerializerMethodField
()
class
Meta
(
object
):
class
Meta
(
object
):
model
=
Asset
model
=
Asset
fields
=
(
"id"
,
"hostname"
,
"ip"
,
"port"
,
"system_users"
,
"is_inherited"
,
fields
=
(
"id"
,
"hostname"
,
"ip"
,
"port"
,
"system_users
_granted
"
,
"is_inherited"
,
"is_active"
,
"system_users_join"
,
"comment"
)
"is_active"
,
"system_users_join"
,
"comment"
)
@staticmethod
@staticmethod
...
@@ -163,7 +169,7 @@ class AssetGrantedSerializer(serializers.ModelSerializer):
...
@@ -163,7 +169,7 @@ class AssetGrantedSerializer(serializers.ModelSerializer):
@staticmethod
@staticmethod
def
get_system_users_join
(
obj
):
def
get_system_users_join
(
obj
):
return
', '
.
join
([
system_user
.
username
for
system_user
in
obj
.
system_users
.
all
()
])
return
', '
.
join
([
system_user
.
username
for
system_user
in
obj
.
system_users
_granted
])
class
IDCSerializer
(
BulkSerializerMixin
,
serializers
.
ModelSerializer
):
class
IDCSerializer
(
BulkSerializerMixin
,
serializers
.
ModelSerializer
):
...
...
apps/audits/models.py
View file @
25cb47d2
...
@@ -17,10 +17,13 @@ class LoginLog(models.Model):
...
@@ -17,10 +17,13 @@ class LoginLog(models.Model):
username
=
models
.
CharField
(
max_length
=
20
,
verbose_name
=
_
(
'Username'
))
username
=
models
.
CharField
(
max_length
=
20
,
verbose_name
=
_
(
'Username'
))
name
=
models
.
CharField
(
max_length
=
20
,
blank
=
True
,
verbose_name
=
_
(
'Name'
))
name
=
models
.
CharField
(
max_length
=
20
,
blank
=
True
,
verbose_name
=
_
(
'Name'
))
login_type
=
models
.
CharField
(
choices
=
LOGIN_TYPE_CHOICE
,
max_length
=
2
,
verbose_name
=
_
(
'Login type'
))
login_type
=
models
.
CharField
(
choices
=
LOGIN_TYPE_CHOICE
,
max_length
=
2
,
verbose_name
=
_
(
'Login type'
))
login_ip
=
models
.
GenericIPAddressField
(
verbose_name
=
_
(
'Login ip'
))
login_ip
=
models
.
GenericIPAddressField
(
verbose_name
=
_
(
'Login ip'
))
login_city
=
models
.
CharField
(
max_length
=
100
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'Login city'
))
login_city
=
models
.
CharField
(
max_length
=
100
,
blank
=
True
,
null
=
True
,
user_agent
=
models
.
CharField
(
max_length
=
100
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'User agent'
))
verbose_name
=
_
(
'Login city'
))
user_agent
=
models
.
CharField
(
max_length
=
100
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'User agent'
))
date_login
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'Date login'
))
date_login
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'Date login'
))
class
Meta
:
class
Meta
:
...
@@ -66,7 +69,8 @@ class ProxyLog(models.Model):
...
@@ -66,7 +69,8 @@ class ProxyLog(models.Model):
class
CommandLog
(
models
.
Model
):
class
CommandLog
(
models
.
Model
):
proxy_log
=
models
.
ForeignKey
(
ProxyLog
,
on_delete
=
models
.
CASCADE
,
related_name
=
'commands'
)
proxy_log
=
models
.
ForeignKey
(
ProxyLog
,
on_delete
=
models
.
CASCADE
,
related_name
=
'commands'
)
command_no
=
models
.
IntegerField
()
command_no
=
models
.
IntegerField
()
command
=
models
.
CharField
(
max_length
=
1000
,
blank
=
True
)
command
=
models
.
CharField
(
max_length
=
1000
,
blank
=
True
)
output
=
models
.
TextField
(
blank
=
True
)
output
=
models
.
TextField
(
blank
=
True
)
...
@@ -78,7 +82,8 @@ class CommandLog(models.Model):
...
@@ -78,7 +82,8 @@ class CommandLog(models.Model):
@property
@property
def
output_decode
(
self
):
def
output_decode
(
self
):
try
:
try
:
return
base64
.
b64decode
(
self
.
output
)
.
replace
(
'
\n
'
,
'<br />'
)
return
base64
.
b64decode
(
self
.
output
)
.
decode
(
'utf-8'
)
\
.
replace
(
'
\n
'
,
'<br />'
)
except
UnicodeDecodeError
:
except
UnicodeDecodeError
:
return
'UnicodeDecodeError'
return
'UnicodeDecodeError'
...
...
apps/audits/serializers.py
View file @
25cb47d2
...
@@ -13,8 +13,9 @@ class ProxyLogSerializer(serializers.ModelSerializer):
...
@@ -13,8 +13,9 @@ class ProxyLogSerializer(serializers.ModelSerializer):
class
Meta
:
class
Meta
:
model
=
models
.
ProxyLog
model
=
models
.
ProxyLog
fields
=
[
'id'
,
'name'
,
'username'
,
'hostname'
,
'ip'
,
'system_user'
,
'login_type'
,
'terminal'
,
fields
=
[
'id'
,
'name'
,
'username'
,
'hostname'
,
'ip'
,
'system_user'
,
'log_file'
,
'was_failed'
,
'is_finished'
,
'date_start'
,
'date_finished'
,
'time'
,
'login_type'
,
'terminal'
,
'log_file'
,
'was_failed'
,
'is_finished'
,
'date_start'
,
'date_finished'
,
'time'
,
'command_length'
,
"commands_dict"
]
'command_length'
,
"commands_dict"
]
@staticmethod
@staticmethod
...
@@ -32,3 +33,4 @@ class ProxyLogSerializer(serializers.ModelSerializer):
...
@@ -32,3 +33,4 @@ class ProxyLogSerializer(serializers.ModelSerializer):
class
CommandLogSerializer
(
serializers
.
ModelSerializer
):
class
CommandLogSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
class
Meta
:
model
=
models
.
CommandLog
model
=
models
.
CommandLog
fields
=
'__all__'
apps/audits/templates/audits/command_log_list.html
View file @
25cb47d2
...
@@ -83,7 +83,7 @@
...
@@ -83,7 +83,7 @@
<td>
{{ command.proxy_log.system_user }}
</td>
<td>
{{ command.proxy_log.system_user }}
</td>
<td><a
href=
"{% url 'audits:proxy-log-detail' pk=command.proxy_log.id %}"
>
{{ command.proxy_log.id}}
</a></td>
<td><a
href=
"{% url 'audits:proxy-log-detail' pk=command.proxy_log.id %}"
>
{{ command.proxy_log.id}}
</a></td>
<td>
{{ command.datetime }}
</td>
<td>
{{ command.datetime }}
</td>
<td>
{{ command.output_decode
|safe }}
</td>
<td>
{{ command.output_decode|safe }}
</td>
</tr>
</tr>
{% endfor %}
{% endfor %}
</tbody>
</tbody>
...
...
apps/audits/templates/audits/proxy_log_detail.html
View file @
25cb47d2
...
@@ -52,7 +52,7 @@
...
@@ -52,7 +52,7 @@
<tr>
<tr>
<td>
{{ command.command_no }}
</td>
<td>
{{ command.command_no }}
</td>
<td>
{{ command.command }}
</td>
<td>
{{ command.command }}
</td>
<td>
{{ command.output_decode
|safe }}
</td>
<td>
{{ command.output_decode|safe }}
</td>
<td>
{{ command.datetime }}
</td>
<td>
{{ command.datetime }}
</td>
</tr>
</tr>
{% endfor %}
{% endfor %}
...
@@ -68,30 +68,6 @@
...
@@ -68,30 +68,6 @@
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"col-sm-5"
style=
"padding-left: 0;padding-right: 0"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
style=
"float: left"
>
{% trans 'Detail' %}
<b>
{{ user_object.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=
"table2 table-stripped toggle-arrow-tiny"
data-page-size=
"8"
>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
...
...
apps/audits/views.py
View file @
25cb47d2
...
@@ -14,17 +14,16 @@ from .models import ProxyLog, CommandLog, LoginLog
...
@@ -14,17 +14,16 @@ from .models import ProxyLog, CommandLog, LoginLog
from
.hands
import
User
,
Asset
,
SystemUser
,
AdminUserRequiredMixin
from
.hands
import
User
,
Asset
,
SystemUser
,
AdminUserRequiredMixin
date_now
=
timezone
.
localtime
(
timezone
.
now
())
now_s
=
date_now
.
strftime
(
'
%
m/
%
d/
%
Y'
)
seven_days_ago_s
=
(
date_now
-
timezone
.
timedelta
(
7
))
.
strftime
(
'
%
m/
%
d/
%
Y'
)
class
ProxyLogListView
(
AdminUserRequiredMixin
,
ListView
):
class
ProxyLogListView
(
AdminUserRequiredMixin
,
ListView
):
model
=
ProxyLog
model
=
ProxyLog
template_name
=
'audits/proxy_log_list.html'
template_name
=
'audits/proxy_log_list.html'
context_object_name
=
'proxy_log_list'
context_object_name
=
'proxy_log_list'
def
get_queryset
(
self
):
def
get_queryset
(
self
):
date_now
=
timezone
.
localtime
(
timezone
.
now
())
now_s
=
date_now
.
strftime
(
'
%
m/
%
d/
%
Y'
)
seven_days_ago_s
=
(
date_now
-
timezone
.
timedelta
(
7
))
.
strftime
(
'
%
m/
%
d/
%
Y'
)
self
.
queryset
=
super
(
ProxyLogListView
,
self
)
.
get_queryset
()
self
.
queryset
=
super
(
ProxyLogListView
,
self
)
.
get_queryset
()
self
.
keyword
=
keyword
=
self
.
request
.
GET
.
get
(
'keyword'
,
''
)
self
.
keyword
=
keyword
=
self
.
request
.
GET
.
get
(
'keyword'
,
''
)
self
.
username
=
username
=
self
.
request
.
GET
.
get
(
'username'
,
''
)
self
.
username
=
username
=
self
.
request
.
GET
.
get
(
'username'
,
''
)
...
@@ -37,7 +36,8 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView):
...
@@ -37,7 +36,8 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView):
date_from
=
timezone
.
datetime
.
strptime
(
date_from_s
,
'
%
m/
%
d/
%
Y'
)
date_from
=
timezone
.
datetime
.
strptime
(
date_from_s
,
'
%
m/
%
d/
%
Y'
)
self
.
queryset
=
self
.
queryset
.
filter
(
date_start__gt
=
date_from
)
self
.
queryset
=
self
.
queryset
.
filter
(
date_start__gt
=
date_from
)
if
date_to_s
:
if
date_to_s
:
date_to
=
timezone
.
datetime
.
strptime
(
date_to_s
+
' 23:59:59'
,
'
%
m/
%
d/
%
Y
%
H:
%
M:
%
S'
)
date_to
=
timezone
.
datetime
.
strptime
(
date_to_s
+
' 23:59:59'
,
'
%
m/
%
d/
%
Y
%
H:
%
M:
%
S'
)
self
.
queryset
=
self
.
queryset
.
filter
(
date_start__lt
=
date_to
)
self
.
queryset
=
self
.
queryset
.
filter
(
date_start__lt
=
date_to
)
if
username
:
if
username
:
self
.
queryset
=
self
.
queryset
.
filter
(
username
=
username
)
self
.
queryset
=
self
.
queryset
.
filter
(
username
=
username
)
...
@@ -54,7 +54,6 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView):
...
@@ -54,7 +54,6 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView):
return
self
.
queryset
return
self
.
queryset
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
print
(
self
.
date_to_s
)
context
=
{
context
=
{
'app'
:
_
(
'Audits'
),
'app'
:
_
(
'Audits'
),
'action'
:
_
(
'Proxy log list'
),
'action'
:
_
(
'Proxy log list'
),
...
@@ -110,6 +109,9 @@ class CommandLogListView(AdminUserRequiredMixin, ListView):
...
@@ -110,6 +109,9 @@ class CommandLogListView(AdminUserRequiredMixin, ListView):
context_object_name
=
'command_list'
context_object_name
=
'command_list'
def
get_queryset
(
self
):
def
get_queryset
(
self
):
date_now
=
timezone
.
localtime
(
timezone
.
now
())
now_s
=
date_now
.
strftime
(
'
%
m/
%
d/
%
Y'
)
seven_days_ago_s
=
(
date_now
-
timezone
.
timedelta
(
7
))
.
strftime
(
'
%
m/
%
d/
%
Y'
)
self
.
queryset
=
super
(
CommandLogListView
,
self
)
.
get_queryset
()
self
.
queryset
=
super
(
CommandLogListView
,
self
)
.
get_queryset
()
self
.
keyword
=
keyword
=
self
.
request
.
GET
.
get
(
'keyword'
,
''
)
self
.
keyword
=
keyword
=
self
.
request
.
GET
.
get
(
'keyword'
,
''
)
self
.
sort
=
sort
=
self
.
request
.
GET
.
get
(
'sort'
,
'-datetime'
)
self
.
sort
=
sort
=
self
.
request
.
GET
.
get
(
'sort'
,
'-datetime'
)
...
@@ -161,6 +163,9 @@ class LoginLogListView(AdminUserRequiredMixin, ListView):
...
@@ -161,6 +163,9 @@ class LoginLogListView(AdminUserRequiredMixin, ListView):
context_object_name
=
'login_log_list'
context_object_name
=
'login_log_list'
def
get_queryset
(
self
):
def
get_queryset
(
self
):
date_now
=
timezone
.
localtime
(
timezone
.
now
())
now_s
=
date_now
.
strftime
(
'
%
m/
%
d/
%
Y'
)
seven_days_ago_s
=
(
date_now
-
timezone
.
timedelta
(
7
))
.
strftime
(
'
%
m/
%
d/
%
Y'
)
self
.
queryset
=
super
(
LoginLogListView
,
self
)
.
get_queryset
()
self
.
queryset
=
super
(
LoginLogListView
,
self
)
.
get_queryset
()
self
.
keyword
=
keyword
=
self
.
request
.
GET
.
get
(
'keyword'
,
''
)
self
.
keyword
=
keyword
=
self
.
request
.
GET
.
get
(
'keyword'
,
''
)
self
.
username
=
username
=
self
.
request
.
GET
.
get
(
'username'
,
''
)
self
.
username
=
username
=
self
.
request
.
GET
.
get
(
'username'
,
''
)
...
...
apps/common/celery.py
View file @
25cb47d2
...
@@ -16,5 +16,6 @@ app = Celery('jumpserver')
...
@@ -16,5 +16,6 @@ app = Celery('jumpserver')
# Using a string here means the worker will not have to
# Using a string here means the worker will not have to
# pickle the object when using Windows.
# pickle the object when using Windows.
app
.
config_from_object
(
'django.conf:settings'
)
app
.
config_from_object
(
'django.conf:settings'
)
app
.
autodiscover_tasks
(
lambda
:
[
app_config
.
split
(
'.'
)[
0
]
for
app_config
in
settings
.
INSTALLED_APPS
])
app
.
autodiscover_tasks
(
lambda
:
[
app_config
.
split
(
'.'
)[
0
]
for
app_config
in
settings
.
INSTALLED_APPS
])
apps/perms/api.py
View file @
25cb47d2
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
#
#
from
django.shortcuts
import
get_object_or_404
from
rest_framework.views
import
APIView
,
Response
from
rest_framework.views
import
APIView
,
Response
from
rest_framework.decorators
import
api_view
from
rest_framework.decorators
import
api_view
from
rest_framework.generics
import
ListAPIView
,
get_object_or_404
from
rest_framework.generics
import
ListAPIView
,
get_object_or_404
from
rest_framework
import
viewsets
from
rest_framework
import
viewsets
from
users.permissions
import
IsValidUser
,
IsSuperUser
from
users.permissions
import
IsValidUser
,
IsSuperUser
,
IsAppUser
from
common.utils
import
get_object_or_none
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
.utils
import
get_user_granted_assets
,
get_user_granted_asset_groups
,
\
get_user_group_asset_permissions
,
get_user_group_granted_assets
,
get_user_group_granted_asset_groups
get_user_asset_permissions
,
get_user_group_asset_permissions
,
\
get_user_group_granted_assets
,
get_user_group_granted_asset_groups
from
.models
import
AssetPermission
from
.models
import
AssetPermission
from
.hands
import
AssetGrantedSerializer
,
User
,
UserGroup
,
AssetGroup
,
Asset
,
AssetGroup
,
AssetGroupSerializer
from
.hands
import
AssetGrantedSerializer
,
User
,
UserGroup
,
AssetGroup
,
Asset
,
\
AssetGroup
,
AssetGroupSerializer
,
SystemUser
from
.
import
serializers
from
.
import
serializers
...
@@ -80,11 +83,12 @@ class UserGrantedAssetsApi(ListAPIView):
...
@@ -80,11 +83,12 @@ class UserGrantedAssetsApi(ListAPIView):
def
get_queryset
(
self
):
def
get_queryset
(
self
):
user_id
=
self
.
kwargs
.
get
(
'pk'
,
''
)
user_id
=
self
.
kwargs
.
get
(
'pk'
,
''
)
queryset
=
[]
if
user_id
:
if
user_id
:
user
=
get_object_or_404
(
User
,
id
=
user_id
)
user
=
get_object_or_404
(
User
,
id
=
user_id
)
queryset
=
get_user_granted_assets
(
user
)
for
k
,
v
in
get_user_granted_assets
(
user
)
.
items
():
else
:
k
.
system_users_granted
=
v
queryset
=
[]
queryset
.
append
(
k
)
return
queryset
return
queryset
...
@@ -104,19 +108,26 @@ class UserGrantedAssetGroupsApi(ListAPIView):
...
@@ -104,19 +108,26 @@ class UserGrantedAssetGroupsApi(ListAPIView):
class
MyGrantedAssetsApi
(
ListAPIView
):
class
MyGrantedAssetsApi
(
ListAPIView
):
"""授权给用户的资产列表
[{'hostname': 'x','ip': 'x', ..,
'system_users_granted': [{'name': 'x', .}, ...]
"""
permission_classes
=
(
IsValidUser
,)
permission_classes
=
(
IsValidUser
,)
serializer_class
=
AssetGrantedSerializer
serializer_class
=
AssetGrantedSerializer
def
get_queryset
(
self
):
def
get_queryset
(
self
):
queryset
=
[]
user
=
self
.
request
.
user
user
=
self
.
request
.
user
if
user
:
if
user
:
queryset
=
get_user_granted_assets
(
user
)
for
asset
,
system_users
in
get_user_granted_assets
(
user
)
.
items
():
else
:
asset
.
system_users_granted
=
system_users
queryset
=
[]
queryset
.
append
(
asset
)
return
queryset
return
queryset
class
MyGrantedAssetsGroupsApi
(
APIView
):
class
MyGrantedAssetsGroupsApi
(
APIView
):
"""授权给用户的资产组列表, 非直接通过授权规则授权的资产组列表, 而是授权资产的所有
资产组之和"""
permission_classes
=
(
IsValidUser
,)
permission_classes
=
(
IsValidUser
,)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
...
@@ -141,6 +152,7 @@ class MyGrantedAssetsGroupsApi(APIView):
...
@@ -141,6 +152,7 @@ class MyGrantedAssetsGroupsApi(APIView):
class
MyAssetGroupAssetsApi
(
ListAPIView
):
class
MyAssetGroupAssetsApi
(
ListAPIView
):
"""授权用户资产组下的资产列表, 非该资产组的所有资产,而是被授权的"""
permission_classes
=
(
IsValidUser
,)
permission_classes
=
(
IsValidUser
,)
serializer_class
=
AssetGrantedSerializer
serializer_class
=
AssetGrantedSerializer
...
@@ -152,8 +164,9 @@ class MyAssetGroupAssetsApi(ListAPIView):
...
@@ -152,8 +164,9 @@ class MyAssetGroupAssetsApi(ListAPIView):
if
user
and
asset_group
:
if
user
and
asset_group
:
assets
=
get_user_granted_assets
(
user
)
assets
=
get_user_granted_assets
(
user
)
for
asset
in
assets
:
for
asset
in
asset_group
.
assets
.
all
():
if
asset_group
in
asset
.
groups
.
all
():
if
asset
in
assets
:
asset
.
system_users_granted
=
assets
[
asset
]
queryset
.
append
(
asset
)
queryset
.
append
(
asset
)
return
queryset
return
queryset
...
@@ -186,3 +199,23 @@ class UserGroupGrantedAssetGroupsApi(ListAPIView):
...
@@ -186,3 +199,23 @@ class UserGroupGrantedAssetGroupsApi(ListAPIView):
else
:
else
:
queryset
=
[]
queryset
=
[]
return
queryset
return
queryset
class
CheckUserAssetSystemPermission
(
APIView
):
permission_classes
=
(
IsAppUser
,)
def
get
(
self
,
request
):
user_id
=
request
.
params
.
get
(
'user_id'
,
''
)
asset_id
=
request
.
params
.
get
(
'asset_id'
,
''
)
system_id
=
request
.
params
.
get
(
'system_id'
,
''
)
user
=
get_object_or_none
(
User
,
id
=
user_id
)
asset
=
get_object_or_none
(
Asset
,
id
=
asset_id
)
system_user
=
get_object_or_none
(
SystemUser
,
id
=
system_id
)
if
not
(
user
and
asset
and
system_user
):
return
Response
(
status
=
403
)
assets_granted
=
get_user_granted_assets
(
user
)
apps/perms/utils.py
View file @
25cb47d2
...
@@ -37,6 +37,8 @@ def get_user_group_granted_assets(user_group):
...
@@ -37,6 +37,8 @@ def get_user_group_granted_assets(user_group):
if
not
asset_permission
.
is_valid
:
if
not
asset_permission
.
is_valid
:
continue
continue
for
asset
in
asset_permission
.
get_granted_assets
():
for
asset
in
asset_permission
.
get_granted_assets
():
if
not
asset
.
is_active
:
continue
if
asset
in
assets
:
if
asset
in
assets
:
assets
[
asset
]
|=
set
(
asset_permission
.
system_users
.
all
())
assets
[
asset
]
|=
set
(
asset_permission
.
system_users
.
all
())
else
:
else
:
...
@@ -127,6 +129,8 @@ def get_user_granted_assets_direct(user):
...
@@ -127,6 +129,8 @@ def get_user_granted_assets_direct(user):
if
not
asset_permission
.
is_valid
:
if
not
asset_permission
.
is_valid
:
continue
continue
for
asset
in
asset_permission
.
get_granted_assets
():
for
asset
in
asset_permission
.
get_granted_assets
():
if
not
asset
.
is_active
:
continue
if
asset
in
assets
:
if
asset
in
assets
:
assets
[
asset
]
|=
set
(
asset_permission
.
system_users
.
all
())
assets
[
asset
]
|=
set
(
asset_permission
.
system_users
.
all
())
else
:
else
:
...
@@ -147,12 +151,13 @@ def get_user_granted_assets_inherit_from_user_groups(user):
...
@@ -147,12 +151,13 @@ def get_user_granted_assets_inherit_from_user_groups(user):
for
user_group
in
user_groups
:
for
user_group
in
user_groups
:
assets_inherited
=
get_user_group_granted_assets
(
user_group
)
assets_inherited
=
get_user_group_granted_assets
(
user_group
)
for
asset
in
assets_inherited
:
for
asset
in
assets_inherited
:
if
not
asset
.
is_active
:
continue
if
asset
in
assets
:
if
asset
in
assets
:
assets
[
asset
]
|=
assets_inherited
[
asset
]
assets
[
asset
]
|=
assets_inherited
[
asset
]
else
:
else
:
setattr
(
asset
,
'inherited'
,
True
)
setattr
(
asset
,
'inherited'
,
True
)
assets
[
asset
]
=
assets_inherited
[
asset
]
assets
[
asset
]
=
assets_inherited
[
asset
]
return
assets
return
assets
...
@@ -167,6 +172,8 @@ def get_user_granted_assets(user):
...
@@ -167,6 +172,8 @@ def get_user_granted_assets(user):
assets
=
assets_inherited
assets
=
assets_inherited
for
asset
in
assets_direct
:
for
asset
in
assets_direct
:
if
not
asset
.
is_active
:
continue
if
asset
in
assets
:
if
asset
in
assets
:
assets
[
asset
]
|=
assets_direct
[
asset
]
assets
[
asset
]
|=
assets_direct
[
asset
]
else
:
else
:
...
...
apps/users/api.py
View file @
25cb47d2
...
@@ -3,23 +3,22 @@
...
@@ -3,23 +3,22 @@
import
base64
import
base64
from
django.core.cache
import
cache
from
django.conf
import
settings
from
rest_framework
import
generics
,
viewsets
from
rest_framework
import
generics
,
viewsets
from
rest_framework.response
import
Response
from
rest_framework.response
import
Response
from
rest_framework.views
import
APIView
from
rest_framework.views
import
APIView
from
rest_framework.decorators
import
api_view
from
rest_framework.permissions
import
AllowAny
from
rest_framework.permissions
import
AllowAny
from
rest_framework.authentication
import
SessionAuthentication
from
rest_framework_bulk
import
BulkModelViewSet
from
rest_framework_bulk
import
BulkModelViewSet
from
rest_framework.authentication
import
CSRFCheck
# from django_filters.rest_framework import DjangoFilterBackend
# from django_filters.rest_framework import DjangoFilterBackend
from
django.conf
import
settings
from
common.mixins
import
IDInFilterMixin
from
common.mixins
import
IDInFilterMixin
from
common.utils
import
get_logger
from
common.utils
import
get_logger
from
.utils
import
check_user_valid
,
generate_token
from
.utils
import
check_user_valid
,
generate_token
from
.models
import
User
,
UserGroup
from
.models
import
User
,
UserGroup
from
.hands
import
write_login_log_async
from
.hands
import
write_login_log_async
from
.permissions
import
IsSuperUser
,
IsAppUser
,
IsValidUser
,
IsSuperUserOrAppUser
from
.permissions
import
(
IsSuperUser
,
IsAppUser
,
IsValidUser
,
IsSuperUserOrAppUser
)
from
.
import
serializers
from
.
import
serializers
...
@@ -98,7 +97,8 @@ class UserToken(APIView):
...
@@ -98,7 +97,8 @@ class UserToken(APIView):
password
=
request
.
data
.
get
(
'password'
,
''
)
password
=
request
.
data
.
get
(
'password'
,
''
)
public_key
=
request
.
data
.
get
(
'public_key'
,
''
)
public_key
=
request
.
data
.
get
(
'public_key'
,
''
)
user
,
msg
=
check_user_valid
(
username
=
username
,
email
=
email
,
user
,
msg
=
check_user_valid
(
username
=
username
,
email
=
email
,
password
=
password
,
public_key
=
public_key
)
password
=
password
,
public_key
=
public_key
)
else
:
else
:
user
=
request
.
user
user
=
request
.
user
...
@@ -116,24 +116,29 @@ class UserProfile(APIView):
...
@@ -116,24 +116,29 @@ class UserProfile(APIView):
def
get
(
self
,
request
):
def
get
(
self
,
request
):
return
Response
(
request
.
user
.
to_json
())
return
Response
(
request
.
user
.
to_json
())
def
post
(
self
,
request
):
return
Response
(
request
.
user
.
to_json
())
class
UserAuthApi
(
APIView
):
class
UserAuthApi
(
APIView
):
permission_classes
=
(
AllowAny
,)
permission_classes
=
(
AllowAny
,)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
):
username
=
request
.
data
.
get
(
'username'
,
''
)
username
=
request
.
data
.
get
(
'username'
,
''
)
password
=
request
.
data
.
get
(
'password'
,
''
)
password
=
request
.
data
.
get
(
'password'
,
''
)
public_key
=
request
.
data
.
get
(
'public_key'
,
''
)
public_key
=
request
.
data
.
get
(
'public_key'
,
''
)
login_type
=
request
.
data
.
get
(
'login_type'
,
''
)
login_type
=
request
.
data
.
get
(
'login_type'
,
''
)
login_ip
=
request
.
data
.
get
(
'remote_addr'
,
None
)
or
request
.
META
.
get
(
'REMOTE_ADDR'
,
''
)
login_ip
=
request
.
data
.
get
(
'remote_addr'
,
None
)
user_agent
=
request
.
data
.
get
(
'HTTP_USER_AGENT'
,
''
)
user_agent
=
request
.
data
.
get
(
'HTTP_USER_AGENT'
,
''
)
user
,
msg
=
check_user_valid
(
username
=
username
,
password
=
password
,
public_key
=
public_key
)
user
,
msg
=
check_user_valid
(
username
=
username
,
password
=
password
,
public_key
=
public_key
)
if
user
:
if
user
:
token
=
generate_token
(
request
,
user
)
token
=
generate_token
(
request
,
user
)
write_login_log_async
.
delay
(
user
.
username
,
name
=
user
.
name
,
user_agent
=
user_agent
,
write_login_log_async
.
delay
(
user
.
username
,
name
=
user
.
name
,
login_ip
=
login_ip
,
login_type
=
login_type
)
user_agent
=
user_agent
,
login_ip
=
login_ip
,
login_type
=
login_type
)
return
Response
({
'token'
:
token
,
'user'
:
user
.
to_json
()})
return
Response
({
'token'
:
token
,
'user'
:
user
.
to_json
()})
else
:
else
:
return
Response
({
'msg'
:
msg
},
status
=
401
)
return
Response
({
'msg'
:
msg
},
status
=
401
)
apps/users/authentication.py
View file @
25cb47d2
...
@@ -8,10 +8,11 @@ import time
...
@@ -8,10 +8,11 @@ import time
from
django.core.cache
import
cache
from
django.core.cache
import
cache
from
django.conf
import
settings
from
django.conf
import
settings
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
rest_framework
import
authentication
,
exceptions
,
permissions
from
django.utils.six
import
text_type
from
django.utils.six
import
text_type
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
rest_framework
import
HTTP_HEADER_ENCODING
from
rest_framework
import
HTTP_HEADER_ENCODING
from
rest_framework
import
authentication
,
exceptions
,
permissions
from
rest_framework.authentication
import
CSRFCheck
from
common.utils
import
get_object_or_none
,
make_signature
,
http_to_unixtime
from
common.utils
import
get_object_or_none
,
make_signature
,
http_to_unixtime
from
.utils
import
refresh_token
from
.utils
import
refresh_token
...
@@ -27,6 +28,21 @@ def get_request_date_header(request):
...
@@ -27,6 +28,21 @@ def get_request_date_header(request):
class
AccessKeyAuthentication
(
authentication
.
BaseAuthentication
):
class
AccessKeyAuthentication
(
authentication
.
BaseAuthentication
):
"""App使用Access key进行签名认证, 目前签名算法比较简单,
app注册或者手动建立后,会生成 access_key_id 和 access_key_secret,
然后使用 如下算法生成签名:
Signature = md5(access_key_secret + '
\n
' + Date)
example: Signature = md5('d32d2b8b-9a10-4b8d-85bb-1a66976f6fdc' + '
\n
' +
'Thu, 12 Jan 2017 08:19:41 GMT')
请求时设置请求header
header['Authorization'] = 'Sign access_key_id:Signature' 如:
header['Authorization'] =
'Sign d32d2b8b-9a10-4b8d-85bb-1a66976f6fdc:OKOlmdxgYPZ9+SddnUUDbQ=='
验证时根据相同算法进行验证, 取到access_key_id对应的access_key_id, 从request
headers取到Date, 然后进行md5, 判断得到的结果是否相同, 如果是认证通过, 否则 认证
失败
"""
keyword
=
'Sign'
keyword
=
'Sign'
model
=
AccessKey
model
=
AccessKey
...
@@ -40,22 +56,26 @@ class AccessKeyAuthentication(authentication.BaseAuthentication):
...
@@ -40,22 +56,26 @@ class AccessKeyAuthentication(authentication.BaseAuthentication):
msg
=
_
(
'Invalid signature header. No credentials provided.'
)
msg
=
_
(
'Invalid signature header. No credentials provided.'
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
elif
len
(
auth
)
>
2
:
elif
len
(
auth
)
>
2
:
msg
=
_
(
'Invalid signature header. Signature string should not contain spaces.'
)
msg
=
_
(
'Invalid signature header. Signature '
'string should not contain spaces.'
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
try
:
try
:
sign
=
auth
[
1
]
.
decode
()
.
split
(
':'
)
sign
=
auth
[
1
]
.
decode
()
.
split
(
':'
)
if
len
(
sign
)
!=
2
:
if
len
(
sign
)
!=
2
:
msg
=
_
(
'Invalid signature header. Format like AccessKeyId:Signature'
)
msg
=
_
(
'Invalid signature header. '
'Format like AccessKeyId:Signature'
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
except
UnicodeError
:
except
UnicodeError
:
msg
=
_
(
'Invalid signature header. Signature string should not contain invalid characters.'
)
msg
=
_
(
'Invalid signature header. '
'Signature string should not contain invalid characters.'
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
access_key_id
=
sign
[
0
]
access_key_id
=
sign
[
0
]
request_signature
=
sign
[
1
]
request_signature
=
sign
[
1
]
return
self
.
authenticate_credentials
(
request
,
access_key_id
,
request_signature
)
return
self
.
authenticate_credentials
(
request
,
access_key_id
,
request_signature
)
@staticmethod
@staticmethod
def
authenticate_credentials
(
request
,
access_key_id
,
request_signature
):
def
authenticate_credentials
(
request
,
access_key_id
,
request_signature
):
...
@@ -68,14 +88,17 @@ class AccessKeyAuthentication(authentication.BaseAuthentication):
...
@@ -68,14 +88,17 @@ class AccessKeyAuthentication(authentication.BaseAuthentication):
try
:
try
:
request_unix_time
=
http_to_unixtime
(
request_date
)
request_unix_time
=
http_to_unixtime
(
request_date
)
except
ValueError
:
except
ValueError
:
raise
exceptions
.
AuthenticationFailed
(
_
(
'HTTP header: Date not provide or not
%
a,
%
d
%
b
%
Y
%
H:
%
M:
%
S GMT'
))
raise
exceptions
.
AuthenticationFailed
(
_
(
'HTTP header: Date not provide '
'or not
%
a,
%
d
%
b
%
Y
%
H:
%
M:
%
S GMT'
))
if
int
(
time
.
time
())
-
request_unix_time
>
15
*
60
:
if
int
(
time
.
time
())
-
request_unix_time
>
15
*
60
:
raise
exceptions
.
AuthenticationFailed
(
_
(
'Expired, more than 15 minutes'
))
raise
exceptions
.
AuthenticationFailed
(
_
(
'Expired, more than 15 minutes'
))
signature
=
make_signature
(
access_key_secret
,
request_date
)
signature
=
make_signature
(
access_key_secret
,
request_date
)
if
not
signature
==
request_signature
:
if
not
signature
==
request_signature
:
raise
exceptions
.
AuthenticationFailed
(
_
(
'Invalid signature.
%
s:
%
s'
%
(
signature
,
request_signature
)
))
raise
exceptions
.
AuthenticationFailed
(
_
(
'Invalid signature.
'
))
if
not
access_key
.
user
.
is_active
:
if
not
access_key
.
user
.
is_active
:
raise
exceptions
.
AuthenticationFailed
(
_
(
'User disabled.'
))
raise
exceptions
.
AuthenticationFailed
(
_
(
'User disabled.'
))
...
@@ -97,13 +120,15 @@ class AccessTokenAuthentication(authentication.BaseAuthentication):
...
@@ -97,13 +120,15 @@ class AccessTokenAuthentication(authentication.BaseAuthentication):
msg
=
_
(
'Invalid token header. No credentials provided.'
)
msg
=
_
(
'Invalid token header. No credentials provided.'
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
elif
len
(
auth
)
>
2
:
elif
len
(
auth
)
>
2
:
msg
=
_
(
'Invalid token header. Sign string should not contain spaces.'
)
msg
=
_
(
'Invalid token header. Sign string '
'should not contain spaces.'
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
try
:
try
:
token
=
auth
[
1
]
.
decode
()
token
=
auth
[
1
]
.
decode
()
except
UnicodeError
:
except
UnicodeError
:
msg
=
_
(
'Invalid token header. Sign string should not contain invalid characters.'
)
msg
=
_
(
'Invalid token header. Sign string '
'should not contain invalid characters.'
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
return
self
.
authenticate_credentials
(
token
)
return
self
.
authenticate_credentials
(
token
)
...
@@ -125,4 +150,6 @@ class PrivateTokenAuthentication(authentication.TokenAuthentication):
...
@@ -125,4 +150,6 @@ class PrivateTokenAuthentication(authentication.TokenAuthentication):
class
SessionAuthentication
(
authentication
.
SessionAuthentication
):
class
SessionAuthentication
(
authentication
.
SessionAuthentication
):
def
enforce_csrf
(
self
,
request
):
def
enforce_csrf
(
self
,
request
):
return
None
reason
=
CSRFCheck
()
.
process_view
(
request
,
None
,
(),
{})
\ No newline at end of file
if
reason
:
raise
exceptions
.
AuthenticationFailed
(
reason
)
apps/users/models/authentication.py
View file @
25cb47d2
...
@@ -16,7 +16,8 @@ class AccessKey(models.Model):
...
@@ -16,7 +16,8 @@ class AccessKey(models.Model):
default
=
uuid
.
uuid4
,
editable
=
False
)
default
=
uuid
.
uuid4
,
editable
=
False
)
secret
=
models
.
UUIDField
(
verbose_name
=
'AccessKeySecret'
,
secret
=
models
.
UUIDField
(
verbose_name
=
'AccessKeySecret'
,
default
=
uuid
.
uuid4
,
editable
=
False
)
default
=
uuid
.
uuid4
,
editable
=
False
)
user
=
models
.
ForeignKey
(
User
,
verbose_name
=
'User'
,
related_name
=
'access_key'
)
user
=
models
.
ForeignKey
(
User
,
verbose_name
=
'User'
,
related_name
=
'access_key'
)
def
get_id
(
self
):
def
get_id
(
self
):
return
str
(
self
.
id
)
return
str
(
self
.
id
)
...
...
apps/users/urls/api_urls.py
View file @
25cb47d2
...
@@ -18,9 +18,12 @@ urlpatterns = [
...
@@ -18,9 +18,12 @@ urlpatterns = [
url
(
r'^v1/token/$'
,
api
.
UserToken
.
as_view
(),
name
=
'user-token'
),
url
(
r'^v1/token/$'
,
api
.
UserToken
.
as_view
(),
name
=
'user-token'
),
url
(
r'^v1/profile/$'
,
api
.
UserProfile
.
as_view
(),
name
=
'user-profile'
),
url
(
r'^v1/profile/$'
,
api
.
UserProfile
.
as_view
(),
name
=
'user-profile'
),
url
(
r'^v1/auth/$'
,
api
.
UserAuthApi
.
as_view
(),
name
=
'user-auth'
),
url
(
r'^v1/auth/$'
,
api
.
UserAuthApi
.
as_view
(),
name
=
'user-auth'
),
url
(
r'^v1/users/(?P<pk>\d+)/password/reset/$'
,
api
.
UserResetPasswordApi
.
as_view
(),
name
=
'user-reset-password'
),
url
(
r'^v1/users/(?P<pk>\d+)/password/reset/$'
,
url
(
r'^v1/users/(?P<pk>\d+)/public-key/reset/$'
,
api
.
UserResetPKApi
.
as_view
(),
name
=
'user-public-key-reset'
),
api
.
UserResetPasswordApi
.
as_view
(),
name
=
'user-reset-password'
),
url
(
r'^v1/users/(?P<pk>\d+)/public-key/update/$'
,
api
.
UserUpdatePKApi
.
as_view
(),
name
=
'user-public-key-update'
),
url
(
r'^v1/users/(?P<pk>\d+)/public-key/reset/$'
,
api
.
UserResetPKApi
.
as_view
(),
name
=
'user-public-key-reset'
),
url
(
r'^v1/users/(?P<pk>\d+)/public-key/update/$'
,
api
.
UserUpdatePKApi
.
as_view
(),
name
=
'user-public-key-update'
),
url
(
r'^v1/users/(?P<pk>\d+)/groups/$'
,
url
(
r'^v1/users/(?P<pk>\d+)/groups/$'
,
api
.
UserUpdateGroupApi
.
as_view
(),
name
=
'user-update-group'
),
api
.
UserUpdateGroupApi
.
as_view
(),
name
=
'user-update-group'
),
url
(
r'^v1/user-groups/(?P<pk>\d+)/users/$'
,
url
(
r'^v1/user-groups/(?P<pk>\d+)/users/$'
,
...
...
apps/users/urls/views_urls.py
View file @
25cb47d2
...
@@ -6,39 +6,72 @@ from .. import views
...
@@ -6,39 +6,72 @@ from .. import views
app_name
=
'users'
app_name
=
'users'
urlpatterns
=
[
urlpatterns
=
[
# Login view
url
(
r'^login$'
,
views
.
UserLoginView
.
as_view
(),
name
=
'login'
),
url
(
r'^login$'
,
views
.
UserLoginView
.
as_view
(),
name
=
'login'
),
url
(
r'^logout$'
,
views
.
UserLogoutView
.
as_view
(),
name
=
'logout'
),
url
(
r'^logout$'
,
views
.
UserLogoutView
.
as_view
(),
name
=
'logout'
),
url
(
r'^password/forgot$'
,
views
.
UserForgotPasswordView
.
as_view
(),
name
=
'forgot-password'
),
url
(
r'^password/forgot$'
,
views
.
UserForgotPasswordView
.
as_view
(),
name
=
'forgot-password'
),
url
(
r'^password/forgot/sendmail-success$'
,
url
(
r'^password/forgot/sendmail-success$'
,
views
.
UserForgotPasswordSendmailSuccessView
.
as_view
(),
name
=
'forgot-password-sendmail-success'
),
views
.
UserForgotPasswordSendmailSuccessView
.
as_view
(),
url
(
r'^password/reset$'
,
views
.
UserResetPasswordView
.
as_view
(),
name
=
'reset-password'
),
name
=
'forgot-password-sendmail-success'
),
url
(
r'^password/reset/success$'
,
views
.
UserResetPasswordSuccessView
.
as_view
(),
url
(
r'^password/reset$'
,
views
.
UserResetPasswordView
.
as_view
(),
name
=
'reset-password'
),
url
(
r'^password/reset/success$'
,
views
.
UserResetPasswordSuccessView
.
as_view
(),
name
=
'reset-password-success'
),
name
=
'reset-password-success'
),
# User view
# User view
url
(
r'^user$'
,
views
.
UserListView
.
as_view
(),
name
=
'user-list'
),
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]+)$'
,
views
.
UserDetailView
.
as_view
(),
url
(
r'^user/(?P<pk>[0-9]+)/asset-permission$'
,
views
.
UserAssetPermissionView
.
as_view
(),
name
=
'user-detail'
),
url
(
r'^user/(?P<pk>[0-9]+)/asset-permission$'
,
views
.
UserAssetPermissionView
.
as_view
(),
name
=
'user-asset-permission'
),
name
=
'user-asset-permission'
),
url
(
r'^user/(?P<pk>[0-9]+)/asset-permission/create$'
,
views
.
UserAssetPermissionCreateView
.
as_view
(),
url
(
r'^user/(?P<pk>[0-9]+)/asset-permission/create$'
,
views
.
UserAssetPermissionCreateView
.
as_view
(),
name
=
'user-asset-permission-create'
),
name
=
'user-asset-permission-create'
),
url
(
r'^user/(?P<pk>[0-9]+)/assets'
,
views
.
UserGrantedAssetView
.
as_view
(),
name
=
'user-granted-asset'
),
url
(
r'^user/(?P<pk>[0-9]+)/assets'
,
url
(
r'^user/(?P<pk>[0-9]+)/login-history'
,
views
.
UserDetailView
.
as_view
(),
name
=
'user-login-history'
),
views
.
UserGrantedAssetView
.
as_view
(),
url
(
r'^user/export/'
,
views
.
UserExportView
.
as_view
(),
name
=
'user-export'
),
name
=
'user-granted-asset'
),
url
(
r'^first-login/$'
,
views
.
UserFirstLoginView
.
as_view
(),
name
=
'user-first-login'
),
url
(
r'^user/(?P<pk>[0-9]+)/login-history'
,
url
(
r'^user/import/$'
,
views
.
BulkImportUserView
.
as_view
(),
name
=
'user-import'
),
views
.
UserDetailView
.
as_view
(),
# url(r'^user/(?P<pk>[0-9]+)/assets-perm$', views.UserDetailView.as_view(), name='user-detail'),
name
=
'user-login-history'
),
url
(
r'^user/create$'
,
views
.
UserCreateView
.
as_view
(),
name
=
'user-create'
),
url
(
r'^user/export/'
,
url
(
r'^user/(?P<pk>[0-9]+)/update$'
,
views
.
UserUpdateView
.
as_view
(),
name
=
'user-update'
),
views
.
UserExportView
.
as_view
(),
name
=
'user-export'
),
url
(
r'^first-login/$'
,
views
.
UserFirstLoginView
.
as_view
(),
name
=
'user-first-login'
),
url
(
r'^user/import/$'
,
views
.
UserBulkImportView
.
as_view
(),
name
=
'user-import'
),
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'
),
# User group view
# User group view
url
(
r'^user-group$'
,
views
.
UserGroupListView
.
as_view
(),
name
=
'user-group-list'
),
url
(
r'^user-group$'
,
url
(
r'^user-group/(?P<pk>[0-9]+)$'
,
views
.
UserGroupDetailView
.
as_view
(),
name
=
'user-group-detail'
),
views
.
UserGroupListView
.
as_view
(),
url
(
r'^user-group/create$'
,
views
.
UserGroupCreateView
.
as_view
(),
name
=
'user-group-create'
),
name
=
'user-group-list'
),
url
(
r'^user-group/(?P<pk>[0-9]+)/update$'
,
views
.
UserGroupUpdateView
.
as_view
(),
name
=
'user-group-update'
),
url
(
r'^user-group/(?P<pk>[0-9]+)$'
,
url
(
r'^user-group/(?P<pk>[0-9]+)/asset-permission$'
,
views
.
UserGroupAssetPermissionView
.
as_view
(),
views
.
UserGroupDetailView
.
as_view
(),
name
=
'user-group-detail'
),
url
(
r'^user-group/create$'
,
views
.
UserGroupCreateView
.
as_view
(),
name
=
'user-group-create'
),
url
(
r'^user-group/(?P<pk>[0-9]+)/update$'
,
views
.
UserGroupUpdateView
.
as_view
(),
name
=
'user-group-update'
),
url
(
r'^user-group/(?P<pk>[0-9]+)/asset-permission$'
,
views
.
UserGroupAssetPermissionView
.
as_view
(),
name
=
'user-group-asset-permission'
),
name
=
'user-group-asset-permission'
),
url
(
r'^user-group/(?P<pk>[0-9]+)/asset-permission/create$'
,
views
.
UserGroupAssetPermissionCreateView
.
as_view
(),
url
(
r'^user-group/(?P<pk>[0-9]+)/asset-permission/create$'
,
views
.
UserGroupAssetPermissionCreateView
.
as_view
(),
name
=
'user-group-asset-permission-create'
),
name
=
'user-group-asset-permission-create'
),
url
(
r'^user-group/(?P<pk>[0-9]+)/assets'
,
views
.
UserGroupGrantedAssetView
.
as_view
(),
url
(
r'^user-group/(?P<pk>[0-9]+)/assets'
,
views
.
UserGroupGrantedAssetView
.
as_view
(),
name
=
'user-group-granted-asset'
),
name
=
'user-group-granted-asset'
),
]
]
apps/users/views/__init__.py
0 → 100644
View file @
25cb47d2
# ~*~ coding: utf-8 ~*~
from
.login
import
*
from
.user
import
*
from
.group
import
*
apps/users/views/group.py
0 → 100644
View file @
25cb47d2
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
from
django
import
forms
from
django.shortcuts
import
reverse
,
redirect
from
django.utils.translation
import
ugettext
as
_
from
django.urls
import
reverse_lazy
from
django.views.generic
import
ListView
from
django.views.generic.base
import
TemplateView
from
django.views.generic.edit
import
CreateView
,
UpdateView
,
FormMixin
from
django.views.generic.detail
import
DetailView
,
SingleObjectMixin
from
common.utils
import
get_logger
from
perms.models
import
AssetPermission
from
..models
import
User
,
UserGroup
from
..utils
import
AdminUserRequiredMixin
from
..
import
forms
__all__
=
[
'UserGroupListView'
,
'UserGroupCreateView'
,
'UserGroupDetailView'
,
'UserGroupUpdateView'
,
'UserGroupAssetPermissionCreateView'
,
'UserGroupAssetPermissionView'
,
'UserGroupGrantedAssetView'
]
logger
=
get_logger
(
__name__
)
class
UserGroupListView
(
AdminUserRequiredMixin
,
TemplateView
):
template_name
=
'users/user_group_list.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
UserGroupListView
,
self
)
.
get_context_data
(
**
kwargs
)
context
.
update
({
'app'
:
_
(
'Users'
),
'action'
:
_
(
'User group list'
)})
return
context
class
UserGroupCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
UserGroup
form_class
=
forms
.
UserGroupForm
template_name
=
'users/user_group_create_update.html'
success_url
=
reverse_lazy
(
'users:user-group-list'
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
UserGroupCreateView
,
self
)
.
get_context_data
(
**
kwargs
)
users
=
User
.
objects
.
all
()
context
.
update
({
'app'
:
_
(
'Users'
),
'action'
:
_
(
'Create user group'
),
'users'
:
users
})
return
context
def
form_valid
(
self
,
form
):
user_group
=
form
.
save
()
users_id_list
=
self
.
request
.
POST
.
getlist
(
'users'
,
[])
users
=
User
.
objects
.
filter
(
id__in
=
users_id_list
)
user_group
.
created_by
=
self
.
request
.
user
.
username
or
'Admin'
user_group
.
users
.
add
(
*
users
)
user_group
.
save
()
return
super
(
UserGroupCreateView
,
self
)
.
form_valid
(
form
)
class
UserGroupUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
UserGroup
form_class
=
forms
.
UserGroupForm
template_name
=
'users/user_group_create_update.html'
success_url
=
reverse_lazy
(
'users:user-group-list'
)
def
get_context_data
(
self
,
**
kwargs
):
# self.object = self.get_object()
context
=
super
(
UserGroupUpdateView
,
self
)
.
get_context_data
(
**
kwargs
)
users
=
User
.
objects
.
all
()
group_users
=
[
user
.
id
for
user
in
self
.
object
.
users
.
all
()]
context
.
update
({
'app'
:
_
(
'Users'
),
'action'
:
_
(
'Update User Group'
),
'users'
:
users
,
'group_users'
:
group_users
})
return
context
def
form_valid
(
self
,
form
):
user_group
=
form
.
save
()
users_id_list
=
self
.
request
.
POST
.
getlist
(
'users'
,
[])
users
=
User
.
objects
.
filter
(
id__in
=
users_id_list
)
user_group
.
users
.
clear
()
user_group
.
users
.
add
(
*
users
)
user_group
.
save
()
return
super
(
UserGroupUpdateView
,
self
)
.
form_valid
(
form
)
class
UserGroupDetailView
(
AdminUserRequiredMixin
,
DetailView
):
model
=
UserGroup
context_object_name
=
'user_group'
template_name
=
'users/user_group_detail.html'
def
get_context_data
(
self
,
**
kwargs
):
users
=
User
.
objects
.
exclude
(
id__in
=
self
.
object
.
users
.
all
())
context
=
{
'app'
:
_
(
'Users'
),
'action'
:
_
(
'User Group Detail'
),
'users'
:
users
,
}
kwargs
.
update
(
context
)
return
super
(
UserGroupDetailView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserGroupAssetPermissionView
(
AdminUserRequiredMixin
,
FormMixin
,
SingleObjectMixin
,
ListView
):
model
=
UserGroup
template_name
=
'users/user_group_asset_permission.html'
context_object_name
=
'user_group'
form_class
=
forms
.
UserPrivateAssetPermissionForm
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
(
queryset
=
UserGroup
.
objects
.
all
())
return
super
(
UserGroupAssetPermissionView
,
self
)
\
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'Users'
,
'action'
:
'User group asset permissions'
,
}
kwargs
.
update
(
context
)
return
super
(
UserGroupAssetPermissionView
,
self
)
\
.
get_context_data
(
**
kwargs
)
class
UserGroupAssetPermissionCreateView
(
AdminUserRequiredMixin
,
CreateView
):
form_class
=
forms
.
UserGroupPrivateAssetPermissionForm
model
=
AssetPermission
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
user_group
=
self
.
get_object
(
queryset
=
UserGroup
.
objects
.
all
())
return
redirect
(
reverse
(
'users:user-group-asset-permission'
,
kwargs
=
{
'pk'
:
user_group
.
id
}))
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
user_group
=
self
.
get_object
(
queryset
=
UserGroup
.
objects
.
all
())
return
super
(
UserGroupAssetPermissionCreateView
,
self
)
\
.
post
(
request
,
*
args
,
**
kwargs
)
def
get_form
(
self
,
form_class
=
None
):
form
=
super
(
UserGroupAssetPermissionCreateView
,
self
)
\
.
get_form
(
form_class
=
form_class
)
form
.
user_group
=
self
.
user_group
return
form
def
form_invalid
(
self
,
form
):
return
redirect
(
reverse
(
'users:user-group-asset-permission'
,
kwargs
=
{
'pk'
:
self
.
user_group
.
id
}))
def
get_success_url
(
self
):
return
reverse
(
'users:user-group-asset-permission'
,
kwargs
=
{
'pk'
:
self
.
user_group
.
id
})
class
UserGroupGrantedAssetView
(
AdminUserRequiredMixin
,
DetailView
):
model
=
User
template_name
=
'users/user_group_granted_asset.html'
context_object_name
=
'user_group'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
(
queryset
=
UserGroup
.
objects
.
all
())
return
super
(
UserGroupGrantedAssetView
,
self
)
\
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'User'
,
'action'
:
'User group granted asset'
,
}
kwargs
.
update
(
context
)
return
super
(
UserGroupGrantedAssetView
,
self
)
.
get_context_data
(
**
kwargs
)
apps/users/views/login.py
0 → 100644
View file @
25cb47d2
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
from
django
import
forms
from
django.contrib.auth
import
login
as
auth_login
,
logout
as
auth_logout
from
django.contrib.auth.mixins
import
LoginRequiredMixin
from
django.core.files.storage
import
default_storage
from
django.http
import
HttpResponseRedirect
from
django.shortcuts
import
reverse
,
redirect
from
django.utils.decorators
import
method_decorator
from
django.utils.translation
import
ugettext
as
_
from
django.views.decorators.cache
import
never_cache
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.edit
import
FormView
from
formtools.wizard.views
import
SessionWizardView
from
common.utils
import
get_object_or_none
from
..models
import
User
from
..utils
import
send_reset_password_mail
from
..hands
import
write_login_log_async
from
..
import
forms
__all__
=
[
'UserLoginView'
,
'UserLogoutView'
,
'UserForgotPasswordView'
,
'UserForgotPasswordSendmailSuccessView'
,
'UserResetPasswordView'
,
'UserResetPasswordSuccessView'
,
'UserFirstLoginView'
]
@method_decorator
(
sensitive_post_parameters
(),
name
=
'dispatch'
)
@method_decorator
(
csrf_protect
,
name
=
'dispatch'
)
@method_decorator
(
never_cache
,
name
=
'dispatch'
)
class
UserLoginView
(
FormView
):
template_name
=
'users/login.html'
form_class
=
forms
.
UserLoginForm
redirect_field_name
=
'next'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
request
.
user
.
is_staff
:
return
redirect
(
self
.
get_success_url
())
return
super
(
UserLoginView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
form_valid
(
self
,
form
):
auth_login
(
self
.
request
,
form
.
get_user
())
login_ip
=
self
.
request
.
META
.
get
(
'REMOTE_ADDR'
,
''
)
user_agent
=
self
.
request
.
META
.
get
(
'HTTP_USER_AGENT'
,
''
)
write_login_log_async
.
delay
(
self
.
request
.
user
.
username
,
self
.
request
.
user
.
name
,
login_type
=
'W'
,
login_ip
=
login_ip
,
user_agent
=
user_agent
)
return
redirect
(
self
.
get_success_url
())
def
get_success_url
(
self
):
if
self
.
request
.
user
.
is_first_login
:
return
reverse
(
'users:user-first-login'
)
return
self
.
request
.
POST
.
get
(
self
.
redirect_field_name
,
self
.
request
.
GET
.
get
(
self
.
redirect_field_name
,
reverse
(
'index'
)))
@method_decorator
(
never_cache
,
name
=
'dispatch'
)
class
UserLogoutView
(
TemplateView
):
template_name
=
'flash_message_standalone.html'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
auth_logout
(
request
)
return
super
(
UserLogoutView
,
self
)
.
get
(
request
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'title'
:
_
(
'Logout success'
),
'messages'
:
_
(
'Logout success, return login page'
),
'redirect_url'
:
reverse
(
'users:login'
),
'auto_redirect'
:
True
,
}
kwargs
.
update
(
context
)
return
super
(
UserLogoutView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserForgotPasswordView
(
TemplateView
):
template_name
=
'users/forgot_password.html'
def
post
(
self
,
request
):
email
=
request
.
POST
.
get
(
'email'
)
user
=
get_object_or_none
(
User
,
email
=
email
)
if
not
user
:
return
self
.
get
(
request
,
errors
=
_
(
'Email address invalid, input again'
))
else
:
send_reset_password_mail
(
user
)
return
HttpResponseRedirect
(
reverse
(
'users:forgot-password-sendmail-success'
))
class
UserForgotPasswordSendmailSuccessView
(
TemplateView
):
template_name
=
'flash_message_standalone.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'title'
:
_
(
'Send reset password message'
),
'messages'
:
_
(
'Send reset password mail success, '
'login your mail box and follow it '
),
'redirect_url'
:
reverse
(
'users:login'
),
}
kwargs
.
update
(
context
)
return
super
(
UserForgotPasswordSendmailSuccessView
,
self
)
\
.
get_context_data
(
**
kwargs
)
class
UserResetPasswordSuccessView
(
TemplateView
):
template_name
=
'flash_message_standalone.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'title'
:
_
(
'Reset password success'
),
'messages'
:
_
(
'Reset password success, return to login page'
),
'redirect_url'
:
reverse
(
'users:login'
),
'auto_redirect'
:
True
,
}
kwargs
.
update
(
context
)
return
super
(
UserResetPasswordSuccessView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserResetPasswordView
(
TemplateView
):
template_name
=
'users/reset_password.html'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
token
=
request
.
GET
.
get
(
'token'
)
user
=
User
.
validate_reset_token
(
token
)
if
not
user
:
kwargs
.
update
({
'errors'
:
_
(
'Token invalid or expired'
)})
return
super
(
UserResetPasswordView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
password
=
request
.
POST
.
get
(
'password'
)
password_confirm
=
request
.
POST
.
get
(
'password-confirm'
)
token
=
request
.
GET
.
get
(
'token'
)
if
password
!=
password_confirm
:
return
self
.
get
(
request
,
errors
=
_
(
'Password not same'
))
user
=
User
.
validate_reset_token
(
token
)
if
not
user
:
return
self
.
get
(
request
,
errors
=
_
(
'Token invalid or expired'
))
user
.
reset_password
(
password
)
return
HttpResponseRedirect
(
reverse
(
'users:reset-password-success'
))
class
UserFirstLoginView
(
LoginRequiredMixin
,
SessionWizardView
):
template_name
=
'users/first_login.html'
form_list
=
[
forms
.
UserInfoForm
,
forms
.
UserKeyForm
]
file_storage
=
default_storage
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
if
request
.
user
.
is_authenticated
()
and
not
request
.
user
.
is_first_login
:
return
redirect
(
reverse
(
'index'
))
return
super
(
UserFirstLoginView
,
self
)
.
dispatch
(
request
,
*
args
,
**
kwargs
)
def
done
(
self
,
form_list
,
form_dict
,
**
kwargs
):
user
=
self
.
request
.
user
for
form
in
form_list
:
for
field
in
form
:
if
field
.
value
():
setattr
(
user
,
field
.
name
,
field
.
value
())
if
field
.
name
==
'enable_otp'
:
user
.
enable_otp
=
field
.
value
()
user
.
is_first_login
=
False
user
.
is_public_key_valid
=
True
user
.
save
()
return
redirect
(
reverse
(
'index'
))
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
UserFirstLoginView
,
self
)
.
get_context_data
(
**
kwargs
)
context
.
update
({
'app'
:
_
(
'Users'
),
'action'
:
_
(
'First Login'
)})
return
context
def
get_form_initial
(
self
,
step
):
user
=
self
.
request
.
user
if
step
==
'0'
:
return
{
'name'
:
user
.
name
or
user
.
username
,
'enable_otp'
:
user
.
enable_otp
or
True
,
'wechat'
:
user
.
wechat
or
''
,
'phone'
:
user
.
phone
or
''
}
return
super
(
UserFirstLoginView
,
self
)
.
get_form_initial
(
step
)
def
get_form
(
self
,
step
=
None
,
data
=
None
,
files
=
None
):
form
=
super
(
UserFirstLoginView
,
self
)
.
get_form
(
step
,
data
,
files
)
if
step
is
None
:
step
=
self
.
steps
.
current
if
step
==
'1'
:
form
.
user
=
self
.
request
.
user
return
form
apps/users/views.py
→
apps/users/views
/user
.py
View file @
25cb47d2
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
from
__future__
import
unicode_literals
import
json
import
uuid
import
uuid
import
json
from
django.shortcuts
import
redirect
from
openpyxl
import
Workbook
from
openpyxl
import
Workbook
from
openpyxl.writer.excel
import
save_virtual_workbook
from
openpyxl.writer.excel
import
save_virtual_workbook
from
openpyxl
import
load_workbook
from
openpyxl
import
load_workbook
from
django
import
forms
from
django
import
forms
from
django.utils
import
timezone
from
django.core.cache
import
cache
from
django.core.cache
import
cache
from
django.db
import
IntegrityError
from
django.http
import
HttpResponse
,
JsonResponse
from
django.contrib.auth
import
login
as
auth_login
,
logout
as
auth_logout
from
django.contrib.auth.mixins
import
LoginRequiredMixin
from
django.contrib.messages.views
import
SuccessMessageMixin
from
django.contrib.messages.views
import
SuccessMessageMixin
from
django.core.files.storage
import
default_storage
from
django.urls
import
reverse_lazy
,
reverse
from
django.http
import
HttpResponseRedirect
,
HttpResponse
,
JsonResponse
from
django.utils
import
timezone
from
django.shortcuts
import
reverse
,
redirect
from
django.utils.decorators
import
method_decorator
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
django.u
rls
import
reverse_lazy
from
django.u
tils.decorators
import
method_decorator
from
django.views
import
View
from
django.views
import
View
from
django.views.decorators.cache
import
never_cache
from
django.views.generic
import
ListView
from
django.views.decorators.csrf
import
csrf_protect
,
csrf_exempt
from
django.views.decorators.debug
import
sensitive_post_parameters
from
django.views.generic.base
import
TemplateView
from
django.views.generic.base
import
TemplateView
from
django.views.generic.
list
import
ListView
from
django.views.generic.
edit
import
CreateView
,
UpdateView
,
FormMixin
,
\
from
django.views.generic.edit
import
CreateView
,
DeleteView
,
UpdateView
,
FormView
,
SingleObjectMixin
,
FormMixin
FormView
from
django.views.generic.detail
import
DetailView
from
django.views.generic.detail
import
DetailView
,
SingleObjectMixin
from
formtools.wizard.views
import
SessionWizardView
from
django.views.decorators.csrf
import
csrf_exempt
from
common.mixins
import
JSONResponseMixin
from
common.mixins
import
JSONResponseMixin
from
common.utils
import
get_
object_or_none
,
get_
logger
from
common.utils
import
get_logger
from
perms.models
import
AssetPermission
from
perms.models
import
AssetPermission
from
.models
import
User
,
UserGroup
from
..models
import
User
,
UserGroup
from
.utils
import
AdminUserRequiredMixin
,
user_add_success_next
,
send_reset_password_mail
from
..utils
import
AdminUserRequiredMixin
,
user_add_success_next
from
.hands
import
write_login_log_async
from
..
import
forms
from
.
import
forms
__all__
=
[
'UserListView'
,
'UserCreateView'
,
'UserDetailView'
,
'UserUpdateView'
,
'UserAssetPermissionCreateView'
,
'UserAssetPermissionView'
,
'UserGrantedAssetView'
,
'UserExportView'
,
'UserBulkImportView'
]
logger
=
get_logger
(
__name__
)
logger
=
get_logger
(
__name__
)
@method_decorator
(
sensitive_post_parameters
(),
name
=
'dispatch'
)
@method_decorator
(
csrf_protect
,
name
=
'dispatch'
)
@method_decorator
(
never_cache
,
name
=
'dispatch'
)
class
UserLoginView
(
FormView
):
template_name
=
'users/login.html'
form_class
=
forms
.
UserLoginForm
redirect_field_name
=
'next'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
request
.
user
.
is_staff
:
return
redirect
(
self
.
get_success_url
())
return
super
(
UserLoginView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
form_valid
(
self
,
form
):
auth_login
(
self
.
request
,
form
.
get_user
())
login_ip
=
self
.
request
.
META
.
get
(
'REMOTE_ADDR'
,
''
)
user_agent
=
self
.
request
.
META
.
get
(
'HTTP_USER_AGENT'
,
''
)
write_login_log_async
.
delay
(
self
.
request
.
user
.
username
,
self
.
request
.
user
.
name
,
login_type
=
'W'
,
login_ip
=
login_ip
,
user_agent
=
user_agent
)
return
redirect
(
self
.
get_success_url
())
def
get_success_url
(
self
):
if
self
.
request
.
user
.
is_first_login
:
return
reverse
(
'users:user-first-login'
)
return
self
.
request
.
POST
.
get
(
self
.
redirect_field_name
,
self
.
request
.
GET
.
get
(
self
.
redirect_field_name
,
reverse
(
'index'
)))
@method_decorator
(
never_cache
,
name
=
'dispatch'
)
class
UserLogoutView
(
TemplateView
):
template_name
=
'flash_message_standalone.html'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
auth_logout
(
request
)
return
super
(
UserLogoutView
,
self
)
.
get
(
request
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'title'
:
_
(
'Logout success'
),
'messages'
:
_
(
'Logout success, return login page'
),
'redirect_url'
:
reverse
(
'users:login'
),
'auto_redirect'
:
True
,
}
kwargs
.
update
(
context
)
return
super
(
UserLogoutView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserListView
(
AdminUserRequiredMixin
,
TemplateView
):
class
UserListView
(
AdminUserRequiredMixin
,
TemplateView
):
template_name
=
'users/user_list.html'
template_name
=
'users/user_list.html'
...
@@ -159,327 +107,55 @@ class UserDetailView(AdminUserRequiredMixin, DetailView):
...
@@ -159,327 +107,55 @@ class UserDetailView(AdminUserRequiredMixin, DetailView):
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
groups
=
UserGroup
.
objects
.
exclude
(
id__in
=
self
.
object
.
groups
.
all
())
groups
=
UserGroup
.
objects
.
exclude
(
id__in
=
self
.
object
.
groups
.
all
())
context
=
{
'app'
:
_
(
'Users'
),
'action'
:
_
(
'User detail'
),
'groups'
:
groups
}
kwargs
.
update
(
context
)
return
super
(
UserDetailView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserGroupListView
(
AdminUserRequiredMixin
,
TemplateView
):
template_name
=
'users/user_group_list.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
UserGroupListView
,
self
)
.
get_context_data
(
**
kwargs
)
context
.
update
({
'app'
:
_
(
'Users'
),
'action'
:
_
(
'User group list'
)})
return
context
class
UserGroupCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
UserGroup
form_class
=
forms
.
UserGroupForm
template_name
=
'users/user_group_create_update.html'
success_url
=
reverse_lazy
(
'users:user-group-list'
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
UserGroupCreateView
,
self
)
.
get_context_data
(
**
kwargs
)
users
=
User
.
objects
.
all
()
context
.
update
({
'app'
:
_
(
'Users'
),
'action'
:
_
(
'Create user group'
),
'users'
:
users
})
return
context
def
form_valid
(
self
,
form
):
user_group
=
form
.
save
()
users_id_list
=
self
.
request
.
POST
.
getlist
(
'users'
,
[])
users
=
User
.
objects
.
filter
(
id__in
=
users_id_list
)
user_group
.
created_by
=
self
.
request
.
user
.
username
or
'Admin'
user_group
.
users
.
add
(
*
users
)
user_group
.
save
()
return
super
(
UserGroupCreateView
,
self
)
.
form_valid
(
form
)
class
UserGroupUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
UserGroup
form_class
=
forms
.
UserGroupForm
template_name
=
'users/user_group_create_update.html'
success_url
=
reverse_lazy
(
'users:user-group-list'
)
def
get_context_data
(
self
,
**
kwargs
):
# self.object = self.get_object()
context
=
super
(
UserGroupUpdateView
,
self
)
.
get_context_data
(
**
kwargs
)
users
=
User
.
objects
.
all
()
group_users
=
[
user
.
id
for
user
in
self
.
object
.
users
.
all
()]
context
.
update
({
'app'
:
_
(
'Users'
),
'action'
:
_
(
'Update User Group'
),
'users'
:
users
,
'group_users'
:
group_users
})
return
context
def
form_valid
(
self
,
form
):
user_group
=
form
.
save
()
users_id_list
=
self
.
request
.
POST
.
getlist
(
'users'
,
[])
users
=
User
.
objects
.
filter
(
id__in
=
users_id_list
)
user_group
.
users
.
clear
()
user_group
.
users
.
add
(
*
users
)
user_group
.
save
()
return
super
(
UserGroupUpdateView
,
self
)
.
form_valid
(
form
)
class
UserGroupDetailView
(
AdminUserRequiredMixin
,
DetailView
):
model
=
UserGroup
context_object_name
=
'user_group'
template_name
=
'users/user_group_detail.html'
def
get_context_data
(
self
,
**
kwargs
):
users
=
User
.
objects
.
exclude
(
id__in
=
self
.
object
.
users
.
all
())
context
=
{
context
=
{
'app'
:
_
(
'Users'
),
'app'
:
_
(
'Users'
),
'action'
:
_
(
'User
Group D
etail'
),
'action'
:
_
(
'User
d
etail'
),
'
users'
:
users
,
'
groups'
:
groups
}
}
kwargs
.
update
(
context
)
kwargs
.
update
(
context
)
return
super
(
UserGroupDetailView
,
self
)
.
get_context_data
(
**
kwargs
)
return
super
(
UserDetailView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserForgotPasswordView
(
TemplateView
):
template_name
=
'users/forgot_password.html'
def
post
(
self
,
request
):
email
=
request
.
POST
.
get
(
'email'
)
user
=
get_object_or_none
(
User
,
email
=
email
)
if
not
user
:
return
self
.
get
(
request
,
errors
=
_
(
'Email address invalid, input again'
))
else
:
send_reset_password_mail
(
user
)
return
HttpResponseRedirect
(
reverse
(
'users:forgot-password-sendmail-success'
))
class
UserForgotPasswordSendmailSuccessView
(
TemplateView
):
template_name
=
'flash_message_standalone.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'title'
:
_
(
'Send reset password message'
),
'messages'
:
_
(
'Send reset password mail success, login your mail box and follow it '
),
'redirect_url'
:
reverse
(
'users:login'
),
}
kwargs
.
update
(
context
)
return
super
(
UserForgotPasswordSendmailSuccessView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserResetPasswordSuccessView
(
TemplateView
):
template_name
=
'flash_message_standalone.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'title'
:
_
(
'Reset password success'
),
'messages'
:
_
(
'Reset password success, return to login page'
),
'redirect_url'
:
reverse
(
'users:login'
),
'auto_redirect'
:
True
,
}
kwargs
.
update
(
context
)
return
super
(
UserResetPasswordSuccessView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserResetPasswordView
(
TemplateView
):
template_name
=
'users/reset_password.html'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
token
=
request
.
GET
.
get
(
'token'
)
user
=
User
.
validate_reset_token
(
token
)
if
not
user
:
kwargs
.
update
({
'errors'
:
_
(
'Token invalid or expired'
)})
return
super
(
UserResetPasswordView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
password
=
request
.
POST
.
get
(
'password'
)
password_confirm
=
request
.
POST
.
get
(
'password-confirm'
)
token
=
request
.
GET
.
get
(
'token'
)
if
password
!=
password_confirm
:
return
self
.
get
(
request
,
errors
=
_
(
'Password not same'
))
user
=
User
.
validate_reset_token
(
token
)
if
not
user
:
return
self
.
get
(
request
,
errors
=
_
(
'Token invalid or expired'
))
user
.
reset_password
(
password
)
return
HttpResponseRedirect
(
reverse
(
'users:reset-password-success'
))
class
UserFirstLoginView
(
LoginRequiredMixin
,
SessionWizardView
):
template_name
=
'users/first_login.html'
form_list
=
[
forms
.
UserInfoForm
,
forms
.
UserKeyForm
]
file_storage
=
default_storage
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
if
request
.
user
.
is_authenticated
()
and
not
request
.
user
.
is_first_login
:
return
redirect
(
reverse
(
'index'
))
return
super
(
UserFirstLoginView
,
self
)
.
dispatch
(
request
,
*
args
,
**
kwargs
)
def
done
(
self
,
form_list
,
form_dict
,
**
kwargs
):
user
=
self
.
request
.
user
for
form
in
form_list
:
for
field
in
form
:
if
field
.
value
():
setattr
(
user
,
field
.
name
,
field
.
value
())
if
field
.
name
==
'enable_otp'
:
user
.
enable_otp
=
field
.
value
()
user
.
is_first_login
=
False
user
.
is_public_key_valid
=
True
user
.
save
()
return
redirect
(
reverse
(
'index'
))
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
UserFirstLoginView
,
self
)
.
get_context_data
(
**
kwargs
)
context
.
update
({
'app'
:
_
(
'Users'
),
'action'
:
_
(
'First Login'
)})
return
context
def
get_form_initial
(
self
,
step
):
user
=
self
.
request
.
user
if
step
==
'0'
:
return
{
'name'
:
user
.
name
or
user
.
username
,
'enable_otp'
:
user
.
enable_otp
or
True
,
'wechat'
:
user
.
wechat
or
''
,
'phone'
:
user
.
phone
or
''
}
return
super
(
UserFirstLoginView
,
self
)
.
get_form_initial
(
step
)
def
get_form
(
self
,
step
=
None
,
data
=
None
,
files
=
None
):
form
=
super
(
UserFirstLoginView
,
self
)
.
get_form
(
step
,
data
,
files
)
if
step
is
None
:
step
=
self
.
steps
.
current
if
step
==
'1'
:
form
.
user
=
self
.
request
.
user
return
form
class
UserAssetPermissionView
(
AdminUserRequiredMixin
,
FormMixin
,
SingleObjectMixin
,
ListView
):
model
=
User
template_name
=
'users/user_asset_permission.html'
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_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'Users'
,
'action'
:
'User asset permissions'
,
}
kwargs
.
update
(
context
)
return
super
(
UserAssetPermissionView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserGroupAssetPermissionView
(
AdminUserRequiredMixin
,
FormMixin
,
SingleObjectMixin
,
ListView
):
model
=
UserGroup
template_name
=
'users/user_group_asset_permission.html'
context_object_name
=
'user_group'
form_class
=
forms
.
UserPrivateAssetPermissionForm
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
(
queryset
=
UserGroup
.
objects
.
all
())
return
super
(
UserGroupAssetPermissionView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'Users'
,
'action'
:
'User group asset permissions'
,
}
kwargs
.
update
(
context
)
return
super
(
UserGroupAssetPermissionView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserAssetPermissionCreateView
(
AdminUserRequiredMixin
,
CreateView
):
@method_decorator
(
csrf_exempt
,
name
=
'dispatch'
)
form_class
=
forms
.
UserPrivateAssetPermissionForm
class
UserExportView
(
View
):
model
=
AssetPermission
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
user
=
self
.
get_object
(
queryset
=
User
.
objects
.
all
())
spm
=
request
.
GET
.
get
(
'spm'
,
''
)
return
redirect
(
reverse
(
'users:user-asset-permission'
,
kwargs
=
{
'pk'
:
user
.
id
}))
users_id
=
cache
.
get
(
spm
)
if
not
users_id
and
not
isinstance
(
users_id
,
list
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
return
HttpResponse
(
'May be expired'
,
status
=
404
)
self
.
user
=
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
return
form
def
form_invalid
(
self
,
form
):
return
redirect
(
reverse
(
'users:user-asset-permission'
,
kwargs
=
{
'pk'
:
self
.
user
.
id
}))
def
get_success_url
(
self
):
return
reverse
(
'users:user-asset-permission'
,
kwargs
=
{
'pk'
:
self
.
user
.
id
})
users
=
User
.
objects
.
filter
(
id__in
=
users_id
)
wb
=
Workbook
()
ws
=
wb
.
active
ws
.
title
=
'User'
header
=
[
"name"
,
'username'
,
'email'
,
'groups'
,
"role"
,
"phone"
,
"wechat"
,
"comment"
]
ws
.
append
(
header
)
class
UserGroupAssetPermissionCreateView
(
AdminUserRequiredMixin
,
CreateView
):
for
user
in
users
:
form_class
=
forms
.
UserGroupPrivateAssetPermissionForm
ws
.
append
([
user
.
name
,
user
.
username
,
user
.
email
,
model
=
AssetPermission
','
.
join
([
group
.
name
for
group
in
user
.
groups
.
all
()]),
user
.
role
,
user
.
phone
,
user
.
wechat
,
user
.
comment
])
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
filename
=
'users-{}.xlsx'
.
format
(
user_group
=
self
.
get_object
(
queryset
=
UserGroup
.
objects
.
all
())
timezone
.
localtime
(
timezone
.
now
())
.
strftime
(
'
%
Y-
%
m-
%
d_
%
H-
%
M-
%
S'
))
return
redirect
(
reverse
(
'users:user-group-asset-permission'
,
kwargs
=
{
'pk'
:
user_group
.
id
}))
response
=
HttpResponse
(
save_virtual_workbook
(
wb
),
content_type
=
'applications/vnd.ms-excel'
)
response
[
'Content-Disposition'
]
=
'attachment; filename="
%
s"'
%
filename
return
response
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
user_group
=
self
.
get_object
(
queryset
=
UserGroup
.
objects
.
all
())
try
:
return
super
(
UserGroupAssetPermissionCreateView
,
self
)
.
post
(
request
,
*
args
,
**
kwargs
)
users_id
=
json
.
loads
(
request
.
body
)
.
get
(
'users_id'
,
[])
except
ValueError
:
def
get_form
(
self
,
form_class
=
None
):
return
HttpResponse
(
'Json object not valid'
,
status
=
400
)
form
=
super
(
UserGroupAssetPermissionCreateView
,
self
)
.
get_form
(
form_class
=
form_class
)
spm
=
uuid
.
uuid4
()
.
get_hex
()
form
.
user_group
=
self
.
user_group
cache
.
set
(
spm
,
users_id
,
300
)
return
form
url
=
reverse
(
'users:user-export'
)
+
'?spm=
%
s'
%
spm
return
JsonResponse
({
'redirect'
:
url
})
def
form_invalid
(
self
,
form
):
return
redirect
(
reverse
(
'users:user-group-asset-permission'
,
kwargs
=
{
'pk'
:
self
.
user_group
.
id
}))
def
get_success_url
(
self
):
return
reverse
(
'users:user-group-asset-permission'
,
kwargs
=
{
'pk'
:
self
.
user_group
.
id
})
class
UserGrantedAssetView
(
AdminUserRequiredMixin
,
DetailView
):
model
=
User
template_name
=
'users/user_granted_asset.html'
context_object_name
=
'user'
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_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'User'
,
'action'
:
'User granted asset'
,
}
kwargs
.
update
(
context
)
return
super
(
UserGrantedAssetView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserGroupGrantedAssetView
(
AdminUserRequiredMixin
,
DetailView
):
model
=
User
template_name
=
'users/user_group_granted_asset.html'
context_object_name
=
'user_group'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
(
queryset
=
UserGroup
.
objects
.
all
())
return
super
(
UserGroupGrantedAssetView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'User'
,
'action'
:
'User group granted asset'
,
}
kwargs
.
update
(
context
)
return
super
(
UserGroupGrantedAssetView
,
self
)
.
get_context_data
(
**
kwargs
)
class
BulkImportUser
View
(
AdminUserRequiredMixin
,
JSONResponseMixin
,
FormView
):
class
UserBulkImport
View
(
AdminUserRequiredMixin
,
JSONResponseMixin
,
FormView
):
form_class
=
forms
.
FileForm
form_class
=
forms
.
FileForm
def
form_invalid
(
self
,
form
):
def
form_invalid
(
self
,
form
):
...
@@ -526,7 +202,7 @@ class BulkImportUserView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
...
@@ -526,7 +202,7 @@ class BulkImportUserView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
user
=
User
.
objects
.
create
(
**
user_dict
)
user
=
User
.
objects
.
create
(
**
user_dict
)
user_add_success_next
(
user
)
user_add_success_next
(
user
)
created
.
append
(
user_dict
[
'username'
])
created
.
append
(
user_dict
[
'username'
])
except
IntegrityError
as
e
:
except
User
.
IntegrityError
as
e
:
user
=
User
.
objects
.
filter
(
username
=
user_dict
[
'username'
])
user
=
User
.
objects
.
filter
(
username
=
user_dict
[
'username'
])
if
not
user
:
if
not
user
:
failed
.
append
(
user_dict
[
'username'
])
failed
.
append
(
user_dict
[
'username'
])
...
@@ -551,43 +227,74 @@ class BulkImportUserView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
...
@@ -551,43 +227,74 @@ class BulkImportUserView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
'failed'
:
failed
,
'failed'
:
failed
,
'failed_info'
:
'Failed {}'
.
format
(
len
(
failed
)),
'failed_info'
:
'Failed {}'
.
format
(
len
(
failed
)),
'valid'
:
True
,
'valid'
:
True
,
'msg'
:
'Created: {}. Updated: {}, Error: {}'
.
format
(
len
(
created
),
len
(
updated
),
len
(
failed
))
'msg'
:
'Created: {}. Updated: {}, Error: {}'
.
format
(
len
(
created
),
len
(
updated
),
len
(
failed
))
}
}
return
self
.
render_json_response
(
data
)
return
self
.
render_json_response
(
data
)
@method_decorator
(
csrf_exempt
,
name
=
'dispatch'
)
class
UserAssetPermissionView
(
AdminUserRequiredMixin
,
FormMixin
,
class
UserExportView
(
View
):
SingleObjectMixin
,
ListView
):
model
=
User
template_name
=
'users/user_asset_permission.html'
context_object_name
=
'user'
form_class
=
forms
.
UserPrivateAssetPermissionForm
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
spm
=
request
.
GET
.
get
(
'spm'
,
''
)
self
.
object
=
self
.
get_object
(
queryset
=
User
.
objects
.
all
())
users_id
=
cache
.
get
(
spm
)
return
super
(
UserAssetPermissionView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
if
not
users_id
and
not
isinstance
(
users_id
,
list
):
return
HttpResponse
(
'May be expired'
,
status
=
404
)
users
=
User
.
objects
.
filter
(
id__in
=
users_id
)
def
get_context_data
(
self
,
**
kwargs
):
wb
=
Workbook
()
context
=
{
ws
=
wb
.
active
'app'
:
'Users'
,
ws
.
title
=
'User'
'action'
:
'User asset permissions'
,
header
=
[
"name"
,
'username'
,
'email'
,
'groups'
,
"role"
,
"phone"
,
"wechat"
,
"comment"
]
}
ws
.
append
(
header
)
kwargs
.
update
(
context
)
return
super
(
UserAssetPermissionView
,
self
)
.
get_context_data
(
**
kwargs
)
for
user
in
users
:
ws
.
append
([
user
.
name
,
user
.
username
,
user
.
email
,
','
.
join
([
group
.
name
for
group
in
user
.
groups
.
all
()]),
user
.
role
,
user
.
phone
,
user
.
wechat
,
user
.
comment
])
filename
=
'users-{}.xlsx'
.
format
(
timezone
.
localtime
(
timezone
.
now
())
.
strftime
(
'
%
Y-
%
m-
%
d_
%
H-
%
M-
%
S'
))
class
UserAssetPermissionCreateView
(
AdminUserRequiredMixin
,
CreateView
):
response
=
HttpResponse
(
save_virtual_workbook
(
wb
),
content_type
=
'applications/vnd.ms-excel'
)
form_class
=
forms
.
UserPrivateAssetPermissionForm
response
[
'Content-Disposition'
]
=
'attachment; filename="
%
s"'
%
filename
model
=
AssetPermission
return
response
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
user
=
self
.
get_object
(
queryset
=
User
.
objects
.
all
())
return
redirect
(
reverse
(
'users:user-asset-permission'
,
kwargs
=
{
'pk'
:
user
.
id
}))
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
try
:
self
.
user
=
self
.
get_object
(
queryset
=
User
.
objects
.
all
())
users_id
=
json
.
loads
(
request
.
body
)
.
get
(
'users_id'
,
[])
return
super
(
UserAssetPermissionCreateView
,
self
)
\
except
ValueError
:
.
post
(
request
,
*
args
,
**
kwargs
)
return
HttpResponse
(
'Json object not valid'
,
status
=
400
)
spm
=
uuid
.
uuid4
()
.
get_hex
()
def
get_form
(
self
,
form_class
=
None
):
cache
.
set
(
spm
,
users_id
,
300
)
form
=
super
(
UserAssetPermissionCreateView
,
self
)
\
url
=
reverse
(
'users:user-export'
)
+
'?spm=
%
s'
%
spm
.
get_form
(
form_class
=
form_class
)
return
JsonResponse
({
'redirect'
:
url
})
form
.
user
=
self
.
user
return
form
def
form_invalid
(
self
,
form
):
return
redirect
(
reverse
(
'users:user-asset-permission'
,
kwargs
=
{
'pk'
:
self
.
user
.
id
}))
def
get_success_url
(
self
):
return
reverse
(
'users:user-asset-permission'
,
kwargs
=
{
'pk'
:
self
.
user
.
id
})
class
UserGrantedAssetView
(
AdminUserRequiredMixin
,
DetailView
):
model
=
User
template_name
=
'users/user_granted_asset.html'
context_object_name
=
'user'
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_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'User'
,
'action'
:
'User granted asset'
,
}
kwargs
.
update
(
context
)
return
super
(
UserGrantedAssetView
,
self
)
.
get_context_data
(
**
kwargs
)
\ No newline at end of file
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