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
0f9bdab1
Commit
0f9bdab1
authored
8 years ago
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of code.simcu.com:jumpserver/jumpserver
parents
1005fbab
6751c5a6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
92 additions
and
18 deletions
+92
-18
jumpserver.js
apps/static/js/jumpserver.js
+20
-18
_modal.html
apps/templates/_modal.html
+20
-0
api.py
apps/users/api.py
+23
-0
serializers.py
apps/users/serializers.py
+16
-0
_user_reset_pk_modal.html
apps/users/templates/users/_user_reset_pk_modal.html
+8
-0
user_detail.html
apps/users/templates/users/user_detail.html
+0
-0
urls.py
apps/users/urls.py
+2
-0
utils.py
apps/users/utils.py
+3
-0
No files found.
apps/static/js/jumpserver.js
View file @
0f9bdab1
...
...
@@ -4,10 +4,10 @@
var
checked
=
false
;
function
check_all
(
form
)
{
var
checkboxes
=
document
.
getElementById
(
form
);
if
(
checked
==
false
)
{
checked
=
true
if
(
checked
==
=
false
)
{
checked
=
true
;
}
else
{
checked
=
false
checked
=
false
;
}
for
(
var
i
=
0
;
i
<
checkboxes
.
elements
.
length
;
i
++
)
{
if
(
checkboxes
.
elements
[
i
].
type
==
"checkbox"
)
{
...
...
@@ -51,13 +51,13 @@ function GetRowData(row){
//此函数用于在多选提交时至少要选择一行
function
GetTableDataBox
()
{
var
tabProduct
=
document
.
getElementById
(
"editable"
);
var
tableData
=
new
Array
()
;
var
returnData
=
new
Array
()
;
var
tableData
=
[]
;
var
returnData
=
[]
;
var
checkboxes
=
document
.
getElementById
(
"contents_form"
);
var
id_list
=
new
Array
()
;
var
id_list
=
[]
;
len
=
checkboxes
.
elements
.
length
;
for
(
var
i
=
0
;
i
<
len
;
i
++
)
{
if
(
checkboxes
.
elements
[
i
].
type
==
"checkbox"
&&
checkboxes
.
elements
[
i
].
checked
==
true
&&
checkboxes
.
elements
[
i
].
value
!=
"checkall"
)
{
if
(
checkboxes
.
elements
[
i
].
type
==
"checkbox"
&&
checkboxes
.
elements
[
i
].
checked
==
=
true
&&
checkboxes
.
elements
[
i
].
value
!=
"checkall"
)
{
id_list
.
push
(
i
);
}
}
...
...
@@ -67,7 +67,7 @@ function GetTableDataBox() {
tableData
.
push
(
GetRowData
(
tabProduct
.
rows
[
id_list
[
i
]]));
}
if
(
id_list
.
length
==
0
){
if
(
id_list
.
length
==
=
0
){
alert
(
'请至少选择一行!'
);
}
returnData
.
push
(
tableData
);
...
...
@@ -77,7 +77,7 @@ function GetTableDataBox() {
function
move
(
from
,
to
,
from_o
,
to_o
)
{
$
(
"#"
+
from
+
" option"
).
each
(
function
()
{
if
(
$
(
this
).
prop
(
"selected"
)
==
true
)
{
if
(
$
(
this
).
prop
(
"selected"
)
==
=
true
)
{
$
(
"#"
+
to
).
append
(
this
);
if
(
typeof
from_o
!==
'undefined'
){
$
(
"#"
+
to_o
).
append
(
$
(
"#"
+
from_o
+
" option[value='"
+
this
.
value
+
"']"
));
...
...
@@ -88,7 +88,7 @@ function move(from, to, from_o, to_o) {
function
move_left
(
from
,
to
,
from_o
,
to_o
)
{
$
(
"#"
+
from
+
" option"
).
each
(
function
()
{
if
(
$
(
this
).
prop
(
"selected"
)
==
true
)
{
if
(
$
(
this
).
prop
(
"selected"
)
==
=
true
)
{
$
(
"#"
+
to
).
append
(
this
);
if
(
typeof
from_o
!==
'undefined'
){
$
(
"#"
+
to_o
).
append
(
$
(
"#"
+
from_o
+
" option[value='"
+
this
.
value
+
"']"
));
...
...
@@ -126,8 +126,8 @@ function move_left(from, to, from_o, to_o) {
function
selectAll
(){
// 选择该页面所有option
$
(
'option'
).
each
(
function
(){
$
(
this
).
attr
(
'selected'
,
true
)
})
$
(
this
).
attr
(
'selected'
,
true
)
;
})
;
}
...
...
@@ -156,6 +156,8 @@ function getIDall() {
function
APIUpdateAttr
(
props
)
{
// props = {url: .., body: , success: , error: , method: ,}
props
=
props
||
{};
success_message
=
props
.
success_message
||
'Update Successfully!'
;
fail_message
=
props
.
fail_message
||
'Error occurred while updating.'
;
$
.
ajax
({
url
:
props
.
url
,
type
:
props
.
method
||
"PATCH"
,
...
...
@@ -164,18 +166,18 @@ function APIUpdateAttr(props) {
dataType
:
props
.
data_type
||
"json"
,
}).
done
(
function
(
data
,
textStatue
,
jqXHR
)
{
if
(
typeof
props
.
success
===
'function'
)
{
return
props
.
success
(
data
)
return
props
.
success
(
data
)
;
}
else
{
toastr
.
success
(
'Update Success!'
)
toastr
.
success
(
success_message
);
}
}).
fail
(
function
(
jqXHR
,
textStatue
,
errorThrown
)
{
if
(
typeof
props
.
error
===
'function'
)
{
return
props
.
error
(
errorThrown
)
return
props
.
error
(
errorThrown
)
;
}
else
{
toastr
.
error
(
'Error occurred while updating.'
)
toastr
.
error
(
fail_message
);
}
})
})
;
return
true
;
}
var
jumpserver
=
new
Object
()
;
var
jumpserver
=
{}
;
This diff is collapsed.
Click to expand it.
apps/templates/_modal.html
0 → 100644
View file @
0f9bdab1
{% load i18n %}
<div
aria-hidden=
"true"
role=
"dialog"
tabindex=
"-1"
id=
"{% block modal_id %}{% endblock %}"
class=
"modal inmodal"
style=
"display: none;"
>
<div
class=
"modal-dialog"
>
<div
class=
"modal-content animated fadeIn"
>
<div
class=
"modal-header"
>
<button
data-dismiss=
"modal"
class=
"close"
type=
"button"
><span
aria-hidden=
"true"
>
×
</span><span
class=
"sr-only"
>
Close
</span></button>
<h4
class=
"modal-title"
>
{% block modal_title %}{% endblock %}
</h4>
<small>
{% block modal_comment %}{% endblock %}
</small>
</div>
<div
class=
"modal-body"
>
{% block modal_body %}
{% endblock %}
</div>
<div
class=
"modal-footer"
>
<button
data-dismiss=
"modal"
class=
"btn btn-white"
type=
"button"
>
{% trans "Close" %}
</button>
<button
class=
"btn btn-primary"
type=
"button"
id=
"{% block modal_confirm_id %}{% endblock %}"
>
{% trans 'Confirm' %}
</button>
</div>
</div>
</div>
</div>
This diff is collapsed.
Click to expand it.
apps/users/api.py
View file @
0f9bdab1
...
...
@@ -6,6 +6,7 @@ import logging
from
rest_framework
import
generics
from
.serializers
import
UserSerializer
,
UserGroupSerializer
,
UserAttributeSerializer
,
UserGroupEditSerializer
from
.serializers
import
UserPKUpdateSerializer
from
.models
import
User
,
UserGroup
...
...
@@ -49,3 +50,25 @@ class UserAttributeApi(generics.RetrieveUpdateDestroyAPIView):
class
UserGroupEditApi
(
generics
.
RetrieveUpdateAPIView
):
queryset
=
User
.
objects
.
all
()
serializer_class
=
UserGroupEditSerializer
class
UserResetPasswordApi
(
generics
.
UpdateAPIView
):
queryset
=
User
.
objects
.
all
()
serializer_class
=
UserGroupEditSerializer
def
perform_update
(
self
,
serializer
):
# Note: we are not updating the user object here.
# We just do the reset-password staff.
user
=
self
.
get_object
()
from
.utils
import
send_reset_password_mail
send_reset_password_mail
(
user
)
class
UserResetPKApi
(
generics
.
UpdateAPIView
):
queryset
=
User
.
objects
.
all
()
serializer_class
=
UserPKUpdateSerializer
def
perform_update
(
self
,
serializer
):
user
=
self
.
get_object
()
user
.
private_key
=
serializer
.
validated_data
[
'_private_key'
]
user
.
save
()
This diff is collapsed.
Click to expand it.
apps/users/serializers.py
View file @
0f9bdab1
# -*- coding: utf-8 -*-
#
from
django.utils.translation
import
ugettext_lazy
as
_
from
rest_framework
import
serializers
from
.models
import
User
,
UserGroup
...
...
@@ -38,3 +40,17 @@ class UserGroupEditSerializer(serializers.ModelSerializer):
class
Meta
:
model
=
User
fields
=
[
'id'
,
'groups'
]
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.'
))
return
value
This diff is collapsed.
Click to expand it.
apps/users/templates/users/_user_reset_pk_modal.html
0 → 100644
View file @
0f9bdab1
{% 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_body %}
<textarea
id=
"txt_pk"
class=
"form-control"
cols=
"30"
rows=
"10"
placeholder=
"-----BEGIN RSA PRIVATE KEY-----"
></textarea>
{% endblock %}
{% block modal_confirm_id %}btn_user_reset_pk{% endblock %}
This diff is collapsed.
Click to expand it.
apps/users/templates/users/user_detail.html
View file @
0f9bdab1
This diff is collapsed.
Click to expand it.
apps/users/urls.py
View file @
0f9bdab1
...
...
@@ -35,6 +35,8 @@ urlpatterns += [
api
.
UserDetailDeleteUpdateApi
.
as_view
(),
name
=
'user-detail-api'
),
url
(
r'^v1/users/(?P<pk>[0-9]+)/patch$'
,
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/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'
),
...
...
This diff is collapsed.
Click to expand it.
apps/users/utils.py
View file @
0f9bdab1
...
...
@@ -5,6 +5,7 @@ import logging
import
os
import
re
from
django.conf
import
settings
from
django.contrib.auth.mixins
import
UserPassesTestMixin
from
django.urls
import
reverse_lazy
from
django.utils.translation
import
ugettext
as
_
...
...
@@ -121,6 +122,8 @@ def send_reset_password_mail(user):
'email'
:
user
.
email
,
'login_url'
:
reverse
(
'users:login'
,
external
=
True
),
}
if
settings
.
DEBUG
:
logger
.
debug
(
message
)
send_mail_async
.
delay
(
subject
,
message
,
recipient_list
,
html_message
=
message
)
...
...
This diff is collapsed.
Click to expand it.
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