mirror of https://github.com/jumpserver/jumpserver
Merge branch 'master' of code.simcu.com:jumpserver/jumpserver
commit
0f9bdab108
|
@ -4,10 +4,10 @@
|
||||||
var checked=false;
|
var checked=false;
|
||||||
function check_all(form) {
|
function check_all(form) {
|
||||||
var checkboxes = document.getElementById(form);
|
var checkboxes = document.getElementById(form);
|
||||||
if (checked == false) {
|
if (checked === false) {
|
||||||
checked = true
|
checked = true;
|
||||||
} else {
|
} else {
|
||||||
checked = false
|
checked = false;
|
||||||
}
|
}
|
||||||
for (var i = 0; i < checkboxes.elements.length; i++) {
|
for (var i = 0; i < checkboxes.elements.length; i++) {
|
||||||
if (checkboxes.elements[i].type == "checkbox") {
|
if (checkboxes.elements[i].type == "checkbox") {
|
||||||
|
@ -51,13 +51,13 @@ function GetRowData(row){
|
||||||
//此函数用于在多选提交时至少要选择一行
|
//此函数用于在多选提交时至少要选择一行
|
||||||
function GetTableDataBox() {
|
function GetTableDataBox() {
|
||||||
var tabProduct = document.getElementById("editable");
|
var tabProduct = document.getElementById("editable");
|
||||||
var tableData = new Array();
|
var tableData = [];
|
||||||
var returnData = new Array();
|
var returnData = [];
|
||||||
var checkboxes = document.getElementById("contents_form");
|
var checkboxes = document.getElementById("contents_form");
|
||||||
var id_list = new Array();
|
var id_list = [];
|
||||||
len = checkboxes.elements.length;
|
len = checkboxes.elements.length;
|
||||||
for (var i=0; i < len; i++) {
|
for (var i=0; i < len; i++) {
|
||||||
if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked == true && checkboxes.elements[i].value != "checkall") {
|
if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked === true && checkboxes.elements[i].value != "checkall") {
|
||||||
id_list.push(i);
|
id_list.push(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ function GetTableDataBox() {
|
||||||
tableData.push(GetRowData(tabProduct.rows[id_list[i]]));
|
tableData.push(GetRowData(tabProduct.rows[id_list[i]]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id_list.length == 0){
|
if (id_list.length === 0){
|
||||||
alert('请至少选择一行!');
|
alert('请至少选择一行!');
|
||||||
}
|
}
|
||||||
returnData.push(tableData);
|
returnData.push(tableData);
|
||||||
|
@ -77,7 +77,7 @@ function GetTableDataBox() {
|
||||||
|
|
||||||
function move(from, to, from_o, to_o) {
|
function move(from, to, from_o, to_o) {
|
||||||
$("#" + from + " option").each(function () {
|
$("#" + from + " option").each(function () {
|
||||||
if ($(this).prop("selected") == true) {
|
if ($(this).prop("selected") === true) {
|
||||||
$("#" + to).append(this);
|
$("#" + to).append(this);
|
||||||
if( typeof from_o !== 'undefined'){
|
if( typeof from_o !== 'undefined'){
|
||||||
$("#"+to_o).append($("#"+from_o +" option[value='"+this.value+"']"));
|
$("#"+to_o).append($("#"+from_o +" option[value='"+this.value+"']"));
|
||||||
|
@ -88,7 +88,7 @@ function move(from, to, from_o, to_o) {
|
||||||
|
|
||||||
function move_left(from, to, from_o, to_o) {
|
function move_left(from, to, from_o, to_o) {
|
||||||
$("#" + from + " option").each(function () {
|
$("#" + from + " option").each(function () {
|
||||||
if ($(this).prop("selected") == true) {
|
if ($(this).prop("selected") === true) {
|
||||||
$("#" + to).append(this);
|
$("#" + to).append(this);
|
||||||
if( typeof from_o !== 'undefined'){
|
if( typeof from_o !== 'undefined'){
|
||||||
$("#"+to_o).append($("#"+from_o +" option[value='"+this.value+"']"));
|
$("#"+to_o).append($("#"+from_o +" option[value='"+this.value+"']"));
|
||||||
|
@ -126,8 +126,8 @@ function move_left(from, to, from_o, to_o) {
|
||||||
function selectAll(){
|
function selectAll(){
|
||||||
// 选择该页面所有option
|
// 选择该页面所有option
|
||||||
$('option').each(function(){
|
$('option').each(function(){
|
||||||
$(this).attr('selected', true)
|
$(this).attr('selected', true);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,6 +156,8 @@ function getIDall() {
|
||||||
function APIUpdateAttr(props) {
|
function APIUpdateAttr(props) {
|
||||||
// props = {url: .., body: , success: , error: , method: ,}
|
// props = {url: .., body: , success: , error: , method: ,}
|
||||||
props = props || {};
|
props = props || {};
|
||||||
|
success_message = props.success_message || 'Update Successfully!';
|
||||||
|
fail_message = props.fail_message || 'Error occurred while updating.';
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: props.url,
|
url: props.url,
|
||||||
type: props.method || "PATCH",
|
type: props.method || "PATCH",
|
||||||
|
@ -164,18 +166,18 @@ function APIUpdateAttr(props) {
|
||||||
dataType: props.data_type || "json",
|
dataType: props.data_type || "json",
|
||||||
}).done(function(data, textStatue, jqXHR) {
|
}).done(function(data, textStatue, jqXHR) {
|
||||||
if (typeof props.success === 'function') {
|
if (typeof props.success === 'function') {
|
||||||
return props.success(data)
|
return props.success(data);
|
||||||
} else {
|
} else {
|
||||||
toastr.success('Update Success!')
|
toastr.success(success_message);
|
||||||
}
|
}
|
||||||
}).fail(function(jqXHR, textStatue, errorThrown) {
|
}).fail(function(jqXHR, textStatue, errorThrown) {
|
||||||
if (typeof props.error === 'function') {
|
if (typeof props.error === 'function') {
|
||||||
return props.error(errorThrown)
|
return props.error(errorThrown);
|
||||||
} else {
|
} else {
|
||||||
toastr.error('Error occurred while updating.')
|
toastr.error(fail_message);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var jumpserver = new Object();
|
var jumpserver = {};
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
{% load i18n %}
|
||||||
|
<div aria-hidden="true" role="dialog" tabindex="-1" id="{% block modal_id %}{% endblock %}" class="modal inmodal" style="display: none;">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content animated fadeIn">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button data-dismiss="modal" class="close" type="button"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
||||||
|
<h4 class="modal-title">{% block modal_title %}{% endblock %}</h4>
|
||||||
|
<small>{% block modal_comment %}{% endblock %}</small>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
{% block modal_body %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button data-dismiss="modal" class="btn btn-white" type="button">{% trans "Close" %}</button>
|
||||||
|
<button class="btn btn-primary" type="button" id="{% block modal_confirm_id %}{% endblock %}">{% trans 'Confirm' %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -6,6 +6,7 @@ import logging
|
||||||
from rest_framework import generics
|
from rest_framework import generics
|
||||||
|
|
||||||
from .serializers import UserSerializer, UserGroupSerializer, UserAttributeSerializer, UserGroupEditSerializer
|
from .serializers import UserSerializer, UserGroupSerializer, UserAttributeSerializer, UserGroupEditSerializer
|
||||||
|
from .serializers import UserPKUpdateSerializer
|
||||||
from .models import User, UserGroup
|
from .models import User, UserGroup
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,3 +50,25 @@ class UserAttributeApi(generics.RetrieveUpdateDestroyAPIView):
|
||||||
class UserGroupEditApi(generics.RetrieveUpdateAPIView):
|
class UserGroupEditApi(generics.RetrieveUpdateAPIView):
|
||||||
queryset = User.objects.all()
|
queryset = User.objects.all()
|
||||||
serializer_class = UserGroupEditSerializer
|
serializer_class = UserGroupEditSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class UserResetPasswordApi(generics.UpdateAPIView):
|
||||||
|
queryset = User.objects.all()
|
||||||
|
serializer_class = UserGroupEditSerializer
|
||||||
|
|
||||||
|
def perform_update(self, serializer):
|
||||||
|
# Note: we are not updating the user object here.
|
||||||
|
# We just do the reset-password staff.
|
||||||
|
user = self.get_object()
|
||||||
|
from .utils import send_reset_password_mail
|
||||||
|
send_reset_password_mail(user)
|
||||||
|
|
||||||
|
|
||||||
|
class UserResetPKApi(generics.UpdateAPIView):
|
||||||
|
queryset = User.objects.all()
|
||||||
|
serializer_class = UserPKUpdateSerializer
|
||||||
|
|
||||||
|
def perform_update(self, serializer):
|
||||||
|
user = self.get_object()
|
||||||
|
user.private_key = serializer.validated_data['_private_key']
|
||||||
|
user.save()
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from .models import User, UserGroup
|
from .models import User, UserGroup
|
||||||
|
@ -38,3 +40,17 @@ class UserGroupEditSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ['id', 'groups']
|
fields = ['id', 'groups']
|
||||||
|
|
||||||
|
|
||||||
|
class UserPKUpdateSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
fields = ['id', '_private_key']
|
||||||
|
|
||||||
|
def validate__private_key(self, value):
|
||||||
|
from users.utils import validate_ssh_pk
|
||||||
|
checked, reason = validate_ssh_pk(value)
|
||||||
|
if not checked:
|
||||||
|
raise serializers.ValidationError(_('Not a valid ssh private key.'))
|
||||||
|
return value
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
{% extends '_modal.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block modal_id %}user_reset_pk_modal{% endblock %}
|
||||||
|
{% block modal_title%}{% trans 'Reset User SSH Private Key' %}{% endblock %}
|
||||||
|
{% block modal_body %}
|
||||||
|
<textarea id="txt_pk" class="form-control" cols="30" rows="10" placeholder="-----BEGIN RSA PRIVATE KEY-----"></textarea>
|
||||||
|
{% endblock %}
|
||||||
|
{% block modal_confirm_id %}btn_user_reset_pk{% endblock %}
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
{% block custom_head_css_js %}
|
{% block custom_head_css_js %}
|
||||||
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
|
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
|
||||||
|
<link href="{% static "css/plugins/sweetalert/sweetalert.css" %}" rel="stylesheet">
|
||||||
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
|
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
|
||||||
|
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="wrapper wrapper-content animated fadeInRight">
|
<div class="wrapper wrapper-content animated fadeInRight">
|
||||||
|
@ -22,7 +24,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="col-sm-7" style="padding-left: 0px;">
|
<div class="col-sm-7" style="padding-left: 0">
|
||||||
<div class="ibox float-e-margins">
|
<div class="ibox float-e-margins">
|
||||||
<div class="ibox-title">
|
<div class="ibox-title">
|
||||||
<span class="label"><b>{{ user_object.name }}</b></span>
|
<span class="label"><b>{{ user_object.name }}</b></span>
|
||||||
|
@ -108,14 +110,14 @@
|
||||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
||||||
<div class="panel panel-primary">
|
<div class="panel panel-primary">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Quick update' %}
|
<i class="fa fa-info-circle"></i> {% trans 'Quick modify' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr">
|
||||||
<td width="50%">Active:</td>
|
<td width="50%">{% trans 'Active' %}:</td>
|
||||||
<td><span style="float: right">
|
<td><span class="pull-right">
|
||||||
<div class="switch">
|
<div class="switch">
|
||||||
<div class="onoffswitch">
|
<div class="onoffswitch">
|
||||||
<input type="checkbox" {% if user_object.is_active %} checked {% endif %} class="onoffswitch-checkbox" id="is_active">
|
<input type="checkbox" {% if user_object.is_active %} checked {% endif %} class="onoffswitch-checkbox" id="is_active">
|
||||||
|
@ -128,8 +130,8 @@
|
||||||
</span></td>
|
</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>二次验证:</td>
|
<td>{% trans 'Enable OTP' %}:</td>
|
||||||
<td><span style="float: right">
|
<td><span class="pull-right">
|
||||||
<div class="switch">
|
<div class="switch">
|
||||||
<div class="onoffswitch">
|
<div class="onoffswitch">
|
||||||
<input type="checkbox" class="onoffswitch-checkbox" {% if user_object.enable_otp %} checked {% endif %}
|
<input type="checkbox" class="onoffswitch-checkbox" {% if user_object.enable_otp %} checked {% endif %}
|
||||||
|
@ -145,16 +147,16 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>{% trans 'Reset password' %}:</td>
|
<td>{% trans 'Reset password' %}:</td>
|
||||||
<td>
|
<td>
|
||||||
<span style="float: right">
|
<span class="pull-right">
|
||||||
<button type="button" class="btn btn-primary btn-xs" style="width: 54px">{% trans 'Reset' %}</button>
|
<button type="button" class="btn btn-primary btn-xs" id="btn_reset_password" style="width: 54px">{% trans 'Reset' %}</button>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{% trans 'Reset ssh key' %}:</td>
|
<td>{% trans 'Reset ssh key' %}:</td>
|
||||||
<td>
|
<td>
|
||||||
<span style="float: right">
|
<span class="pull-right">
|
||||||
<button type="button" class="btn btn-primary btn-xs" style="width: 54px;">{% trans 'Reset' %}</button>
|
<button type="button" class="btn btn-primary btn-xs" id="btn_reset_pk" style="width: 54px;" data-toggle="modal" data-target="#user_reset_pk_modal">{% trans 'Reset' %}</button>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -191,7 +193,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td ><b class="bdg_user_group" data-gid={{ group.id }}>{{ group.name }}</b></td>
|
<td ><b class="bdg_user_group" data-gid={{ group.id }}>{{ group.name }}</b></td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-danger btn-xs btn_delete_user_group" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
|
<button class="btn btn-danger pull-right btn-sm btn_delete_user_group" type="button"><i class="fa fa-minus"></i></button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -205,12 +207,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% include 'users/_user_reset_pk_modal.html' %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
jumpserver.selected_groups = new Object();
|
jumpserver.selected_groups = {};
|
||||||
function updateUserGroups(user_groups) {
|
function updateUserGroups(user_groups) {
|
||||||
var the_url = "{% url 'users:user-group-edit-api' pk=user_object.id%}";
|
var the_url = "{% url 'users:user-group-edit-api' pk=user_object.id%}";
|
||||||
var body = {
|
var body = {
|
||||||
|
@ -227,43 +228,38 @@ function updateUserGroups(user_groups) {
|
||||||
$('.group_edit tbody').append(
|
$('.group_edit tbody').append(
|
||||||
'<tr>' +
|
'<tr>' +
|
||||||
'<td><b class="bdg_user_group" data-gid="' + index + '">' + group_name + '</b></td>' +
|
'<td><b class="bdg_user_group" data-gid="' + index + '">' + group_name + '</b></td>' +
|
||||||
'<td><button class="btn btn-danger btn-sm btn_delete_user_group" type="button" style="float: right;"><i class="fa fa-minus"></i></button></td>' +
|
'<td><button class="btn btn-danger btn-sm pull-right btn_delete_user_group" type="button"><i class="fa fa-minus"></i></button></td>' +
|
||||||
'</tr>'
|
'</tr>'
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
// clear jumpserver.selected_groups
|
// clear jumpserver.selected_groups
|
||||||
jumpserver.selected_groups = {};
|
jumpserver.selected_groups = {};
|
||||||
toastr.success('{% trans "Update success!" %}')
|
toastr.success('{% trans "UserGroup Update Success!" %}')
|
||||||
}
|
};
|
||||||
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success: success, method: 'PUT'});
|
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success: success, method: 'PUT'});
|
||||||
|
|
||||||
}
|
}
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.select2').select2()
|
$('.select2').select2()
|
||||||
.on('select2:select', function(evt, params) {
|
.on('select2:select', function(evt) {
|
||||||
var data = evt.params.data;
|
var data = evt.params.data;
|
||||||
jumpserver.selected_groups[data.id] = data.text;
|
jumpserver.selected_groups[data.id] = data.text;
|
||||||
}).on('select2:unselect', function(evt) {
|
}).on('select2:unselect', function(evt) {
|
||||||
var data = evt.params.data;
|
var data = evt.params.data;
|
||||||
delete jumpserver.selected_groups[data.id]
|
delete jumpserver.selected_groups[data.id]
|
||||||
})
|
})
|
||||||
});
|
}).on('click', '#is_active', function(){
|
||||||
$(document).on('click', '#is_active', function(){
|
|
||||||
var the_url = "{% url 'users:user-patch-api' pk=user_object.id %}";
|
var the_url = "{% url 'users:user-patch-api' pk=user_object.id %}";
|
||||||
var checked = !$(this).prop('checked');
|
var checked = !$(this).prop('checked');
|
||||||
var body = {'is_active': checked };
|
var body = {'is_active': checked };
|
||||||
var success = function(data) {
|
var success = '{% trans "Update Successfully!" %}';
|
||||||
toastr.success('{% trans "Update success!" %}')
|
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success_message: success});
|
||||||
}
|
|
||||||
APIUpdateAttr({ url: the_url, body: body, success: success});
|
|
||||||
}).on('click', '#enable_otp', function(){
|
}).on('click', '#enable_otp', function(){
|
||||||
var the_url = "{% url 'users:user-patch-api' pk=user_object.id %}";
|
var the_url = "{% url 'users:user-patch-api' pk=user_object.id %}";
|
||||||
var checked = !$(this).prop('checked');
|
var checked = !$(this).prop('checked');
|
||||||
var body = {'enable_otp': checked };
|
var body = {'enable_otp': checked };
|
||||||
var success = function(data) {
|
var success = '{% trans "Update Successfully!" %}';
|
||||||
toastr.success('{% trans "Update success!" %}')
|
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success_message: success});
|
||||||
}
|
|
||||||
APIUpdateAttr({ url: the_url, body: body, success: success});
|
|
||||||
}).on('click', '#btn_add_user_group', function(){
|
}).on('click', '#btn_add_user_group', function(){
|
||||||
if (Object.keys(jumpserver.selected_groups).length === 0) {
|
if (Object.keys(jumpserver.selected_groups).length === 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -290,6 +286,56 @@ $(document).on('click', '#is_active', function(){
|
||||||
return $(this).data('gid');
|
return $(this).data('gid');
|
||||||
}).get();
|
}).get();
|
||||||
updateUserGroups(user_groups)
|
updateUserGroups(user_groups)
|
||||||
})
|
}).on('click', '#btn_reset_password', function(){
|
||||||
|
function doReset() {
|
||||||
|
var the_url = '{% url "users:user-reset-password-api" pk=user_object.id %}';
|
||||||
|
var body = {};
|
||||||
|
var success = function() {
|
||||||
|
var msg = "{% trans 'E-mail sent successfully. An e-mail has been sent to the user\'s mailbox.' %}";
|
||||||
|
swal("{% trans 'Password-Reset' %}", msg, "success");
|
||||||
|
}
|
||||||
|
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success: success});
|
||||||
|
}
|
||||||
|
swal({
|
||||||
|
title: "{% trans 'Are you sure?' %}",
|
||||||
|
text: "{% trans 'This will reset the user\'s password.' %}",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: "#DD6B55",
|
||||||
|
confirmButtonText: "{% trans 'Confirm' %}",
|
||||||
|
closeOnConfirm: false
|
||||||
|
}, function () {
|
||||||
|
doReset();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}).on('click', '#btn_user_reset_pk', function(){
|
||||||
|
var $this = $(this);
|
||||||
|
var pk = $('#txt_pk').val();
|
||||||
|
var the_url = '{% url "users:user-reset-pk-api" pk=user_object.id %}';
|
||||||
|
var body = {'_private_key': pk};
|
||||||
|
var success = function() {
|
||||||
|
$('#txt_pk').val('');
|
||||||
|
$this.closest('.modal').modal('hide');
|
||||||
|
var msg = "{% trans 'Successfully updated the SSH private key.' %}";
|
||||||
|
swal("{% trans 'User SSH Private Key Reset' %}", msg, "success");
|
||||||
|
};
|
||||||
|
var fail = function() {
|
||||||
|
var msg = "{% trans 'Failed to update the user\'s SSH private key.' %}";
|
||||||
|
swal({
|
||||||
|
title: "{% trans 'User SSH Private Key Reset' %}",
|
||||||
|
text: msg,
|
||||||
|
type: "error",
|
||||||
|
showCancelButton: false,
|
||||||
|
confirmButtonColor: "#DD6B55",
|
||||||
|
confirmButtonText: "{% trans 'Confirm' %}",
|
||||||
|
closeOnConfirm: true
|
||||||
|
}, function () {
|
||||||
|
$('#txt_pk').focus();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success: success, error: fail});
|
||||||
|
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -35,6 +35,8 @@ urlpatterns += [
|
||||||
api.UserDetailDeleteUpdateApi.as_view(), name='user-detail-api'),
|
api.UserDetailDeleteUpdateApi.as_view(), name='user-detail-api'),
|
||||||
url(r'^v1/users/(?P<pk>[0-9]+)/patch$',
|
url(r'^v1/users/(?P<pk>[0-9]+)/patch$',
|
||||||
api.UserAttributeApi.as_view(), name='user-patch-api'),
|
api.UserAttributeApi.as_view(), name='user-patch-api'),
|
||||||
|
url(r'^v1/users/(?P<pk>\d+)/reset-password/$', api.UserResetPasswordApi.as_view(), name='user-reset-password-api'),
|
||||||
|
url(r'^v1/users/(?P<pk>\d+)/reset-pk/$', api.UserResetPKApi.as_view(), name='user-reset-pk-api'),
|
||||||
url(r'^v1/user-groups$', api.UserGroupListAddApi.as_view(), name='user-group-list-api'),
|
url(r'^v1/user-groups$', api.UserGroupListAddApi.as_view(), name='user-group-list-api'),
|
||||||
url(r'^v1/user-groups/(?P<pk>[0-9]+)$',
|
url(r'^v1/user-groups/(?P<pk>[0-9]+)$',
|
||||||
api.UserGroupDetailDeleteUpdateApi.as_view(), name='user-group-detail-api'),
|
api.UserGroupDetailDeleteUpdateApi.as_view(), name='user-group-detail-api'),
|
||||||
|
|
|
@ -5,6 +5,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.mixins import UserPassesTestMixin
|
from django.contrib.auth.mixins import UserPassesTestMixin
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
@ -121,6 +122,8 @@ def send_reset_password_mail(user):
|
||||||
'email': user.email,
|
'email': user.email,
|
||||||
'login_url': reverse('users:login', external=True),
|
'login_url': reverse('users:login', external=True),
|
||||||
}
|
}
|
||||||
|
if settings.DEBUG:
|
||||||
|
logger.debug(message)
|
||||||
|
|
||||||
send_mail_async.delay(subject, message, recipient_list, html_message=message)
|
send_mail_async.delay(subject, message, recipient_list, html_message=message)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue