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
b0551449
Commit
b0551449
authored
Mar 01, 2017
by
ibuler
Browse files
Options
Browse Files
Download
Plain Diff
Merge with audits
parents
7825c107
dd5dd9d7
Show whitespace changes
Inline
Side-by-side
Showing
49 changed files
with
354 additions
and
203 deletions
+354
-203
.gitignore
.gitignore
+2
-0
forms.py
apps/assets/forms.py
+7
-7
_asset_bulk_update_modal.html
apps/assets/templates/assets/_asset_bulk_update_modal.html
+0
-5
admin_user_detail.html
apps/assets/templates/assets/admin_user_detail.html
+0
-2
admin_user_list.html
apps/assets/templates/assets/admin_user_list.html
+5
-2
asset_detail.html
apps/assets/templates/assets/asset_detail.html
+0
-1
asset_group_detail.html
apps/assets/templates/assets/asset_group_detail.html
+0
-2
asset_group_list.html
apps/assets/templates/assets/asset_group_list.html
+2
-0
asset_list.html
apps/assets/templates/assets/asset_list.html
+38
-3
asset_tag_detail.html
apps/assets/templates/assets/asset_tag_detail.html
+0
-2
asset_tags_list.html
apps/assets/templates/assets/asset_tags_list.html
+0
-1
idc_assets.html
apps/assets/templates/assets/idc_assets.html
+0
-2
idc_create_update.html
apps/assets/templates/assets/idc_create_update.html
+1
-0
idc_detail.html
apps/assets/templates/assets/idc_detail.html
+0
-2
system_user_asset.html
apps/assets/templates/assets/system_user_asset.html
+0
-2
system_user_asset_group.html
apps/assets/templates/assets/system_user_asset_group.html
+0
-2
system_user_detail.html
apps/assets/templates/assets/system_user_detail.html
+0
-2
system_user_list.html
apps/assets/templates/assets/system_user_list.html
+2
-1
views.py
apps/assets/views.py
+9
-9
command_log_list.html
apps/audits/templates/audits/command_log_list.html
+0
-1
proxy_log_detail.html
apps/audits/templates/audits/proxy_log_detail.html
+0
-1
proxy_log_list.html
apps/audits/templates/audits/proxy_log_list.html
+0
-1
fake.json
apps/fixtures/fake.json
+0
-0
settings.py
apps/jumpserver/settings.py
+6
-6
task.py
apps/ops/models/task.py
+2
-2
detail.html
apps/ops/templates/cron/detail.html
+0
-2
detail.html
apps/ops/templates/sudo/detail.html
+0
-2
detail.html
apps/ops/templates/task/detail.html
+0
-2
asset_permission_asset.html
apps/perms/templates/perms/asset_permission_asset.html
+0
-2
asset_permission_detail.html
apps/perms/templates/perms/asset_permission_detail.html
+0
-2
asset_permission_list.html
apps/perms/templates/perms/asset_permission_list.html
+0
-1
asset_permission_user.html
apps/perms/templates/perms/asset_permission_user.html
+0
-2
jumpserver.css
apps/static/css/jumpserver.css
+13
-0
_base_list.html
apps/templates/_base_list.html
+0
-1
base.html
apps/templates/base.html
+4
-3
api.py
apps/users/api.py
+9
-11
user.py
apps/users/models/user.py
+24
-3
permissions.py
apps/users/permissions.py
+7
-14
user_asset_permission.html
apps/users/templates/users/user_asset_permission.html
+0
-2
user_detail.html
apps/users/templates/users/user_detail.html
+27
-37
user_granted_asset.html
apps/users/templates/users/user_granted_asset.html
+0
-2
user_group_asset_permission.html
apps/users/templates/users/user_group_asset_permission.html
+0
-2
user_group_granted_asset.html
apps/users/templates/users/user_group_granted_asset.html
+0
-2
user_profile.html
apps/users/templates/users/user_profile.html
+148
-0
__init__.py
apps/users/templatetags/__init__.py
+0
-0
users_tags.py
apps/users/templatetags/users_tags.py
+0
-38
views_urls.py
apps/users/urls/views_urls.py
+6
-0
user.py
apps/users/views/user.py
+40
-18
config_example.py
config_example.py
+2
-1
No files found.
.gitignore
View file @
b0551449
...
@@ -19,3 +19,5 @@ config.py
...
@@ -19,3 +19,5 @@ config.py
migrations/
migrations/
*.log
*.log
host_rsa_key
host_rsa_key
*.bat
tags
apps/assets/forms.py
View file @
b0551449
...
@@ -20,13 +20,13 @@ class AssetCreateForm(forms.ModelForm):
...
@@ -20,13 +20,13 @@ class AssetCreateForm(forms.ModelForm):
self
.
instance
.
tags
.
clear
()
self
.
instance
.
tags
.
clear
()
self
.
instance
.
tags
.
add
(
*
tuple
(
tags
))
self
.
instance
.
tags
.
add
(
*
tuple
(
tags
))
def
clean
(
self
):
#
def clean(self):
clean_data
=
super
(
AssetCreateForm
,
self
)
.
clean
()
#
clean_data = super(AssetCreateForm, self).clean()
ip
=
clean_data
.
get
(
'ip'
)
#
ip = clean_data.get('ip')
port
=
clean_data
.
get
(
'port'
)
#
port = clean_data.get('port')
query
=
Asset
.
objects
.
filter
(
ip
=
ip
,
port
=
port
)
#
query = Asset.objects.filter(ip=ip, port=port)
if
query
:
#
if query:
raise
forms
.
ValidationError
(
'this asset has exists.'
)
#
raise forms.ValidationError('this asset has exists.')
class
Meta
:
class
Meta
:
model
=
Asset
model
=
Asset
...
...
apps/assets/templates/assets/_asset_bulk_update_modal.html
View file @
b0551449
...
@@ -77,10 +77,6 @@
...
@@ -77,10 +77,6 @@
</div>
</div>
</form>
</form>
{% endblock %}
{% endblock %}
{% block modal_confirm_id %}btn_asset_bulk_update{% endblock %}
{% block modal_confirm_id %}btn_asset_bulk_update{% endblock %}
\ No newline at end of file
apps/assets/templates/assets/admin_user_detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/assets/templates/assets/admin_user_list.html
View file @
b0551449
...
@@ -52,10 +52,11 @@ $(document).ready(function(){
...
@@ -52,10 +52,11 @@ $(document).ready(function(){
$
(
td
).
html
(
'<a href="javascript:void(0);" data-toggle="tooltip" title="'
+
cellData
+
'">'
+
innerHtml
+
'</a>'
);
$
(
td
).
html
(
'<a href="javascript:void(0);" data-toggle="tooltip" title="'
+
cellData
+
'">'
+
innerHtml
+
'</a>'
);
}},
}},
{
targets
:
6
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
{
targets
:
6
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
script_btn
=
'<a href="{% url "assets:admin-user-update" pk=99991937 %}" class="btn btn-xs btn-primary">{% trans "Script" %}</a>'
.
replace
(
'99991937'
,
cellData
);
{
#
var
script_btn
=
'<a href="{% url "assets:admin-user-update" pk=99991937 %}" class="btn btn-xs btn-primary">{% trans "Script" %}</a>'
.
replace
(
'99991937'
,
cellData
);
#
}
var
update_btn
=
'<a href="{% url "assets:admin-user-update" pk=99991937 %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'
.
replace
(
'99991937'
,
cellData
);
var
update_btn
=
'<a href="{% url "assets:admin-user-update" pk=99991937 %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'
.
replace
(
'99991937'
,
cellData
);
var
del_btn
=
'<a class="btn btn-xs btn-danger m-l-xs btn_admin_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'
.
replace
(
'99991937'
,
cellData
);
var
del_btn
=
'<a class="btn btn-xs btn-danger m-l-xs btn_admin_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'
.
replace
(
'99991937'
,
cellData
);
$
(
td
).
html
(
script_btn
+
update_btn
+
del_btn
)
{
#
$
(
td
).
html
(
script_btn
+
update_btn
+
del_btn
)
#
}
$
(
td
).
html
(
update_btn
+
del_btn
)
}}],
}}],
ajax_url
:
'{% url "api-assets:admin-user-list" %}'
,
ajax_url
:
'{% url "api-assets:admin-user-list" %}'
,
columns
:
[{
data
:
function
(){
return
""
}},
{
data
:
"name"
},
{
data
:
"username"
},
{
data
:
"assets_amount"
},
{
data
:
function
()
{
return
'lost'
}
},
columns
:
[{
data
:
function
(){
return
""
}},
{
data
:
"name"
},
{
data
:
"username"
},
{
data
:
"assets_amount"
},
{
data
:
function
()
{
return
'lost'
}
},
...
@@ -72,7 +73,9 @@ $(document).ready(function(){
...
@@ -72,7 +73,9 @@ $(document).ready(function(){
var
uid
=
$this
.
data
(
'uid'
);
var
uid
=
$this
.
data
(
'uid'
);
var
the_url
=
'{% url "api-assets:admin-user-detail" pk=99991937 %}'
.
replace
(
'99991937'
,
uid
);
var
the_url
=
'{% url "api-assets:admin-user-detail" pk=99991937 %}'
.
replace
(
'99991937'
,
uid
);
objectDelete
(
$this
,
name
,
the_url
);
objectDelete
(
$this
,
name
,
the_url
);
setTimeout
(
function
()
{
$data_table
.
ajax
.
reload
();
$data_table
.
ajax
.
reload
();
},
3000
);
})
})
.
on
(
'click'
,
'#btn_bulk_update'
,
function
()
{
.
on
(
'click'
,
'#btn_bulk_update'
,
function
()
{
...
...
apps/assets/templates/assets/asset_detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/assets/templates/assets/asset_group_detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/assets/templates/assets/asset_group_list.html
View file @
b0551449
...
@@ -70,7 +70,9 @@ $(document).ready(function(){
...
@@ -70,7 +70,9 @@ $(document).ready(function(){
var
uid
=
$this
.
data
(
'uid'
);
var
uid
=
$this
.
data
(
'uid'
);
var
the_url
=
'{% url "api-assets:asset-group-detail" pk=99991937 %}'
.
replace
(
'99991937'
,
uid
);
var
the_url
=
'{% url "api-assets:asset-group-detail" pk=99991937 %}'
.
replace
(
'99991937'
,
uid
);
objectDelete
(
$this
,
name
,
the_url
);
objectDelete
(
$this
,
name
,
the_url
);
setTimeout
(
function
()
{
$data_table
.
ajax
.
reload
();
$data_table
.
ajax
.
reload
();
},
3000
);
})
})
.
on
(
'click'
,
'#btn_bulk_update'
,
function
()
{
.
on
(
'click'
,
'#btn_bulk_update'
,
function
()
{
...
...
apps/assets/templates/assets/asset_list.html
View file @
b0551449
{% extends '_base_list.html' %}
{% extends '_base_list.html' %}
{% load i18n %}
{% load i18n %}
{% load static %}
{% load static %}
{% load common_tags %}
{% block custom_head_css_js %}
{% block custom_head_css_js %}
<link
href=
"{% static 'css/plugins/select2/select2.min.css' %}"
rel=
"stylesheet"
>
<link
href=
"{% static 'css/plugins/select2/select2.min.css' %}"
rel=
"stylesheet"
>
<script
src=
"{% static 'js/plugins/select2/select2.full.min.js' %}"
></script>
<script
src=
"{% static 'js/plugins/select2/select2.full.min.js' %}"
></script>
...
@@ -33,7 +32,7 @@
...
@@ -33,7 +32,7 @@
<div
class=
"tagBtnList"
>
<div
class=
"tagBtnList"
>
{% for tag in tag_list %}
{% for tag in tag_list %}
<a
href=
"{% url 'assets:asset-tags' tag_id=tag.0 %}"
<a
href=
"{% url 'assets:asset-tags' tag_id=tag.0 %}"
{%
if
tag
.
0
|
int_to_str
=
=
tag_id
%}
{%
if
tag
.
0 =
=
tag_id
%}
class=
"tagBtn2 label label-warning"
name=
"tag_on"
>
class=
"tagBtn2 label label-warning"
name=
"tag_on"
>
{% else %}
{% else %}
class="tagBtn2 label label-default">
class="tagBtn2 label label-default">
...
@@ -105,6 +104,38 @@ function tagShow() {
...
@@ -105,6 +104,38 @@ function tagShow() {
}
}
}
//onload;
}
//onload;
function
objDelete
(
obj
,
name
,
url
)
{
function
doDelete
()
{
var
body
=
{};
var
success
=
function
()
{
swal
(
'Deleted!'
,
"[ "
+
name
+
"]"
+
" has been deleted "
,
"success"
);
$
(
obj
).
parent
().
parent
().
remove
();
};
var
fail
=
function
()
{
swal
(
"Failed"
,
"Delete"
+
"[ "
+
name
+
" ]"
+
"failed"
,
"error"
);
};
APIUpdateAttr
({
url
:
url
,
body
:
JSON
.
stringify
(
body
),
method
:
'DELETE'
,
success
:
success
,
error
:
fail
});
}
swal
({
title
:
'Are you sure delete ?'
,
text
:
" ["
+
name
+
"] "
,
type
:
"warning"
,
showCancelButton
:
true
,
cancelButtonText
:
'Cancel'
,
confirmButtonColor
:
"#DD6B55"
,
confirmButtonText
:
'Confirm'
,
closeOnConfirm
:
false
},
function
()
{
doDelete
()
});
}
$
(
document
).
ready
(
function
(){
$
(
document
).
ready
(
function
(){
var
options
=
{
var
options
=
{
ele
:
$
(
'#asset_list_table'
),
ele
:
$
(
'#asset_list_table'
),
...
@@ -187,8 +218,11 @@ $(document).ready(function(){
...
@@ -187,8 +218,11 @@ $(document).ready(function(){
var
name
=
$
(
this
).
closest
(
"tr"
).
find
(
":nth-child(2)"
).
children
(
'a'
).
html
();
var
name
=
$
(
this
).
closest
(
"tr"
).
find
(
":nth-child(2)"
).
children
(
'a'
).
html
();
var
uid
=
$this
.
data
(
'uid'
);
var
uid
=
$this
.
data
(
'uid'
);
var
the_url
=
'{% url "api-assets:asset-detail" pk=99991937 %}'
.
replace
(
'99991937'
,
uid
);
var
the_url
=
'{% url "api-assets:asset-detail" pk=99991937 %}'
.
replace
(
'99991937'
,
uid
);
objectDelete
(
$this
,
name
,
the_url
);
console
.
log
(
the_url
);
objDelete
(
$this
,
name
,
the_url
);
setTimeout
(
function
()
{
$data_table
.
ajax
.
reload
();
$data_table
.
ajax
.
reload
();
},
3000
);
})
})
.
on
(
'click'
,
'#btn_bulk_update'
,
function
()
{
.
on
(
'click'
,
'#btn_bulk_update'
,
function
()
{
...
@@ -324,5 +358,6 @@ $(document).ready(function(){
...
@@ -324,5 +358,6 @@ $(document).ready(function(){
{
#
APIUpdateAttr
({
url
:
the_url
,
method
:
'PATCH'
,
body
:
JSON
.
stringify
(
post_list
),
success
:
success
});
#
}
{
#
APIUpdateAttr
({
url
:
the_url
,
method
:
'PATCH'
,
body
:
JSON
.
stringify
(
post_list
),
success
:
success
});
#
}
$
(
'#asset_bulk_update_modal'
).
modal
(
'hide'
);
$
(
'#asset_bulk_update_modal'
).
modal
(
'hide'
);
});
});
</script>
</script>
{% endblock %}
{% endblock %}
apps/assets/templates/assets/asset_tag_detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/assets/templates/assets/asset_tags_list.html
View file @
b0551449
{% extends '_base_list.html' %}
{% extends '_base_list.html' %}
{% load i18n static %}
{% load i18n static %}
{#{% load common_tags %}#}
{% block custom_head_css_js %}
{% block custom_head_css_js %}
<link
href=
"{% static 'css/plugins/select2/select2.min.css' %}"
rel=
"stylesheet"
>
<link
href=
"{% static 'css/plugins/select2/select2.min.css' %}"
rel=
"stylesheet"
>
<script
src=
"{% static 'js/plugins/select2/select2.full.min.js' %}"
></script>
<script
src=
"{% static 'js/plugins/select2/select2.full.min.js' %}"
></script>
...
...
apps/assets/templates/assets/idc_assets.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/assets/templates/assets/idc_create_update.html
View file @
b0551449
...
@@ -41,6 +41,7 @@
...
@@ -41,6 +41,7 @@
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<h3
class=
"widget-head-color-box"
>
IP段
</h3>
<h3
class=
"widget-head-color-box"
>
IP段
</h3>
{{ form.operator|bootstrap_horizontal }}
{{ form.intranet|bootstrap_horizontal }}
{{ form.intranet|bootstrap_horizontal }}
{{ form.extranet|bootstrap_horizontal }}
{{ form.extranet|bootstrap_horizontal }}
...
...
apps/assets/templates/assets/idc_detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/assets/templates/assets/system_user_asset.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/assets/templates/assets/system_user_asset_group.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/assets/templates/assets/system_user_detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/assets/templates/assets/system_user_list.html
View file @
b0551449
{% extends '_base_list.html' %}
{% extends '_base_list.html' %}
{% load i18n %}
{% load i18n %}
{% load common_tags %}
{% block table_search %}
{% block table_search %}
{% endblock %}
{% endblock %}
...
@@ -75,7 +74,9 @@ $(document).ready(function(){
...
@@ -75,7 +74,9 @@ $(document).ready(function(){
var
uid
=
$this
.
data
(
'uid'
);
var
uid
=
$this
.
data
(
'uid'
);
var
the_url
=
'{% url "api-assets:system-user-detail" pk=99991937 %}'
.
replace
(
'99991937'
,
uid
);
var
the_url
=
'{% url "api-assets:system-user-detail" pk=99991937 %}'
.
replace
(
'99991937'
,
uid
);
objectDelete
(
$this
,
name
,
the_url
);
objectDelete
(
$this
,
name
,
the_url
);
setTimeout
(
function
()
{
$data_table
.
ajax
.
reload
();
$data_table
.
ajax
.
reload
();
},
3000
);
})
})
.
on
(
'click'
,
'#btn_bulk_update'
,
function
()
{
.
on
(
'click'
,
'#btn_bulk_update'
,
function
()
{
...
...
apps/assets/views.py
View file @
b0551449
...
@@ -139,15 +139,15 @@ class AssetUpdateView(AdminUserRequiredMixin, UpdateAssetTagsMiXin, UpdateView):
...
@@ -139,15 +139,15 @@ class AssetUpdateView(AdminUserRequiredMixin, UpdateAssetTagsMiXin, UpdateView):
print
(
form
.
errors
)
print
(
form
.
errors
)
return
super
(
AssetUpdateView
,
self
)
.
form_invalid
(
form
)
return
super
(
AssetUpdateView
,
self
)
.
form_invalid
(
form
)
def
form_valid
(
self
,
form
):
#
def form_valid(self, form):
asset
=
form
.
save
(
commit
=
False
)
#
asset = form.save(commit=False)
#
def
prn_obj_key
(
obj_form
):
#
def prn_obj_key(obj_form):
return
obj_form
.
clean
()
.
keys
()
#
return obj_form.clean().keys()
#
for
i
in
prn_obj_key
(
form
):
#
for i in prn_obj_key(form):
if
i
not
in
self
.
new_form
.
keys
():
#
if i not in self.new_form.keys():
print
i
#
print i
#delattr(asset, '"%s" % i')
#delattr(asset, '"%s" % i')
#del asset.i
#del asset.i
...
...
apps/audits/templates/audits/command_log_list.html
View file @
b0551449
{% extends '_base_list.html' %}
{% extends '_base_list.html' %}
{% load i18n %}
{% load i18n %}
{% load static %}
{% load static %}
{% load common_tags %}
{% block content_left_head %}
{% block content_left_head %}
<link
href=
"{% static "
css
/
plugins
/
footable
/
footable
.
core
.
css
"
%}"
rel=
"stylesheet"
>
<link
href=
"{% static "
css
/
plugins
/
footable
/
footable
.
core
.
css
"
%}"
rel=
"stylesheet"
>
<link
href=
"{% static 'css/plugins/datepicker/datepicker3.css' %}"
rel=
"stylesheet"
>
<link
href=
"{% static 'css/plugins/datepicker/datepicker3.css' %}"
rel=
"stylesheet"
>
...
...
apps/audits/templates/audits/proxy_log_detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/audits/templates/audits/proxy_log_list.html
View file @
b0551449
{% extends '_base_list.html' %}
{% extends '_base_list.html' %}
{% load i18n %}
{% load i18n %}
{% load static %}
{% load static %}
{% load common_tags %}
{% block content_left_head %}
{% block content_left_head %}
<link
href=
"{% static 'css/plugins/datepicker/datepicker3.css' %}"
rel=
"stylesheet"
>
<link
href=
"{% static 'css/plugins/datepicker/datepicker3.css' %}"
rel=
"stylesheet"
>
<style>
<style>
...
...
apps/fixtures/fake.json
View file @
b0551449
This source diff could not be displayed because it is too large. You can
view the blob
instead.
apps/jumpserver/settings.py
View file @
b0551449
...
@@ -14,7 +14,6 @@ import os
...
@@ -14,7 +14,6 @@ import os
import
sys
import
sys
from
django.urls
import
reverse_lazy
from
django.urls
import
reverse_lazy
from
datetime
import
timedelta
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR
=
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
)))
BASE_DIR
=
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
)))
...
@@ -300,11 +299,11 @@ CELERY_RESULT_BACKEND = BROKER_URL
...
@@ -300,11 +299,11 @@ CELERY_RESULT_BACKEND = BROKER_URL
# crontab job
# crontab job
# CELERYBEAT_SCHEDULE = {
# CELERYBEAT_SCHEDULE = {
# Check applications is alive every 10m
# Check applications is alive every 10m
# 'check_terminal_alive': {
# 'check_terminal_alive': {
# 'task': 'applications.tasks.check_terminal_alive',
# 'task': 'applications.tasks.check_terminal_alive',
# 'schedule': timedelta(seconds=TERMINAL_HEATBEAT_INTERVAL),
# 'schedule': timedelta(seconds=TERMINAL_HEATBEAT_INTERVAL),
# 'args': (),
# 'args': (),
# },
# },
# }
# }
...
@@ -326,3 +325,4 @@ CAPTCHA_FOREGROUND_COLOR = '#001100'
...
@@ -326,3 +325,4 @@ CAPTCHA_FOREGROUND_COLOR = '#001100'
COMMAND_STORE_BACKEND
=
'audits.backends.command.db'
COMMAND_STORE_BACKEND
=
'audits.backends.command.db'
RECORD_STORE_BACKEND
=
'audits.backends.record.db'
RECORD_STORE_BACKEND
=
'audits.backends.record.db'
CAPTCHA_TEST_MODE
=
CONFIG
.
CAPTCHA_TEST_MODE
apps/ops/models/task.py
View file @
b0551449
...
@@ -6,7 +6,6 @@ import logging
...
@@ -6,7 +6,6 @@ import logging
from
uuid
import
uuid4
from
uuid
import
uuid4
from
assets.models
import
Asset
from
assets.models
import
Asset
from
ops.models
import
TaskRecord
from
ops.models
import
TaskRecord
from
ops.utils.ansible_api
import
ADHocRunner
,
Config
from
django.db
import
models
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
...
@@ -20,7 +19,7 @@ logger = logging.getLogger(__name__)
...
@@ -20,7 +19,7 @@ logger = logging.getLogger(__name__)
class
Task
(
models
.
Model
):
class
Task
(
models
.
Model
):
record
=
models
.
OneToOneField
(
TaskRecord
)
record
=
models
.
OneToOneField
(
TaskRecord
)
name
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Name'
))
name
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Name'
))
is_gather_facts
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
'Is Gather Ansible Facts'
))
is_gather_facts
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
'Is Gather Ansible Facts'
))
assets
=
models
.
ManyToManyField
(
Asset
,
related_name
=
'tasks'
)
assets
=
models
.
ManyToManyField
(
Asset
,
related_name
=
'tasks'
)
def
__unicode__
(
self
):
def
__unicode__
(
self
):
...
@@ -31,6 +30,7 @@ class Task(models.Model):
...
@@ -31,6 +30,7 @@ class Task(models.Model):
return
[]
return
[]
def
run
(
self
):
def
run
(
self
):
from
ops.utils.ansible_api
import
ADHocRunner
,
Config
conf
=
Config
()
conf
=
Config
()
gather_facts
=
"yes"
if
self
.
is_gather_facts
else
"no"
gather_facts
=
"yes"
if
self
.
is_gather_facts
else
"no"
play_source
=
{
play_source
=
{
...
...
apps/ops/templates/cron/detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/ops/templates/sudo/detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/ops/templates/task/detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/perms/templates/perms/asset_permission_asset.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/perms/templates/perms/asset_permission_detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/perms/templates/perms/asset_permission_list.html
View file @
b0551449
{% extends '_base_list.html' %}
{% extends '_base_list.html' %}
{% load i18n %}
{% load i18n %}
{% load common_tags %}
{% block content_left_head %}
{% block content_left_head %}
<a
href=
"{% url 'perms:asset-permission-create' %}"
class=
"btn btn-sm btn-primary"
>
<a
href=
"{% url 'perms:asset-permission-create' %}"
class=
"btn btn-sm btn-primary"
>
{% trans "Create permission" %}
{% trans "Create permission" %}
...
...
apps/perms/templates/perms/asset_permission_user.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/static/css/jumpserver.css
View file @
b0551449
...
@@ -225,6 +225,7 @@ table.dataTable tbody td.selected td i.text-navy
...
@@ -225,6 +225,7 @@ table.dataTable tbody td.selected td i.text-navy
background
:
#f1f1f1
;
background
:
#f1f1f1
;
margin-right
:
2px
;
margin-right
:
2px
;
}
}
.form-asset-on
{
.form-asset-on
{
border
:
1px
solid
#e5e6e7
;
border
:
1px
solid
#e5e6e7
;
padding-top
:
5px
;
padding-top
:
5px
;
...
@@ -264,3 +265,15 @@ div.dataTables_wrapper div.dataTables_filter,
...
@@ -264,3 +265,15 @@ div.dataTables_wrapper div.dataTables_filter,
div
.dataTables_wrapper
div
.dataTables_filter
{
div
.dataTables_wrapper
div
.dataTables_filter
{
margin-left
:
15px
;
margin-left
:
15px
;
}
}
.simple-tag
{
background-color
:
#f3f3f4
;
border
:
1px
solid
#e7eaec
;
border-radius
:
2px
;
color
:
inherit
;
display
:
inline-block
;
font-size
:
10px
;
margin-right
:
5px
;
margin-top
:
5px
;
padding
:
5px
12px
;
}
apps/templates/_base_list.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load static %}
{% load static %}
{% load common_tags %}
{% block custom_head_css_js %}
{% block custom_head_css_js %}
<link
href=
"{% static "
css
/
plugins
/
dataTables
/
dataTables
.
min
.
css
"
%}"
rel=
"stylesheet"
>
<link
href=
"{% static "
css
/
plugins
/
dataTables
/
dataTables
.
min
.
css
"
%}"
rel=
"stylesheet"
>
<link
href=
"{% static "
css
/
plugins
/
awesome-bootstrap-checkbox
/
awesome-bootstrap-checkbox
.
css
"
%}"
rel=
"stylesheet"
>
<link
href=
"{% static "
css
/
plugins
/
awesome-bootstrap-checkbox
/
awesome-bootstrap-checkbox
.
css
"
%}"
rel=
"stylesheet"
>
...
...
apps/templates/base.html
View file @
b0551449
...
@@ -24,9 +24,9 @@
...
@@ -24,9 +24,9 @@
{% block first_login_message %}
{% block first_login_message %}
{% if user.is_authenticated and user.is_first_login %}
{% if user.is_authenticated and user.is_first_login %}
<div
class=
"alert alert-danger"
style=
"margin: 20px auto 0px"
>
<div
class=
"alert alert-danger"
style=
"margin: 20px auto 0px"
>
{% url 'users:user-first-login' as
the
_url %}
{% url 'users:user-first-login' as
first_login
_url %}
{% blocktrans %}
{% blocktrans %}
Your information was incomplete. Please click
<a
href=
"{{
the
_url }}"
>
this link
</a>
to complete your information.
Your information was incomplete. Please click
<a
href=
"{{
first_login
_url }}"
>
this link
</a>
to complete your information.
{% endblocktrans %}
{% endblocktrans %}
</div>
</div>
{% endif %}
{% endif %}
...
@@ -34,8 +34,9 @@
...
@@ -34,8 +34,9 @@
{% block update_public_key_message %}
{% block update_public_key_message %}
{% if user.is_authenticated and not user.is_public_key_valid %}
{% if user.is_authenticated and not user.is_public_key_valid %}
<div
class=
"alert alert-danger"
style=
"margin: 20px auto 0px"
>
<div
class=
"alert alert-danger"
style=
"margin: 20px auto 0px"
>
{% url 'users:user-profile' as profile_url %}
{% blocktrans %}
{% blocktrans %}
Your ssh-public-key has been expired. Please click
<a
href=
"
#"
>
this link
</a>
to
update your ssh-public-key.
Your ssh-public-key has been expired. Please click
<a
href=
"
{{ profile_url }}"
>
this link
</a>
to
update your ssh-public-key.
{% endblocktrans %}
{% endblocktrans %}
</div>
</div>
{% endif %}
{% endif %}
...
...
apps/users/api.py
View file @
b0551449
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
#
from
rest_framework
import
generics
,
viewsets
from
rest_framework
import
generics
from
rest_framework.permissions
import
AllowAny
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.permissions
import
AllowAny
from
rest_framework_bulk
import
BulkModelViewSet
from
rest_framework_bulk
import
BulkModelViewSet
# from django_filters.rest_framework import DjangoFilterBackend
from
.
import
serializers
from
.hands
import
write_login_log_async
from
.models
import
User
,
UserGroup
from
.permissions
import
IsSuperUser
,
IsValidUser
,
IsCurrentUserOrReadOnly
from
.utils
import
check_user_valid
,
generate_token
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
.models
import
User
,
UserGroup
from
.hands
import
write_login_log_async
from
.permissions
import
(
IsSuperUser
,
IsAppUser
,
IsValidUser
)
from
.
import
serializers
logger
=
get_logger
(
__name__
)
logger
=
get_logger
(
__name__
)
...
@@ -41,7 +38,7 @@ class UserResetPasswordApi(generics.UpdateAPIView):
...
@@ -41,7 +38,7 @@ class UserResetPasswordApi(generics.UpdateAPIView):
def
perform_update
(
self
,
serializer
):
def
perform_update
(
self
,
serializer
):
# Note: we are not updating the user object here.
# Note: we are not updating the user object here.
# We just do the reset-password st
a
ff.
# We just do the reset-password st
u
ff.
import
uuid
import
uuid
from
.utils
import
send_reset_password_mail
from
.utils
import
send_reset_password_mail
user
=
self
.
get_object
()
user
=
self
.
get_object
()
...
@@ -65,6 +62,7 @@ class UserResetPKApi(generics.UpdateAPIView):
...
@@ -65,6 +62,7 @@ class UserResetPKApi(generics.UpdateAPIView):
class
UserUpdatePKApi
(
generics
.
UpdateAPIView
):
class
UserUpdatePKApi
(
generics
.
UpdateAPIView
):
queryset
=
User
.
objects
.
all
()
queryset
=
User
.
objects
.
all
()
serializer_class
=
serializers
.
UserPKUpdateSerializer
serializer_class
=
serializers
.
UserPKUpdateSerializer
permission_classes
=
(
IsCurrentUserOrReadOnly
,)
def
perform_update
(
self
,
serializer
):
def
perform_update
(
self
,
serializer
):
user
=
self
.
get_object
()
user
=
self
.
get_object
()
...
...
apps/users/models/user.py
View file @
b0551449
#!/usr/bin/env python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
import
os
from
collections
import
OrderedDict
from
collections
import
OrderedDict
from
django.conf
import
settings
from
django.contrib.auth.hashers
import
make_password
from
django.contrib.auth.hashers
import
make_password
from
django.contrib.auth.models
import
AbstractUser
from
django.contrib.auth.models
import
AbstractUser
from
django.core
import
signing
from
django.core
import
signing
from
django.conf
import
settings
from
django.db
import
models
from
django.db
import
models
,
IntegrityError
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.shortcuts
import
reverse
from
django.shortcuts
import
reverse
from
common.utils
import
signer
,
date_expired_default
from
.
import
UserGroup
from
.
import
UserGroup
from
common.utils
import
signer
,
date_expired_default
__all__
=
[
'User'
]
__all__
=
[
'User'
]
...
@@ -61,6 +62,15 @@ class User(AbstractUser):
...
@@ -61,6 +62,15 @@ class User(AbstractUser):
def
get_absolute_url
(
self
):
def
get_absolute_url
(
self
):
return
reverse
(
'users:user-detail'
,
args
=
(
self
.
id
,))
return
reverse
(
'users:user-detail'
,
args
=
(
self
.
id
,))
def
is_public_key_valid
(
self
):
"""
Check if the user's ssh public key is valid.
This function is used in base.html.
"""
if
self
.
_public_key
:
return
True
return
False
@property
@property
def
is_expired
(
self
):
def
is_expired
(
self
):
if
self
.
date_expired
<
timezone
.
now
():
if
self
.
date_expired
<
timezone
.
now
():
...
@@ -156,6 +166,17 @@ class User(AbstractUser):
...
@@ -156,6 +166,17 @@ class User(AbstractUser):
return
True
return
True
return
False
return
False
def
avatar_url
(
self
):
if
self
.
avatar
:
return
self
.
avatar
.
url
else
:
default_dir
=
os
.
path
.
join
(
settings
.
MEDIA_ROOT
,
'avatar'
,
'default'
)
if
os
.
path
.
isdir
(
default_dir
):
default_avatar_list
=
os
.
listdir
(
default_dir
)
default_avatar
=
default_avatar_list
[
len
(
self
.
username
)
%
len
(
default_avatar_list
)]
return
os
.
path
.
join
(
settings
.
MEDIA_URL
,
'avatar'
,
'default'
,
default_avatar
)
return
'https://www.gravatar.com/avatar/c6812ab450230979465d7bf288eadce2a?s=120&d=identicon'
def
generate_reset_token
(
self
):
def
generate_reset_token
(
self
):
return
signer
.
sign_t
({
'reset'
:
self
.
id
,
'email'
:
self
.
email
},
expires_in
=
3600
)
return
signer
.
sign_t
({
'reset'
:
self
.
id
,
'email'
:
self
.
email
},
expires_in
=
3600
)
...
...
apps/users/permissions.py
View file @
b0551449
#!/usr/bin/env python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
import
base64
from
rest_framework
import
permissions
from
django.core.cache
import
cache
from
django.conf
import
settings
from
django.utils.translation
import
ugettext
as
_
from
rest_framework
import
authentication
,
exceptions
,
permissions
from
rest_framework.compat
import
is_authenticated
from
common.utils
import
signer
,
get_object_or_none
from
.hands
import
Terminal
from
.models
import
User
class
IsValidUser
(
permissions
.
IsAuthenticated
,
permissions
.
BasePermission
):
class
IsValidUser
(
permissions
.
IsAuthenticated
,
permissions
.
BasePermission
):
...
@@ -47,5 +36,9 @@ class IsSuperUserOrAppUser(IsValidUser, permissions.BasePermission):
...
@@ -47,5 +36,9 @@ class IsSuperUserOrAppUser(IsValidUser, permissions.BasePermission):
and
(
request
.
user
.
is_superuser
or
request
.
user
.
is_app
)
and
(
request
.
user
.
is_superuser
or
request
.
user
.
is_app
)
if
__name__
==
'__main__'
:
class
IsCurrentUserOrReadOnly
(
permissions
.
BasePermission
):
pass
def
has_object_permission
(
self
,
request
,
view
,
obj
):
if
request
.
method
in
permissions
.
SAFE_METHODS
:
return
True
return
obj
==
request
.
user
apps/users/templates/users/user_asset_permission.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load bootstrap %}
{% load bootstrap %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/users/templates/users/user_detail.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
@@ -18,16 +16,16 @@
...
@@ -18,16 +16,16 @@
<div
class=
"panel-options"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<ul
class=
"nav nav-tabs"
>
<li
class=
"active"
>
<li
class=
"active"
>
<a
href=
"{% url 'users:user-detail' pk=user.id %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'User detail' %}
</a>
<a
href=
"{% url 'users:user-detail' pk=user
_object
.id %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'User detail' %}
</a>
</li>
</li>
<li>
<li>
<a
href=
"{% url 'users:user-asset-permission' pk=user.id %}"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Asset permission' %}
</a>
<a
href=
"{% url 'users:user-asset-permission' pk=user
_object
.id %}"
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Asset permission' %}
</a>
</li>
</li>
<li>
<li>
<a
href=
"{% url 'users:user-granted-asset' pk=user.id %}"
class=
"text-center"
><i
class=
"fa fa-cubes"
></i>
{% trans 'Asset granted' %}
</a>
<a
href=
"{% url 'users:user-granted-asset' pk=user
_object
.id %}"
class=
"text-center"
><i
class=
"fa fa-cubes"
></i>
{% trans 'Asset granted' %}
</a>
</li>
</li>
<li
class=
"pull-right"
>
<li
class=
"pull-right"
>
<a
class=
"btn btn-outline btn-default"
href=
"{% url 'users:user-update' pk=user.id %}"
><i
class=
"fa fa-edit"
></i>
Update
</a>
<a
class=
"btn btn-outline btn-default"
href=
"{% url 'users:user-update' pk=user
_object
.id %}"
><i
class=
"fa fa-edit"
></i>
Update
</a>
</li>
</li>
<li
class=
"pull-right"
>
<li
class=
"pull-right"
>
<a
class=
"btn btn-outline btn-danger btn-delete-user"
>
<a
class=
"btn btn-outline btn-danger btn-delete-user"
>
...
@@ -40,7 +38,7 @@
...
@@ -40,7 +38,7 @@
<div
class=
"col-sm-7"
style=
"padding-left: 0"
>
<div
class=
"col-sm-7"
style=
"padding-left: 0"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<div
class=
"ibox-title"
>
<span
class=
"label"
><b>
{{ user.name }}
</b></span>
<span
class=
"label"
><b>
{{ user
_object
.name }}
</b></span>
<div
class=
"ibox-tools"
>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
<i
class=
"fa fa-chevron-up"
></i>
...
@@ -60,56 +58,56 @@
...
@@ -60,56 +58,56 @@
<tbody>
<tbody>
<tr
class=
"no-borders-tr"
>
<tr
class=
"no-borders-tr"
>
<td
colspan=
"2"
>
<td
colspan=
"2"
>
<img
src=
"{{ user
|user_
avatar_url }}"
class=
"img-circle"
width=
"64"
height=
"64"
>
<img
src=
"{{ user
_object.
avatar_url }}"
class=
"img-circle"
width=
"64"
height=
"64"
>
</td>
</td>
</tr>
</tr>
<tr>
<tr>
<td
width=
"20%"
>
{% trans 'Name' %}:
</td>
<td
width=
"20%"
>
{% trans 'Name' %}:
</td>
<td><b>
{{ user.name }}
</b></td>
<td><b>
{{ user
_object
.name }}
</b></td>
</tr>
</tr>
<tr>
<tr>
<td>
{% trans 'Username' %}:
</td>
<td>
{% trans 'Username' %}:
</td>
<td><b>
{{ user.username }}
</b></td>
<td><b>
{{ user
_object
.username }}
</b></td>
</tr>
</tr>
<tr>
<tr>
<td>
{% trans 'Email' %}:
</td>
<td>
{% trans 'Email' %}:
</td>
<td><b>
{{ user.email }}
</b></td>
<td><b>
{{ user
_object
.email }}
</b></td>
</tr>
</tr>
{% if user.phone %}
{% if user.phone %}
<tr>
<tr>
<td>
{% trans 'Phone' %}:
</td>
<td>
{% trans 'Phone' %}:
</td>
<td><b>
{{ user.phone }}
</b></td>
<td><b>
{{ user
_object
.phone }}
</b></td>
</tr>
</tr>
{% endif %}
{% endif %}
{% if user.wechat %}
{% if user
_object
.wechat %}
<tr>
<tr>
<td>
{% trans 'Wechat' %}:
</td>
<td>
{% trans 'Wechat' %}:
</td>
<td><b>
{{ user.wechat }}
</b></td>
<td><b>
{{ user
_object
.wechat }}
</b></td>
</tr>
</tr>
{% endif %}
{% endif %}
<tr>
<tr>
<td>
{% trans 'Role' %}:
</td>
<td>
{% trans 'Role' %}:
</td>
<td><b>
{{ user.get_role_display }}
</b></td>
<td><b>
{{ user
_object
.get_role_display }}
</b></td>
</tr>
</tr>
<tr>
<tr>
<td>
{% trans 'Date expired' %}:
</td>
<td>
{% trans 'Date expired' %}:
</td>
<td><b>
{{ user.date_expired|date:"Y-m-j H:i:s" }}
</b></td>
<td><b>
{{ user
_object
.date_expired|date:"Y-m-j H:i:s" }}
</b></td>
</tr>
</tr>
<tr>
<tr>
<td>
{% trans 'Created by' %}:
</td>
<td>
{% trans 'Created by' %}:
</td>
<td><b>
{{ user.created_by }}
</b></td>
<td><b>
{{ user
_object
.created_by }}
</b></td>
</tr>
</tr>
<tr>
<tr>
<td>
{% trans 'Date joined' %}:
</td>
<td>
{% trans 'Date joined' %}:
</td>
<td><b>
{{ user.date_joined|date:"Y-m-j H:i:s" }}
</b></td>
<td><b>
{{ user
_object
.date_joined|date:"Y-m-j H:i:s" }}
</b></td>
</tr>
</tr>
<tr>
<tr>
<td>
{% trans 'Last login' %}:
</td>
<td>
{% trans 'Last login' %}:
</td>
<td><b>
{{ user.last_login|date:"Y-m-j H:i:s" }}
</b></td>
<td><b>
{{ user
_object
.last_login|date:"Y-m-j H:i:s" }}
</b></td>
</tr>
</tr>
<tr>
<tr>
<td>
{% trans 'Comment' %}:
</td>
<td>
{% trans 'Comment' %}:
</td>
<td><b>
{{ user.comment }}
</b></td>
<td><b>
{{ user
_object
.comment }}
</b></td>
</tr>
</tr>
</tbody>
</tbody>
</table>
</table>
...
@@ -129,7 +127,7 @@
...
@@ -129,7 +127,7 @@
<td><span
class=
"pull-right"
>
<td><span
class=
"pull-right"
>
<div
class=
"switch"
>
<div
class=
"switch"
>
<div
class=
"onoffswitch"
>
<div
class=
"onoffswitch"
>
<input
type=
"checkbox"
{%
if
user
.
is_active
%}
checked
{%
endif
%}
class=
"onoffswitch-checkbox"
id=
"is_active"
>
<input
type=
"checkbox"
{%
if
user
_object
.
is_active
%}
checked
{%
endif
%}
class=
"onoffswitch-checkbox"
id=
"is_active"
>
<label
class=
"onoffswitch-label"
for=
"is_active"
>
<label
class=
"onoffswitch-label"
for=
"is_active"
>
<span
class=
"onoffswitch-inner"
></span>
<span
class=
"onoffswitch-inner"
></span>
<span
class=
"onoffswitch-switch"
></span>
<span
class=
"onoffswitch-switch"
></span>
...
@@ -143,7 +141,7 @@
...
@@ -143,7 +141,7 @@
<td><span
class=
"pull-right"
>
<td><span
class=
"pull-right"
>
<div
class=
"switch"
>
<div
class=
"switch"
>
<div
class=
"onoffswitch"
>
<div
class=
"onoffswitch"
>
<input
type=
"checkbox"
class=
"onoffswitch-checkbox"
{%
if
user
.
enable_otp
%}
checked
{%
endif
%}
<input
type=
"checkbox"
class=
"onoffswitch-checkbox"
{%
if
user
_object
.
enable_otp
%}
checked
{%
endif
%}
id=
"enable_otp"
>
id=
"enable_otp"
>
<label
class=
"onoffswitch-label"
for=
"enable_otp"
>
<label
class=
"onoffswitch-label"
for=
"enable_otp"
>
<span
class=
"onoffswitch-inner"
></span>
<span
class=
"onoffswitch-inner"
></span>
...
@@ -169,14 +167,6 @@
...
@@ -169,14 +167,6 @@
</span>
</span>
</td>
</td>
</tr>
</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>
</tbody>
</table>
</table>
</div>
</div>
...
@@ -206,7 +196,7 @@
...
@@ -206,7 +196,7 @@
</tr>
</tr>
</form>
</form>
{% for group in user.groups.all %}
{% for group in user
_object
.groups.all %}
<tr>
<tr>
<td
>
<td
>
<b
class=
"bdg_group"
data-gid=
{{
group
.
id
}}
>
{{ group.name }}
</b>
<b
class=
"bdg_group"
data-gid=
{{
group
.
id
}}
>
{{ group.name }}
</b>
...
@@ -233,7 +223,7 @@
...
@@ -233,7 +223,7 @@
jumpserver
.
groups_selected
=
{};
jumpserver
.
groups_selected
=
{};
function
updateUserGroups
(
groups
)
{
function
updateUserGroups
(
groups
)
{
var
the_url
=
"{% url 'api-users:user-update-group' pk=user.id %}"
;
var
the_url
=
"{% url 'api-users:user-update-group' pk=user
_object
.id %}"
;
var
body
=
{
var
body
=
{
groups
:
Object
.
assign
([],
groups
)
groups
:
Object
.
assign
([],
groups
)
};
};
...
@@ -273,7 +263,7 @@ $(document).ready(function() {
...
@@ -273,7 +263,7 @@ $(document).ready(function() {
})
})
})
})
.
on
(
'click'
,
'#is_active'
,
function
()
{
.
on
(
'click'
,
'#is_active'
,
function
()
{
var
the_url
=
"{% url 'api-users:user-detail' pk=user.id %}"
;
var
the_url
=
"{% url 'api-users:user-detail' pk=user
_object
.id %}"
;
var
checked
=
$
(
this
).
prop
(
'checked'
);
var
checked
=
$
(
this
).
prop
(
'checked'
);
var
body
=
{
var
body
=
{
'is_active'
:
checked
'is_active'
:
checked
...
@@ -286,7 +276,7 @@ $(document).ready(function() {
...
@@ -286,7 +276,7 @@ $(document).ready(function() {
});
});
})
})
.
on
(
'click'
,
'#enable_otp'
,
function
()
{
.
on
(
'click'
,
'#enable_otp'
,
function
()
{
var
the_url
=
"{% url 'api-users:user-detail' pk=user.id %}"
;
var
the_url
=
"{% url 'api-users:user-detail' pk=user
_object
.id %}"
;
var
checked
=
$
(
this
).
prop
(
'checked'
);
var
checked
=
$
(
this
).
prop
(
'checked'
);
var
body
=
{
var
body
=
{
'enable_otp'
:
checked
'enable_otp'
:
checked
...
@@ -326,7 +316,7 @@ $(document).ready(function() {
...
@@ -326,7 +316,7 @@ $(document).ready(function() {
updateUserGroups
(
groups
)
updateUserGroups
(
groups
)
}).
on
(
'click'
,
'#btn_reset_password'
,
function
()
{
}).
on
(
'click'
,
'#btn_reset_password'
,
function
()
{
function
doReset
()
{
function
doReset
()
{
var
the_url
=
'{% url "api-users:user-reset-password" pk=user.id %}'
;
var
the_url
=
'{% url "api-users:user-reset-password" pk=user
_object
.id %}'
;
var
body
=
{};
var
body
=
{};
var
success
=
function
()
{
var
success
=
function
()
{
var
msg
=
"{% trans "
An
e
-
mail
has
been
sent
to
the
user
\
's mailbox." %}";
var
msg
=
"{% trans "
An
e
-
mail
has
been
sent
to
the
user
\
's mailbox." %}";
...
@@ -340,7 +330,7 @@ $(document).ready(function() {
...
@@ -340,7 +330,7 @@ $(document).ready(function() {
}
}
swal({
swal({
title: "{% trans '
Are
you
sure
?
' %}",
title: "{% trans '
Are
you
sure
?
' %}",
text: "{% trans '
This
will
reset
the
user
\
's password.'
%
}
",
text: "{% trans '
This
will
reset
the
user
\
's password.
A password-reset email will be sent to the user
\'
s mailbox.
'
%
}
",
type: "
warning
",
type: "
warning
",
showCancelButton: true,
showCancelButton: true,
confirmButtonColor: "
#
DD6B55
",
confirmButtonColor: "
#
DD6B55
",
...
@@ -351,7 +341,7 @@ $(document).ready(function() {
...
@@ -351,7 +341,7 @@ $(document).ready(function() {
});
});
}).on('click', '#btn_reset_pk', function() {
}).on('click', '#btn_reset_pk', function() {
function doReset() {
function doReset() {
var the_url = '{% url "
api
-
users
:
user
-
public
-
key
-
reset
" pk=user.id %}';
var the_url = '{% url "
api
-
users
:
user
-
public
-
key
-
reset
" pk=user
_object
.id %}';
var body = {};
var body = {};
var success = function() {
var success = function() {
var msg = "
{
%
trans
'The reset-ssh-public-key E-mail has been sent successfully. Please inform the user to update his new ssh public key.'
%
}
";
var msg = "
{
%
trans
'The reset-ssh-public-key E-mail has been sent successfully. Please inform the user to update his new ssh public key.'
%
}
";
...
...
apps/users/templates/users/user_granted_asset.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load bootstrap %}
{% load bootstrap %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/users/templates/users/user_group_asset_permission.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load bootstrap %}
{% load bootstrap %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/users/templates/users/user_group_granted_asset.html
View file @
b0551449
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load bootstrap %}
{% load bootstrap %}
{% load static %}
{% load static %}
{% load i18n %}
{% load i18n %}
...
...
apps/users/templates/users/user_profile.html
0 → 100644
View file @
b0551449
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link
href=
"{% static "
css
/
plugins
/
sweetalert
/
sweetalert
.
css
"
%}"
rel=
"stylesheet"
>
<script
src=
"{% static "
js
/
plugins
/
sweetalert
/
sweetalert
.
min
.
js
"
%}"
></script>
{% endblock %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-6"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
{{ user.name }}
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
</a>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content"
>
<div
class=
"text-left"
>
<table
class=
"table"
>
<tr>
<td
class=
"text-navy"
>
用户名
</td>
<td>
{{ user.username }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
姓名
</td>
<td>
{{ user.name }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
权限
</td>
<td>
{{ user.get_role_display }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
Email
</td>
<td>
{{ user.email }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
激活
</td>
<td>
{{ user.is_active }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
添加日期
</td>
<td>
{{ user.date_joined|date:"Y-m-d H:i:s" }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
最后登录
</td>
<td>
{{ user.last_login|date:"Y-m-d H:i:s" }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
所在用户组
</td>
<td>
{% for group in user.groups.all %}
<span
class=
"simple-tag with-link"
>
<a
href=
"{% url 'users:user-group-detail' group.id %}"
>
{{ group.name }}
</a>
</span>
{% endfor %}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
授权主机数量
</td>
<td>
{{ assets | length }}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
授权主机组
</td>
<td>
{% for group in asset_groups %}
<span
class=
"simple-tag with-link"
>
<a
href=
"{% url 'assets:asset-group-detail' group.id %}"
>
{{ group.name }}
</a>
</span>
{% endfor %}
</td>
</tr>
<tr>
<td
class=
"text-navy"
>
授权规则
</td>
<td>
{% for perm in permissions %}
<span
class=
"simple-tag with-link"
>
<a
href=
"{% url 'perms:asset-permission-detail' perm.id %}"
>
{{ perm.name }}
</a>
</span>
{% endfor %}
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div
class=
"col-sm-6"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label label-primary"
><b>
{% trans "Update Public Key" %}
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
</a>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content"
>
<p>
{% trans "Paste your SSH Public Key here" %}
</p>
<textarea
id=
"txt_pk"
class=
"form-control"
cols=
"30"
rows=
"10"
placeholder=
"ssh-rsa AAAAB3NzaC1yc2EAA....."
></textarea>
<button
id=
"btn_update_pk"
class=
"btn btn-primary m-t-15"
>
{% trans 'Update' %}
</button>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
on
(
'click'
,
'#btn_update_pk'
,
function
()
{
var
$this
=
$
(
this
);
var
pk
=
$
(
'#txt_pk'
).
val
();
var
the_url
=
'{% url "api-users:user-public-key-update" pk=user.id %}'
;
var
body
=
{
'_public_key'
:
pk
};
var
success
=
function
()
{
$
(
'#txt_pk'
).
val
(
''
);
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 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/templatetags/__init__.py
deleted
100644 → 0
View file @
7825c107
apps/users/templatetags/users_tags.py
deleted
100644 → 0
View file @
7825c107
# ~*~ coding: utf-8 ~*~
import
os
import
urllib
import
hashlib
from
django
import
template
from
django.utils
import
timezone
from
django.conf
import
settings
register
=
template
.
Library
()
@register.filter
def
join_queryset_attr
(
queryset
,
attr
,
delimiter
=
', '
):
return
delimiter
.
join
([
getattr
(
obj
,
attr
,
''
)
for
obj
in
queryset
])
@register.filter
def
is_expired
(
datetime
):
if
datetime
>
timezone
.
now
():
return
False
else
:
return
True
@register.filter
def
user_avatar_url
(
user
):
if
user
.
avatar
:
return
user
.
avatar
.
url
else
:
default_dir
=
os
.
path
.
join
(
settings
.
MEDIA_ROOT
,
'avatar'
,
'default'
)
if
os
.
path
.
isdir
(
default_dir
):
default_avatar_list
=
os
.
listdir
(
default_dir
)
default_avatar
=
default_avatar_list
[
len
(
user
.
username
)
%
len
(
default_avatar_list
)]
return
os
.
path
.
join
(
settings
.
MEDIA_URL
,
'avatar'
,
'default'
,
default_avatar
)
return
'https://www.gravatar.com/avatar/c6812ab450230979465d7bf288eadce2a?s=120&d=identicon'
apps/users/urls/views_urls.py
View file @
b0551449
from
__future__
import
absolute_import
from
__future__
import
absolute_import
from
django.conf.urls
import
url
from
django.conf.urls
import
url
from
..
import
views
from
..
import
views
app_name
=
'users'
app_name
=
'users'
...
@@ -20,6 +21,11 @@ urlpatterns = [
...
@@ -20,6 +21,11 @@ urlpatterns = [
views
.
UserResetPasswordSuccessView
.
as_view
(),
views
.
UserResetPasswordSuccessView
.
as_view
(),
name
=
'reset-password-success'
),
name
=
'reset-password-success'
),
# Profile
url
(
r'^profile/$'
,
views
.
UserProfileView
.
as_view
(),
name
=
'user-profile'
),
# 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
(),
url
(
r'^user/(?P<pk>[0-9]+)$'
,
views
.
UserDetailView
.
as_view
(),
...
...
apps/users/views/user.py
View file @
b0551449
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
from
__future__
import
unicode_literals
import
uuid
import
json
import
json
import
uuid
from
django.shortcuts
import
redirect
from
openpyxl
import
load_workbook
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
django
import
forms
from
django.contrib.auth.mixins
import
LoginRequiredMixin
from
django.contrib.messages.views
import
SuccessMessageMixin
from
django.core.cache
import
cache
from
django.core.cache
import
cache
from
django.http
import
HttpResponse
,
JsonResponse
from
django.http
import
HttpResponse
,
JsonResponse
from
django.
contrib.messages.views
import
SuccessMessageMixin
from
django.
shortcuts
import
redirect
from
django.urls
import
reverse_lazy
,
reverse
from
django.urls
import
reverse_lazy
,
reverse
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
...
@@ -19,22 +21,23 @@ from django.utils.decorators import method_decorator
...
@@ -19,22 +21,23 @@ from django.utils.decorators import method_decorator
from
django.views
import
View
from
django.views
import
View
from
django.views.generic
import
ListView
from
django.views.generic
import
ListView
from
django.views.generic.base
import
TemplateView
from
django.views.generic.base
import
TemplateView
from
django.views.generic.edit
import
CreateView
,
UpdateView
,
FormMixin
,
\
from
django.views.generic.edit
import
(
CreateView
,
UpdateView
,
FormMixin
,
FormView
FormView
)
from
django.views.generic.detail
import
DetailView
,
SingleObjectMixin
from
django.views.generic.detail
import
DetailView
,
SingleObjectMixin
from
django.views.decorators.csrf
import
csrf_exempt
from
django.views.decorators.csrf
import
csrf_exempt
from
..
import
forms
from
..models
import
User
,
UserGroup
from
..utils
import
AdminUserRequiredMixin
,
user_add_success_next
from
common.mixins
import
JSONResponseMixin
from
common.mixins
import
JSONResponseMixin
from
common.utils
import
get_logger
from
common.utils
import
get_logger
from
perms.models
import
AssetPermission
from
perms.models
import
AssetPermission
from
..models
import
User
,
UserGroup
from
..utils
import
AdminUserRequiredMixin
,
user_add_success_next
from
..
import
forms
__all__
=
[
'UserListView'
,
'UserCreateView'
,
'UserDetailView'
,
__all__
=
[
'UserListView'
,
'UserCreateView'
,
'UserDetailView'
,
'UserUpdateView'
,
'UserAssetPermissionCreateView'
,
'UserUpdateView'
,
'UserAssetPermissionCreateView'
,
'UserAssetPermissionView'
,
'UserGrantedAssetView'
,
'UserAssetPermissionView'
,
'UserGrantedAssetView'
,
'UserExportView'
,
'UserBulkImportView'
]
'UserExportView'
,
'UserBulkImportView'
,
'UserProfileView'
]
logger
=
get_logger
(
__name__
)
logger
=
get_logger
(
__name__
)
...
@@ -103,7 +106,7 @@ class UserUpdateView(AdminUserRequiredMixin, UpdateView):
...
@@ -103,7 +106,7 @@ class UserUpdateView(AdminUserRequiredMixin, UpdateView):
class
UserDetailView
(
AdminUserRequiredMixin
,
DetailView
):
class
UserDetailView
(
AdminUserRequiredMixin
,
DetailView
):
model
=
User
model
=
User
template_name
=
'users/user_detail.html'
template_name
=
'users/user_detail.html'
context_object_name
=
"user"
context_object_name
=
"user
_object
"
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
())
...
@@ -134,18 +137,16 @@ class UserExportView(View):
...
@@ -134,18 +137,16 @@ class UserExportView(View):
ws
.
append
(
header
)
ws
.
append
(
header
)
for
user
in
users
:
for
user
in
users
:
print
(
user
.
name
)
ws
.
append
([
user
.
name
,
user
.
username
,
user
.
email
,
ws
.
append
([
user
.
name
,
user
.
username
,
user
.
email
,
','
.
join
([
group
.
name
for
group
in
user
.
groups
.
all
()]),
','
.
join
([
group
.
name
for
group
in
user
.
groups
.
all
()]),
user
.
role
,
user
.
phone
,
user
.
wechat
,
user
.
comment
,
user
.
role
,
user
.
phone
,
user
.
wechat
,
user
.
comment
])
])
filename
=
'users-{}.xlsx'
.
format
(
filename
=
'users-{}.xlsx'
.
format
(
timezone
.
localtime
(
timezone
.
now
())
.
strftime
(
'
%
Y-
%
m-
%
d_
%
H-
%
M-
%
S'
))
timezone
.
localtime
(
timezone
.
now
())
.
strftime
(
'
%
Y-
%
m-
%
d_
%
H-
%
M-
%
S'
))
response
=
HttpResponse
(
save_virtual_workbook
(
wb
),
response
=
HttpResponse
(
save_virtual_workbook
(
wb
),
content_type
=
'applications/vnd.ms-excel'
)
content_type
=
'applications/vnd.ms-excel'
)
response
[
'Content-Disposition'
]
=
'attachment; filename="
%
s"'
%
filename
response
[
'Content-Disposition'
]
=
'attachment; filename="
%
s"'
%
filename
return
response
return
response
def
post
(
self
,
request
):
def
post
(
self
,
request
):
...
@@ -304,3 +305,24 @@ class UserGrantedAssetView(AdminUserRequiredMixin, DetailView):
...
@@ -304,3 +305,24 @@ class UserGrantedAssetView(AdminUserRequiredMixin, DetailView):
}
}
kwargs
.
update
(
context
)
kwargs
.
update
(
context
)
return
super
(
UserGrantedAssetView
,
self
)
.
get_context_data
(
**
kwargs
)
return
super
(
UserGrantedAssetView
,
self
)
.
get_context_data
(
**
kwargs
)
class
UserProfileView
(
LoginRequiredMixin
,
TemplateView
):
template_name
=
'users/user_profile.html'
def
get_context_data
(
self
,
**
kwargs
):
from
perms.utils
import
(
get_user_granted_assets
,
get_user_granted_asset_groups
,
get_user_asset_permissions
)
assets
=
get_user_granted_assets
(
self
.
request
.
user
)
asset_groups
=
get_user_granted_asset_groups
(
self
.
request
.
user
)
permissions
=
get_user_asset_permissions
(
self
.
request
.
user
)
context
=
{
'app'
:
'User'
,
'action'
:
'User Profile'
,
'assets'
:
assets
,
'asset_groups'
:
asset_groups
,
'permissions'
:
permissions
}
kwargs
.
update
(
context
)
return
super
(
UserProfileView
,
self
)
.
get_context_data
(
**
kwargs
)
config_example.py
View file @
b0551449
...
@@ -81,6 +81,8 @@ class Config:
...
@@ -81,6 +81,8 @@ class Config:
# EMAIL_USE_TLS = False # If port is 587, set True
# EMAIL_USE_TLS = False # If port is 587, set True
# EMAIL_SUBJECT_PREFIX = '[Jumpserver] '
# EMAIL_SUBJECT_PREFIX = '[Jumpserver] '
CAPTCHA_TEST_MODE
=
False
def
__init__
(
self
):
def
__init__
(
self
):
pass
pass
...
@@ -121,4 +123,3 @@ config = {
...
@@ -121,4 +123,3 @@ config = {
}
}
env
=
'development'
env
=
'development'
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