Commit 0f9bdab1 authored by unknown's avatar unknown

Merge branch 'master' of code.simcu.com:jumpserver/jumpserver

parents 1005fbab 6751c5a6
...@@ -4,10 +4,10 @@ ...@@ -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){ ...@@ -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() { ...@@ -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() { ...@@ -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) { ...@@ -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) { ...@@ -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() { ...@@ -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) { ...@@ -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 = {};
{% 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 ...@@ -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): ...@@ -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()
# -*- 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): ...@@ -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
{% extends '_modal.html' %}
{% load i18n %}
{% block modal_id %}user_reset_pk_modal{% endblock %}
{% block modal_title%}{% trans 'Reset User SSH Private Key' %}{% endblock %}
{% block modal_body %}
<textarea id="txt_pk" class="form-control" cols="30" rows="10" placeholder="-----BEGIN RSA PRIVATE KEY-----"></textarea>
{% endblock %}
{% block modal_confirm_id %}btn_user_reset_pk{% endblock %}
This diff is collapsed.
...@@ -35,6 +35,8 @@ urlpatterns += [ ...@@ -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 ...@@ -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): ...@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment