Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gjl2004yn
jumpserver
提交
8a5a4f33
J
jumpserver
项目概览
gjl2004yn
/
jumpserver
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jumpserver
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8a5a4f33
编写于
9月 18, 2016
作者:
X
xiaoyu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix #14
上级
8cdc4674
变更
13
展开全部
隐藏空白更改
内联
并排
Showing
13 changed file
with
114 addition
and
18 deletion
+114
-18
apps/static/css/style.css
apps/static/css/style.css
+2
-2
apps/static/js/plugins/toastr/toastr.js.map
apps/static/js/plugins/toastr/toastr.js.map
+0
-1
apps/static/js/plugins/toastr/toastr.min.js
apps/static/js/plugins/toastr/toastr.min.js
+0
-1
apps/templates/base.html
apps/templates/base.html
+21
-2
apps/users/api.py
apps/users/api.py
+13
-2
apps/users/forms.py
apps/users/forms.py
+3
-1
apps/users/models.py
apps/users/models.py
+1
-0
apps/users/serializers.py
apps/users/serializers.py
+14
-7
apps/users/templates/users/_user_update_pk_modal.html
apps/users/templates/users/_user_update_pk_modal.html
+8
-0
apps/users/templates/users/first_login.html
apps/users/templates/users/first_login.html
+2
-0
apps/users/templates/users/user_detail.html
apps/users/templates/users/user_detail.html
+36
-0
apps/users/urls.py
apps/users/urls.py
+1
-0
apps/users/views.py
apps/users/views.py
+13
-2
未找到文件。
apps/static/css/style.css
浏览文件 @
8a5a4f33
@import
url("https://fonts.
useso
.com/css?family=Open+Sans:300,400,600,700")
;
@import
url("https://fonts.
useso
.com/css?family=Roboto:400,300,500,700")
;
@import
url("https://fonts.
googleapis
.com/css?family=Open+Sans:300,400,600,700")
;
@import
url("https://fonts.
googleapis
.com/css?family=Roboto:400,300,500,700")
;
/*
*
* INSPINIA - Responsive Admin Theme
...
...
apps/static/js/plugins/toastr/toastr.js.map
已删除
100644 → 0
浏览文件 @
8cdc4674
此差异已折叠。
点击以展开。
apps/static/js/plugins/toastr/toastr.min.js
浏览文件 @
8a5a4f33
!
function
(
e
){
e
([
"
jquery
"
],
function
(
e
){
return
function
(){
function
t
(
e
,
t
,
n
){
return
g
({
type
:
O
.
error
,
iconClass
:
m
().
iconClasses
.
error
,
message
:
e
,
optionsOverride
:
n
,
title
:
t
})}
function
n
(
t
,
n
){
return
t
||
(
t
=
m
()),
v
=
e
(
"
#
"
+
t
.
containerId
),
v
.
length
?
v
:(
n
&&
(
v
=
d
(
t
)),
v
)}
function
o
(
e
,
t
,
n
){
return
g
({
type
:
O
.
info
,
iconClass
:
m
().
iconClasses
.
info
,
message
:
e
,
optionsOverride
:
n
,
title
:
t
})}
function
s
(
e
){
C
=
e
}
function
i
(
e
,
t
,
n
){
return
g
({
type
:
O
.
success
,
iconClass
:
m
().
iconClasses
.
success
,
message
:
e
,
optionsOverride
:
n
,
title
:
t
})}
function
a
(
e
,
t
,
n
){
return
g
({
type
:
O
.
warning
,
iconClass
:
m
().
iconClasses
.
warning
,
message
:
e
,
optionsOverride
:
n
,
title
:
t
})}
function
r
(
e
,
t
){
var
o
=
m
();
v
||
n
(
o
),
u
(
e
,
o
,
t
)
||
l
(
o
)}
function
c
(
t
){
var
o
=
m
();
return
v
||
n
(
o
),
t
&&
0
===
e
(
"
:focus
"
,
t
).
length
?
void
h
(
t
):
void
(
v
.
children
().
length
&&
v
.
remove
())}
function
l
(
t
){
for
(
var
n
=
v
.
children
(),
o
=
n
.
length
-
1
;
o
>=
0
;
o
--
)
u
(
e
(
n
[
o
]),
t
)}
function
u
(
t
,
n
,
o
){
var
s
=!
(
!
o
||!
o
.
force
)
&&
o
.
force
;
return
!
(
!
t
||!
s
&&
0
!==
e
(
"
:focus
"
,
t
).
length
)
&&
(
t
[
n
.
hideMethod
]({
duration
:
n
.
hideDuration
,
easing
:
n
.
hideEasing
,
complete
:
function
(){
h
(
t
)}}),
!
0
)}
function
d
(
t
){
return
v
=
e
(
"
<div/>
"
).
attr
(
"
id
"
,
t
.
containerId
).
addClass
(
t
.
positionClass
),
v
.
appendTo
(
e
(
t
.
target
)),
v
}
function
p
(){
return
{
tapToDismiss
:
!
0
,
toastClass
:
"
toast
"
,
containerId
:
"
toast-container
"
,
debug
:
!
1
,
showMethod
:
"
fadeIn
"
,
showDuration
:
300
,
showEasing
:
"
swing
"
,
onShown
:
void
0
,
hideMethod
:
"
fadeOut
"
,
hideDuration
:
1
e3
,
hideEasing
:
"
swing
"
,
onHidden
:
void
0
,
closeMethod
:
!
1
,
closeDuration
:
!
1
,
closeEasing
:
!
1
,
closeOnHover
:
!
0
,
extendedTimeOut
:
1
e3
,
iconClasses
:{
error
:
"
toast-error
"
,
info
:
"
toast-info
"
,
success
:
"
toast-success
"
,
warning
:
"
toast-warning
"
},
iconClass
:
"
toast-info
"
,
positionClass
:
"
toast-top-right
"
,
timeOut
:
5
e3
,
titleClass
:
"
toast-title
"
,
messageClass
:
"
toast-message
"
,
escapeHtml
:
!
1
,
target
:
"
body
"
,
closeHtml
:
'
<button type="button">×</button>
'
,
closeClass
:
"
toast-close-button
"
,
newestOnTop
:
!
0
,
preventDuplicates
:
!
1
,
progressBar
:
!
1
,
progressClass
:
"
toast-progress
"
,
rtl
:
!
1
}}
function
f
(
e
){
C
&&
C
(
e
)}
function
g
(
t
){
function
o
(
e
){
return
null
==
e
&&
(
e
=
""
),
e
.
replace
(
/&/g
,
"
&
"
).
replace
(
/"/g
,
"
"
"
).
replace
(
/'/g
,
"
'
"
).
replace
(
/</g
,
"
<
"
).
replace
(
/>/g
,
"
>
"
)}
function
s
(){
c
(),
u
(),
d
(),
p
(),
g
(),
C
(),
l
(),
i
()}
function
i
(){
var
e
=
""
;
switch
(
t
.
iconClass
){
case
"
toast-success
"
:
case
"
toast-info
"
:
e
=
"
polite
"
;
break
;
default
:
e
=
"
assertive
"
}
I
.
attr
(
"
aria-live
"
,
e
)}
function
a
(){
E
.
closeOnHover
&&
I
.
hover
(
H
,
D
),
!
E
.
onclick
&&
E
.
tapToDismiss
&&
I
.
click
(
b
),
E
.
closeButton
&&
j
&&
j
.
click
(
function
(
e
){
e
.
stopPropagation
?
e
.
stopPropagation
():
void
0
!==
e
.
cancelBubble
&&
e
.
cancelBubble
!==!
0
&&
(
e
.
cancelBubble
=!
0
),
E
.
onCloseClick
&&
E
.
onCloseClick
(
e
),
b
(
!
0
)}),
E
.
onclick
&&
I
.
click
(
function
(
e
){
E
.
onclick
(
e
),
b
()})}
function
r
(){
I
.
hide
(),
I
[
E
.
showMethod
]({
duration
:
E
.
showDuration
,
easing
:
E
.
showEasing
,
complete
:
E
.
onShown
}),
E
.
timeOut
>
0
&&
(
k
=
setTimeout
(
b
,
E
.
timeOut
),
F
.
maxHideTime
=
parseFloat
(
E
.
timeOut
),
F
.
hideEta
=
(
new
Date
).
getTime
()
+
F
.
maxHideTime
,
E
.
progressBar
&&
(
F
.
intervalId
=
setInterval
(
x
,
10
)))}
function
c
(){
t
.
iconClass
&&
I
.
addClass
(
E
.
toastClass
).
addClass
(
y
)}
function
l
(){
E
.
newestOnTop
?
v
.
prepend
(
I
):
v
.
append
(
I
)}
function
u
(){
if
(
t
.
title
){
var
e
=
t
.
title
;
E
.
escapeHtml
&&
(
e
=
o
(
t
.
title
)),
M
.
append
(
e
).
addClass
(
E
.
titleClass
),
I
.
append
(
M
)}}
function
d
(){
if
(
t
.
message
){
var
e
=
t
.
message
;
E
.
escapeHtml
&&
(
e
=
o
(
t
.
message
)),
B
.
append
(
e
).
addClass
(
E
.
messageClass
),
I
.
append
(
B
)}}
function
p
(){
E
.
closeButton
&&
(
j
.
addClass
(
E
.
closeClass
).
attr
(
"
role
"
,
"
button
"
),
I
.
prepend
(
j
))}
function
g
(){
E
.
progressBar
&&
(
q
.
addClass
(
E
.
progressClass
),
I
.
prepend
(
q
))}
function
C
(){
E
.
rtl
&&
I
.
addClass
(
"
rtl
"
)}
function
O
(
e
,
t
){
if
(
e
.
preventDuplicates
){
if
(
t
.
message
===
w
)
return
!
0
;
w
=
t
.
message
}
return
!
1
}
function
b
(
t
){
var
n
=
t
&&
E
.
closeMethod
!==!
1
?
E
.
closeMethod
:
E
.
hideMethod
,
o
=
t
&&
E
.
closeDuration
!==!
1
?
E
.
closeDuration
:
E
.
hideDuration
,
s
=
t
&&
E
.
closeEasing
!==!
1
?
E
.
closeEasing
:
E
.
hideEasing
;
if
(
!
e
(
"
:focus
"
,
I
).
length
||
t
)
return
clearTimeout
(
F
.
intervalId
),
I
[
n
]({
duration
:
o
,
easing
:
s
,
complete
:
function
(){
h
(
I
),
clearTimeout
(
k
),
E
.
onHidden
&&
"
hidden
"
!==
P
.
state
&&
E
.
onHidden
(),
P
.
state
=
"
hidden
"
,
P
.
endTime
=
new
Date
,
f
(
P
)}})}
function
D
(){(
E
.
timeOut
>
0
||
E
.
extendedTimeOut
>
0
)
&&
(
k
=
setTimeout
(
b
,
E
.
extendedTimeOut
),
F
.
maxHideTime
=
parseFloat
(
E
.
extendedTimeOut
),
F
.
hideEta
=
(
new
Date
).
getTime
()
+
F
.
maxHideTime
)}
function
H
(){
clearTimeout
(
k
),
F
.
hideEta
=
0
,
I
.
stop
(
!
0
,
!
0
)[
E
.
showMethod
]({
duration
:
E
.
showDuration
,
easing
:
E
.
showEasing
})}
function
x
(){
var
e
=
(
F
.
hideEta
-
(
new
Date
).
getTime
())
/
F
.
maxHideTime
*
100
;
q
.
width
(
e
+
"
%
"
)}
var
E
=
m
(),
y
=
t
.
iconClass
||
E
.
iconClass
;
if
(
"
undefined
"
!=
typeof
t
.
optionsOverride
&&
(
E
=
e
.
extend
(
E
,
t
.
optionsOverride
),
y
=
t
.
optionsOverride
.
iconClass
||
y
),
!
O
(
E
,
t
)){
T
++
,
v
=
n
(
E
,
!
0
);
var
k
=
null
,
I
=
e
(
"
<div/>
"
),
M
=
e
(
"
<div/>
"
),
B
=
e
(
"
<div/>
"
),
q
=
e
(
"
<div/>
"
),
j
=
e
(
E
.
closeHtml
),
F
=
{
intervalId
:
null
,
hideEta
:
null
,
maxHideTime
:
null
},
P
=
{
toastId
:
T
,
state
:
"
visible
"
,
startTime
:
new
Date
,
options
:
E
,
map
:
t
};
return
s
(),
r
(),
a
(),
f
(
P
),
E
.
debug
&&
console
&&
console
.
log
(
P
),
I
}}
function
m
(){
return
e
.
extend
({},
p
(),
b
.
options
)}
function
h
(
e
){
v
||
(
v
=
n
()),
e
.
is
(
"
:visible
"
)
||
(
e
.
remove
(),
e
=
null
,
0
===
v
.
children
().
length
&&
(
v
.
remove
(),
w
=
void
0
))}
var
v
,
C
,
w
,
T
=
0
,
O
=
{
error
:
"
error
"
,
info
:
"
info
"
,
success
:
"
success
"
,
warning
:
"
warning
"
},
b
=
{
clear
:
r
,
remove
:
c
,
error
:
t
,
getContainer
:
n
,
info
:
o
,
options
:{},
subscribe
:
s
,
success
:
i
,
version
:
"
2.1.3
"
,
warning
:
a
};
return
b
}()})}(
"
function
"
==
typeof
define
&&
define
.
amd
?
define
:
function
(
e
,
t
){
"
undefined
"
!=
typeof
module
&&
module
.
exports
?
module
.
exports
=
t
(
require
(
"
jquery
"
)):
window
.
toastr
=
t
(
window
.
jQuery
)});
//# sourceMappingURL=toastr.js.map
apps/templates/base.html
浏览文件 @
8a5a4f33
{% load static %}
{% load static
i18n
%}
<!DOCTYPE html>
<html>
<head>
...
...
@@ -20,6 +20,25 @@
<div
id=
"page-wrapper"
class=
"gray-bg"
>
{% include '_header_bar.html' %}
{% include '_message.html' %}
{% block first_login_message %}
{% if user.is_authenticated and user.is_first_login %}
<div
class=
"alert alert-danger"
style=
"margin: 20px auto 0px"
>
{% url 'users:user-first-login' as the_url %}
{% blocktrans %}
Your information was incomplete. Please click
<a
href=
"{{ the_url }}"
>
this link
</a>
to complete your information.
{% endblocktrans %}
</div>
{% endif %}
{% endblock %}
{% block update_public_key_message %}
{% if user.is_authenticated and not user.is_public_key_valid %}
<div
class=
"alert alert-danger"
style=
"margin: 20px auto 0px"
>
{% blocktrans %}
Your ssh-public-key has been expired. Please click
<a
href=
"#"
>
this link
</a>
to update your ssh-public-key.
{% endblocktrans %}
</div>
{% endif %}
{% endblock %}
{% block content %}{% endblock %}
{% include '_footer.html' %}
</div>
...
...
@@ -28,4 +47,4 @@
</body>
{% include '_foot_js.html' %}
{% block custom_foot_js %} {% endblock %}
</html>
\ No newline at end of file
</html>
apps/users/api.py
浏览文件 @
8a5a4f33
...
...
@@ -5,7 +5,8 @@ import logging
from
rest_framework
import
generics
from
.serializers
import
UserSerializer
,
UserGroupSerializer
,
UserAttributeSerializer
,
UserGroupEditSerializer
from
.serializers
import
UserSerializer
,
UserGroupSerializer
,
UserAttributeSerializer
,
UserGroupEditSerializer
,
\
UserPKUpdateSerializer
from
.models
import
User
,
UserGroup
...
...
@@ -72,7 +73,17 @@ class UserResetPKApi(generics.UpdateAPIView):
def
perform_update
(
self
,
serializer
):
user
=
self
.
get_object
()
user
.
_public_key
=
''
user
.
is_public_key_valid
=
False
user
.
save
()
from
.utils
import
send_reset_ssh_key_mail
send_reset_ssh_key_mail
(
user
)
class
UserUpdatePKApi
(
generics
.
UpdateAPIView
):
queryset
=
User
.
objects
.
all
()
serializer_class
=
UserPKUpdateSerializer
def
perform_update
(
self
,
serializer
):
user
=
self
.
get_object
()
user
.
private_key
=
serializer
.
validated_data
[
'_public_key'
]
user
.
save
()
apps/users/forms.py
浏览文件 @
8a5a4f33
...
...
@@ -79,9 +79,11 @@ class UserKeyForm(forms.Form):
help_text
=
_
(
'Paste your id_ras.pub here.'
))
def
clean_public_key
(
self
):
public_key
=
self
.
cleaned_data
[
'public_key'
]
if
self
.
user
.
_public_key
and
public_key
==
self
.
user
.
public_key
:
raise
forms
.
ValidationError
(
_
(
'Public key should not be the same as your old one.'
))
from
sshpubkeys
import
SSHKey
from
sshpubkeys.exceptions
import
InvalidKeyException
public_key
=
self
.
cleaned_data
[
'public_key'
]
ssh
=
SSHKey
(
public_key
)
try
:
ssh
.
parse
()
...
...
apps/users/models.py
浏览文件 @
8a5a4f33
...
...
@@ -80,6 +80,7 @@ class User(AbstractUser):
date_expired
=
models
.
DateTimeField
(
default
=
date_expired_default
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'Date expired'
))
created_by
=
models
.
CharField
(
max_length
=
30
,
default
=
''
,
verbose_name
=
_
(
'Created by'
))
is_public_key_valid
=
models
.
BooleanField
(
default
=
False
)
@
property
def
password_raw
(
self
):
...
...
apps/users/serializers.py
浏览文件 @
8a5a4f33
...
...
@@ -46,11 +46,18 @@ class UserPKUpdateSerializer(serializers.ModelSerializer):
class
Meta
:
model
=
User
fields
=
[
'id'
,
'_private_key'
]
def
validate__private_key
(
self
,
value
):
from
users.utils
import
validate_ssh_pk
checked
,
reason
=
validate_ssh_pk
(
value
)
if
not
checked
:
raise
serializers
.
ValidationError
(
_
(
'Not a valid ssh private key.'
))
fields
=
[
'id'
,
'_public_key'
]
def
validate__public_key
(
self
,
value
):
from
sshpubkeys
import
SSHKey
from
sshpubkeys.exceptions
import
InvalidKeyException
ssh
=
SSHKey
(
value
)
try
:
ssh
.
parse
()
except
InvalidKeyException
as
e
:
print
e
raise
serializers
.
ValidationError
(
_
(
'Not a valid ssh public key'
))
except
NotImplementedError
as
e
:
print
e
raise
serializers
.
ValidationError
(
_
(
'Not a valid ssh public key'
))
return
value
apps/users/templates/users/_user_
reset
_pk_modal.html
→
apps/users/templates/users/_user_
update
_pk_modal.html
浏览文件 @
8a5a4f33
{% extends '_modal.html' %}
{% load i18n %}
{% block modal_id %}user_
reset
_pk_modal{% endblock %}
{% block modal_title%}{% trans
'Reset User SSH Private Key'
%}{% endblock %}
{% block modal_id %}user_
update
_pk_modal{% endblock %}
{% block modal_title%}{% trans
"Update User SSH Public Key"
%}{% endblock %}
{% block modal_body %}
<textarea
id=
"txt_pk"
class=
"form-control"
cols=
"30"
rows=
"10"
placeholder=
"
-----BEGIN RSA PRIVATE KEY-----
"
></textarea>
<textarea
id=
"txt_pk"
class=
"form-control"
cols=
"30"
rows=
"10"
placeholder=
"
ssh-rsa AAAAB3NzaC1yc2EAA.....
"
></textarea>
{% endblock %}
{% block modal_confirm_id %}btn_user_
reset
_pk{% endblock %}
{% block modal_confirm_id %}btn_user_
update
_pk{% endblock %}
apps/users/templates/users/first_login.html
浏览文件 @
8a5a4f33
...
...
@@ -3,10 +3,12 @@
{% load i18n %}
{% load bootstrap %}
{% block custom_head_css_js %}
{{ wizard.form.media }}
<link
href=
"{% static 'css/plugins/steps/jquery.steps.css' %}"
rel=
"stylesheet"
>
{% endblock %}
{% block first_login_message %}{% endblock %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
...
...
apps/users/templates/users/user_detail.html
浏览文件 @
8a5a4f33
...
...
@@ -160,6 +160,14 @@
</span>
</td>
</tr>
<tr>
<td>
{% trans 'Update ssh key' %}:
</td>
<td>
<span
class=
"pull-right"
>
<button
type=
"button"
class=
"btn btn-primary btn-xs"
id=
"btn_update_pk"
style=
"width: 54px;"
data-toggle=
"modal"
data-target=
"#user_update_pk_modal"
>
{% trans 'Update' %}
</button>
</span>
</td>
</tr>
</tbody>
</table>
</div>
...
...
@@ -207,6 +215,7 @@
</div>
</div>
</div>
{% include 'users/_user_update_pk_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
<script>
...
...
@@ -352,6 +361,33 @@ $(document).ready(function() {
},
function
()
{
doReset
();
});
}).
on
(
'
click
'
,
'
#btn_user_update_pk
'
,
function
(){
var
$this
=
$
(
this
);
var
pk
=
$
(
'
#txt_pk
'
).
val
();
var
the_url
=
'
{% url "users:user-update-pk-api" pk=user_object.id %}
'
;
var
body
=
{
'
_public_key
'
:
pk
};
var
success
=
function
()
{
$
(
'
#txt_pk
'
).
val
(
''
);
$this
.
closest
(
'
.modal
'
).
modal
(
'
hide
'
);
var
msg
=
"
{% trans 'Successfully updated the SSH public key.' %}
"
;
swal
(
"
{% trans 'User SSH Public Key Update' %}
"
,
msg
,
"
success
"
);
};
var
fail
=
function
()
{
var
msg
=
"
{% trans 'Failed to update the user
\
's SSH public key.' %}
"
;
swal
({
title
:
"
{% trans 'User SSH Public Key Update' %}
"
,
text
:
msg
,
type
:
"
error
"
,
showCancelButton
:
false
,
confirmButtonColor
:
"
#DD6B55
"
,
confirmButtonText
:
"
{% trans 'Confirm' %}
"
,
closeOnConfirm
:
true
},
function
()
{
$
(
'
#txt_pk
'
).
focus
();
}
);
}
APIUpdateAttr
({
url
:
the_url
,
body
:
JSON
.
stringify
(
body
),
success
:
success
,
error
:
fail
});
});
</script>
{% endblock %}
apps/users/urls.py
浏览文件 @
8a5a4f33
...
...
@@ -43,6 +43,7 @@ urlpatterns += [
api
.
UserAttributeApi
.
as_view
(),
name
=
'user-patch-api'
),
url
(
r
'^v1/users/(?P<pk>\d+)/reset-password/$'
,
api
.
UserResetPasswordApi
.
as_view
(),
name
=
'user-reset-password-api'
),
url
(
r
'^v1/users/(?P<pk>\d+)/reset-pk/$'
,
api
.
UserResetPKApi
.
as_view
(),
name
=
'user-reset-pk-api'
),
url
(
r
'^v1/users/(?P<pk>\d+)/update-pk/$'
,
api
.
UserUpdatePKApi
.
as_view
(),
name
=
'user-update-pk-api'
),
url
(
r
'^v1/user-groups$'
,
api
.
UserGroupListAddApi
.
as_view
(),
name
=
'user-group-list-api'
),
url
(
r
'^v1/user-groups/(?P<pk>[0-9]+)$'
,
api
.
UserGroupDetailDeleteUpdateApi
.
as_view
(),
name
=
'user-group-detail-api'
),
...
...
apps/users/views.py
浏览文件 @
8a5a4f33
...
...
@@ -19,7 +19,7 @@ from django.views.decorators.debug import sensitive_post_parameters
from
django.views.generic.base
import
TemplateView
from
django.views.generic.list
import
ListView
from
django.views.generic.edit
import
CreateView
,
DeleteView
,
UpdateView
,
FormView
,
SingleObjectMixin
,
\
FormMixin
,
ModelFormMixin
,
ProcessFormView
,
BaseCreateView
FormMixin
from
django.views.generic.detail
import
DetailView
from
formtools.wizard.views
import
SessionWizardView
...
...
@@ -332,6 +332,7 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
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'
))
...
...
@@ -351,6 +352,16 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
}
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
):
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
...
...
@@ -376,7 +387,7 @@ class UserAssetPermissionView(AdminUserRequiredMixin, FormMixin, SingleObjectMix
def
get_queryset
(
self
):
asset_permissions
=
set
(
self
.
object
.
asset_permissions
.
all
())
\
|
self
.
get_asset_permission_inherit_from_user_group
()
|
self
.
get_asset_permission_inherit_from_user_group
()
return
list
(
asset_permissions
)
def
get_context_data
(
self
,
**
kwargs
):
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录