mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-07-06 11:36:32 +00:00
perf: 优化公钥设置,并删掉一部分不用的 html
This commit is contained in:
parent
d9552c0038
commit
ab0fda93f6
@ -222,7 +222,6 @@ class Config(dict):
|
|||||||
|
|
||||||
'TERMINAL_PASSWORD_AUTH': True,
|
'TERMINAL_PASSWORD_AUTH': True,
|
||||||
'TERMINAL_PUBLIC_KEY_AUTH': True,
|
'TERMINAL_PUBLIC_KEY_AUTH': True,
|
||||||
'TERMINAL_ONLY_SOURCE_LOCAL_CAN_PUBLIC_KEY_AUTH': True,
|
|
||||||
'TERMINAL_HEARTBEAT_INTERVAL': 20,
|
'TERMINAL_HEARTBEAT_INTERVAL': 20,
|
||||||
'TERMINAL_ASSET_LIST_SORT_BY': 'hostname',
|
'TERMINAL_ASSET_LIST_SORT_BY': 'hostname',
|
||||||
'TERMINAL_ASSET_LIST_PAGE_SIZE': 'auto',
|
'TERMINAL_ASSET_LIST_PAGE_SIZE': 'auto',
|
||||||
|
@ -124,4 +124,3 @@ FORGOT_PASSWORD_URL = CONFIG.FORGOT_PASSWORD_URL
|
|||||||
# 自定义默认组织名
|
# 自定义默认组织名
|
||||||
GLOBAL_ORG_DISPLAY_NAME = CONFIG.GLOBAL_ORG_DISPLAY_NAME
|
GLOBAL_ORG_DISPLAY_NAME = CONFIG.GLOBAL_ORG_DISPLAY_NAME
|
||||||
HEALTH_CHECK_TOKEN = CONFIG.HEALTH_CHECK_TOKEN
|
HEALTH_CHECK_TOKEN = CONFIG.HEALTH_CHECK_TOKEN
|
||||||
TERMINAL_ONLY_SOURCE_LOCAL_CAN_PUBLIC_KEY_AUTH = CONFIG.TERMINAL_ONLY_SOURCE_LOCAL_CAN_PUBLIC_KEY_AUTH
|
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -121,7 +121,11 @@ class TerminalSettingSerializer(serializers.Serializer):
|
|||||||
('50', '50'),
|
('50', '50'),
|
||||||
)
|
)
|
||||||
TERMINAL_PASSWORD_AUTH = serializers.BooleanField(required=False, label=_('Password auth'))
|
TERMINAL_PASSWORD_AUTH = serializers.BooleanField(required=False, label=_('Password auth'))
|
||||||
TERMINAL_PUBLIC_KEY_AUTH = serializers.BooleanField(required=False, label=_('Public key auth'))
|
TERMINAL_PUBLIC_KEY_AUTH = serializers.BooleanField(
|
||||||
|
required=False, label=_('Public key auth'),
|
||||||
|
help_text=_('Tips: If use other auth method, like AD/LDAP, you should disable this to '
|
||||||
|
'avoid being able to log in after deleting')
|
||||||
|
)
|
||||||
TERMINAL_ASSET_LIST_SORT_BY = serializers.ChoiceField(SORT_BY_CHOICES, required=False, label=_('List sort by'))
|
TERMINAL_ASSET_LIST_SORT_BY = serializers.ChoiceField(SORT_BY_CHOICES, required=False, label=_('List sort by'))
|
||||||
TERMINAL_ASSET_LIST_PAGE_SIZE = serializers.ChoiceField(PAGE_SIZE_CHOICES, required=False, label=_('List page size'))
|
TERMINAL_ASSET_LIST_PAGE_SIZE = serializers.ChoiceField(PAGE_SIZE_CHOICES, required=False, label=_('List page size'))
|
||||||
TERMINAL_SESSION_KEEP_DURATION = serializers.IntegerField(
|
TERMINAL_SESSION_KEEP_DURATION = serializers.IntegerField(
|
||||||
|
@ -66,13 +66,9 @@ class AuthMixin:
|
|||||||
def can_update_ssh_key(self):
|
def can_update_ssh_key(self):
|
||||||
return self.can_use_ssh_key_login()
|
return self.can_use_ssh_key_login()
|
||||||
|
|
||||||
def can_use_ssh_key_login(self):
|
@staticmethod
|
||||||
if not settings.TERMINAL_PUBLIC_KEY_AUTH:
|
def can_use_ssh_key_login():
|
||||||
return False
|
return settings.TERMINAL_PUBLIC_KEY_AUTH
|
||||||
if self.is_local or settings.TERMINAL_ONLY_SOURCE_LOCAL_CAN_PUBLIC_KEY_AUTH:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def is_public_key_valid(self):
|
def is_public_key_valid(self):
|
||||||
"""
|
"""
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
{% extends '_base_create_update.html' %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load static %}
|
|
||||||
{% load bootstrap3 %}
|
|
||||||
{% block form %}
|
|
||||||
{% if form.non_field_errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
{{ form.non_field_errors }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<form method="post" class="form-horizontal" action="" enctype="multipart/form-data">
|
|
||||||
{% csrf_token %}
|
|
||||||
<h3>{% trans 'Account' %}</h3>
|
|
||||||
{% bootstrap_field form.name layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.username layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.email layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.groups layout="horizontal" %}
|
|
||||||
|
|
||||||
<div class="hr-line-dashed"></div>
|
|
||||||
|
|
||||||
<h3>{% trans 'Auth' %}</h3>
|
|
||||||
{% block password %}{% endblock %}
|
|
||||||
{% bootstrap_field form.mfa_level layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.source layout="horizontal" %}
|
|
||||||
|
|
||||||
<div class="hr-line-dashed"></div>
|
|
||||||
<h3>{% trans 'Security and Role' %}</h3>
|
|
||||||
{% bootstrap_field form.role layout="horizontal" %}
|
|
||||||
<div class="form-group {% if form.date_expired.errors %} has-error {% endif %}" id="date_5">
|
|
||||||
<label for="{{ form.date_expired.id_for_label }}" class="col-sm-2 control-label">{{ form.date_expired.label }}</label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<div class="input-group date">
|
|
||||||
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
|
|
||||||
{% if form.errors %}
|
|
||||||
<input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value }}">
|
|
||||||
{% else %}
|
|
||||||
<input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value|date:'Y-m-d H:i' }}">
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<span class="help-block ">{{ form.date_expired.errors }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="hr-line-dashed"></div>
|
|
||||||
<h3>{% trans 'Profile' %}</h3>
|
|
||||||
{% bootstrap_field form.phone layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.wechat layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.comment layout="horizontal" %}
|
|
||||||
<div class="hr-line-dashed"></div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-4 col-sm-offset-2">
|
|
||||||
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
|
|
||||||
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
|
|
||||||
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.zh-CN.min.js' %}"></script>
|
|
||||||
<script type="text/javascript" src='{% static "js/plugins/daterangepicker/moment.min.js" %}'></script>
|
|
||||||
<script type="text/javascript" src='{% static "js/plugins/daterangepicker/daterangepicker.min.js" %}'></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href={% static "css/plugins/daterangepicker/daterangepicker.css" %} />
|
|
||||||
|
|
||||||
<script>
|
|
||||||
var role_id = '#' + '{{ form.role.id_for_label }}';
|
|
||||||
var groups_id = '#' + '{{ form.groups.id_for_label }}';
|
|
||||||
function fieldDisplay(){
|
|
||||||
var role = $(role_id).val();
|
|
||||||
if (role === 'Auditor'){
|
|
||||||
$(groups_id).closest('.form-group').addClass('hidden');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$(groups_id).closest('.form-group').removeClass('hidden');
|
|
||||||
}}
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
$('.select2').select2();
|
|
||||||
initDateRangePicker('#id_date_expired');
|
|
||||||
var mfa_radio = $('#id_mfa_level');
|
|
||||||
mfa_radio.addClass("form-inline");
|
|
||||||
mfa_radio.children().css("margin-right","15px");
|
|
||||||
fieldDisplay()
|
|
||||||
}).on('change', role_id, function(){
|
|
||||||
fieldDisplay();
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,70 +0,0 @@
|
|||||||
{% extends '_base_create_update.html' %}
|
|
||||||
{% load static %}
|
|
||||||
{% load bootstrap3 %}
|
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block form %}
|
|
||||||
<div class="ydxbd" id="formlists" style="display: block;">
|
|
||||||
<p id="tags_p" class="mgl-5 c02">{% trans 'Select properties that need to be modified' %}</p>
|
|
||||||
<div class="tagBtnList">
|
|
||||||
<a class="label label-primary" id="change_all" value="1">{% trans 'Select all' %}</a>
|
|
||||||
{% for field in form %}
|
|
||||||
{% if field.name != 'users' %}
|
|
||||||
<a data-id="{{ field.id_for_label }}" class="label label-default label-primary field-tag" value="1">{{ field.label }}</a>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form method="post" class="form-horizontal" id="add_form">
|
|
||||||
{% csrf_token %}
|
|
||||||
{% bootstrap_form form layout="horizontal" %}
|
|
||||||
<div class="form-group abc">
|
|
||||||
<div class="col-sm-4 col-sm-offset-2">
|
|
||||||
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
|
|
||||||
<button class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script>
|
|
||||||
$(document).ready(function () {
|
|
||||||
$('.select2').select2();
|
|
||||||
usersSelect2Init('.users-select2')
|
|
||||||
}).on('click', '.field-tag', function() {
|
|
||||||
changeField(this);
|
|
||||||
}).on('click', '#change_all', function () {
|
|
||||||
var tag_fields = $('.field-tag');
|
|
||||||
var $this = $(this);
|
|
||||||
var active = '1';
|
|
||||||
if ($this.attr('value') == '0'){
|
|
||||||
active = '0';
|
|
||||||
$this.attr('value', '1').addClass('label-primary')
|
|
||||||
} else {
|
|
||||||
active = '1';
|
|
||||||
$this.attr('value', '0').removeClass('label-primary')
|
|
||||||
}
|
|
||||||
$.each(tag_fields, function (k, v) {
|
|
||||||
changeField(v, active)
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
function changeField(obj, active) {
|
|
||||||
var $this = $(obj);
|
|
||||||
var field_id = $this.data('id');
|
|
||||||
if (!active) {
|
|
||||||
active = $this.attr('value');
|
|
||||||
}
|
|
||||||
if (active == '0') {
|
|
||||||
$this.attr('value', '1').addClass('label-primary');
|
|
||||||
var form_groups = $('#add_form .form-group');
|
|
||||||
form_groups.filter(':has(#' + field_id + ')').show().find('select,input').prop('disabled', false)
|
|
||||||
} else {
|
|
||||||
$this.attr('value', '0').removeClass('label-primary');
|
|
||||||
var form_groups = $('#add_form .form-group');
|
|
||||||
form_groups.filter(':has(#' + field_id + ')').hide().find('select,input').prop('disabled', true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,100 +0,0 @@
|
|||||||
{% extends 'users/_user.html' %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load bootstrap3 %}
|
|
||||||
{% block user_template_title %}{% trans "Create user" %}{% endblock %}
|
|
||||||
{% block password %}
|
|
||||||
{% bootstrap_field form.password_strategy layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.password layout="horizontal" %}
|
|
||||||
{# 密码popover #}
|
|
||||||
<div id="container">
|
|
||||||
<div class="popover fade bottom in" role="tooltip" id="popover777" style=" display: none; width:260px;">
|
|
||||||
<div class="arrow" style="left: 50%;"></div>
|
|
||||||
<h3 class="popover-title" style="display: none;"></h3>
|
|
||||||
<h4>{% trans 'Your password must satisfy' %}</h4><div id="id_password_rules" style="color: #908a8a; margin-left:20px; font-size:15px;"></div>
|
|
||||||
<h4 style="margin-top: 10px;">{% trans 'Password strength' %}</h4><div id="id_progress"></div>
|
|
||||||
<div class="popover-content"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
function passwordCheck() {
|
|
||||||
if ($('#id_password').length != 1) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var el = $('#id_password_rules'),
|
|
||||||
idPassword = $('#id_password'),
|
|
||||||
idPopover = $('#popover777'),
|
|
||||||
container = $('#container'),
|
|
||||||
progress = $('#id_progress'),
|
|
||||||
password_check_rules = {{ password_check_rules|safe }},
|
|
||||||
minLength = 6,
|
|
||||||
top = idPassword.offset().top - $('.navbar').outerHeight(true) - $('.page-heading').outerHeight(true) -77 + 34,
|
|
||||||
left = 377,
|
|
||||||
i18n_fallback = {
|
|
||||||
"veryWeak": "{% trans 'Very weak' %}",
|
|
||||||
"weak": "{% trans 'Weak' %}",
|
|
||||||
"normal": "{% trans 'Normal' %}",
|
|
||||||
"medium": "{% trans 'Medium' %}",
|
|
||||||
"strong": "{% trans 'Strong' %}",
|
|
||||||
"veryStrong": "{% trans 'Very strong' %}"
|
|
||||||
};
|
|
||||||
|
|
||||||
$.each(password_check_rules, function (idx, rules) {
|
|
||||||
if(rules.key === 'id_security_password_min_length'){
|
|
||||||
minLength = rules.value
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化popover
|
|
||||||
initPopover(container, progress, idPassword, el, password_check_rules, i18n_fallback);
|
|
||||||
|
|
||||||
// 监听事件
|
|
||||||
idPassword.on('focus', function () {
|
|
||||||
idPopover.css('top', top);
|
|
||||||
idPopover.css('left', left);
|
|
||||||
idPopover.css('display', 'block');
|
|
||||||
});
|
|
||||||
idPassword.on('blur', function () {
|
|
||||||
idPopover.css('display', 'none');
|
|
||||||
});
|
|
||||||
idPassword.on('keyup', function(){
|
|
||||||
var password = idPassword.val();
|
|
||||||
checkPasswordRules(password, minLength);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
var password_strategy_radio_input = 'input[type=radio][name=password_strategy]';
|
|
||||||
function passwordStrategyFieldsDisplay(){
|
|
||||||
var val = $('input:radio[name="password_strategy"]:checked').val();
|
|
||||||
if(val === '0'){
|
|
||||||
$('#id_password').parents('.form-group').addClass('hidden')
|
|
||||||
}else {
|
|
||||||
$('#id_password').parents('.form-group').removeClass('hidden')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$(document).ready(function () {
|
|
||||||
passwordCheck();
|
|
||||||
passwordStrategyFieldsDisplay()
|
|
||||||
|
|
||||||
}).on('change', password_strategy_radio_input, function(){
|
|
||||||
passwordStrategyFieldsDisplay()
|
|
||||||
})
|
|
||||||
.on("submit", "form", function (evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
var the_url = '{% url 'api-users:user-list' %}';
|
|
||||||
var redirect_to = '{% url "users:user-list" %}';
|
|
||||||
var method = "POST";
|
|
||||||
var form = $("form");
|
|
||||||
var data = form.serializeObject();
|
|
||||||
objectAttrsIsList(data, ['groups']);
|
|
||||||
objectAttrsIsDatetime(data,['date_expired']);
|
|
||||||
var props = {
|
|
||||||
url: the_url,
|
|
||||||
data: data,
|
|
||||||
method: method,
|
|
||||||
form: form,
|
|
||||||
redirect_to: redirect_to
|
|
||||||
};
|
|
||||||
formSubmit(props);
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -1,550 +0,0 @@
|
|||||||
{% extends 'users/_base_user_detail.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_nav_delete_update %}
|
|
||||||
<li class="pull-right">
|
|
||||||
<a class="btn btn-outline {% if can_update %} btn-default {% else %} disabled {% endif %}" href="{% url 'users:user-update' pk=object.id %}"><i class="fa fa-edit"></i>{% trans 'Update' %}</a>
|
|
||||||
</li>
|
|
||||||
<li class="pull-right">
|
|
||||||
<a class="btn btn-outline {% if can_delete %} btn-danger btn-delete-user {% else %} disabled {% endif %}">
|
|
||||||
<i class="fa fa-trash-o"></i>{% trans 'Delete' %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content_table %}
|
|
||||||
<div class="col-sm-8" style="padding-left: 0">
|
|
||||||
<div class="ibox float-e-margins">
|
|
||||||
<div class="ibox-title">
|
|
||||||
<span class="label"><b>{{ object.name }}</b></span>
|
|
||||||
<div class="ibox-tools">
|
|
||||||
<a class="collapse-link">
|
|
||||||
<i class="fa fa-chevron-up"></i>
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
|
||||||
<i class="fa fa-wrench"></i>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu dropdown-user">
|
|
||||||
</ul>
|
|
||||||
<a class="close-link">
|
|
||||||
<i class="fa fa-times"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ibox-content">
|
|
||||||
<table class="table">
|
|
||||||
<tbody>
|
|
||||||
<tr class="no-borders-tr">
|
|
||||||
<td colspan="2">
|
|
||||||
<img src="{{ object.avatar_url }}" class="img-circle" width="64" height="64">
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td width="20%">{% trans 'Name' %}:</td>
|
|
||||||
<td><b>{{ object.name }}</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Username' %}:</td>
|
|
||||||
<td><b>{{ object.username }}</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Email' %}:</td>
|
|
||||||
<td><b>{{ object.email }}</b></td>
|
|
||||||
</tr>
|
|
||||||
{% if user.phone %}
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Phone' %}:</td>
|
|
||||||
<td><b>{{ object.phone }}</b></td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% if object.wechat %}
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Wechat' %}:</td>
|
|
||||||
<td><b>{{ object.wechat }}</b></td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Role' %}:</td>
|
|
||||||
<td><b>{{ object.org_role_display }}</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'MFA' %}:</td>
|
|
||||||
<td><b>
|
|
||||||
{% if object.mfa_force_enabled %}
|
|
||||||
{% trans 'Force enabled' %}
|
|
||||||
{% elif object.mfa_enabled%}
|
|
||||||
{% trans 'Enabled' %}
|
|
||||||
{% else %}
|
|
||||||
{% trans 'Disabled' %}
|
|
||||||
{% endif %}
|
|
||||||
</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Source' %}:</td>
|
|
||||||
<td><b>{{ object.get_source_display }}</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Date expired' %}:</td>
|
|
||||||
<td><b>{{ object.date_expired|date:"Y-m-j H:i:s" }}</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Created by' %}:</td>
|
|
||||||
<td><b>{{ object.created_by }}</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Date joined' %}:</td>
|
|
||||||
<td><b>{{ object.date_joined|date:"Y-m-j H:i:s" }}</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Last login' %}:</td>
|
|
||||||
<td><b>{{ object.last_login|date:"Y-m-j H:i:s" }}</b></td>
|
|
||||||
</tr>
|
|
||||||
{% if object.can_update_password %}
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Last password updated' %}:</td>
|
|
||||||
<td><b>{{ object.date_password_last_updated|date:"Y-m-j H:i:s" }}</b></td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Comment' %}:</td>
|
|
||||||
<td><b>{{ object.comment }}</b></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4" style="padding-left: 0;padding-right: 0">
|
|
||||||
<div class="panel panel-primary">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Quick modify' %}
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<table class="table">
|
|
||||||
<tbody>
|
|
||||||
<tr class="no-borders-tr">
|
|
||||||
<td width="50%">{% trans 'Active' %}:</td>
|
|
||||||
<td>
|
|
||||||
<span class="pull-right">
|
|
||||||
<div class="switch">
|
|
||||||
<div class="onoffswitch">
|
|
||||||
<input type="checkbox" {% if object.is_active %} checked {% endif %} {% if request.user == object %} disabled {% endif %} class="onoffswitch-checkbox" id="is_active">
|
|
||||||
<label class="onoffswitch-label" for="is_active">
|
|
||||||
<span class="onoffswitch-inner"></span>
|
|
||||||
<span class="onoffswitch-switch"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Force enabled MFA' %}:</td>
|
|
||||||
<td>
|
|
||||||
<span class="pull-right">
|
|
||||||
<div class="switch">
|
|
||||||
<div class="onoffswitch">
|
|
||||||
<input type="checkbox" class="onoffswitch-checkbox" {% if object.mfa_force_enabled %} checked {% endif %}
|
|
||||||
id="force_enable_mfa">
|
|
||||||
<label class="onoffswitch-label" for="force_enable_mfa">
|
|
||||||
<span class="onoffswitch-inner"></span>
|
|
||||||
<span class="onoffswitch-switch"></span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Reset MFA' %}:</td>
|
|
||||||
<td>
|
|
||||||
<span class="pull-right">
|
|
||||||
<button type="button" class="btn btn-primary btn-xs" id="btn-reset-mfa" style="width: 54px">{% trans 'Reset' %}</button>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% if object.can_update_password %}
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Send reset password mail' %}:</td>
|
|
||||||
<td>
|
|
||||||
<span class="pull-right">
|
|
||||||
<button type="button" class="btn btn-primary btn-xs" {% if request.user == object %} disabled="disabled" {% endif %} id="btn-reset-password" style="width: 54px">{% trans 'Send' %}</button>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% if object.can_update_ssh_key %}
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Send reset ssh key mail' %}:</td>
|
|
||||||
<td>
|
|
||||||
<span class="pull-right">
|
|
||||||
<button type="button" class="btn btn-primary btn-xs" {% if request.user == object %} disabled="disabled" {% endif %} id="btn-reset-pk" style="width: 54px;">{% trans 'Send' %}</button>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
<tr style="{% if not unblock %}display:none{% endif %}">
|
|
||||||
<td>{% trans 'Unblock user' %}</td>
|
|
||||||
<td>
|
|
||||||
<span class="pull-right">
|
|
||||||
<button type="button" class="btn btn-primary btn-xs" id="btn-unblock-user" style="width: 54px">{% trans 'Unblock' %}</button>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% if request.user.can_admin_current_org %}
|
|
||||||
|
|
||||||
{% if object.can_user_current_org or object.can_admin_current_org %}
|
|
||||||
<div class="panel panel-info">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'User group' %}
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<table class="table group_edit">
|
|
||||||
<tbody>
|
|
||||||
<form>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2" class="no-borders">
|
|
||||||
<select data-placeholder="{% trans 'Join user groups' %}" id="groups_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
|
|
||||||
{% for group in groups %}
|
|
||||||
<option value="{{ group.id }}" id="opt_{{ group.id }}" >{{ group.name }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2" class="no-borders">
|
|
||||||
<button type="button" class="btn btn-info btn-small" id="btn_join_group">{% trans 'Join' %}</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{% for group in object.groups.all %}
|
|
||||||
<tr>
|
|
||||||
<td >
|
|
||||||
<b class="bdg_group" >{{ group.name }}</b>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger pull-right btn-xs btn_leave_group" data-uid={{ group.id }} type="button"><i class="fa fa-minus"></i></button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if LICENSE_VALID and LOGIN_CONFIRM_ENABLE %}
|
|
||||||
<div class="panel panel-warning">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Login confirm' %}
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<table class="table">
|
|
||||||
<tbody>
|
|
||||||
<form>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2" class="no-borders">
|
|
||||||
<select data-placeholder="{% trans 'Reviewers' %}" id="id_assignees" class="users-select2" style="width: 100%" multiple="" tabindex="4">
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2" class="no-borders">
|
|
||||||
<button type="button" class="btn btn-warning btn-small" id="btn_reviewer_confirm">{% trans 'Confirm' %}</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</form>
|
|
||||||
{% if object.get_login_confirm_setting %}
|
|
||||||
{% for u in object.login_confirm_setting.reviewers.all %}
|
|
||||||
<tr>
|
|
||||||
<td >
|
|
||||||
<b class="bdg_reviewer">{{ u }}</b>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger pull-right btn-xs btn-leave-reviewer" data-uid={{ u.id }} type="button"><i class="fa fa-minus"></i></button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% include 'users/_user_update_pk_modal.html' %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script>
|
|
||||||
var usersSelect2;
|
|
||||||
|
|
||||||
function updateUserLoginReviewer(reviewers) {
|
|
||||||
var url = "{% url 'api-auth:login-confirm-setting-update' user_id=object.id %}";
|
|
||||||
var data = {reviewers: reviewers};
|
|
||||||
requestApi({
|
|
||||||
url: url,
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
method: 'PATCH',
|
|
||||||
success: function () {
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var usersGroupsRelationUrl = "{% url 'api-users:users-groups-relation-list' %}";
|
|
||||||
|
|
||||||
function addObjects(objectsId) {
|
|
||||||
if (!objectsId || objectsId.length === 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var theUrl = usersGroupsRelationUrl;
|
|
||||||
var body = [];
|
|
||||||
objectsId.forEach(function (v) {
|
|
||||||
var data = {user: "{{ object.id }}"};
|
|
||||||
data["usergroup"] = v;
|
|
||||||
body.push(data)
|
|
||||||
});
|
|
||||||
requestApi({
|
|
||||||
url: theUrl,
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
method: "POST",
|
|
||||||
success: reloadPage
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeObject(objectId) {
|
|
||||||
if (!objectId) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var theUrl = usersGroupsRelationUrl;
|
|
||||||
theUrl = setUrlParam(theUrl, 'user', "{{ object.id }}");
|
|
||||||
theUrl = setUrlParam(theUrl, 'usergroup', objectId);
|
|
||||||
requestApi({
|
|
||||||
url: theUrl,
|
|
||||||
method: "DELETE",
|
|
||||||
success: reloadPage
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('.select2').select2();
|
|
||||||
usersSelect2 = usersSelect2Init('.users-select2')
|
|
||||||
})
|
|
||||||
.on('click', '#is_active', function() {
|
|
||||||
var the_url = "{% url 'api-users:user-detail' pk=object.id %}";
|
|
||||||
var checked = $(this).prop('checked');
|
|
||||||
var body = {
|
|
||||||
'is_active': checked
|
|
||||||
};
|
|
||||||
var success = '{% trans "Update successfully!" %}';
|
|
||||||
requestApi({
|
|
||||||
url: the_url,
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
success_message: success
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on('click', '#force_enable_mfa', function() {
|
|
||||||
{% if request.user == object %}
|
|
||||||
toastr.error("{% trans 'Goto profile page enable MFA' %}");
|
|
||||||
return;
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
var the_url = "{% url 'api-users:user-detail' pk=object.id %}";
|
|
||||||
var checked = $(this).prop('checked');
|
|
||||||
var mfa_level;
|
|
||||||
var otp_secret_key;
|
|
||||||
if(checked){
|
|
||||||
mfa_level = 2
|
|
||||||
}else{
|
|
||||||
mfa_level = 0;
|
|
||||||
otp_secret_key = '';
|
|
||||||
}
|
|
||||||
var body = {
|
|
||||||
'mfa_level': mfa_level,
|
|
||||||
'otp_secret_key': otp_secret_key
|
|
||||||
};
|
|
||||||
var success = '{% trans "Update successfully!" %}';
|
|
||||||
requestApi({
|
|
||||||
url: the_url,
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
success_message: success
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on('click', '#btn_join_group', function() {
|
|
||||||
var objectsId = $("#groups_selected").val();
|
|
||||||
addObjects(objectsId);
|
|
||||||
}).on('click', '.btn_leave_group', function() {
|
|
||||||
var objectId = $(this).data('uid');
|
|
||||||
removeObject(objectId)
|
|
||||||
}).on('click', '#btn-reset-password', function() {
|
|
||||||
function doReset() {
|
|
||||||
var the_url = '{% url "api-users:user-reset-password" pk=object.id %}';
|
|
||||||
var body = {};
|
|
||||||
var success = function() {
|
|
||||||
var msg = "{% trans "An e-mail has been sent to the user`s mailbox." %}";
|
|
||||||
swal("{% trans 'Reset password' %}", msg, "success");
|
|
||||||
};
|
|
||||||
requestApi({
|
|
||||||
url: the_url,
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
success: success
|
|
||||||
});
|
|
||||||
}
|
|
||||||
swal({
|
|
||||||
title: "{% trans 'Are you sure?' %}",
|
|
||||||
text: "{% trans "This will reset the user password and send a reset mail"%}",
|
|
||||||
type: "warning",
|
|
||||||
showCancelButton: true,
|
|
||||||
cancelButtonText: "{% trans 'Cancel' %}",
|
|
||||||
confirmButtonColor: "#DD6B55",
|
|
||||||
confirmButtonText: "{% trans 'Confirm' %}",
|
|
||||||
closeOnConfirm: false
|
|
||||||
}, function() {
|
|
||||||
doReset();
|
|
||||||
});
|
|
||||||
}).on('click', '#btn-reset-pk', function() {
|
|
||||||
function doReset() {
|
|
||||||
var the_url = '{% url "api-users:user-public-key-reset" pk=object.id %}';
|
|
||||||
var body = {};
|
|
||||||
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.' %}";
|
|
||||||
swal("{% trans 'Reset SSH public key' %}", msg, "success");
|
|
||||||
};
|
|
||||||
requestApi({
|
|
||||||
url: the_url,
|
|
||||||
body: body,
|
|
||||||
success: success
|
|
||||||
});
|
|
||||||
}
|
|
||||||
swal({
|
|
||||||
title: "{% trans 'Are you sure?' %}",
|
|
||||||
text: "{% trans 'This will reset the user public key and send a reset mail' %}",
|
|
||||||
type: "warning",
|
|
||||||
showCancelButton: true,
|
|
||||||
cancelButtonText: "{% trans 'Cancel' %}",
|
|
||||||
confirmButtonColor: "#DD6B55",
|
|
||||||
confirmButtonText: "{% trans 'Confirm' %}",
|
|
||||||
closeOnConfirm: false
|
|
||||||
}, function() {
|
|
||||||
doReset();
|
|
||||||
});
|
|
||||||
}).on('click', '#btn-user-update-pk', function(){
|
|
||||||
var $this = $(this);
|
|
||||||
var pk = $('#txt_pk').val();
|
|
||||||
var the_url = '{% url "api-users:user-public-key-reset" pk=user.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(msg) {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
requestApi({ url: the_url, body: JSON.stringify(body), success: success, error: fail});
|
|
||||||
}).on('click', '.btn-delete-user', function () {
|
|
||||||
var $this = $(this);
|
|
||||||
var name = "{{ object.name }}";
|
|
||||||
var uid = "{{ object.id }}";
|
|
||||||
var the_url = '{% url "api-users:user-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
|
|
||||||
var redirect_url = "{% url 'users:user-list' %}";
|
|
||||||
objectDelete($this, name, the_url, redirect_url);
|
|
||||||
}).on('click', '#btn-unblock-user', function () {
|
|
||||||
function doReset() {
|
|
||||||
{#var the_url = '{% url "api-users:user-reset-password" pk=object.id %}';#}
|
|
||||||
var the_url = '{% url "api-users:user-unblock" pk=object.id %}';
|
|
||||||
var body = {};
|
|
||||||
var success = function() {
|
|
||||||
var msg = "{% trans "Success" %}";
|
|
||||||
{#swal("{% trans 'Unblock user' %}", msg, "success");#}
|
|
||||||
swal({
|
|
||||||
title: "{% trans 'Unblock user' %}",
|
|
||||||
text: msg,
|
|
||||||
type: "success"
|
|
||||||
}, function() {
|
|
||||||
location.reload()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
requestApi({
|
|
||||||
url: the_url,
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
success: success
|
|
||||||
});
|
|
||||||
}
|
|
||||||
swal({
|
|
||||||
title: "{% trans 'Are you sure?' %}",
|
|
||||||
text: "{% trans "After unlocking the user, the user can log in normally."%}",
|
|
||||||
type: "warning",
|
|
||||||
showCancelButton: true,
|
|
||||||
cancelButtonText: "{% trans 'Cancel' %}",
|
|
||||||
confirmButtonColor: "#DD6B55",
|
|
||||||
confirmButtonText: "{% trans 'Confirm' %}",
|
|
||||||
closeOnConfirm: false
|
|
||||||
}, function() {
|
|
||||||
doReset();
|
|
||||||
});
|
|
||||||
}).on('click', '#btn-reset-mfa', function () {
|
|
||||||
requestApi({
|
|
||||||
url: "{% url 'api-users:user-reset-otp' pk=object.id %}",
|
|
||||||
method: "GET",
|
|
||||||
success_message: "{% trans 'Reset user MFA success' %}"
|
|
||||||
})
|
|
||||||
}).on('click', '.btn-leave-reviewer', function () {
|
|
||||||
var reviewersId = [];
|
|
||||||
var removeReviewerId = $(this).data('uid');
|
|
||||||
$('.btn-leave-reviewer').each(function (i, v) {
|
|
||||||
var reviewerId = $(v).data('uid');
|
|
||||||
if (reviewerId !== removeReviewerId) {
|
|
||||||
reviewersId.push(reviewerId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateUserLoginReviewer(reviewersId);
|
|
||||||
}).on('click', '#btn_reviewer_confirm', function () {
|
|
||||||
var reviewersId = [];
|
|
||||||
$('.btn-leave-reviewer').each(function (i, v) {
|
|
||||||
var reviewerId = $(v).data('uid');
|
|
||||||
reviewersId.push(reviewerId);
|
|
||||||
});
|
|
||||||
var selectedId = usersSelect2.val();
|
|
||||||
if (selectedId.length === 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
selectedId.forEach(function (i) {
|
|
||||||
if (reviewersId.indexOf(i) === -1) {
|
|
||||||
reviewersId.push(i)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
updateUserLoginReviewer(reviewersId);
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,26 +0,0 @@
|
|||||||
{% extends 'users/_base_user_detail.html' %}
|
|
||||||
{% load bootstrap3 %}
|
|
||||||
{% load static %}
|
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block custom_head_css_js %}
|
|
||||||
<link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet">
|
|
||||||
<script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content_table %}
|
|
||||||
{% include 'users/_granted_assets.html' %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script>
|
|
||||||
var assetTableUrl = "{% url 'api-perms:user-assets' pk=object.id %}?cache_policy=1";
|
|
||||||
var selectUrl = '{% url "api-perms:user-node-assets" pk=object.id node_id=DEFAULT_PK %}?cache_policy=1&all=1';
|
|
||||||
var treeUrl = "{% url 'api-perms:user-nodes-children-as-tree' pk=object.id %}?cache_policy=1";
|
|
||||||
var systemUsersUrl = "{% url 'api-perms:user-asset-system-users' pk=object.id asset_id=DEFAULT_PK %}?cache_policy=1";
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
initTree();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,100 +0,0 @@
|
|||||||
{% extends 'users/_base_user_detail.html' %}
|
|
||||||
{% load i18n static %}
|
|
||||||
|
|
||||||
{% block custom_head_css_js %}
|
|
||||||
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content_table %}
|
|
||||||
<div class="col-sm-10" style="padding-left: 0">
|
|
||||||
<div class="ibox float-e-margins">
|
|
||||||
<div class="ibox-title">
|
|
||||||
<span class="label"><b>{{ object.name }}</b></span>
|
|
||||||
<div class="ibox-tools">
|
|
||||||
<a class="collapse-link">
|
|
||||||
<i class="fa fa-chevron-up"></i>
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
|
||||||
<i class="fa fa-wrench"></i>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu dropdown-user">
|
|
||||||
</ul>
|
|
||||||
<a class="close-link">
|
|
||||||
<i class="fa fa-times"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ibox-content">
|
|
||||||
<table class="table table-striped table-bordered table-hover " id="database_app_list_table" >
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="text-center">
|
|
||||||
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
|
||||||
</th>
|
|
||||||
<th class="text-center">{% trans 'Name' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Type' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Host' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Database' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Comment' %}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script>
|
|
||||||
var inited = false;
|
|
||||||
var database_app_table, url;
|
|
||||||
|
|
||||||
function initTable() {
|
|
||||||
if (inited){
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
inited = true;
|
|
||||||
}
|
|
||||||
url = '{% url "api-perms:user-database-apps" pk=object.id %}';
|
|
||||||
var options = {
|
|
||||||
ele: $('#database_app_list_table'),
|
|
||||||
columnDefs: [
|
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
|
||||||
cellData = htmlEscape(cellData);
|
|
||||||
{% url 'applications:database-app-detail' pk=DEFAULT_PK as the_url %}
|
|
||||||
var detail_btn = '<a href="{{ the_url }}">' + cellData + '</a>';
|
|
||||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
|
||||||
}},
|
|
||||||
{targets: 2, createdCell: function (td, cellData, rowData) {
|
|
||||||
var type = htmlEscape(rowData.get_type_display);
|
|
||||||
$(td).html(type);
|
|
||||||
}},
|
|
||||||
{targets: 3, createdCell: function (td, cellData, rowData) {
|
|
||||||
var host = htmlEscape(cellData);
|
|
||||||
$(td).html(host);
|
|
||||||
}},
|
|
||||||
{targets: 4, createdCell: function (td, cellData, rowData) {
|
|
||||||
var database = htmlEscape(cellData);
|
|
||||||
$(td).html(database);
|
|
||||||
}}
|
|
||||||
],
|
|
||||||
ajax_url: url,
|
|
||||||
columns: [
|
|
||||||
{data: "id"},
|
|
||||||
{data: "name"},
|
|
||||||
{data: "type"},
|
|
||||||
{data: "host"},
|
|
||||||
{data: "database"},
|
|
||||||
{data: "comment", orderable: false},
|
|
||||||
]
|
|
||||||
};
|
|
||||||
database_app_table = jumpserver.initServerSideDataTable(options);
|
|
||||||
return database_app_table
|
|
||||||
}
|
|
||||||
$(document).ready(function(){
|
|
||||||
initTable();
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,93 +0,0 @@
|
|||||||
{% extends 'users/_base_user_detail.html' %}
|
|
||||||
{% load i18n static %}
|
|
||||||
|
|
||||||
{% block custom_head_css_js %}
|
|
||||||
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content_table %}
|
|
||||||
<div class="col-sm-10" style="padding-left: 0">
|
|
||||||
<div class="ibox float-e-margins">
|
|
||||||
<div class="ibox-title">
|
|
||||||
<span class="label"><b>{{ object.name }}</b></span>
|
|
||||||
<div class="ibox-tools">
|
|
||||||
<a class="collapse-link">
|
|
||||||
<i class="fa fa-chevron-up"></i>
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
|
||||||
<i class="fa fa-wrench"></i>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu dropdown-user">
|
|
||||||
</ul>
|
|
||||||
<a class="close-link">
|
|
||||||
<i class="fa fa-times"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ibox-content">
|
|
||||||
<table class="table table-striped table-bordered table-hover " id="remote_app_list_table" >
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="text-center">
|
|
||||||
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
|
||||||
</th>
|
|
||||||
<th class="text-center">{% trans 'Name' %}</th>
|
|
||||||
<th class="text-center">{% trans 'App type' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Asset' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Comment' %}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script>
|
|
||||||
var inited = false;
|
|
||||||
var remote_app_table, url;
|
|
||||||
|
|
||||||
function initTable() {
|
|
||||||
if (inited){
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
inited = true;
|
|
||||||
}
|
|
||||||
url = '{% url "api-perms:user-remote-apps" pk=object.id %}';
|
|
||||||
var options = {
|
|
||||||
ele: $('#remote_app_list_table'),
|
|
||||||
columnDefs: [
|
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
|
||||||
cellData = htmlEscape(cellData);
|
|
||||||
{% url 'applications:remote-app-detail' pk=DEFAULT_PK as the_url %}
|
|
||||||
var detail_btn = '<a href="{{ the_url }}">' + cellData + '</a>';
|
|
||||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
|
||||||
}},
|
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
|
||||||
$(td).html(rowData.get_type_display)
|
|
||||||
}},
|
|
||||||
{targets: 3, createdCell: function (td, cellData, rowData) {
|
|
||||||
var hostname = htmlEscape(cellData.hostname);
|
|
||||||
$(td).html(hostname);
|
|
||||||
}}
|
|
||||||
],
|
|
||||||
ajax_url: url,
|
|
||||||
columns: [
|
|
||||||
{data: "id"},
|
|
||||||
{data: "name"},
|
|
||||||
{data: "type"},
|
|
||||||
{data: "asset_info", orderable: false},
|
|
||||||
{data: "comment", orderable: false}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
remote_app_table = jumpserver.initServerSideDataTable(options);
|
|
||||||
return remote_app_table
|
|
||||||
}
|
|
||||||
$(document).ready(function(){
|
|
||||||
initTable();
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,69 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
{% load static %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load bootstrap3 %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="wrapper wrapper-content animated fadeInRight">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="ibox float-e-margins">
|
|
||||||
<div class="ibox-title">
|
|
||||||
<h5>{{ action }}</h5>
|
|
||||||
</div>
|
|
||||||
<div class="ibox-content">
|
|
||||||
{% if form.non_field_errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
{{ form.non_field_errors }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<form method="post" class="form-horizontal" action="" >
|
|
||||||
{% csrf_token %}
|
|
||||||
{% bootstrap_field form.name layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.users layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.comment layout="horizontal" %}
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-4 col-sm-offset-2">
|
|
||||||
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
|
|
||||||
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Confirm' %}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% include "users/_select_user_modal.html" %}
|
|
||||||
{% endblock %}
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script>
|
|
||||||
$(document).ready(function () {
|
|
||||||
$('.select2').select2({
|
|
||||||
closeOnSelect: false
|
|
||||||
});
|
|
||||||
usersSelect2Init('.users-select2')
|
|
||||||
})
|
|
||||||
.on("submit", "form", function (evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
var the_url = '{% url 'api-users:user-group-list' %}';
|
|
||||||
var redirect_to = '{% url "users:user-group-list" %}';
|
|
||||||
var method = "POST";
|
|
||||||
{% if type == "update" %}
|
|
||||||
the_url = '{% url 'api-users:user-group-detail' pk=object.id %}';
|
|
||||||
method = "PUT";
|
|
||||||
{% endif %}
|
|
||||||
var form = $("form");
|
|
||||||
var data = form.serializeObject();
|
|
||||||
objectAttrsIsList(data, ['users']);
|
|
||||||
var props = {
|
|
||||||
url: the_url,
|
|
||||||
data: data,
|
|
||||||
method: method,
|
|
||||||
form: form,
|
|
||||||
redirect_to: redirect_to
|
|
||||||
};
|
|
||||||
formSubmit(props);
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,168 +0,0 @@
|
|||||||
{% 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-12">
|
|
||||||
<div class="ibox float-e-margins">
|
|
||||||
<div class="panel-options">
|
|
||||||
<ul class="nav nav-tabs">
|
|
||||||
<li class="active">
|
|
||||||
<a href="{% url 'users:user-group-detail' pk=user_group.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User group detail' %} </a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="{% url 'users:user-group-granted-asset' pk=user_group.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
|
||||||
</li>
|
|
||||||
<li class="pull-right">
|
|
||||||
<a class="btn btn-outline btn-default" href="{% url 'users:user-group-update' pk=user_group.id %}"><i class="fa fa-edit"></i>{% trans 'Update' %}</a>
|
|
||||||
</li>
|
|
||||||
<li class="pull-right">
|
|
||||||
<a class="btn btn-outline btn-danger btn-delete-user-group">
|
|
||||||
<i class="fa fa-trash-o"></i>{% trans 'Delete' %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="tab-content">
|
|
||||||
<div class="col-sm-7" style="padding-left: 0">
|
|
||||||
<div class="ibox float-e-margins">
|
|
||||||
<div class="ibox-title">
|
|
||||||
<span class="label"><b>{{ user_group.name }}</b></span>
|
|
||||||
<div class="ibox-tools">
|
|
||||||
<a class="collapse-link">
|
|
||||||
<i class="fa fa-chevron-up"></i>
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
|
||||||
<i class="fa fa-wrench"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ibox-content">
|
|
||||||
<table class="table">
|
|
||||||
<tbody>
|
|
||||||
<tr class="no-borders-tr">
|
|
||||||
<td width="20%">{% trans 'Name' %}:</td>
|
|
||||||
<td><b>{{ user_group.name }}</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Create by' %}:</td>
|
|
||||||
<td><b>{{ user_group.created_by }}</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Date created' %}:</td>
|
|
||||||
<td><b>{{ user_group.date_created }}</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Comment' %}:</td>
|
|
||||||
<td><b>{{ user_group.comment }}</b></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
|
||||||
<div class="panel panel-primary">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'User' %}
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<table class="table user_edit">
|
|
||||||
<tbody>
|
|
||||||
<form>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2" class="no-borders">
|
|
||||||
<select data-placeholder="{% trans 'Add user' %}" id="slct_users" class="select2" style="width: 100%" multiple="" tabindex="4">
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2" class="no-borders">
|
|
||||||
<button type="button" class="btn btn-primary btn-small" id="btn_add_user">{% trans 'Add' %}</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{% for user in user_group.users.all %}
|
|
||||||
<tr>
|
|
||||||
<td ><b class="bdg_user" >{{ user.name }}</b></td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger pull-right btn-xs btn-remove-user" data-uid={{ user.id }} type="button"><i class="fa fa-minus"></i></button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script>
|
|
||||||
|
|
||||||
var usersGroupsRelationUrl = "{% url 'api-users:users-groups-relation-list' %}";
|
|
||||||
|
|
||||||
function addObjects(objectsId) {
|
|
||||||
if (!objectsId || objectsId.length === 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var theUrl = usersGroupsRelationUrl;
|
|
||||||
var body = [];
|
|
||||||
objectsId.forEach(function (v) {
|
|
||||||
var data = {usergroup: "{{ object.id }}"};
|
|
||||||
data["user"] = v;
|
|
||||||
body.push(data)
|
|
||||||
});
|
|
||||||
requestApi({
|
|
||||||
url: theUrl,
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
method: "POST",
|
|
||||||
success: reloadPage
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeObject(objectId, type) {
|
|
||||||
if (!objectId) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var theUrl = usersGroupsRelationUrl;
|
|
||||||
theUrl = setUrlParam(theUrl, 'usergroup', "{{ object.id }}");
|
|
||||||
theUrl = setUrlParam(theUrl, 'user', objectId);
|
|
||||||
requestApi({
|
|
||||||
url: theUrl,
|
|
||||||
method: "DELETE",
|
|
||||||
success: reloadPage
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
$('.select2').select2();
|
|
||||||
usersSelect2Init('#slct_users')
|
|
||||||
}).on('click', '.btn-remove-user', function() {
|
|
||||||
var objectId = $(this).data("uid");
|
|
||||||
removeObject(objectId);
|
|
||||||
}).on('click', '#btn_add_user', function() {
|
|
||||||
var objectsId = $("#slct_users").val();
|
|
||||||
addObjects(objectsId);
|
|
||||||
}).on('click', '.btn-delete-user-group', function () {
|
|
||||||
var $this = $(this);
|
|
||||||
var name = "{{ user_group.name }}";
|
|
||||||
var uid = "{{ user_group.id }}";
|
|
||||||
var the_url = '{% url "api-users:user-group-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
|
|
||||||
var redirect_url = "{% url 'users:user-group-list' %}";
|
|
||||||
objectDelete($this, name, the_url, redirect_url);
|
|
||||||
})
|
|
||||||
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,47 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
{% load bootstrap3 %}
|
|
||||||
{% load static %}
|
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block custom_head_css_js %}
|
|
||||||
<link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet">
|
|
||||||
<script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script>
|
|
||||||
{% endblock %}
|
|
||||||
{% block content %}
|
|
||||||
<div class="wrapper wrapper-content animated fadeInRight">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="ibox float-e-margins">
|
|
||||||
<div class="panel-options">
|
|
||||||
<ul class="nav nav-tabs">
|
|
||||||
<li>
|
|
||||||
<a href="{% url 'users:user-group-detail' pk=object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User group detail' %} </a>
|
|
||||||
</li>
|
|
||||||
<li class="active">
|
|
||||||
<a href="{% url 'users:user-group-granted-asset' pk=object.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="tab-content">
|
|
||||||
{% include 'users/_granted_assets.html' %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script>
|
|
||||||
var assetTableUrl = "{% url 'api-perms:user-group-assets' pk=object.id %}?cache_policy=1";
|
|
||||||
var selectUrl = '{% url "api-perms:user-group-node-assets" pk=object.id node_id=DEFAULT_PK %}?cache_policy=1&all=1';
|
|
||||||
var treeUrl = "{% url 'api-perms:user-group-nodes-children-as-tree' pk=object.id %}?cache_policy=1";
|
|
||||||
var systemUsersUrl = "{% url 'api-perms:user-group-asset-system-users' pk=object.id asset_id=DEFAULT_PK %}?cache_policy=1";
|
|
||||||
var showAssetHref = true; // Need input default true
|
|
||||||
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
initTree();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,112 +0,0 @@
|
|||||||
{% extends '_base_list.html' %}
|
|
||||||
{% load i18n static %}
|
|
||||||
{% block table_search %}
|
|
||||||
{% include '_csv_import_export.html' %}
|
|
||||||
{% endblock %}
|
|
||||||
{% block table_container %}
|
|
||||||
<div class="pull-left m-r-5"><a href="{% url 'users:user-group-create' %}" class="btn btn-sm btn-primary ">{% trans "Create user group" %}</a></div>
|
|
||||||
<table class="table table-striped table-bordered table-hover " id="group_list_table" >
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="text-center">
|
|
||||||
<input id="" type="checkbox" class="ipt_check_all">
|
|
||||||
</th>
|
|
||||||
<th class="text-center">{% trans 'Name' %}</th>
|
|
||||||
<th class="text-center">{% trans 'User' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Comment' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Action' %}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
</table>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content_bottom_left %}{% endblock %}
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script>
|
|
||||||
var groupsTable = 0;
|
|
||||||
var usersAmountTpl = '<a class="group-users-amount" data-uid="ID">NUM</a>';
|
|
||||||
function initTable() {
|
|
||||||
var options = {
|
|
||||||
ele: $('#group_list_table'),
|
|
||||||
buttons: [],
|
|
||||||
columnDefs: [
|
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
|
||||||
cellData = htmlEscape(cellData);
|
|
||||||
var detail_btn = '<a href="{% url "users:user-group-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
|
|
||||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
|
||||||
}},
|
|
||||||
{targets: 2, createdCell: function (td, cellData, rowData) {
|
|
||||||
var data = usersAmountTpl
|
|
||||||
.replace("ID", rowData.id)
|
|
||||||
.replace('NUM', cellData);
|
|
||||||
$(td).html(data);
|
|
||||||
}},
|
|
||||||
{targets: 3, createdCell: function (td, cellData) {
|
|
||||||
cellData = htmlEscape(cellData);
|
|
||||||
var innerHtml = cellData.length > 30 ? cellData.substring(0, 30) + '...': cellData;
|
|
||||||
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
|
|
||||||
}},
|
|
||||||
{targets: 4, createdCell: function (td, cellData, rowData) {
|
|
||||||
var name = htmlEscape(rowData.name);
|
|
||||||
var update_btn = '<a href="{% url "users:user-group-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'
|
|
||||||
.replace('{{ DEFAULT_PK }}', cellData);
|
|
||||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_delete_user_group" data-gid="{{ DEFAULT_PK }}" data-name="99991938">{% trans "Delete" %}</a>'
|
|
||||||
.replace('{{ DEFAULT_PK }}', cellData)
|
|
||||||
.replace('99991938', name);
|
|
||||||
if (rowData.id === 1) {
|
|
||||||
$(td).html(update_btn)
|
|
||||||
} else {
|
|
||||||
$(td).html(update_btn + del_btn)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
],
|
|
||||||
ajax_url: '{% url "api-users:user-group-list" %}',
|
|
||||||
columns: [{data: "id"}, {data: "name" }, {data: "users_amount", orderable: false},
|
|
||||||
{data: "comment"}, {data: "id", orderable: false, width: "120px"}],
|
|
||||||
op_html: $('#actions').html()
|
|
||||||
};
|
|
||||||
groupsTable = jumpserver.initServerSideDataTable(options);
|
|
||||||
return groupsTable
|
|
||||||
}
|
|
||||||
|
|
||||||
var usersGroupsRelationUrl = "{% url 'api-users:users-groups-relation-list' %}";
|
|
||||||
|
|
||||||
function getGroupUsers(groupId, callback) {
|
|
||||||
var theUrl = setUrlParam(usersGroupsRelationUrl, "usergroup", groupId);
|
|
||||||
if (!callback) {
|
|
||||||
callback = function (data) {
|
|
||||||
console.log(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
requestApi({
|
|
||||||
url: theUrl,
|
|
||||||
method: "GET",
|
|
||||||
success: callback,
|
|
||||||
flash_message: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
$(document).ready(function() {
|
|
||||||
groupsTable = initTable();
|
|
||||||
initCsvImportExport(groupsTable, "{% trans 'User groups' %}")
|
|
||||||
}).on('click', '.btn_delete_user_group', function(){
|
|
||||||
var $this = $(this);
|
|
||||||
var group_id = $this.data('gid');
|
|
||||||
var name = $this.data('name');
|
|
||||||
var the_url = "{% url 'api-users:user-group-detail' pk=DEFAULT_PK %}".replace('{{ DEFAULT_PK }}', group_id);
|
|
||||||
objectDelete($this, name, the_url)
|
|
||||||
})
|
|
||||||
.on('click', '.group-users-amount', function () {
|
|
||||||
var $this = $(this);
|
|
||||||
var groupId = $(this).data("uid");
|
|
||||||
getGroupUsers(groupId, function (data) {
|
|
||||||
var groups = [];
|
|
||||||
data.forEach(function (v) {
|
|
||||||
groups.push(v.user_display);
|
|
||||||
});
|
|
||||||
var popover = createPopover(groups);
|
|
||||||
$this.parent().html(popover);
|
|
||||||
$(popover).trigger('click');
|
|
||||||
})
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,280 +0,0 @@
|
|||||||
{% extends '_base_list.html' %}
|
|
||||||
{% load i18n static %}
|
|
||||||
{% block table_search %}
|
|
||||||
{% include '_csv_import_export.html' %}
|
|
||||||
{% endblock %}
|
|
||||||
{% block table_container %}
|
|
||||||
<div class="uc pull-left m-r-5"><a href="{% url "users:user-create" %}" class="btn btn-sm btn-primary"> {% trans "Create user" %} </a></div>
|
|
||||||
<table class="table table-striped table-bordered table-hover " id="user_list_table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="text-center">
|
|
||||||
<input id="" type="checkbox" class="ipt_check_all">
|
|
||||||
</th>
|
|
||||||
<th class="text-center">{% trans 'Name' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Username' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Role' %}</th>
|
|
||||||
<th class="text-center">{% trans 'User group' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Source' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Validity' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Action' %}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div id="actions" class="hide">
|
|
||||||
<div class="input-group">
|
|
||||||
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
|
|
||||||
{% if CURRENT_ORG.is_default %}
|
|
||||||
<option value="delete">{% trans 'Delete selected' %}</option>
|
|
||||||
{% else %}
|
|
||||||
<option value="remove">{% trans 'Remove selected' %}</option>
|
|
||||||
{% endif %}
|
|
||||||
<option value="update">{% trans 'Update selected' %}</option>
|
|
||||||
<option value="deactive">{% trans 'Deactive selected' %}</option>
|
|
||||||
<option value="active">{% trans 'Active selected' %}</option>
|
|
||||||
</select>
|
|
||||||
<div class="input-group-btn pull-left" style="padding-left: 5px;">
|
|
||||||
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
|
|
||||||
{% trans 'Submit' %}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
{% block content_bottom_left %}{% endblock %}
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
|
||||||
<script>
|
|
||||||
var usersTable = 0;
|
|
||||||
function initTable() {
|
|
||||||
var options = {
|
|
||||||
ele: $('#user_list_table'),
|
|
||||||
columnDefs: [
|
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
|
||||||
cellData = htmlEscape(cellData);
|
|
||||||
var detail_btn = '<a href="{% url "users:user-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
|
|
||||||
$(td).html(detail_btn.replace("{{ DEFAULT_PK }}", rowData.id));
|
|
||||||
}},
|
|
||||||
{targets: 3, createdCell: function (td, cellData, rowData) {
|
|
||||||
$(td).html(rowData.role_display);
|
|
||||||
}},
|
|
||||||
{targets: 4, createdCell: function (td, cellData) {
|
|
||||||
var innerHtml = cellData.length > 20 ? cellData.substring(0, 20) + '...': cellData;
|
|
||||||
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
|
|
||||||
}},
|
|
||||||
{targets: 5, createdCell: function (td, cellData, rowData) {
|
|
||||||
$(td).html(rowData.source_display);
|
|
||||||
}},
|
|
||||||
{targets: 6, createdCell: function (td, cellData, rowData) {
|
|
||||||
if (cellData) {
|
|
||||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
|
||||||
} else if (!rowData.is_active) {
|
|
||||||
|
|
||||||
$(td).html('<i class="fa fa-times text-danger inactive"></i>')
|
|
||||||
} else if (rowData.is_expired) {
|
|
||||||
$(td).html('<i class="fa fa-times text-danger expired"></i>')
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
{targets: 7, createdCell: function (td, cellData, rowData) {
|
|
||||||
var name = htmlEscape(rowData.name);
|
|
||||||
var update_btn = "";
|
|
||||||
if (rowData.can_update === false){
|
|
||||||
update_btn = '<a class="btn btn-xs disabled btn-info">{% trans "Update" %}</a>';
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
update_btn = '<a href="{% url "users:user-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('00000000-0000-0000-0000-000000000000', cellData);
|
|
||||||
}
|
|
||||||
|
|
||||||
var del_btn = "";
|
|
||||||
var rm_btn = "";
|
|
||||||
if ("{{ CURRENT_ORG }}" === 'DEFAULT'){
|
|
||||||
if (rowData.can_delete === false){
|
|
||||||
del_btn = '<a class="btn btn-xs btn-danger m-l-xs" disabled>{% trans "Delete" %}</a>'
|
|
||||||
.replace('{{ DEFAULT_PK }}', cellData)
|
|
||||||
.replace('99991938', name);
|
|
||||||
} else {
|
|
||||||
del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_user_delete" data-action="delete" data-uid="{{ DEFAULT_PK }}" data-name="99991938">{% trans "Delete" %}</a>'
|
|
||||||
.replace('{{ DEFAULT_PK }}', cellData)
|
|
||||||
.replace('99991938', name);
|
|
||||||
}
|
|
||||||
$(td).html(update_btn + del_btn)
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (rowData.can_delete === false){
|
|
||||||
rm_btn = '<a class="btn btn-xs btn-warning m-l-xs" disabled>{% trans "Remove" %}</a>'
|
|
||||||
.replace('{{ DEFAULT_PK }}', cellData)
|
|
||||||
.replace('99991938', name);
|
|
||||||
} else {
|
|
||||||
rm_btn = '<a class="btn btn-xs btn-warning m-l-xs btn_user_delete" data-action="remove" data-uid="{{ DEFAULT_PK }}" data-name="99991938">{% trans "Remove" %}</a>'
|
|
||||||
.replace('{{ DEFAULT_PK }}', cellData)
|
|
||||||
.replace('99991938', name);
|
|
||||||
}
|
|
||||||
$(td).html(update_btn + rm_btn)
|
|
||||||
}
|
|
||||||
}}],
|
|
||||||
ajax_url: '{% url "api-users:user-list" %}',
|
|
||||||
columns: [
|
|
||||||
{data: "id"}, {data: "name" }, {data: "username" },
|
|
||||||
{data: "role"},
|
|
||||||
{data: "groups_display", orderable: false},
|
|
||||||
{data: "source"},
|
|
||||||
{data: "is_valid", orderable: false, width: "50px"},
|
|
||||||
{data: "id", orderable: false, width: "120px"}
|
|
||||||
],
|
|
||||||
op_html: $('#actions').html()
|
|
||||||
};
|
|
||||||
usersTable = jumpserver.initServerSideDataTable(options);
|
|
||||||
return usersTable
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$(document).ready(function(){
|
|
||||||
usersTable = initTable();
|
|
||||||
initCsvImportExport(usersTable, "{% trans 'User' %}")
|
|
||||||
}).on('click', '#btn_bulk_update', function(){
|
|
||||||
var action = $('#slct_bulk_update').val();
|
|
||||||
var id_list = usersTable.selected;
|
|
||||||
if (id_list.length === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var the_url = "{% url 'api-users:user-list' %}";
|
|
||||||
var data = {
|
|
||||||
'resources': id_list
|
|
||||||
};
|
|
||||||
function reloadPage() {
|
|
||||||
setTimeout( function () {window.location.reload();}, 300);
|
|
||||||
}
|
|
||||||
function doDeactive() {
|
|
||||||
var data = [];
|
|
||||||
$.each(id_list, function(index, object_id) {
|
|
||||||
var obj = {"pk": object_id, "is_active": false};
|
|
||||||
data.push(obj);
|
|
||||||
});
|
|
||||||
requestApi({
|
|
||||||
url: the_url,
|
|
||||||
method: 'PATCH',
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
success: reloadPage
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function doActive() {
|
|
||||||
var data = [];
|
|
||||||
$.each(id_list, function(index, object_id) {
|
|
||||||
var obj = {"pk": object_id, "is_active": true};
|
|
||||||
data.push(obj);
|
|
||||||
});
|
|
||||||
requestApi({
|
|
||||||
url: the_url,
|
|
||||||
method: 'PATCH',
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
success: reloadPage
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function doDelete(props) {
|
|
||||||
props = props || {};
|
|
||||||
swal({
|
|
||||||
title: "{% trans 'Are you sure?' %}",
|
|
||||||
text: props.text || "{% trans 'This will delete the selected users !!!' %}",
|
|
||||||
type: "warning",
|
|
||||||
showCancelButton: true,
|
|
||||||
cancelButtonText: "{% trans 'Cancel' %}",
|
|
||||||
confirmButtonColor: "#DD6B55",
|
|
||||||
confirmButtonText: "{% trans 'Confirm' %}",
|
|
||||||
closeOnConfirm: false
|
|
||||||
},function () {
|
|
||||||
function success(data) {
|
|
||||||
url = setUrlParam(the_url, 'spm', data.spm);
|
|
||||||
function fail() {
|
|
||||||
var msg = "{% trans 'User Deleting failed.' %}";
|
|
||||||
swal("{% trans 'User Delete' %}", msg, "error");
|
|
||||||
}
|
|
||||||
requestApi({
|
|
||||||
url:url,
|
|
||||||
method:'DELETE',
|
|
||||||
flash_message:true,
|
|
||||||
success:reloadPage,
|
|
||||||
error: props.fail || fail
|
|
||||||
});
|
|
||||||
}
|
|
||||||
requestApi({
|
|
||||||
url: "{% url 'api-common:resources-cache' %}",
|
|
||||||
method:'POST',
|
|
||||||
body:JSON.stringify(data),
|
|
||||||
flash_message:false,
|
|
||||||
success:success,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function doRemove(){
|
|
||||||
var props = {
|
|
||||||
text: "{% trans 'This will remove the selected users !!' %}",
|
|
||||||
fail: function fail(){
|
|
||||||
var msg = "{% trans 'User Removing failed.' %}";
|
|
||||||
swal("{% trans 'User Remove' %}", msg, "error");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
doDelete(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
function doUpdate() {
|
|
||||||
function fail(data) {
|
|
||||||
toastr.error(JSON.parse(data))
|
|
||||||
}
|
|
||||||
function success(data) {
|
|
||||||
var url = "{% url 'users:user-bulk-update' %}";
|
|
||||||
location.href= setUrlParam(url, 'spm', data.spm);
|
|
||||||
}
|
|
||||||
requestApi({
|
|
||||||
url: "{% url 'api-common:resources-cache' %}",
|
|
||||||
method:'POST',
|
|
||||||
body:JSON.stringify(data),
|
|
||||||
flash_message:false,
|
|
||||||
success:success,
|
|
||||||
error:fail
|
|
||||||
})
|
|
||||||
}
|
|
||||||
switch(action) {
|
|
||||||
case 'deactive':
|
|
||||||
doDeactive();
|
|
||||||
break;
|
|
||||||
case 'delete':
|
|
||||||
doDelete();
|
|
||||||
break;
|
|
||||||
case 'remove':
|
|
||||||
doRemove();
|
|
||||||
break;
|
|
||||||
case 'update':
|
|
||||||
doUpdate();
|
|
||||||
break;
|
|
||||||
case 'active':
|
|
||||||
doActive();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}).on('click', '.btn_user_delete', function(){
|
|
||||||
var $this = $(this);
|
|
||||||
var name = $this.data('name');
|
|
||||||
var uid = $this.data('uid');
|
|
||||||
var action = $this.data('action');
|
|
||||||
var title, success_message = null;
|
|
||||||
if (action === 'remove'){
|
|
||||||
title = "{% trans 'Are you sure about removing it?' %}";
|
|
||||||
success_message = "{% trans 'Remove the success' %}";
|
|
||||||
}
|
|
||||||
var the_url = '{% url "api-users:user-detail" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", uid);
|
|
||||||
objectDelete($this, name, the_url, null, title, success_message);
|
|
||||||
}).on('click', '.expired', function () {
|
|
||||||
var msg = '{% trans "User is expired" %}';
|
|
||||||
toastr.error(msg)
|
|
||||||
}).on('click', '.inactive', function () {
|
|
||||||
var msg = '{% trans 'User is inactive' %}';
|
|
||||||
toastr.error(msg)
|
|
||||||
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -1,233 +0,0 @@
|
|||||||
{% 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-12">
|
|
||||||
<div class="ibox float-e-margins">
|
|
||||||
<div class="panel-options">
|
|
||||||
<ul class="nav nav-tabs">
|
|
||||||
<li class="active">
|
|
||||||
<a href="" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Profile' %} </a>
|
|
||||||
</li>
|
|
||||||
<li class="pull-right">
|
|
||||||
<a class="btn btn-outline btn-default" href="{% url 'users:user-profile-update' %}"><i class="fa fa-edit"></i>{% trans 'Setting' %}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="tab-content">
|
|
||||||
<div class="col-sm-8" style="padding-left: 0;">
|
|
||||||
<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 class="no-borders-tr">
|
|
||||||
<td colspan="2">
|
|
||||||
<img src="{{ user.avatar_url }}" class="img-circle" width="64" height="64">
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="no-borders-tr">
|
|
||||||
<td class="text-navy">{% trans 'Username' %}</td>
|
|
||||||
<td>{{ user.username }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'Name' %}</td>
|
|
||||||
<td>{{ user.name }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'Role' %}</td>
|
|
||||||
<td>{{ user.get_role_display }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'Email' %}</td>
|
|
||||||
<td>{{ user.email }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'Active' %}</td>
|
|
||||||
<td>{{ user.is_active|yesno:"Yes,No,Unkown" }}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
{% if user.can_update_ssh_key %}
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'Public key' %}</td>
|
|
||||||
<td>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{{ user.public_key_obj.comment }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{{ user.public_key_obj.hash_md5 }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'MFA' %}</td>
|
|
||||||
<td>
|
|
||||||
{% if user.mfa_force_enabled %}
|
|
||||||
{% trans 'Force enable' %}
|
|
||||||
{% elif user.mfa_enabled%}
|
|
||||||
{% trans 'Enable' %}
|
|
||||||
{% else %}
|
|
||||||
{% trans 'Disable' %}
|
|
||||||
{% endif %}
|
|
||||||
{% if mfa_setting %}
|
|
||||||
( {% trans 'Administrator Settings force MFA login' %} )
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'Source' %}</td>
|
|
||||||
<td>{{ user.get_source_display }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'Date joined' %}</td>
|
|
||||||
<td>{{ user.date_joined|date:"Y-m-d H:i:s" }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'Last login' %}</td>
|
|
||||||
<td>{{ user.last_login|date:"Y-m-d H:i:s" }}</td>
|
|
||||||
</tr>
|
|
||||||
{% if user.can_update_password %}
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'Last password updated' %}</td>
|
|
||||||
<td>{{ user.date_password_last_updated|date:"Y-m-d H:i:s" }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'Date expired' %}</td>
|
|
||||||
<td>{{ user.date_expired|date:"Y-m-d H:i:s" }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'User groups' %}</td>
|
|
||||||
<td>
|
|
||||||
<table>
|
|
||||||
{% for group in user.groups.all %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{{ group.name }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="text-navy">{% trans 'Comment' %}:</td>
|
|
||||||
<td><b>{{ user.comment }}</b></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4" style="padding-left: 0;padding-right: 0">
|
|
||||||
<div class="panel panel-primary">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Quick modify' %}
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<table class="table">
|
|
||||||
<tbody>
|
|
||||||
<tr class="no-borders-tr">
|
|
||||||
<td>{% trans 'Set MFA' %}:</td>
|
|
||||||
<td>
|
|
||||||
<span class="pull-right">
|
|
||||||
<a type="button" class="btn btn-primary btn-xs" style="width: 54px" id=""
|
|
||||||
href="
|
|
||||||
{% if request.user.mfa_enabled %}
|
|
||||||
{% if request.user.mfa_force_enabled %}
|
|
||||||
" disabled >{% trans 'Disable' %}
|
|
||||||
{% else %}
|
|
||||||
{% url 'authentication:user-otp-disable-authentication' %}
|
|
||||||
">{% trans 'Disable' %}
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
{% url 'authentication:user-otp-enable-start' %}
|
|
||||||
">{% trans 'Enable' %}
|
|
||||||
{% endif %}
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% if request.user.mfa_enabled %}
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Update MFA' %}:</td>
|
|
||||||
<td>
|
|
||||||
<span class="pull-right">
|
|
||||||
<a type="button" class="btn btn-primary btn-xs" style="width: 54px" href="{% url 'authentication:user-otp-update' %}">{% trans 'Update' %}</a>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% if request.user.can_update_password %}
|
|
||||||
<tr class="no-borders">
|
|
||||||
<td>{% trans 'Update password' %}:</td>
|
|
||||||
<td>
|
|
||||||
<span class="pull-right">
|
|
||||||
<a type="button" class="btn btn-primary btn-xs" style="width: 54px" href="{% url 'users:user-password-update' %}">{% trans 'Update' %}</a>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% if request.user.can_update_ssh_key %}
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Update SSH public key' %}:</td>
|
|
||||||
<td>
|
|
||||||
<span class="pull-right">
|
|
||||||
<a type="button" class="btn btn-primary btn-xs" style="width: 54px" href="{% url 'users:user-pubkey-update' %}">{% trans 'Update' %}</a>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>{% trans 'Reset public key and download' %}:</td>
|
|
||||||
<td>
|
|
||||||
<span class="pull-right">
|
|
||||||
<a type="button" class="btn btn-primary btn-xs btn-reset-pubkey" style="width: 54px">{% trans 'Reset' %}</a>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script>
|
|
||||||
$(document).ready(function () {
|
|
||||||
})
|
|
||||||
.on('click', '.btn-reset-pubkey', function () {
|
|
||||||
var the_url = '{% url "users:user-pubkey-generate" %}';
|
|
||||||
window.open(the_url, "_blank")
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,84 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
{% load static %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load bootstrap3 %}
|
|
||||||
|
|
||||||
{% block custom_head_css_js %}
|
|
||||||
<link href="{% static "css/plugins/cropper/cropper.min.css" %}" rel="stylesheet">
|
|
||||||
<link href="{% static "css/plugins/sweetalert/sweetalert.css" %}" rel="stylesheet">
|
|
||||||
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.crop {
|
|
||||||
width: 200px;
|
|
||||||
height: 150px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-preview-sm img {
|
|
||||||
width: 64px;
|
|
||||||
height: 64px;
|
|
||||||
margin: -75px 0 0 -100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 100%; /* This rule is very important, please do not ignore this! */
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
{% block content %}
|
|
||||||
<div class="wrapper wrapper-content animated fadeInRight">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="ibox float-e-margins">
|
|
||||||
<div class="panel-options">
|
|
||||||
<ul class="nav nav-tabs">
|
|
||||||
<li class="active">
|
|
||||||
<a href="{% url 'users:user-profile-update' %}" class="text-center">{% trans 'Profile' %} </a>
|
|
||||||
</li>
|
|
||||||
{% if request.user.can_update_password %}
|
|
||||||
<li>
|
|
||||||
<a href="{% url 'users:user-password-update' %}" class="text-center">{% trans 'Password' %} </a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% if request.user.can_update_ssh_key %}
|
|
||||||
<li>
|
|
||||||
<a href="{% url 'users:user-pubkey-update' %}" class="text-center">{% trans 'Public key' %} </a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="tab-content" style="background-color: #ffffff">
|
|
||||||
<div class="wrapper wrapper-content animated fadeInRight">
|
|
||||||
<form method="post" class="form-horizontal" action="" enctype="multipart/form-data">
|
|
||||||
{% csrf_token %}
|
|
||||||
<h3>{% trans 'Account' %}</h3>
|
|
||||||
{% bootstrap_field form.username layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.name layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.email layout="horizontal" %}
|
|
||||||
|
|
||||||
<div class="hr-line-dashed"></div>
|
|
||||||
<h3>{% trans 'Profile' %}</h3>
|
|
||||||
{% bootstrap_field form.phone layout="horizontal" %}
|
|
||||||
{% bootstrap_field form.wechat layout="horizontal" %}
|
|
||||||
<div class="hr-line-dashed"></div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-4 col-sm-offset-2">
|
|
||||||
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
|
|
||||||
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script src="{% static 'js/plugins/cropper/cropper.min.js' %}"></script>
|
|
||||||
<script>
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,102 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
{% load static %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load bootstrap3 %}
|
|
||||||
|
|
||||||
{% block custom_head_css_js %}
|
|
||||||
<link href="{% static "css/plugins/cropper/cropper.min.css" %}" rel="stylesheet">
|
|
||||||
<link href="{% static "css/plugins/sweetalert/sweetalert.css" %}" rel="stylesheet">
|
|
||||||
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.crop {
|
|
||||||
width: 200px;
|
|
||||||
height: 150px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-preview-sm img {
|
|
||||||
width: 64px;
|
|
||||||
height: 64px;
|
|
||||||
margin: -75px 0 0 -100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 100%; /* This rule is very important, please do not ignore this! */
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
{% block content %}
|
|
||||||
<div class="wrapper wrapper-content animated fadeInRight">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="ibox float-e-margins">
|
|
||||||
<div class="panel-options">
|
|
||||||
<ul class="nav nav-tabs">
|
|
||||||
<li>
|
|
||||||
<a href="{% url 'users:user-profile-update' %}" class="text-center">{% trans 'Profile' %} </a>
|
|
||||||
</li>
|
|
||||||
{% if request.user.can_update_password %}
|
|
||||||
<li>
|
|
||||||
<a href="{% url 'users:user-password-update' %}" class="text-center">{% trans 'Password' %} </a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% if request.user.can_update_ssh_key %}
|
|
||||||
<li class="active">
|
|
||||||
<a href="{% url 'users:user-pubkey-update' %}" class="text-center">{% trans 'Public key' %} </a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="tab-content" style="background-color: #ffffff">
|
|
||||||
<div class="wrapper wrapper-content animated fadeInRight">
|
|
||||||
<form method="post" class="form-horizontal" action="" enctype="multipart/form-data">
|
|
||||||
{% csrf_token %}
|
|
||||||
<h3>{% trans 'Old public key' %}</h3>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label col-sm-2 col-lg-2" style="padding-top: 0" >{% trans 'Name' %}</label>
|
|
||||||
<div class=" col-sm-9 col-lg-9">
|
|
||||||
<label>{{ user.public_key_obj.comment }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label col-sm-2 col-lg-2" style="padding-top: 0">{% trans 'Fingerprint' %}</label>
|
|
||||||
<div class=" col-sm-9 col-lg-9 ">
|
|
||||||
<label>{{ user.public_key_obj.hash_md5 }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="hr-line-dashed"></div>
|
|
||||||
<h3>{% trans 'Update public key' %}</h3>
|
|
||||||
{% bootstrap_field form.public_key layout="horizontal" %}
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label col-sm-2 col-lg-2" style="padding-top: 0">{% trans 'Or reset by server' %}</label>
|
|
||||||
<div class=" col-sm-9 col-lg-9 ">
|
|
||||||
<a id="reset_pubkey" href="{% url 'users:user-pubkey-generate' %}">{% trans 'Reset' %}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="hr-line-dashed"></div>
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-sm-4 col-sm-offset-2">
|
|
||||||
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
|
|
||||||
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script src="{% static 'js/plugins/cropper/cropper.min.js' %}"></script>
|
|
||||||
<script>
|
|
||||||
$(document).ready(function () {
|
|
||||||
}).on('click', '#reset_pubkey', function () {
|
|
||||||
var message = "{% trans 'The new public key has been set successfully, Please download the corresponding private key.' %}";
|
|
||||||
toastr.success(message)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,168 +0,0 @@
|
|||||||
{% extends 'users/_base_user_detail.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_table %}
|
|
||||||
<div class="col-sm-10" style="padding-left: 0">
|
|
||||||
<div class="ibox float-e-margins">
|
|
||||||
<div class="ibox-title">
|
|
||||||
<span class="label"><b>{{ object.name }}</b></span>
|
|
||||||
<div class="ibox-tools">
|
|
||||||
<a class="collapse-link">
|
|
||||||
<i class="fa fa-chevron-up"></i>
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
|
||||||
<i class="fa fa-wrench"></i>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu dropdown-user">
|
|
||||||
</ul>
|
|
||||||
<a class="close-link">
|
|
||||||
<i class="fa fa-times"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ibox-content">
|
|
||||||
<table class="table table-striped table-bordered table-hover"
|
|
||||||
id="permission_list_table"
|
|
||||||
style="width: 100%">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
<th>{% trans 'Name' %}</th>
|
|
||||||
<th class="text-center">{% trans 'User' %}</th>
|
|
||||||
<th class="text-center">{% trans 'User group' %}</th>
|
|
||||||
<th class="text-center">{% trans 'RemoteApp' %}</th>
|
|
||||||
<th class="text-center">{% trans 'System user' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Validity' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Action' %}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
<script>
|
|
||||||
function format(d) {
|
|
||||||
var data = "";
|
|
||||||
if (d.users.length > 0 ) {
|
|
||||||
data += makeLabel(["{% trans 'User' %}", d.users.join(", ")])
|
|
||||||
}
|
|
||||||
if (d.user_groups.length > 0) {
|
|
||||||
data += makeLabel(["{% trans 'User group' %}", d.user_groups.join(", ")])
|
|
||||||
}
|
|
||||||
if (d.remote_apps.length > 0) {
|
|
||||||
data += makeLabel(["{% trans 'RemoteApp' %}", d.remote_apps.join(", ")])
|
|
||||||
}
|
|
||||||
if (d.system_users.length > 0) {
|
|
||||||
data += makeLabel(["{% trans 'System user' %}", d.system_users.join(", ")])
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
function initTable() {
|
|
||||||
var options = {
|
|
||||||
ele: $('#permission_list_table'),
|
|
||||||
toggle: true,
|
|
||||||
columnDefs: [
|
|
||||||
{targets: 0, createdCell: function (td, cellData, rowData) {
|
|
||||||
$(td).addClass("toggle");
|
|
||||||
$(td).html("<i class='fa fa-angle-right'></i>");
|
|
||||||
}},
|
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
|
||||||
cellData = htmlEscape(cellData);
|
|
||||||
var detail_btn = '<a href="{% url "perms:remote-app-permission-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
|
|
||||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
|
||||||
}},
|
|
||||||
{targets: 2, createdCell: function (td, cellData) {
|
|
||||||
var num = cellData.length;
|
|
||||||
$(td).html(num);
|
|
||||||
}},
|
|
||||||
{targets: 3, createdCell: function (td, cellData) {
|
|
||||||
var num = cellData.length;
|
|
||||||
$(td).html(num);
|
|
||||||
}},
|
|
||||||
{targets: 4, createdCell: function (td, cellData) {
|
|
||||||
var num = cellData.length;
|
|
||||||
$(td).html(num);
|
|
||||||
}},
|
|
||||||
{targets: 5, createdCell: function (td, cellData) {
|
|
||||||
var num = cellData.length;
|
|
||||||
$(td).html(num);
|
|
||||||
}},
|
|
||||||
{targets: 6, createdCell: function (td, cellData) {
|
|
||||||
if (!cellData) {
|
|
||||||
$(td).html('<i class="fa fa-times text-danger"></i>')
|
|
||||||
} else {
|
|
||||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
{targets: 7, createdCell: function (td, cellData, rowData) {
|
|
||||||
var name = htmlEscape(rowData.name);
|
|
||||||
var update_btn = '<a href="{% url "perms:remote-app-permission-update" pk=DEFAULT_PK %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
|
|
||||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-del" data-uid="{{ DEFAULT_PK }}" mark=1 data-name="99991938">{% trans "Delete" %}</a>'
|
|
||||||
.replace('{{ DEFAULT_PK }}', cellData)
|
|
||||||
.replace('99991938', name);
|
|
||||||
$(td).html(update_btn + del_btn);
|
|
||||||
}}
|
|
||||||
],
|
|
||||||
ajax_url: '{% url "api-perms:remote-app-permission-list" %}?user_id={{ object.id }}',
|
|
||||||
columns: [
|
|
||||||
{data: "id"}, {data: "name"}, {data: "users", orderable: false},
|
|
||||||
{data: "user_groups", orderable: false}, {data: "remote_apps", orderable: false},
|
|
||||||
{data: "system_users", orderable: false}, {data: "is_valid", orderable: false},
|
|
||||||
{data: "id", orderable: false, width: "120px"}
|
|
||||||
],
|
|
||||||
select: {},
|
|
||||||
op_html: $('#actions').html()
|
|
||||||
};
|
|
||||||
table = jumpserver.initServerSideDataTable(options);
|
|
||||||
return table
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
initTable();
|
|
||||||
})
|
|
||||||
.on('click', '.toggle', function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var detailRows = [];
|
|
||||||
var tr = $(this).closest('tr');
|
|
||||||
var row = table.row(tr);
|
|
||||||
var idx = $.inArray(tr.attr('id'), detailRows);
|
|
||||||
|
|
||||||
if (row.child.isShown()) {
|
|
||||||
tr.removeClass('details');
|
|
||||||
$(this).children('i:first-child').removeClass('fa-angle-down').addClass('fa-angle-right');
|
|
||||||
row.child.hide();
|
|
||||||
|
|
||||||
// Remove from the 'open' array
|
|
||||||
detailRows.splice(idx, 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tr.addClass('details');
|
|
||||||
$(this).children('i:first-child').removeClass('fa-angle-right').addClass('fa-angle-down');
|
|
||||||
row.child(format(row.data())).show();
|
|
||||||
// Add to the 'open' array
|
|
||||||
if ( idx === -1 ) {
|
|
||||||
detailRows.push(tr.attr('id'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on('click', '.btn-del', function () {
|
|
||||||
var $this = $(this);
|
|
||||||
var uid = $this.data('uid');
|
|
||||||
var name = $this.data('name');
|
|
||||||
var the_url = '{% url "api-perms:remote-app-permission-detail" pk=DEFAULT_PK %}'
|
|
||||||
.replace('{{ DEFAULT_PK }}', uid);
|
|
||||||
objectDelete($this, name, the_url);
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
@ -1,117 +0,0 @@
|
|||||||
{% extends 'users/_user.html' %}
|
|
||||||
{% load i18n %}
|
|
||||||
{% load bootstrap3 %}
|
|
||||||
{% block user_template_title %}{% trans "Update user" %}{% endblock %}
|
|
||||||
{% block password %}
|
|
||||||
{% if object.can_update_password %}
|
|
||||||
{% bootstrap_field form.password layout="horizontal" %}
|
|
||||||
{# 密码popover #}
|
|
||||||
<div id="container">
|
|
||||||
<div class="popover fade bottom in" role="tooltip" id="popover777" style=" display: none; width:260px;">
|
|
||||||
<div class="arrow" style="left: 50%;"></div>
|
|
||||||
<h3 class="popover-title" style="display: none;"></h3>
|
|
||||||
<h4>{% trans 'Your password must satisfy' %}</h4><div id="id_password_rules" style="color: #908a8a; margin-left:20px; font-size:15px;"></div>
|
|
||||||
<h4 style="margin-top: 10px;">{% trans 'Password strength' %}</h4><div id="id_progress"></div>
|
|
||||||
<div class="popover-content"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-sm-2 control-label">{% trans 'Password' %}</label>
|
|
||||||
<div class="col-sm-8 controls" style="margin-top: 8px;" id="password_help_text">
|
|
||||||
{% trans 'User auth from {}, go there change password' %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% if object.can_update_ssh_key %}
|
|
||||||
{% bootstrap_field form.public_key layout="horizontal" %}
|
|
||||||
{% else %}
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-sm-2 control-label">{% trans 'ssh public key' %}</label>
|
|
||||||
<div class="col-sm-8 controls" style="margin-top: 8px;" id="ssh_key_help_text">
|
|
||||||
{% trans 'User auth from {}, ssh key login is not supported' %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
|
||||||
{{ block.super }}
|
|
||||||
<script>
|
|
||||||
function passwordCheck() {
|
|
||||||
if ($('#id_password').length != 1) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var el = $('#id_password_rules'),
|
|
||||||
idPassword = $('#id_password'),
|
|
||||||
idPopover = $('#popover777'),
|
|
||||||
container = $('#container'),
|
|
||||||
progress = $('#id_progress'),
|
|
||||||
password_check_rules = {{ password_check_rules|safe }},
|
|
||||||
minLength = 6,
|
|
||||||
top = idPassword.offset().top - $('.navbar').outerHeight(true) - $('.page-heading').outerHeight(true) - 10 + 34,
|
|
||||||
left = 377,
|
|
||||||
i18n_fallback = {
|
|
||||||
"veryWeak": "{% trans 'Very weak' %}",
|
|
||||||
"weak": "{% trans 'Weak' %}",
|
|
||||||
"normal": "{% trans 'Normal' %}",
|
|
||||||
"medium": "{% trans 'Medium' %}",
|
|
||||||
"strong": "{% trans 'Strong' %}",
|
|
||||||
"veryStrong": "{% trans 'Very strong' %}"
|
|
||||||
};
|
|
||||||
|
|
||||||
$.each(password_check_rules, function (idx, rules) {
|
|
||||||
if(rules.key === 'id_security_password_min_length'){
|
|
||||||
minLength = rules.value
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化popover
|
|
||||||
initPopover(container, progress, idPassword, el, password_check_rules, i18n_fallback);
|
|
||||||
|
|
||||||
// 监听事件
|
|
||||||
idPassword.on('focus', function () {
|
|
||||||
idPopover.css('top', top);
|
|
||||||
idPopover.css('left', left);
|
|
||||||
idPopover.css('display', 'block');
|
|
||||||
});
|
|
||||||
idPassword.on('blur', function () {
|
|
||||||
idPopover.css('display', 'none');
|
|
||||||
});
|
|
||||||
idPassword.on('keyup', function(){
|
|
||||||
var password = idPassword.val();
|
|
||||||
checkPasswordRules(password, minLength);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
$(document).ready(function(){
|
|
||||||
passwordCheck();
|
|
||||||
|
|
||||||
var origin_password_text = $("#password_help_text").text();
|
|
||||||
var new_password_text = origin_password_text.replace('{}', "{{ object.source_display }}");
|
|
||||||
$("#password_help_text").html(new_password_text);
|
|
||||||
|
|
||||||
var origin_ssh_key_text = $("#ssh_key_help_text").text();
|
|
||||||
var new_ssh_key_text = origin_ssh_key_text.replace('{}', "{{ object.source_display }}");
|
|
||||||
$("#ssh_key_help_text").html(new_ssh_key_text)
|
|
||||||
|
|
||||||
})
|
|
||||||
.on("submit", "form", function (evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
var the_url = '{% url 'api-users:user-detail' pk=object.id %}';
|
|
||||||
var redirect_to = '{% url "users:user-list" %}';
|
|
||||||
var method = "PUT";
|
|
||||||
var form = $("form");
|
|
||||||
var data = form.serializeObject();
|
|
||||||
objectAttrsIsList(data, ['groups']);
|
|
||||||
objectAttrsIsDatetime(data,['date_expired']);
|
|
||||||
var props = {
|
|
||||||
url: the_url,
|
|
||||||
data: data,
|
|
||||||
method: method,
|
|
||||||
form: form,
|
|
||||||
redirect_to: redirect_to
|
|
||||||
};
|
|
||||||
formSubmit(props);
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
Loading…
Reference in New Issue
Block a user