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
8a5a4f33
Commit
8a5a4f33
authored
Sep 18, 2016
by
xiaoyu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix #14
parent
8cdc4674
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
110 additions
and
22 deletions
+110
-22
style.css
apps/static/css/style.css
+2
-2
toastr.js.map
apps/static/js/plugins/toastr/toastr.js.map
+0
-0
toastr.min.js
apps/static/js/plugins/toastr/toastr.min.js
+0
-1
base.html
apps/templates/base.html
+21
-3
api.py
apps/users/api.py
+13
-2
forms.py
apps/users/forms.py
+3
-1
models.py
apps/users/models.py
+1
-0
serializers.py
apps/users/serializers.py
+14
-7
_user_update_pk_modal.html
apps/users/templates/users/_user_update_pk_modal.html
+4
-4
first_login.html
apps/users/templates/users/first_login.html
+2
-0
user_detail.html
apps/users/templates/users/user_detail.html
+36
-0
urls.py
apps/users/urls.py
+1
-0
views.py
apps/users/views.py
+13
-2
No files found.
apps/static/css/style.css
View file @
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
deleted
100644 → 0
View file @
8cdc4674
This diff is collapsed.
Click to expand it.
apps/static/js/plugins/toastr/toastr.min.js
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
):
...
...
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