mirror of https://github.com/jumpserver/jumpserver
添加忘记密码
parent
44c69ded78
commit
c21cdc2131
126
jperm/views.py
126
jperm/views.py
|
@ -262,70 +262,70 @@ def unicode2str(unicode_list):
|
|||
return [str(i) for i in unicode_list]
|
||||
|
||||
|
||||
def sudo_ldap_add(user_group, user_runas, asset_groups_select,
|
||||
cmd_groups_select):
|
||||
if not LDAP_ENABLE:
|
||||
return True
|
||||
|
||||
assets = []
|
||||
cmds = []
|
||||
user_runas = user_runas.split(',')
|
||||
if len(asset_groups_select) == 1 and asset_groups_select[0].name == 'ALL':
|
||||
asset_all = True
|
||||
else:
|
||||
asset_all = False
|
||||
for asset_group in asset_groups_select:
|
||||
assets.extend(asset_group.asset_set.all())
|
||||
# def sudo_ldap_add(user_group, user_runas, asset_groups_select,
|
||||
# cmd_groups_select):
|
||||
# if not LDAP_ENABLE:
|
||||
# return True
|
||||
#
|
||||
# assets = []
|
||||
# cmds = []
|
||||
# user_runas = user_runas.split(',')
|
||||
# if len(asset_groups_select) == 1 and asset_groups_select[0].name == 'ALL':
|
||||
# asset_all = True
|
||||
# else:
|
||||
# asset_all = False
|
||||
# for asset_group in asset_groups_select:
|
||||
# assets.extend(asset_group.asset_set.all())
|
||||
#
|
||||
# if user_group.name == 'ALL':
|
||||
# user_all = True
|
||||
# users = []
|
||||
# else:
|
||||
# user_all = False
|
||||
# users = user_group.user_set.all()
|
||||
#
|
||||
# for cmd_group in cmd_groups_select:
|
||||
# cmds.extend(cmd_group.cmd.split(','))
|
||||
#
|
||||
# if user_all:
|
||||
# users_name = ['ALL']
|
||||
# else:
|
||||
# users_name = list(set([user.username for user in users]))
|
||||
#
|
||||
# if asset_all:
|
||||
# assets_ip = ['ALL']
|
||||
# else:
|
||||
# assets_ip = list(set([asset.ip for asset in assets]))
|
||||
#
|
||||
# name = 'sudo%s' % user_group.id
|
||||
# sudo_dn = 'cn=%s,ou=Sudoers,%s' % (name, LDAP_BASE_DN)
|
||||
# sudo_attr = {'objectClass': ['top', 'sudoRole'],
|
||||
# 'cn': ['%s' % name],
|
||||
# 'sudoCommand': unicode2str(cmds),
|
||||
# 'sudoHost': unicode2str(assets_ip),
|
||||
# 'sudoOption': ['!authenticate'],
|
||||
# 'sudoRunAsUser': unicode2str(user_runas),
|
||||
# 'sudoUser': unicode2str(users_name)}
|
||||
# ldap_conn.delete(sudo_dn)
|
||||
# ldap_conn.add(sudo_dn, sudo_attr)
|
||||
|
||||
if user_group.name == 'ALL':
|
||||
user_all = True
|
||||
users = []
|
||||
else:
|
||||
user_all = False
|
||||
users = user_group.user_set.all()
|
||||
|
||||
for cmd_group in cmd_groups_select:
|
||||
cmds.extend(cmd_group.cmd.split(','))
|
||||
|
||||
if user_all:
|
||||
users_name = ['ALL']
|
||||
else:
|
||||
users_name = list(set([user.username for user in users]))
|
||||
|
||||
if asset_all:
|
||||
assets_ip = ['ALL']
|
||||
else:
|
||||
assets_ip = list(set([asset.ip for asset in assets]))
|
||||
|
||||
name = 'sudo%s' % user_group.id
|
||||
sudo_dn = 'cn=%s,ou=Sudoers,%s' % (name, LDAP_BASE_DN)
|
||||
sudo_attr = {'objectClass': ['top', 'sudoRole'],
|
||||
'cn': ['%s' % name],
|
||||
'sudoCommand': unicode2str(cmds),
|
||||
'sudoHost': unicode2str(assets_ip),
|
||||
'sudoOption': ['!authenticate'],
|
||||
'sudoRunAsUser': unicode2str(user_runas),
|
||||
'sudoUser': unicode2str(users_name)}
|
||||
ldap_conn.delete(sudo_dn)
|
||||
ldap_conn.add(sudo_dn, sudo_attr)
|
||||
|
||||
|
||||
def sudo_update(user_group, user_runas, asset_groups_select, cmd_groups_select, comment):
|
||||
asset_groups_select_list, cmd_groups_select_list = \
|
||||
asset_cmd_groups_get(asset_groups_select, cmd_groups_select)
|
||||
sudo_perm = user_group.sudoperm_set.all()
|
||||
if sudo_perm:
|
||||
sudo_perm.update(user_runas=user_runas, comment=comment)
|
||||
sudo_perm = sudo_perm[0]
|
||||
sudo_perm.asset_group = asset_groups_select_list
|
||||
sudo_perm.cmd_group = cmd_groups_select_list
|
||||
else:
|
||||
sudo_perm = SudoPerm(user_group=user_group, user_runas=user_runas, comment=comment)
|
||||
sudo_perm.save()
|
||||
sudo_perm.asset_group = asset_groups_select_list
|
||||
sudo_perm.cmd_group = cmd_groups_select_list
|
||||
|
||||
sudo_ldap_add(user_group, user_runas, asset_groups_select_list, cmd_groups_select_list)
|
||||
#
|
||||
# def sudo_update(user_group, user_runas, asset_groups_select, cmd_groups_select, comment):
|
||||
# asset_groups_select_list, cmd_groups_select_list = \
|
||||
# asset_cmd_groups_get(asset_groups_select, cmd_groups_select)
|
||||
# sudo_perm = user_group.sudoperm_set.all()
|
||||
# if sudo_perm:
|
||||
# sudo_perm.update(user_runas=user_runas, comment=comment)
|
||||
# sudo_perm = sudo_perm[0]
|
||||
# sudo_perm.asset_group = asset_groups_select_list
|
||||
# sudo_perm.cmd_group = cmd_groups_select_list
|
||||
# else:
|
||||
# sudo_perm = SudoPerm(user_group=user_group, user_runas=user_runas, comment=comment)
|
||||
# sudo_perm.save()
|
||||
# sudo_perm.asset_group = asset_groups_select_list
|
||||
# sudo_perm.cmd_group = cmd_groups_select_list
|
||||
#
|
||||
# sudo_ldap_add(user_group, user_runas, asset_groups_select_list, cmd_groups_select_list)
|
||||
|
||||
|
||||
@require_super_user
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#coding: utf8
|
||||
|
||||
[base]
|
||||
ip = 192.168.20.209
|
||||
port = 80
|
||||
url = http://192.168.244.129
|
||||
key = 88aaaf7ffe3c6c04
|
||||
log = debug
|
||||
|
||||
|
|
|
@ -6,15 +6,12 @@ import getpass
|
|||
from Crypto.Cipher import AES
|
||||
import crypt
|
||||
from binascii import b2a_hex, a2b_hex
|
||||
import ldap
|
||||
from ldap import modlist
|
||||
import hashlib
|
||||
import datetime
|
||||
import random
|
||||
import subprocess
|
||||
import paramiko
|
||||
import struct, fcntl, signal,socket, select, fnmatch
|
||||
from functools import partial
|
||||
|
||||
from django.core.paginator import Paginator, EmptyPage, InvalidPage
|
||||
from django.http import HttpResponse, Http404
|
||||
|
@ -23,7 +20,7 @@ from juser.models import User, UserGroup
|
|||
from jasset.models import Asset, BisGroup, IDC
|
||||
from jlog.models import Log
|
||||
from jasset.models import AssetAlias
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render_to_response
|
||||
from django.core.mail import send_mail
|
||||
|
@ -48,9 +45,8 @@ SSH_KEY_DIR = os.path.join(BASE_DIR, 'keys')
|
|||
# SERVER_KEY_DIR = os.path.join(SSH_KEY_DIR, 'server')
|
||||
KEY = CONF.get('base', 'key')
|
||||
LOGIN_NAME = getpass.getuser()
|
||||
LDAP_ENABLE = CONF.getint('ldap', 'ldap_enable')
|
||||
SEND_IP = CONF.get('base', 'ip')
|
||||
SEND_PORT = CONF.get('base', 'port')
|
||||
# LDAP_ENABLE = CONF.getint('ldap', 'ldap_enable')
|
||||
URL = CONF.get('base', 'url')
|
||||
MAIL_ENABLE = CONF.get('mail', 'mail_enable')
|
||||
MAIL_FROM = CONF.get('mail', 'email_host_user')
|
||||
log_dir = os.path.join(BASE_DIR, 'logs')
|
||||
|
@ -73,73 +69,73 @@ def set_log(level):
|
|||
return logger_f
|
||||
|
||||
|
||||
class LDAPMgmt():
|
||||
"""
|
||||
LDAP class for add, select, del, update
|
||||
LDAP 管理类,增删改查
|
||||
"""
|
||||
def __init__(self,
|
||||
host_url,
|
||||
base_dn,
|
||||
root_cn,
|
||||
root_pw):
|
||||
self.ldap_host = host_url
|
||||
self.ldap_base_dn = base_dn
|
||||
self.conn = ldap.initialize(host_url)
|
||||
self.conn.set_option(ldap.OPT_REFERRALS, 0)
|
||||
self.conn.protocol_version = ldap.VERSION3
|
||||
self.conn.simple_bind_s(root_cn, root_pw)
|
||||
|
||||
def list(self, filter, scope=ldap.SCOPE_SUBTREE, attr=None):
|
||||
"""
|
||||
query
|
||||
查询
|
||||
"""
|
||||
result = {}
|
||||
try:
|
||||
ldap_result = self.conn.search_s(self.ldap_base_dn, scope, filter, attr)
|
||||
for entry in ldap_result:
|
||||
name, data = entry
|
||||
for k, v in data.items():
|
||||
print '%s: %s' % (k, v)
|
||||
result[k] = v
|
||||
return result
|
||||
except ldap.LDAPError, e:
|
||||
print e
|
||||
|
||||
def add(self, dn, attrs):
|
||||
"""
|
||||
add
|
||||
添加
|
||||
"""
|
||||
try:
|
||||
ldif = modlist.addModlist(attrs)
|
||||
self.conn.add_s(dn, ldif)
|
||||
except ldap.LDAPError, e:
|
||||
print e
|
||||
|
||||
def modify(self, dn, attrs):
|
||||
"""
|
||||
modify
|
||||
更改
|
||||
"""
|
||||
try:
|
||||
attr_s = []
|
||||
for k, v in attrs.items():
|
||||
attr_s.append((2, k, v))
|
||||
self.conn.modify_s(dn, attr_s)
|
||||
except ldap.LDAPError, e:
|
||||
print e
|
||||
|
||||
def delete(self, dn):
|
||||
"""
|
||||
delete
|
||||
删除
|
||||
"""
|
||||
try:
|
||||
self.conn.delete_s(dn)
|
||||
except ldap.LDAPError, e:
|
||||
print e
|
||||
# class LDAPMgmt():
|
||||
# """
|
||||
# LDAP class for add, select, del, update
|
||||
# LDAP 管理类,增删改查
|
||||
# """
|
||||
# def __init__(self,
|
||||
# host_url,
|
||||
# base_dn,
|
||||
# root_cn,
|
||||
# root_pw):
|
||||
# self.ldap_host = host_url
|
||||
# self.ldap_base_dn = base_dn
|
||||
# self.conn = ldap.initialize(host_url)
|
||||
# self.conn.set_option(ldap.OPT_REFERRALS, 0)
|
||||
# self.conn.protocol_version = ldap.VERSION3
|
||||
# self.conn.simple_bind_s(root_cn, root_pw)
|
||||
#
|
||||
# def list(self, filter, scope=ldap.SCOPE_SUBTREE, attr=None):
|
||||
# """
|
||||
# query
|
||||
# 查询
|
||||
# """
|
||||
# result = {}
|
||||
# try:
|
||||
# ldap_result = self.conn.search_s(self.ldap_base_dn, scope, filter, attr)
|
||||
# for entry in ldap_result:
|
||||
# name, data = entry
|
||||
# for k, v in data.items():
|
||||
# print '%s: %s' % (k, v)
|
||||
# result[k] = v
|
||||
# return result
|
||||
# except ldap.LDAPError, e:
|
||||
# print e
|
||||
#
|
||||
# def add(self, dn, attrs):
|
||||
# """
|
||||
# add
|
||||
# 添加
|
||||
# """
|
||||
# try:
|
||||
# ldif = modlist.addModlist(attrs)
|
||||
# self.conn.add_s(dn, ldif)
|
||||
# except ldap.LDAPError, e:
|
||||
# print e
|
||||
#
|
||||
# def modify(self, dn, attrs):
|
||||
# """
|
||||
# modify
|
||||
# 更改
|
||||
# """
|
||||
# try:
|
||||
# attr_s = []
|
||||
# for k, v in attrs.items():
|
||||
# attr_s.append((2, k, v))
|
||||
# self.conn.modify_s(dn, attr_s)
|
||||
# except ldap.LDAPError, e:
|
||||
# print e
|
||||
#
|
||||
# def delete(self, dn):
|
||||
# """
|
||||
# delete
|
||||
# 删除
|
||||
# """
|
||||
# try:
|
||||
# self.conn.delete_s(dn)
|
||||
# except ldap.LDAPError, e:
|
||||
# print e
|
||||
|
||||
|
||||
def page_list_return(total, current=1):
|
||||
|
@ -480,9 +476,10 @@ def get_object(model, **kwargs):
|
|||
use this function for query
|
||||
使用改封装函数查询数据库
|
||||
"""
|
||||
try:
|
||||
the_object = model.objects.get(**kwargs)
|
||||
except ObjectDoesNotExist:
|
||||
the_object = model.objects.filter(**kwargs)
|
||||
if len(the_object) == 1:
|
||||
the_object = the_object[0]
|
||||
else:
|
||||
the_object = None
|
||||
return the_object
|
||||
|
||||
|
@ -498,10 +495,10 @@ def require_role(role='user'):
|
|||
if not request.session.get('user_id'):
|
||||
return HttpResponseRedirect('/login/')
|
||||
elif role == 'admin':
|
||||
if request.session.get('role_id', 0) != 1:
|
||||
if request.session.get('role_id', 0) < 1:
|
||||
return HttpResponseRedirect('/')
|
||||
elif role == 'super':
|
||||
if request.session.get('role_id', 0) != 2:
|
||||
if request.session.get('role_id', 0) < 2:
|
||||
return HttpResponseRedirect('/')
|
||||
return func(request, *args, **kwargs)
|
||||
return __deco
|
||||
|
@ -531,8 +528,7 @@ def get_session_user_dept(request):
|
|||
user = User.objects.filter(id=user_id)
|
||||
if user:
|
||||
user = user[0]
|
||||
dept = user.dept
|
||||
return user, dept
|
||||
return user, None
|
||||
|
||||
|
||||
@require_role
|
||||
|
@ -704,14 +700,14 @@ def http_error(request, emg):
|
|||
|
||||
CRYPTOR = PyCrypt(KEY)
|
||||
|
||||
if LDAP_ENABLE:
|
||||
LDAP_HOST_URL = CONF.get('ldap', 'host_url')
|
||||
LDAP_BASE_DN = CONF.get('ldap', 'base_dn')
|
||||
LDAP_ROOT_DN = CONF.get('ldap', 'root_dn')
|
||||
LDAP_ROOT_PW = CONF.get('ldap', 'root_pw')
|
||||
ldap_conn = LDAPMgmt(LDAP_HOST_URL, LDAP_BASE_DN, LDAP_ROOT_DN, LDAP_ROOT_PW)
|
||||
else:
|
||||
ldap_conn = None
|
||||
# if LDAP_ENABLE:
|
||||
# LDAP_HOST_URL = CONF.get('ldap', 'host_url')
|
||||
# LDAP_BASE_DN = CONF.get('ldap', 'base_dn')
|
||||
# LDAP_ROOT_DN = CONF.get('ldap', 'root_dn')
|
||||
# LDAP_ROOT_PW = CONF.get('ldap', 'root_pw')
|
||||
# ldap_conn = LDAPMgmt(LDAP_HOST_URL, LDAP_BASE_DN, LDAP_ROOT_DN, LDAP_ROOT_PW)
|
||||
# else:
|
||||
# ldap_conn = None
|
||||
|
||||
log_level = CONF.get('base', 'log')
|
||||
logger = set_log(log_level)
|
|
@ -213,7 +213,7 @@ def login(request):
|
|||
user_filter.update(last_login=datetime.datetime.now())
|
||||
if user.role == 'SU':
|
||||
request.session['role_id'] = 2
|
||||
elif user.role == 'DA':
|
||||
elif user.role == 'GA':
|
||||
request.session['role_id'] = 1
|
||||
else:
|
||||
request.session['role_id'] = 0
|
||||
|
|
|
@ -30,8 +30,8 @@ class User(models.Model):
|
|||
name = models.CharField(max_length=80)
|
||||
email = models.EmailField(max_length=75)
|
||||
role = models.CharField(max_length=2, choices=USER_ROLE_CHOICES, default='CU')
|
||||
uuid = models.CharField(max_length=100)
|
||||
group = models.ManyToManyField(UserGroup)
|
||||
ldap_pwd = models.CharField(max_length=128)
|
||||
ssh_key_pwd = models.CharField(max_length=200)
|
||||
is_active = models.BooleanField(default=True)
|
||||
last_login = models.DateTimeField(null=True)
|
||||
|
@ -128,4 +128,6 @@ class AdminGroup(models.Model):
|
|||
"""
|
||||
|
||||
user = models.ForeignKey(User)
|
||||
group = models.ForeignKey(UserGroup)
|
||||
group = models.ForeignKey(UserGroup)
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,10 @@ urlpatterns = patterns('juser.views',
|
|||
(r'^group_del_ajax', group_del_ajax),
|
||||
(r'^group_edit/$', group_edit),
|
||||
(r'^user_add/$', user_add),
|
||||
(r'^user_list/$', view_splitter, {'su': user_list, 'adm': user_list_adm}),
|
||||
(r'^user_list/$', user_list),
|
||||
(r'^send_mail_retry/$', send_mail_retry),
|
||||
(r'^reset_password/$', reset_password),
|
||||
(r'^forget_password/$', forget_password),
|
||||
(r'^user_detail/$', 'user_detail'),
|
||||
(r'^user_del/$', 'user_del'),
|
||||
(r'^user_del_ajax/$', 'user_del_ajax'),
|
||||
|
|
|
@ -101,11 +101,9 @@ def db_del_user(username):
|
|||
delete a user from database
|
||||
从数据库中删除用户
|
||||
"""
|
||||
try:
|
||||
user = User.objects.get(username=username)
|
||||
user = get_object(User, username=username)
|
||||
if user:
|
||||
user.delete()
|
||||
except ObjectDoesNotExist:
|
||||
pass
|
||||
|
||||
|
||||
def gen_ssh_key(username, password=None, length=2048):
|
||||
|
@ -134,13 +132,14 @@ def gen_ssh_key(username, password=None, length=2048):
|
|||
print "gen_ssh_key_end" + str(time.time())
|
||||
|
||||
|
||||
def server_add_user(username, password, ssh_key_pwd):
|
||||
def server_add_user(username, password, ssh_key_pwd, ssh_key_login_need):
|
||||
"""
|
||||
add a system user in jumpserver
|
||||
在jumpserver服务器上添加一个用户
|
||||
"""
|
||||
bash("useradd '%s'; echo '%s' | passwd --stdin '%s'" % (username, password, username))
|
||||
gen_ssh_key(username, ssh_key_pwd)
|
||||
bash("useradd '%s'; echo '%s'; echo '%s' | passwd --stdin '%s'" % (username, password, password, username))
|
||||
if ssh_key_login_need:
|
||||
gen_ssh_key(username, ssh_key_pwd)
|
||||
|
||||
|
||||
def user_add_mail(user, kwargs):
|
||||
|
@ -156,10 +155,10 @@ def user_add_mail(user, kwargs):
|
|||
您的角色: %s
|
||||
您的web登录密码: %s
|
||||
您的ssh密钥文件密码: %s
|
||||
密钥下载地址: http://%s:%s/juser/down_key/?id=%s
|
||||
密钥下载地址: %s/juser/down_key/?uuid=%s
|
||||
说明: 请登陆后再下载密钥!
|
||||
""" % (user.name, user.username, user_role.get(user.role, u'普通用户'),
|
||||
kwargs.get('password'), kwargs.get('ssh_key_pwd'), SEND_IP, SEND_PORT, user.id)
|
||||
kwargs.get('password'), kwargs.get('ssh_key_pwd'), URL, user.uuid)
|
||||
send_mail(mail_title, mail_msg, MAIL_FROM, [user.email], fail_silently=False)
|
||||
|
||||
|
||||
|
@ -171,49 +170,73 @@ def server_del_user(username):
|
|||
bash('userdel -r %s' % username)
|
||||
|
||||
|
||||
def ldap_add_user(username, ldap_pwd):
|
||||
"""
|
||||
add a user in ldap database
|
||||
在LDAP中添加用户
|
||||
"""
|
||||
user_dn = "uid=%s,ou=People,%s" % (username, LDAP_BASE_DN)
|
||||
password_sha512 = PyCrypt.gen_sha512(PyCrypt.random_pass(6), ldap_pwd)
|
||||
user = get_object(User, username=username)
|
||||
if not user:
|
||||
raise ServerError(u'用户 %s 不存在' % username)
|
||||
def get_display_msg(user, password, ssh_key_pwd, ssh_key_login_need, send_mail_need):
|
||||
if send_mail_need:
|
||||
msg = u'添加用户 %s 成功! 用户密码已发送到 %s 邮箱!' % (user.name, user.email)
|
||||
return msg
|
||||
|
||||
user_attr = {'uid': [str(username)],
|
||||
'cn': [str(username)],
|
||||
'objectClass': ['account', 'posixAccount', 'top', 'shadowAccount'],
|
||||
'userPassword': ['{crypt}%s' % password_sha512],
|
||||
'shadowLastChange': ['16328'],
|
||||
'shadowMin': ['0'],
|
||||
'shadowMax': ['99999'],
|
||||
'shadowWarning': ['7'],
|
||||
'loginShell': ['/bin/bash'],
|
||||
'uidNumber': [str(user.id)],
|
||||
'gidNumber': [str(user.id)],
|
||||
'homeDirectory': [str('/home/%s' % username)]}
|
||||
if ssh_key_login_need:
|
||||
msg = u"""
|
||||
跳板机地址: %s
|
||||
用户名:%s
|
||||
密码:%s
|
||||
密钥密码:%s
|
||||
密钥下载url: %s/juser/down_key/?id=%s
|
||||
该账号密码可以登陆web和跳板机。
|
||||
""" % (URL, user.username, password, ssh_key_pwd, URL, user.id)
|
||||
else:
|
||||
msg = u"""
|
||||
跳板机地址: %s \n
|
||||
用户名:%s \n
|
||||
密码:%s \n
|
||||
该账号密码可以登陆web和跳板机。
|
||||
""" % (URL, user.username, password)
|
||||
|
||||
group_dn = "cn=%s,ou=Group,%s" % (username, LDAP_BASE_DN)
|
||||
group_attr = {'objectClass': ['posixGroup', 'top'],
|
||||
'cn': [str(username)],
|
||||
'userPassword': ['{crypt}x'],
|
||||
'gidNumber': [str(user.id)]}
|
||||
return msg
|
||||
|
||||
ldap_conn.add(user_dn, user_attr)
|
||||
ldap_conn.add(group_dn, group_attr)
|
||||
# def ldap_add_user(username, ldap_pwd):
|
||||
# """
|
||||
# add a user in ldap database
|
||||
# 在LDAP中添加用户
|
||||
# """
|
||||
# user_dn = "uid=%s,ou=People,%s" % (username, LDAP_BASE_DN)
|
||||
# password_sha512 = PyCrypt.gen_sha512(PyCrypt.random_pass(6), ldap_pwd)
|
||||
# user = get_object(User, username=username)
|
||||
# if not user:
|
||||
# raise ServerError(u'用户 %s 不存在' % username)
|
||||
#
|
||||
# user_attr = {'uid': [str(username)],
|
||||
# 'cn': [str(username)],
|
||||
# 'objectClass': ['account', 'posixAccount', 'top', 'shadowAccount'],
|
||||
# 'userPassword': ['{crypt}%s' % password_sha512],
|
||||
# 'shadowLastChange': ['16328'],
|
||||
# 'shadowMin': ['0'],
|
||||
# 'shadowMax': ['99999'],
|
||||
# 'shadowWarning': ['7'],
|
||||
# 'loginShell': ['/bin/bash'],
|
||||
# 'uidNumber': [str(user.id)],
|
||||
# 'gidNumber': [str(user.id)],
|
||||
# 'homeDirectory': [str('/home/%s' % username)]}
|
||||
#
|
||||
# group_dn = "cn=%s,ou=Group,%s" % (username, LDAP_BASE_DN)
|
||||
# group_attr = {'objectClass': ['posixGroup', 'top'],
|
||||
# 'cn': [str(username)],
|
||||
# 'userPassword': ['{crypt}x'],
|
||||
# 'gidNumber': [str(user.id)]}
|
||||
#
|
||||
# ldap_conn.add(user_dn, user_attr)
|
||||
# ldap_conn.add(group_dn, group_attr)
|
||||
|
||||
|
||||
def ldap_del_user(username):
|
||||
"""
|
||||
delete a user in ldap database
|
||||
在ldap中删除某用户
|
||||
"""
|
||||
user_dn = "uid=%s,ou=People,%s" % (username, LDAP_BASE_DN)
|
||||
group_dn = "cn=%s,ou=Group,%s" % (username, LDAP_BASE_DN)
|
||||
sudo_dn = 'cn=%s,ou=Sudoers,%s' % (username, LDAP_BASE_DN)
|
||||
|
||||
ldap_conn.delete(user_dn)
|
||||
ldap_conn.delete(group_dn)
|
||||
ldap_conn.delete(sudo_dn)
|
||||
# def ldap_del_user(username):
|
||||
# """
|
||||
# delete a user in ldap database
|
||||
# 在ldap中删除某用户
|
||||
# """
|
||||
# user_dn = "uid=%s,ou=People,%s" % (username, LDAP_BASE_DN)
|
||||
# group_dn = "cn=%s,ou=Group,%s" % (username, LDAP_BASE_DN)
|
||||
# sudo_dn = 'cn=%s,ou=Sudoers,%s' % (username, LDAP_BASE_DN)
|
||||
#
|
||||
# ldap_conn.delete(user_dn)
|
||||
# ldap_conn.delete(group_dn)
|
||||
# ldap_conn.delete(sudo_dn)
|
192
juser/views.py
192
juser/views.py
|
@ -4,6 +4,7 @@
|
|||
|
||||
import random
|
||||
from Crypto.PublicKey import RSA
|
||||
import uuid as uuid_r
|
||||
|
||||
from django.db.models import Q
|
||||
from django.template import RequestContext
|
||||
|
@ -235,13 +236,15 @@ def user_add(request):
|
|||
groups = request.POST.getlist('groups', [])
|
||||
admin_groups = request.POST.getlist('admin_groups', [])
|
||||
role = request.POST.get('role', 'CU')
|
||||
uuid = uuid_r.uuid1()
|
||||
ssh_key_pwd = PyCrypt.random_pass(16)
|
||||
extra = request.POST.getlist('extra', [])
|
||||
is_active = True if '0' in extra else False
|
||||
ldap_pwd = PyCrypt.random_pass(32, especial=True)
|
||||
ssh_key_login_need = True if '1' in extra else False
|
||||
send_mail_need = True if '2' in extra else False
|
||||
|
||||
try:
|
||||
if '' in [username, password, ssh_key_pwd, name, groups, role, is_active]:
|
||||
if '' in [username, password, ssh_key_pwd, name, role]:
|
||||
error = u'带*内容不能为空'
|
||||
raise ServerError
|
||||
user_test = get_object(User, username=username)
|
||||
|
@ -253,30 +256,25 @@ def user_add(request):
|
|||
pass
|
||||
else:
|
||||
try:
|
||||
user = db_add_user(username=username,
|
||||
user = db_add_user(username=username, name=name,
|
||||
password=CRYPTOR.md5_crypt(password),
|
||||
name=name, email=email, role=role,
|
||||
email=email, role=role, uuid=uuid,
|
||||
groups=groups, admin_groups=admin_groups,
|
||||
ssh_key_pwd=CRYPTOR.md5_crypt(ssh_key_pwd),
|
||||
ldap_pwd=CRYPTOR.encrypt(ldap_pwd),
|
||||
is_active=is_active,
|
||||
date_joined=datetime.datetime.now())
|
||||
if LDAP_ENABLE:
|
||||
ldap_add_user(username, ldap_pwd)
|
||||
|
||||
except IndexError, e:
|
||||
server_add_user(username, password, ssh_key_pwd, ssh_key_login_need)
|
||||
except Exception, e:
|
||||
error = u'添加用户 %s 失败 %s ' % (username, e)
|
||||
try:
|
||||
db_del_user(username)
|
||||
server_del_user(username)
|
||||
if LDAP_ENABLE:
|
||||
ldap_del_user(username)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
if MAIL_ENABLE:
|
||||
if MAIL_ENABLE and send_mail_need:
|
||||
user_add_mail(user, kwargs=locals())
|
||||
msg = u'添加用户 %s 成功! 用户密码已发送到 %s 邮箱!' % (username, email)
|
||||
msg = get_display_msg(user, password, ssh_key_pwd, ssh_key_login_need, send_mail_need)
|
||||
return render_to_response('juser/user_add.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
|
@ -358,7 +356,6 @@ def user_list(request):
|
|||
header_title, path1, path2 = '查看用户', '用户管理', '用户列表'
|
||||
keyword = request.GET.get('keyword', '')
|
||||
gid = request.GET.get('gid', '')
|
||||
did = request.GET.get('did', '')
|
||||
contact_list = User.objects.all().order_by('name')
|
||||
|
||||
if gid:
|
||||
|
@ -367,12 +364,6 @@ def user_list(request):
|
|||
user_group = user_group[0]
|
||||
contact_list = user_group.user_set.all()
|
||||
|
||||
if did:
|
||||
dept = DEPT.objects.filter(id=did)
|
||||
if dept:
|
||||
dept = dept[0]
|
||||
contact_list = dept.user_set.all().order_by('name')
|
||||
|
||||
if keyword:
|
||||
contact_list = contact_list.filter(Q(username__icontains=keyword) | Q(name__icontains=keyword)).order_by('name')
|
||||
|
||||
|
@ -381,49 +372,48 @@ def user_list(request):
|
|||
return render_to_response('juser/user_list.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_role(role='admin')
|
||||
def user_list_adm(request):
|
||||
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
||||
header_title, path1, path2 = '查看用户', '用户管理', '用户列表'
|
||||
keyword = request.GET.get('keyword', '')
|
||||
user, dept = get_session_user_dept(request)
|
||||
gid = request.GET.get('gid', '')
|
||||
contact_list = dept.user_set.all().order_by('name')
|
||||
|
||||
if gid:
|
||||
if not validate(request, user_group=[gid]):
|
||||
return HttpResponseRedirect('/juser/user_list/')
|
||||
user_group = UserGroup.objects.filter(id=gid)
|
||||
if user_group:
|
||||
user_group = user_group[0]
|
||||
contact_list = user_group.user_set.all()
|
||||
|
||||
if keyword:
|
||||
contact_list = contact_list.filter(Q(username__icontains=keyword) | Q(name__icontains=keyword)).order_by('name')
|
||||
|
||||
contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(contact_list, request)
|
||||
|
||||
return render_to_response('juser/user_list.html', locals(), context_instance=RequestContext(request))
|
||||
# @require_role(role='admin')
|
||||
# def user_list_adm(request):
|
||||
# user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
||||
# header_title, path1, path2 = '查看用户', '用户管理', '用户列表'
|
||||
# keyword = request.GET.get('keyword', '')
|
||||
# user, dept = get_session_user_dept(request)
|
||||
# gid = request.GET.get('gid', '')
|
||||
# contact_list = dept.user_set.all().order_by('name')
|
||||
#
|
||||
# if gid:
|
||||
# if not validate(request, user_group=[gid]):
|
||||
# return HttpResponseRedirect('/juser/user_list/')
|
||||
# user_group = UserGroup.objects.filter(id=gid)
|
||||
# if user_group:
|
||||
# user_group = user_group[0]
|
||||
# contact_list = user_group.user_set.all()
|
||||
#
|
||||
# if keyword:
|
||||
# contact_list = contact_list.filter(Q(username__icontains=keyword) | Q(name__icontains=keyword)).order_by('name')
|
||||
#
|
||||
# contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(contact_list, request)
|
||||
#
|
||||
# return render_to_response('juser/user_list.html', locals(), context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@require_role(role='user')
|
||||
def user_detail(request):
|
||||
header_title, path1, path2 = '查看用户', '用户管理', '用户详情'
|
||||
header_title, path1, path2 = '用户详情', '用户管理', '用户详情'
|
||||
if request.session.get('role_id') == 0:
|
||||
user_id = request.session.get('user_id')
|
||||
else:
|
||||
user_id = request.GET.get('id', '')
|
||||
if request.session.get('role_id') == 1:
|
||||
user, dept = get_session_user_dept(request)
|
||||
if not validate(request, user=[user_id]):
|
||||
return HttpResponseRedirect('/')
|
||||
if not user_id:
|
||||
return HttpResponseRedirect('/juser/user_list/')
|
||||
# if request.session.get('role_id') == 1:
|
||||
# user, dept = get_session_user_dept(request)
|
||||
# if not validate(request, user=[user_id]):
|
||||
# return HttpResponseRedirect('/')
|
||||
# if not user_id:
|
||||
# return HttpResponseRedirect('/juser/user_list/')
|
||||
|
||||
user = User.objects.filter(id=user_id)
|
||||
user = get_object(User, id=user_id)
|
||||
if user:
|
||||
user = user[0]
|
||||
asset_group_permed = user.get_asset_group()
|
||||
# asset_group_permed = user.get_asset_group()
|
||||
logs_last = Log.objects.filter(user=user.name).order_by('-start_time')[0:10]
|
||||
logs_all = Log.objects.filter(user=user.name).order_by('-start_time')
|
||||
logs_num = len(logs_all)
|
||||
|
@ -437,17 +427,10 @@ def user_del(request):
|
|||
if not user_id:
|
||||
return HttpResponseRedirect('/juser/user_list/')
|
||||
|
||||
if request.session.get('role_id', '') == '1':
|
||||
if not validate(request, user=[user_id]):
|
||||
return HttpResponseRedirect('/juser/user_list/')
|
||||
|
||||
user = User.objects.filter(id=user_id)
|
||||
if user and user[0].username != 'admin':
|
||||
user = user[0]
|
||||
user = get_object(User, id=user_id)
|
||||
if user and user.username != 'admin':
|
||||
user.delete()
|
||||
server_del_user(user.username)
|
||||
if LDAP_ENABLE:
|
||||
ldap_del_user(user.username)
|
||||
return HttpResponseRedirect('/juser/user_list/')
|
||||
|
||||
|
||||
|
@ -458,32 +441,97 @@ def user_del_ajax(request):
|
|||
if request.session.get('role_id', '') == 1:
|
||||
if not validate(request, user=user_ids):
|
||||
return "error"
|
||||
|
||||
for user_id in user_ids:
|
||||
user = User.objects.filter(id=user_id)
|
||||
if user and user[0].username != 'admin':
|
||||
user = user[0]
|
||||
user = get_object(User, id=user_id)
|
||||
if user and user.username != 'admin':
|
||||
user.delete()
|
||||
server_del_user(user.username)
|
||||
if LDAP_ENABLE:
|
||||
ldap_del_user(user.username)
|
||||
|
||||
return HttpResponse('删除成功')
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
def send_mail_retry(request):
|
||||
user_uuid = request.GET.get('uuid', '1')
|
||||
user = get_object(User, uuid=user_uuid)
|
||||
msg = u"""
|
||||
跳板机地址: %s
|
||||
用户名:%s
|
||||
重设密码:%s/juser/forget_password/
|
||||
请登录web重新生成key
|
||||
""" % (URL, user.username, URL)
|
||||
|
||||
try:
|
||||
send_mail(u'邮件重发', msg, MAIL_FROM, [user.email], fail_silently=False)
|
||||
except IndexError:
|
||||
return Http404
|
||||
return HttpResponse('发送成功')
|
||||
|
||||
|
||||
def forget_password(request):
|
||||
if request.method == 'POST':
|
||||
email = request.POST.get('email', '')
|
||||
username = request.POST.get('username', '')
|
||||
user = get_object(User, username=username, email=email)
|
||||
if user:
|
||||
timestamp = int(time.time())
|
||||
hash_encode = PyCrypt.md5_crypt(str(user.uuid) + str(timestamp) + KEY)
|
||||
msg = u"""
|
||||
Hi %s, 请点击下面链接重设密码!
|
||||
%s/juser/reset_password/?uuid=%s×tamp=%s&hash=%s
|
||||
""" % (user.name, URL, user.uuid, timestamp, hash_encode)
|
||||
send_mail('忘记跳板机密码', msg, MAIL_FROM, [email], fail_silently=False)
|
||||
msg = u'请登陆邮箱,点击邮件重设密码'
|
||||
return HttpResponse(msg)
|
||||
else:
|
||||
error = u'用户不存在或邮件地址错误'
|
||||
|
||||
return render_to_response('juser/forget_password.html', locals())
|
||||
|
||||
|
||||
def reset_password(request):
|
||||
uuid = request.GET.get('uuid', '')
|
||||
timestamp = request.GET.get('timestamp', '')
|
||||
hash_encode = request.GET.get('hash', '')
|
||||
action = '/juser/reset_password/?uuid=%s×tamp=%s&hash=%s' % (uuid, timestamp, hash_encode)
|
||||
|
||||
if request.method == 'POST':
|
||||
password = request.POST.get('password')
|
||||
password_confirm = request.POST.get('password_confirm')
|
||||
if password != password_confirm:
|
||||
return HttpResponse('密码不匹配')
|
||||
else:
|
||||
user = get_object(User, uuid=uuid)
|
||||
if user:
|
||||
user.password = PyCrypt.md5_crypt(password)
|
||||
user.save()
|
||||
return HttpResponse('密码重设成功')
|
||||
else:
|
||||
return HttpResponse('用户不存在')
|
||||
|
||||
if hash_encode == PyCrypt.md5_crypt(uuid + timestamp + KEY):
|
||||
if int(time.time()) - int(timestamp) > 600:
|
||||
return HttpResponse('链接已超时')
|
||||
else:
|
||||
return render_to_response('juser/reset_password.html', locals())
|
||||
|
||||
return http_error(request, u'错误请求')
|
||||
|
||||
|
||||
@require_role(role='super')
|
||||
def user_edit(request):
|
||||
header_title, path1, path2 = '编辑用户', '用户管理', '用户编辑'
|
||||
header_title, path1, path2 = '编辑用户', '用户管理', '编辑用户'
|
||||
if request.method == 'GET':
|
||||
user_id = request.GET.get('id', '')
|
||||
if not user_id:
|
||||
return HttpResponseRedirect('/')
|
||||
|
||||
user_role = {'SU': u'超级管理员', 'DA': u'部门管理员', 'CU': u'普通用户'}
|
||||
user = User.objects.filter(id=user_id)
|
||||
dept_all = DEPT.objects.all()
|
||||
user_role = {'SU': u'超级管理员', 'DA': u'组管理员', 'CU': u'普通用户'}
|
||||
user = get_object(User, id=user_id)
|
||||
group_all = UserGroup.objects.all()
|
||||
|
||||
if user:
|
||||
user = user[0]
|
||||
groups_str = ' '.join([str(group.id) for group in user.group.all()])
|
||||
|
||||
else:
|
||||
|
|
|
@ -3516,8 +3516,8 @@ body.modal-open {
|
|||
z-index: 100;
|
||||
}
|
||||
.lockscreen.middle-box {
|
||||
width: 200px;
|
||||
margin-left: -100px;
|
||||
width: 400px;
|
||||
margin-left: -200px;
|
||||
margin-top: -190px;
|
||||
}
|
||||
.loginscreen.middle-box {
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<html><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>忘记密码</title>
|
||||
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
|
||||
|
||||
<link href="/static/css/animate.css" rel="stylesheet">
|
||||
<link href="/static/css/style.css" rel="stylesheet">
|
||||
|
||||
<style type="text/css"></style></head>
|
||||
|
||||
<body class="gray-bg">
|
||||
|
||||
<div class="lock-word animated fadeInDown">
|
||||
<span class="first-word">Jumperver</span>
|
||||
</div>
|
||||
<div class="middle-box text-center lockscreen animated fadeInDown">
|
||||
<div>
|
||||
<div class="m-b-md">
|
||||
{# <img alt="image" class="img-circle circle-border" src="https://s3.amazonaws.com/uifaces/faces/twitter/ok/128.jpg">#}
|
||||
{% if error %}
|
||||
<div class="alert alert-warning text-center">{{ error }}</div>
|
||||
{% endif %}
|
||||
{% if msg %}
|
||||
<div class="alert alert-success text-center">{{ msg }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<h3>忘记密码</h3>
|
||||
<p>请输入您原来的信息</p>
|
||||
<form class="m-t" role="form" action="" method="post">
|
||||
<div class="form-group">
|
||||
<input type="text" name='username' class="form-control" placeholder="Username" required="">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" name='email' class="form-control" placeholder="Email" required="">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary block full-width">确定</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mainly scripts -->
|
||||
<script src="/static/js/jquery-2.1.1.js"></script>
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
</body></html>
|
|
@ -0,0 +1,50 @@
|
|||
<html><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>重置{{ name }}</title>
|
||||
|
||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
|
||||
|
||||
<link href="/static/css/animate.css" rel="stylesheet">
|
||||
<link href="/static/css/style.css" rel="stylesheet">
|
||||
|
||||
<style type="text/css"></style></head>
|
||||
|
||||
<body class="gray-bg">
|
||||
|
||||
<div class="lock-word animated fadeInDown">
|
||||
<span class="first-word">Jump</span><span>Server</span>
|
||||
</div>
|
||||
<div class="middle-box text-center lockscreen animated fadeInDown">
|
||||
<div>
|
||||
<div class="m-b-md">
|
||||
{# <img alt="image" class="img-circle circle-border" src="https://s3.amazonaws.com/uifaces/faces/twitter/ok/128.jpg">#}
|
||||
{% if error %}
|
||||
<div class="alert alert-warning text-center">{{ error }}</div>
|
||||
{% endif %}
|
||||
{% if msg %}
|
||||
<div class="alert alert-success text-center">{{ msg }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<h3>请输入新密码</h3>
|
||||
<form class="m-t" role="form" action="{{ action }}" method="post">
|
||||
<div class="form-group">
|
||||
<input type="password" name='password' class="form-control" placeholder="New Password" required="">
|
||||
<input type="password" name='password_confirm' class="form-control" placeholder="Password Confirm" required="">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary block full-width">确定</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mainly scripts -->
|
||||
<script src="/static/js/jquery-2.1.1.js"></script>
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
</body></html>
|
|
@ -96,7 +96,7 @@
|
|||
<div class="form-group"><label class="col-sm-2 control-label">额外</label>
|
||||
<div class="col-sm-2">
|
||||
<div class="checkbox i-checks">
|
||||
<label><input type="checkbox" value="0" name="extra" checked>禁用 </label>
|
||||
<label><input type="checkbox" value="0" name="extra" >禁用 </label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
|
@ -106,7 +106,7 @@
|
|||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="checkbox i-checks">
|
||||
<label><input type="checkbox" value="1" name="extra">发送邮件 </label>
|
||||
<label><input type="checkbox" value="2" name="extra">发送邮件 </label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -17,12 +17,6 @@
|
|||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#">未启用 1</a>
|
||||
</li>
|
||||
<li><a href="#">未启用 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
|
@ -71,23 +65,6 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
{% ifequal session_role_id 2 %}
|
||||
<div class="form-group">
|
||||
<label for="dept_id" class="col-lg-2 control-label">部门<span class="red-fonts">*</span></label>
|
||||
<div class="col-sm-8">
|
||||
<select id="dept_id" name="dept_id" class="form-control m-b">
|
||||
{% for dept in dept_all %}
|
||||
{% ifequal user.dept.id dept.id %}
|
||||
<option selected value="{{ dept.id }}">{{ dept.name }}</option>
|
||||
{% else %}
|
||||
<option value="{{ dept.id }}">{{ dept.name }}</option>
|
||||
{% endifequal %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
{% endifequal %}
|
||||
<div class="form-group">
|
||||
<label for="groups" class="col-lg-2 control-label">小组</label>
|
||||
<div class="col-sm-8">
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<input type="text" class="form-control input-sm" id="search_input" name="keyword" placeholder="Search">
|
||||
<div class="input-group-btn">
|
||||
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
|
||||
Search
|
||||
- 搜索 -
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -52,7 +52,6 @@
|
|||
</th>
|
||||
<th class="text-center">用户名</th>
|
||||
<th class="text-center">姓名</th>
|
||||
<th class="text-center">部门</th>
|
||||
<th class="text-center">小组</th>
|
||||
<th class="text-center">角色</th>
|
||||
<th class="text-center">激活</th>
|
||||
|
@ -68,20 +67,15 @@
|
|||
</td>
|
||||
<td class="text-center"> {{ user.username }} </td>
|
||||
<td class="text-center"> {{ user.name }} </td>
|
||||
<td class="text-center"> {{ user.dept.name }} </td>
|
||||
<td class="text-center" title="{% for user_group in user.group.all %} {{ user_group.name }} {% endfor %}"> {{ user.group.all | group_str2 }} </td>
|
||||
<td class="text-center"> {{ user.id | get_role }}</td>
|
||||
<td class="text-center">{{ user.is_active|bool2str }}</td>
|
||||
<td class="text-center"><a href="/juser/down_key/?id={{ user.id }}">下载</a></td>
|
||||
<td class="text-center">
|
||||
<a href="../user_detail/?id={{ user.id }}" class="btn btn-xs btn-primary">详情</a>
|
||||
{% ifequal session_role_id 2 %}
|
||||
<a href="../user_edit/?id={{ user.id }}" class="btn btn-xs btn-info">编辑</a>
|
||||
<a value="{{ user.uuid }}" class="btn btn-xs btn-warning email">Email</a>
|
||||
<a href="../user_del/?id={{ user.id }}" class="btn btn-xs btn-danger {% if user.username == 'admin' %} disabled {% endif %}">删除</a>
|
||||
{% else %}
|
||||
<a href="../user_edit/?id={{ user.id }}" class="btn btn-xs btn-info {% if user.role != 'CU' %} disabled {% endif %}">编辑</a>
|
||||
<a href="../user_del/?id={{ user.id }}" class="btn btn-xs btn-danger {% if user.role != 'CU' %} disabled {% endif %}">删除</a>
|
||||
{% endifequal %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -101,6 +95,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% block self_head_css_js %}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$(".iframe").on('click', function() {
|
||||
|
@ -117,23 +113,30 @@
|
|||
iframe: {src: url}
|
||||
})
|
||||
});
|
||||
|
||||
var check_array = [];
|
||||
$('#del_btn').click(function(){
|
||||
if (confirm("确定删除")) {
|
||||
$(".gradeX input:checked").each(function() {check_array.push($(this).attr("value")) });
|
||||
$(".gradeX input:checked").closest("tr").remove();
|
||||
$.post("/juser/user_del_ajax/",
|
||||
{ids: check_array.join(",")},
|
||||
function(data){
|
||||
$(".gradeX input:checked").closest("tr").remove();
|
||||
window.open("/juser/user_list/", "_self");
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$('.email').click(function(){
|
||||
$.get('/juser/send_mail_retry/?uuid=' + $(this).attr('value'),
|
||||
{},
|
||||
function(data){
|
||||
alert(data)
|
||||
}
|
||||
)
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
|
@ -31,7 +31,7 @@
|
|||
</div>
|
||||
<button type="submit" class="btn btn-primary block full-width m-b">Login</button>
|
||||
|
||||
<a href="#"><small>Forgot password? Contact Administrator. </small></a>
|
||||
<a href="/juser/forget_password/"><small>Forgot password? </small></a>
|
||||
</form>
|
||||
<p class="m-t"> <small><b>Copyright</b> Jumpserver.org Organization © 2014-2015</small> </p>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue