mirror of https://github.com/jumpserver/jumpserver
删除部门前
parent
c1facb939e
commit
913f93b91f
25
connect.py
25
connect.py
|
@ -17,8 +17,8 @@ from multiprocessing import Pool
|
||||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings'
|
os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings'
|
||||||
if django.get_version() != '1.6':
|
if django.get_version() != '1.6':
|
||||||
django.setup()
|
django.setup()
|
||||||
from jumpserver.api import BASE_DIR, ServerError, User, UserGroup, Asset, Jtty, get_object
|
from jumpserver.api import ServerError, User, Asset, Jtty, get_object
|
||||||
from jumpserver.api import CRYPTOR, logger, is_dir
|
from jumpserver.api import logger
|
||||||
from jumpserver.api import BisGroup as AssetGroup
|
from jumpserver.api import BisGroup as AssetGroup
|
||||||
|
|
||||||
login_user = get_object(User, username=getpass.getuser())
|
login_user = get_object(User, username=getpass.getuser())
|
||||||
|
@ -27,7 +27,7 @@ login_user = get_object(User, username=getpass.getuser())
|
||||||
def color_print(msg, color='red', exits=False):
|
def color_print(msg, color='red', exits=False):
|
||||||
"""
|
"""
|
||||||
Print colorful string.
|
Print colorful string.
|
||||||
颜色打印
|
颜色打印字符或者退出
|
||||||
"""
|
"""
|
||||||
color_msg = {'blue': '\033[1;36m%s\033[0m',
|
color_msg = {'blue': '\033[1;36m%s\033[0m',
|
||||||
'green': '\033[1;32m%s\033[0m',
|
'green': '\033[1;32m%s\033[0m',
|
||||||
|
@ -40,7 +40,10 @@ def color_print(msg, color='red', exits=False):
|
||||||
|
|
||||||
|
|
||||||
def verify_connect(user, option):
|
def verify_connect(user, option):
|
||||||
"""鉴定用户是否有该主机权限 或 匹配到的ip是否唯一"""
|
"""
|
||||||
|
Check user was permed or not . Check ip is unique or not.
|
||||||
|
鉴定用户是否有该主机权限 或 匹配到的ip是否唯一
|
||||||
|
"""
|
||||||
ip_matched = []
|
ip_matched = []
|
||||||
try:
|
try:
|
||||||
assets_info = login_user.get_asset_info()
|
assets_info = login_user.get_asset_info()
|
||||||
|
@ -60,7 +63,7 @@ def verify_connect(user, option):
|
||||||
logger.debug('%s matched input %s: %s' % (login_user.username, option, ip_matched))
|
logger.debug('%s matched input %s: %s' % (login_user.username, option, ip_matched))
|
||||||
ip_matched = list(set(ip_matched))
|
ip_matched = list(set(ip_matched))
|
||||||
|
|
||||||
if len(ip_matched) > 1:
|
if len(ip_matched) > 1: # 如果匹配ip不唯一
|
||||||
ip_comment = {}
|
ip_comment = {}
|
||||||
for ip in ip_matched:
|
for ip in ip_matched:
|
||||||
ip_comment[ip] = assets_info[ip][2]
|
ip_comment[ip] = assets_info[ip][2]
|
||||||
|
@ -71,15 +74,19 @@ def verify_connect(user, option):
|
||||||
else:
|
else:
|
||||||
print '%-15s' % ip
|
print '%-15s' % ip
|
||||||
print ''
|
print ''
|
||||||
elif len(ip_matched) < 1:
|
elif len(ip_matched) < 1: # 如果没匹配到
|
||||||
color_print('没有该主机,或者您没有该主机的权限 No Permission or No host.', 'red')
|
color_print('没有该主机,或者您没有该主机的权限 No Permission or No host.', 'red')
|
||||||
else:
|
else: # 恰好是1个
|
||||||
asset = get_object(Asset, ip=ip_matched[0])
|
asset = get_object(Asset, ip=ip_matched[0])
|
||||||
jtty = Jtty(user, asset)
|
jtty = Jtty(user, asset)
|
||||||
jtty.connect()
|
jtty.connect()
|
||||||
|
|
||||||
|
|
||||||
def print_prompt():
|
def print_prompt():
|
||||||
|
"""
|
||||||
|
Print prompt
|
||||||
|
打印提示导航
|
||||||
|
"""
|
||||||
msg = """\033[1;32m### Welcome Use JumpServer To Login. ### \033[0m
|
msg = """\033[1;32m### Welcome Use JumpServer To Login. ### \033[0m
|
||||||
1) Type \033[32mIP or Part IP, Host Alias or Comments \033[0m To Login.
|
1) Type \033[32mIP or Part IP, Host Alias or Comments \033[0m To Login.
|
||||||
2) Type \033[32mP/p\033[0m To Print The Servers You Available.
|
2) Type \033[32mP/p\033[0m To Print The Servers You Available.
|
||||||
|
@ -162,6 +169,10 @@ def print_prompt():
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
"""
|
||||||
|
he he
|
||||||
|
主程序
|
||||||
|
"""
|
||||||
if not login_user: # 判断用户是否存在
|
if not login_user: # 判断用户是否存在
|
||||||
color_print(u'没有该用户,或许你是以root运行的 No that user.', exits=True)
|
color_print(u'没有该用户,或许你是以root运行的 No that user.', exits=True)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import os, sys, time
|
||||||
from ConfigParser import ConfigParser
|
from ConfigParser import ConfigParser
|
||||||
import getpass
|
import getpass
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
|
import crypt
|
||||||
from binascii import b2a_hex, a2b_hex
|
from binascii import b2a_hex, a2b_hex
|
||||||
import ldap
|
import ldap
|
||||||
from ldap import modlist
|
from ldap import modlist
|
||||||
|
@ -13,15 +14,18 @@ import random
|
||||||
import subprocess
|
import subprocess
|
||||||
import paramiko
|
import paramiko
|
||||||
import struct, fcntl, signal,socket, select, fnmatch
|
import struct, fcntl, signal,socket, select, fnmatch
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
from django.core.paginator import Paginator, EmptyPage, InvalidPage
|
from django.core.paginator import Paginator, EmptyPage, InvalidPage
|
||||||
from django.http import HttpResponse, Http404
|
from django.http import HttpResponse, Http404
|
||||||
from django.shortcuts import render_to_response
|
from django.template import RequestContext
|
||||||
from juser.models import User, UserGroup, DEPT
|
from juser.models import User, UserGroup, DEPT
|
||||||
from jasset.models import Asset, BisGroup, IDC
|
from jasset.models import Asset, BisGroup, IDC
|
||||||
from jlog.models import Log
|
from jlog.models import Log
|
||||||
from jasset.models import AssetAlias
|
from jasset.models import AssetAlias
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.shortcuts import render_to_response
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
@ -50,20 +54,29 @@ SEND_PORT = CONF.get('base', 'port')
|
||||||
MAIL_FROM = CONF.get('mail', 'email_host_user')
|
MAIL_FROM = CONF.get('mail', 'email_host_user')
|
||||||
log_dir = os.path.join(BASE_DIR, 'logs')
|
log_dir = os.path.join(BASE_DIR, 'logs')
|
||||||
|
|
||||||
|
|
||||||
def set_log(level):
|
def set_log(level):
|
||||||
|
"""
|
||||||
|
return a log file object
|
||||||
|
根据提示设置log打印
|
||||||
|
"""
|
||||||
log_level_total = {'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARN, 'error': logging.ERROR,
|
log_level_total = {'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARN, 'error': logging.ERROR,
|
||||||
'critical': logging.CRITICAL}
|
'critical': logging.CRITICAL}
|
||||||
logger = logging.getLogger('jumpserver')
|
logger_f = logging.getLogger('jumpserver')
|
||||||
logger.setLevel(logging.DEBUG)
|
logger_f.setLevel(logging.DEBUG)
|
||||||
fh = logging.FileHandler(JLOG_FILE)
|
fh = logging.FileHandler(JLOG_FILE)
|
||||||
fh.setLevel(log_level_total.get(level, logging.DEBUG))
|
fh.setLevel(log_level_total.get(level, logging.DEBUG))
|
||||||
formatter = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s')
|
formatter = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s')
|
||||||
fh.setFormatter(formatter)
|
fh.setFormatter(formatter)
|
||||||
logger.addHandler(fh)
|
logger_f.addHandler(fh)
|
||||||
return logger
|
return logger_f
|
||||||
|
|
||||||
|
|
||||||
class LDAPMgmt():
|
class LDAPMgmt():
|
||||||
|
"""
|
||||||
|
LDAP class for add, select, del, update
|
||||||
|
LDAP 管理类,增删改查
|
||||||
|
"""
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
host_url,
|
host_url,
|
||||||
base_dn,
|
base_dn,
|
||||||
|
@ -77,6 +90,10 @@ class LDAPMgmt():
|
||||||
self.conn.simple_bind_s(root_cn, root_pw)
|
self.conn.simple_bind_s(root_cn, root_pw)
|
||||||
|
|
||||||
def list(self, filter, scope=ldap.SCOPE_SUBTREE, attr=None):
|
def list(self, filter, scope=ldap.SCOPE_SUBTREE, attr=None):
|
||||||
|
"""
|
||||||
|
query
|
||||||
|
查询
|
||||||
|
"""
|
||||||
result = {}
|
result = {}
|
||||||
try:
|
try:
|
||||||
ldap_result = self.conn.search_s(self.ldap_base_dn, scope, filter, attr)
|
ldap_result = self.conn.search_s(self.ldap_base_dn, scope, filter, attr)
|
||||||
|
@ -90,6 +107,10 @@ class LDAPMgmt():
|
||||||
print e
|
print e
|
||||||
|
|
||||||
def add(self, dn, attrs):
|
def add(self, dn, attrs):
|
||||||
|
"""
|
||||||
|
add
|
||||||
|
添加
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
ldif = modlist.addModlist(attrs)
|
ldif = modlist.addModlist(attrs)
|
||||||
self.conn.add_s(dn, ldif)
|
self.conn.add_s(dn, ldif)
|
||||||
|
@ -97,6 +118,10 @@ class LDAPMgmt():
|
||||||
print e
|
print e
|
||||||
|
|
||||||
def modify(self, dn, attrs):
|
def modify(self, dn, attrs):
|
||||||
|
"""
|
||||||
|
modify
|
||||||
|
更改
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
attr_s = []
|
attr_s = []
|
||||||
for k, v in attrs.items():
|
for k, v in attrs.items():
|
||||||
|
@ -106,6 +131,10 @@ class LDAPMgmt():
|
||||||
print e
|
print e
|
||||||
|
|
||||||
def delete(self, dn):
|
def delete(self, dn):
|
||||||
|
"""
|
||||||
|
delete
|
||||||
|
删除
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
self.conn.delete_s(dn)
|
self.conn.delete_s(dn)
|
||||||
except ldap.LDAPError, e:
|
except ldap.LDAPError, e:
|
||||||
|
@ -113,6 +142,10 @@ class LDAPMgmt():
|
||||||
|
|
||||||
|
|
||||||
def page_list_return(total, current=1):
|
def page_list_return(total, current=1):
|
||||||
|
"""
|
||||||
|
page
|
||||||
|
分页,返回本次分页的最小页数到最大页数列表
|
||||||
|
"""
|
||||||
min_page = current - 2 if current - 4 > 0 else 1
|
min_page = current - 2 if current - 4 > 0 else 1
|
||||||
max_page = min_page + 4 if min_page + 4 < total else total
|
max_page = min_page + 4 if min_page + 4 < total else total
|
||||||
|
|
||||||
|
@ -120,7 +153,10 @@ def page_list_return(total, current=1):
|
||||||
|
|
||||||
|
|
||||||
def pages(posts, r):
|
def pages(posts, r):
|
||||||
"""分页公用函数"""
|
"""
|
||||||
|
page public function , return page's object tuple
|
||||||
|
分页公用函数,返回分页的对象元组
|
||||||
|
"""
|
||||||
contact_list = posts
|
contact_list = posts
|
||||||
p = paginator = Paginator(contact_list, 10)
|
p = paginator = Paginator(contact_list, 10)
|
||||||
try:
|
try:
|
||||||
|
@ -148,6 +184,10 @@ def pages(posts, r):
|
||||||
|
|
||||||
|
|
||||||
class Jtty(object):
|
class Jtty(object):
|
||||||
|
"""
|
||||||
|
A virtual tty class
|
||||||
|
一个虚拟终端类,实现连接ssh和记录日志
|
||||||
|
"""
|
||||||
def __init__(self, user, asset):
|
def __init__(self, user, asset):
|
||||||
self.chan = None
|
self.chan = None
|
||||||
self.username = user.username
|
self.username = user.username
|
||||||
|
@ -260,7 +300,10 @@ class Jtty(object):
|
||||||
log.save()
|
log.save()
|
||||||
|
|
||||||
def get_connect_item(self):
|
def get_connect_item(self):
|
||||||
"""获取连接需要的参数,也就是服务ip, 端口, 用户账号和密码"""
|
"""
|
||||||
|
get args for connect: ip, port, username, passwd
|
||||||
|
获取连接需要的参数,也就是服务ip, 端口, 用户账号和密码
|
||||||
|
"""
|
||||||
if not self.asset.is_active:
|
if not self.asset.is_active:
|
||||||
raise ServerError('该主机被禁用 Host %s is not active.' % self.ip)
|
raise ServerError('该主机被禁用 Host %s is not active.' % self.ip)
|
||||||
|
|
||||||
|
@ -283,15 +326,13 @@ class Jtty(object):
|
||||||
else:
|
else:
|
||||||
raise ServerError('不支持的服务器登录方式 Login type is not in ["L", "M"]')
|
raise ServerError('不支持的服务器登录方式 Login type is not in ["L", "M"]')
|
||||||
|
|
||||||
def connect(self):
|
def get_connection(self):
|
||||||
"""
|
"""
|
||||||
Connect server.
|
Get the ssh connection for reuse
|
||||||
连接服务器
|
获取连接套接字
|
||||||
"""
|
"""
|
||||||
username, password, ip, port = self.get_connect_item()
|
username, password, ip, port = self.get_connect_item()
|
||||||
logger.debug("username: %s, password: %s, ip: %s, port: %s" % (username, password, ip, port))
|
logger.debug("username: %s, password: %s, ip: %s, port: %s" % (username, password, ip, port))
|
||||||
ps1 = "PS1='[\u@%s \W]\$ '\n" % self.ip
|
|
||||||
login_msg = "clear;echo -e '\\033[32mLogin %s done. Enjoy it.\\033[0m'\n" % ip
|
|
||||||
|
|
||||||
# 发起ssh连接请求 Make a ssh connection
|
# 发起ssh连接请求 Make a ssh connection
|
||||||
ssh = paramiko.SSHClient()
|
ssh = paramiko.SSHClient()
|
||||||
|
@ -303,6 +344,19 @@ class Jtty(object):
|
||||||
raise ServerError('认证错误 Authentication Error.')
|
raise ServerError('认证错误 Authentication Error.')
|
||||||
except socket.error:
|
except socket.error:
|
||||||
raise ServerError('端口可能不对 Connect SSH Socket Port Error, Please Correct it.')
|
raise ServerError('端口可能不对 Connect SSH Socket Port Error, Please Correct it.')
|
||||||
|
else:
|
||||||
|
return ssh
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
"""
|
||||||
|
Connect server.
|
||||||
|
连接服务器
|
||||||
|
"""
|
||||||
|
ps1 = "PS1='[\u@%s \W]\$ '\n" % self.ip
|
||||||
|
login_msg = "clear;echo -e '\\033[32mLogin %s done. Enjoy it.\\033[0m'\n" % self.asset.ip
|
||||||
|
|
||||||
|
# 发起ssh连接请求 Make a ssh connection
|
||||||
|
ssh = self.get_connection()
|
||||||
|
|
||||||
# 获取连接的隧道并设置窗口大小 Make a channel and set windows size
|
# 获取连接的隧道并设置窗口大小 Make a channel and set windows size
|
||||||
global channel
|
global channel
|
||||||
|
@ -324,11 +378,18 @@ class Jtty(object):
|
||||||
channel.close()
|
channel.close()
|
||||||
ssh.close()
|
ssh.close()
|
||||||
|
|
||||||
|
def execute(self, cmd):
|
||||||
|
"""
|
||||||
|
execute cmd on the asset
|
||||||
|
执行命令
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PyCrypt(object):
|
class PyCrypt(object):
|
||||||
"""
|
"""
|
||||||
This class used to encrypt and decrypt password.
|
This class used to encrypt and decrypt password.
|
||||||
对称加密库
|
加密类
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, key):
|
def __init__(self, key):
|
||||||
|
@ -353,12 +414,24 @@ class PyCrypt(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def md5_crypt(string):
|
def md5_crypt(string):
|
||||||
|
"""
|
||||||
|
md5 encrypt method
|
||||||
|
md5非对称加密方法
|
||||||
|
"""
|
||||||
return hashlib.new("md5", string).hexdigest()
|
return hashlib.new("md5", string).hexdigest()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def gen_sha512(salt, password):
|
||||||
|
"""
|
||||||
|
generate sha512 format password
|
||||||
|
生成sha512加密密码
|
||||||
|
"""
|
||||||
|
return crypt.crypt(password, '$6$%s$' % salt)
|
||||||
|
|
||||||
def encrypt(self, passwd=None):
|
def encrypt(self, passwd=None):
|
||||||
"""
|
"""
|
||||||
encrypt gen password
|
encrypt gen password
|
||||||
加密生成密码
|
对称加密之加密生成密码
|
||||||
"""
|
"""
|
||||||
if not passwd:
|
if not passwd:
|
||||||
passwd = self.random_pass()
|
passwd = self.random_pass()
|
||||||
|
@ -376,6 +449,10 @@ class PyCrypt(object):
|
||||||
return b2a_hex(cipher_text)
|
return b2a_hex(cipher_text)
|
||||||
|
|
||||||
def decrypt(self, text):
|
def decrypt(self, text):
|
||||||
|
"""
|
||||||
|
decrypt pass base the same key
|
||||||
|
对称加密之解密,同一个加密随机数
|
||||||
|
"""
|
||||||
cryptor = AES.new(self.key, self.mode, b'8122ca7d906ad5e1')
|
cryptor = AES.new(self.key, self.mode, b'8122ca7d906ad5e1')
|
||||||
try:
|
try:
|
||||||
plain_text = cryptor.decrypt(a2b_hex(text))
|
plain_text = cryptor.decrypt(a2b_hex(text))
|
||||||
|
@ -386,10 +463,18 @@ class PyCrypt(object):
|
||||||
|
|
||||||
|
|
||||||
class ServerError(Exception):
|
class ServerError(Exception):
|
||||||
|
"""
|
||||||
|
self define exception
|
||||||
|
自定义异常
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def get_object(model, **kwargs):
|
def get_object(model, **kwargs):
|
||||||
|
"""
|
||||||
|
use this function for query
|
||||||
|
使用改封装函数查询数据库
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
the_object = model.objects.get(**kwargs)
|
the_object = model.objects.get(**kwargs)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
|
@ -399,7 +484,8 @@ def get_object(model, **kwargs):
|
||||||
|
|
||||||
def require_role(role='user'):
|
def require_role(role='user'):
|
||||||
"""
|
"""
|
||||||
要求用户是某种角色 ["super", "admin", "user"]
|
decorator for require user role in ["super", "admin", "user"]
|
||||||
|
要求用户是某种角色 ["super", "admin", "user"]的装饰器
|
||||||
"""
|
"""
|
||||||
def _deco(func):
|
def _deco(func):
|
||||||
def __deco(request, *args, **kwargs):
|
def __deco(request, *args, **kwargs):
|
||||||
|
@ -413,27 +499,30 @@ def require_role(role='user'):
|
||||||
if request.session.get('role_id', 0) != 2:
|
if request.session.get('role_id', 0) != 2:
|
||||||
return HttpResponseRedirect('/')
|
return HttpResponseRedirect('/')
|
||||||
return func(request, *args, **kwargs)
|
return func(request, *args, **kwargs)
|
||||||
return __deco()
|
return __deco
|
||||||
return _deco
|
return _deco
|
||||||
|
|
||||||
|
|
||||||
def is_role_request(request, role='user'):
|
def is_role_request(request, role='user'):
|
||||||
"""
|
"""
|
||||||
:param request: 请求
|
require this request of user is right
|
||||||
:param role: 角色
|
|
||||||
:return: bool
|
|
||||||
要求请求角色正确
|
要求请求角色正确
|
||||||
"""
|
"""
|
||||||
role_all = {'user': 0, 'admin': 1, 'super': 2}
|
role_all = {'user': 0, 'admin': 1, 'super': 2}
|
||||||
if request.session.get('role_id') == role_all.get(role, '0'):
|
if request.session.get('role_id') == role_all.get(role, 0):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@require_role
|
|
||||||
def get_session_user_dept(request):
|
def get_session_user_dept(request):
|
||||||
|
"""
|
||||||
|
get department of the user in session
|
||||||
|
获取session中用户的部门
|
||||||
|
"""
|
||||||
user_id = request.session.get('user_id', 0)
|
user_id = request.session.get('user_id', 0)
|
||||||
|
print '#' * 20
|
||||||
|
print user_id
|
||||||
user = User.objects.filter(id=user_id)
|
user = User.objects.filter(id=user_id)
|
||||||
if user:
|
if user:
|
||||||
user = user[0]
|
user = user[0]
|
||||||
|
@ -443,6 +532,10 @@ def get_session_user_dept(request):
|
||||||
|
|
||||||
@require_role
|
@require_role
|
||||||
def get_session_user_info(request):
|
def get_session_user_info(request):
|
||||||
|
"""
|
||||||
|
get the user info of the user in session, for example id, username etc.
|
||||||
|
获取用户的信息
|
||||||
|
"""
|
||||||
user_id = request.session.get('user_id', 0)
|
user_id = request.session.get('user_id', 0)
|
||||||
user = User.objects.filter(id=user_id)
|
user = User.objects.filter(id=user_id)
|
||||||
if user:
|
if user:
|
||||||
|
@ -452,6 +545,10 @@ def get_session_user_info(request):
|
||||||
|
|
||||||
|
|
||||||
def get_user_dept(request):
|
def get_user_dept(request):
|
||||||
|
"""
|
||||||
|
get the user dept id
|
||||||
|
获取用户的部门id
|
||||||
|
"""
|
||||||
user_id = request.session.get('user_id')
|
user_id = request.session.get('user_id')
|
||||||
if user_id:
|
if user_id:
|
||||||
user_dept = User.objects.get(id=user_id).dept
|
user_dept = User.objects.get(id=user_id).dept
|
||||||
|
@ -466,16 +563,24 @@ def api_user(request):
|
||||||
return HttpResponse(json_data)
|
return HttpResponse(json_data)
|
||||||
|
|
||||||
|
|
||||||
# def view_splitter(request, su=None, adm=None):
|
def view_splitter(request, su=None, adm=None):
|
||||||
# if is_super_user(request):
|
"""
|
||||||
# return su(request)
|
for different user use different view
|
||||||
# elif is_group_admin(request):
|
视图分页器
|
||||||
# return adm(request)
|
"""
|
||||||
# else:
|
if is_role_request(request, 'super'):
|
||||||
# return HttpResponseRedirect('/login/')
|
return su(request)
|
||||||
|
elif is_role_request(request, 'admin'):
|
||||||
|
return adm(request)
|
||||||
|
else:
|
||||||
|
return HttpResponseRedirect('/login/')
|
||||||
|
|
||||||
|
|
||||||
def validate(request, user_group=None, user=None, asset_group=None, asset=None, edept=None):
|
def validate(request, user_group=None, user=None, asset_group=None, asset=None, edept=None):
|
||||||
|
"""
|
||||||
|
validate the user request
|
||||||
|
判定用户请求是否合法
|
||||||
|
"""
|
||||||
dept = get_session_user_dept(request)[1]
|
dept = get_session_user_dept(request)[1]
|
||||||
if edept:
|
if edept:
|
||||||
if dept.id != int(edept[0]):
|
if dept.id != int(edept[0]):
|
||||||
|
@ -565,12 +670,18 @@ def verify(request, user_group=None, user=None, asset_group=None, asset=None, ed
|
||||||
|
|
||||||
|
|
||||||
def bash(cmd):
|
def bash(cmd):
|
||||||
"""执行bash命令"""
|
"""
|
||||||
|
run a bash shell command
|
||||||
|
执行bash命令
|
||||||
|
"""
|
||||||
return subprocess.call(cmd, shell=True)
|
return subprocess.call(cmd, shell=True)
|
||||||
|
|
||||||
|
|
||||||
def is_dir(dir_name, username='root', mode=0755):
|
def is_dir(dir_name, username='root', mode=0755):
|
||||||
"""目录存在,如果不存在就建立,并且权限正确"""
|
"""
|
||||||
|
insure the dir exist and mode ok
|
||||||
|
目录存在,如果不存在就建立,并且权限正确
|
||||||
|
"""
|
||||||
if not os.path.isdir(dir_name):
|
if not os.path.isdir(dir_name):
|
||||||
os.makedirs(dir_name)
|
os.makedirs(dir_name)
|
||||||
bash("chown %s:%s '%s'" % (username, username, dir_name))
|
bash("chown %s:%s '%s'" % (username, username, dir_name))
|
||||||
|
|
|
@ -14,10 +14,12 @@ def name_proc(request):
|
||||||
host_active_num = Asset.objects.filter(is_active=True).count()
|
host_active_num = Asset.objects.filter(is_active=True).count()
|
||||||
else:
|
else:
|
||||||
user, dept = get_session_user_dept(request)
|
user, dept = get_session_user_dept(request)
|
||||||
|
print user, dept
|
||||||
user_total_num = dept.user_set.all().count()
|
user_total_num = dept.user_set.all().count()
|
||||||
user_active_num = dept.user_set.filter(is_active=True).count()
|
user_active_num = dept.user_set.filter(is_active=True).count()
|
||||||
host_total_num = dept.asset_set.all().count()
|
host_total_num = dept.asset_set.all().count()
|
||||||
host_active_num = dept.asset_set.all().filter(is_active=True).count()
|
host_active_num = dept.asset_set.all().filter(is_active=True).count()
|
||||||
|
pass
|
||||||
|
|
||||||
username = User.objects.get(id=user_id).name
|
username = User.objects.get(id=user_id).name
|
||||||
apply_info = Apply.objects.filter(admin=username, status=0, read=0)
|
apply_info = Apply.objects.filter(admin=username, status=0, read=0)
|
||||||
|
|
|
@ -56,9 +56,9 @@ INSTALLED_APPS = (
|
||||||
'django.contrib.humanize',
|
'django.contrib.humanize',
|
||||||
'jumpserver',
|
'jumpserver',
|
||||||
'juser',
|
'juser',
|
||||||
'jasset',
|
# 'jasset',
|
||||||
'jperm',
|
# 'jperm',
|
||||||
'jlog',
|
# 'jlog',
|
||||||
)
|
)
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = (
|
MIDDLEWARE_CLASSES = (
|
||||||
|
|
|
@ -14,9 +14,9 @@ urlpatterns = patterns('',
|
||||||
(r'^file/download/$', 'jumpserver.views.download'),
|
(r'^file/download/$', 'jumpserver.views.download'),
|
||||||
(r'^error/$', 'jumpserver.views.httperror'),
|
(r'^error/$', 'jumpserver.views.httperror'),
|
||||||
(r'^juser/', include('juser.urls')),
|
(r'^juser/', include('juser.urls')),
|
||||||
(r'^jasset/', include('jasset.urls')),
|
# (r'^jasset/', include('jasset.urls')),
|
||||||
(r'^jlog/', include('jlog.urls')),
|
# (r'^jlog/', include('jlog.urls')),
|
||||||
(r'^jperm/', include('jperm.urls')),
|
# (r'^jperm/', include('jperm.urls')),
|
||||||
(r'^node_auth/', 'jumpserver.views.node_auth'),
|
(r'^node_auth/', 'jumpserver.views.node_auth'),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
|
import uuid
|
||||||
|
import urllib
|
||||||
|
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
from django.template import RequestContext
|
from django.template import RequestContext
|
||||||
from django.http import HttpResponseNotFound
|
from django.http import HttpResponseNotFound
|
||||||
|
from django.http import HttpResponse
|
||||||
from jperm.models import Apply
|
from jperm.models import Apply
|
||||||
import paramiko
|
import paramiko
|
||||||
from jumpserver.api import *
|
from jumpserver.api import *
|
||||||
import uuid
|
|
||||||
import urllib
|
|
||||||
|
|
||||||
|
|
||||||
def getDaysByNum(num):
|
def getDaysByNum(num):
|
||||||
|
@ -44,7 +47,7 @@ def get_data(data, items, option):
|
||||||
return dic
|
return dic
|
||||||
|
|
||||||
|
|
||||||
@require_login
|
@require_role(role='user')
|
||||||
def index_cu(request):
|
def index_cu(request):
|
||||||
user_id = request.session.get('user_id')
|
user_id = request.session.get('user_id')
|
||||||
user = User.objects.filter(id=user_id)
|
user = User.objects.filter(id=user_id)
|
||||||
|
@ -53,7 +56,7 @@ def index_cu(request):
|
||||||
login_types = {'L': 'LDAP', 'M': 'MAP'}
|
login_types = {'L': 'LDAP', 'M': 'MAP'}
|
||||||
user_id = request.session.get('user_id')
|
user_id = request.session.get('user_id')
|
||||||
username = User.objects.get(id=user_id).username
|
username = User.objects.get(id=user_id).username
|
||||||
posts = user_perm_asset_api(username)
|
posts = user.get_asset()
|
||||||
host_count = len(posts)
|
host_count = len(posts)
|
||||||
new_posts = []
|
new_posts = []
|
||||||
post_five = []
|
post_five = []
|
||||||
|
@ -68,16 +71,16 @@ def index_cu(request):
|
||||||
return render_to_response('index_cu.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('index_cu.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_login
|
@require_role(role='user')
|
||||||
def index(request):
|
def index(request):
|
||||||
li_date, li_str = getDaysByNum(7)
|
li_date, li_str = getDaysByNum(7)
|
||||||
today = datetime.datetime.now().day
|
today = datetime.datetime.now().day
|
||||||
from_week = datetime.datetime.now() - datetime.timedelta(days=7)
|
from_week = datetime.datetime.now() - datetime.timedelta(days=7)
|
||||||
|
|
||||||
if is_common_user(request):
|
if is_role_request(request, 'user'):
|
||||||
return index_cu(request)
|
return index_cu(request)
|
||||||
|
|
||||||
elif is_super_user(request):
|
elif is_role_request(request, 'super'):
|
||||||
users = User.objects.all()
|
users = User.objects.all()
|
||||||
hosts = Asset.objects.all()
|
hosts = Asset.objects.all()
|
||||||
online = Log.objects.filter(is_finished=0)
|
online = Log.objects.filter(is_finished=0)
|
||||||
|
@ -87,7 +90,7 @@ def index(request):
|
||||||
active_hosts = Asset.objects.filter(is_active=1)
|
active_hosts = Asset.objects.filter(is_active=1)
|
||||||
week_data = Log.objects.filter(start_time__range=[from_week, datetime.datetime.now()])
|
week_data = Log.objects.filter(start_time__range=[from_week, datetime.datetime.now()])
|
||||||
|
|
||||||
elif is_group_admin(request):
|
elif is_role_request(request, 'admin'):
|
||||||
user = get_session_user_info(request)[2]
|
user = get_session_user_info(request)[2]
|
||||||
dept_name, dept = get_session_user_info(request)[4:]
|
dept_name, dept = get_session_user_info(request)[4:]
|
||||||
users = User.objects.filter(dept=dept)
|
users = User.objects.filter(dept=dept)
|
||||||
|
@ -205,7 +208,7 @@ def login(request):
|
||||||
user_filter = User.objects.filter(username=username)
|
user_filter = User.objects.filter(username=username)
|
||||||
if user_filter:
|
if user_filter:
|
||||||
user = user_filter[0]
|
user = user_filter[0]
|
||||||
if md5_crypt(password) == user.password:
|
if PyCrypt.md5_crypt(password) == user.password:
|
||||||
request.session['user_id'] = user.id
|
request.session['user_id'] = user.id
|
||||||
user_filter.update(last_login=datetime.datetime.now())
|
user_filter.update(last_login=datetime.datetime.now())
|
||||||
if user.role == 'SU':
|
if user.role == 'SU':
|
||||||
|
@ -216,7 +219,7 @@ def login(request):
|
||||||
request.session['role_id'] = 0
|
request.session['role_id'] = 0
|
||||||
response = HttpResponseRedirect('/', )
|
response = HttpResponseRedirect('/', )
|
||||||
response.set_cookie('username', username, expires=604800)
|
response.set_cookie('username', username, expires=604800)
|
||||||
response.set_cookie('seed', md5_crypt(password), expires=604800)
|
response.set_cookie('seed', PyCrypt.md5_crypt(password), expires=604800)
|
||||||
return response
|
return response
|
||||||
else:
|
else:
|
||||||
error = '密码错误,请重新输入。'
|
error = '密码错误,请重新输入。'
|
||||||
|
@ -248,7 +251,7 @@ def filter_ajax_api(request):
|
||||||
def install(request):
|
def install(request):
|
||||||
from juser.models import DEPT, User
|
from juser.models import DEPT, User
|
||||||
if User.objects.filter(id=5000):
|
if User.objects.filter(id=5000):
|
||||||
return httperror(request, 'Jumpserver已初始化,不能重复安装!')
|
return http_error(request, 'Jumpserver已初始化,不能重复安装!')
|
||||||
|
|
||||||
dept = DEPT(id=1, name="超管部", comment="超级管理部门")
|
dept = DEPT(id=1, name="超管部", comment="超级管理部门")
|
||||||
dept.save()
|
dept.save()
|
||||||
|
@ -257,7 +260,7 @@ def install(request):
|
||||||
IDC(id=1, name="默认", comment="默认IDC").save()
|
IDC(id=1, name="默认", comment="默认IDC").save()
|
||||||
BisGroup(id=1, name="ALL", dept=dept, comment="所有主机组").save()
|
BisGroup(id=1, name="ALL", dept=dept, comment="所有主机组").save()
|
||||||
|
|
||||||
User(id=5000, username="admin", password=md5_crypt('admin'),
|
User(id=5000, username="admin", password=PyCrypt.md5_crypt('admin'),
|
||||||
name='admin', email='admin@jumpserver.org', role='SU', is_active=True, dept=dept).save()
|
name='admin', email='admin@jumpserver.org', role='SU', is_active=True, dept=dept).save()
|
||||||
return http_success(request, u'Jumpserver初始化成功')
|
return http_success(request, u'Jumpserver初始化成功')
|
||||||
|
|
||||||
|
@ -278,55 +281,56 @@ def transfer(sftp, filenames):
|
||||||
|
|
||||||
|
|
||||||
def upload(request):
|
def upload(request):
|
||||||
user, dept = get_session_user_dept(request)
|
pass
|
||||||
if request.method == 'POST':
|
# user, dept = get_session_user_dept(request)
|
||||||
hosts = request.POST.get('hosts')
|
# if request.method == 'POST':
|
||||||
upload_files = request.FILES.getlist('file[]', None)
|
# hosts = request.POST.get('hosts')
|
||||||
upload_dir = "/tmp/%s" % user.username
|
# upload_files = request.FILES.getlist('file[]', None)
|
||||||
is_dir(upload_dir)
|
# upload_dir = "/tmp/%s" % user.username
|
||||||
date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
# is_dir(upload_dir)
|
||||||
hosts_list = hosts.split(',')
|
# date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
||||||
user_hosts = get_user_host(user.username).keys()
|
# hosts_list = hosts.split(',')
|
||||||
unperm_hosts = []
|
# user_hosts = [asset.ip for asset in user.get_asset()]
|
||||||
filenames = {}
|
# unperm_hosts = []
|
||||||
for ip in hosts_list:
|
# filenames = {}
|
||||||
if ip not in user_hosts:
|
# for ip in hosts_list:
|
||||||
unperm_hosts.append(ip)
|
# if ip not in user_hosts:
|
||||||
|
# unperm_hosts.append(ip)
|
||||||
if not hosts:
|
#
|
||||||
return HttpResponseNotFound(u'地址不能为空')
|
# if not hosts:
|
||||||
|
# return HttpResponseNotFound(u'地址不能为空')
|
||||||
if unperm_hosts:
|
#
|
||||||
print hosts_list
|
# if unperm_hosts:
|
||||||
return HttpResponseNotFound(u'%s 没有权限.' % ', '.join(unperm_hosts))
|
# print hosts_list
|
||||||
|
# return HttpResponseNotFound(u'%s 没有权限.' % ', '.join(unperm_hosts))
|
||||||
for upload_file in upload_files:
|
#
|
||||||
file_path = '%s/%s.%s' % (upload_dir, upload_file.name, date_now)
|
# for upload_file in upload_files:
|
||||||
filenames[upload_file.name] = file_path
|
# file_path = '%s/%s.%s' % (upload_dir, upload_file.name, date_now)
|
||||||
f = open(file_path, 'w')
|
# filenames[upload_file.name] = file_path
|
||||||
for chunk in upload_file.chunks():
|
# f = open(file_path, 'w')
|
||||||
f.write(chunk)
|
# for chunk in upload_file.chunks():
|
||||||
f.close()
|
# f.write(chunk)
|
||||||
|
# f.close()
|
||||||
sftps = []
|
#
|
||||||
for host in hosts_list:
|
# sftps = []
|
||||||
username, password, host, port = get_connect_item(user.username, host)
|
# for host in hosts_list:
|
||||||
try:
|
# username, password, host, port = get_connect_item(user.username, host)
|
||||||
t = paramiko.Transport((host, port))
|
# try:
|
||||||
t.connect(username=username, password=password)
|
# t = paramiko.Transport((host, port))
|
||||||
sftp = paramiko.SFTPClient.from_transport(t)
|
# t.connect(username=username, password=password)
|
||||||
sftps.append(sftp)
|
# sftp = paramiko.SFTPClient.from_transport(t)
|
||||||
except paramiko.AuthenticationException:
|
# sftps.append(sftp)
|
||||||
return HttpResponseNotFound(u'%s 连接失败.' % host)
|
# except paramiko.AuthenticationException:
|
||||||
|
# return HttpResponseNotFound(u'%s 连接失败.' % host)
|
||||||
# pool = Pool(processes=5)
|
#
|
||||||
for sftp in sftps:
|
# # pool = Pool(processes=5)
|
||||||
transfer(sftp, filenames)
|
# for sftp in sftps:
|
||||||
# pool.close()
|
# transfer(sftp, filenames)
|
||||||
# pool.join()
|
# # pool.close()
|
||||||
return HttpResponse('传送成功')
|
# # pool.join()
|
||||||
|
# return HttpResponse('传送成功')
|
||||||
return render_to_response('upload.html', locals(), context_instance=RequestContext(request))
|
#
|
||||||
|
# return render_to_response('upload.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
def node_auth(request):
|
def node_auth(request):
|
||||||
|
|
238
juser/views.py
238
juser/views.py
|
@ -4,174 +4,15 @@
|
||||||
|
|
||||||
import random
|
import random
|
||||||
from Crypto.PublicKey import RSA
|
from Crypto.PublicKey import RSA
|
||||||
import crypt
|
|
||||||
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.template import RequestContext
|
from django.template import RequestContext
|
||||||
from django.db.models import ObjectDoesNotExist
|
from django.db.models import ObjectDoesNotExist
|
||||||
|
|
||||||
from jumpserver.api import *
|
from juser.user_api import *
|
||||||
|
|
||||||
|
|
||||||
def md5_crypt(string):
|
@require_role(role='super')
|
||||||
return hashlib.new("md5", string).hexdigest()
|
|
||||||
|
|
||||||
|
|
||||||
def gen_rand_pwd(num):
|
|
||||||
"""
|
|
||||||
generate random password
|
|
||||||
生成随机密码
|
|
||||||
"""
|
|
||||||
seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
salt_list = []
|
|
||||||
for i in range(num):
|
|
||||||
salt_list.append(random.choice(seed))
|
|
||||||
salt = ''.join(salt_list)
|
|
||||||
return salt
|
|
||||||
|
|
||||||
|
|
||||||
def gen_sha512(salt, password):
|
|
||||||
"""
|
|
||||||
generate sha512 format password
|
|
||||||
生成sha512加密密码
|
|
||||||
"""
|
|
||||||
return crypt.crypt(password, '$6$%s$' % salt)
|
|
||||||
|
|
||||||
|
|
||||||
def group_add_user(group, user_id=None, username=None):
|
|
||||||
"""
|
|
||||||
用户组中添加用户
|
|
||||||
UserGroup Add a user
|
|
||||||
"""
|
|
||||||
if user_id:
|
|
||||||
user = get_object(User, id=user_id)
|
|
||||||
else:
|
|
||||||
user = get_object(User, username=username)
|
|
||||||
group.user_set.add(user)
|
|
||||||
|
|
||||||
|
|
||||||
def db_add_group(**kwargs):
|
|
||||||
name = kwargs.get('name')
|
|
||||||
group = UserGroup.objects.filter(name=name)
|
|
||||||
users = kwargs.pop('users')
|
|
||||||
if group:
|
|
||||||
raise ServerError(u'用户组 %s 已经存在' % name)
|
|
||||||
group = UserGroup(**kwargs)
|
|
||||||
group.save()
|
|
||||||
for user_id in users:
|
|
||||||
group_add_user(group, user_id)
|
|
||||||
|
|
||||||
|
|
||||||
def db_add_user(**kwargs):
|
|
||||||
groups_post = kwargs.pop('groups')
|
|
||||||
user = User(**kwargs)
|
|
||||||
user.save()
|
|
||||||
if groups_post:
|
|
||||||
group_select = []
|
|
||||||
for group_id in groups_post:
|
|
||||||
group = UserGroup.objects.filter(id=group_id)
|
|
||||||
group_select.extend(group)
|
|
||||||
user.group = group_select
|
|
||||||
return user
|
|
||||||
|
|
||||||
|
|
||||||
def db_update_user(**kwargs):
|
|
||||||
groups_post = kwargs.pop('groups')
|
|
||||||
user_id = kwargs.pop('user_id')
|
|
||||||
user = User.objects.filter(id=user_id)
|
|
||||||
if user:
|
|
||||||
user.update(**kwargs)
|
|
||||||
user = User.objects.get(id=user_id)
|
|
||||||
user.save()
|
|
||||||
|
|
||||||
if groups_post:
|
|
||||||
group_select = []
|
|
||||||
for group_id in groups_post:
|
|
||||||
group = UserGroup.objects.filter(id=group_id)
|
|
||||||
group_select.extend(group)
|
|
||||||
user.group = group_select
|
|
||||||
|
|
||||||
|
|
||||||
def db_del_user(username):
|
|
||||||
try:
|
|
||||||
user = User.objects.get(username=username)
|
|
||||||
user.delete()
|
|
||||||
except ObjectDoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def gen_ssh_key(username, password=None, length=2048):
|
|
||||||
private_key_dir = os.path.join(BASE_DIR, 'keys/jumpserver/')
|
|
||||||
private_key_file = os.path.join(private_key_dir, username+".pem")
|
|
||||||
public_key_dir = '/home/%s/.ssh/' % username
|
|
||||||
public_key_file = os.path.join(public_key_dir, 'authorized_keys')
|
|
||||||
is_dir(private_key_dir)
|
|
||||||
is_dir(public_key_dir, username, mode=0700)
|
|
||||||
|
|
||||||
key = RSA.generate(length)
|
|
||||||
with open(private_key_file, 'w') as pri_f:
|
|
||||||
pri_f.write(key.exportKey('PEM', password))
|
|
||||||
os.chmod(private_key_file, 0600)
|
|
||||||
|
|
||||||
pub_key = key.publickey()
|
|
||||||
with open(public_key_file, 'w') as pub_f:
|
|
||||||
pub_f.write(pub_key.exportKey('OpenSSH'))
|
|
||||||
os.chmod(public_key_file, 0600)
|
|
||||||
bash('chown %s:%s %s' % (username, username, public_key_file))
|
|
||||||
|
|
||||||
|
|
||||||
def server_add_user(username, password, ssh_key_pwd):
|
|
||||||
bash("useradd '%s'; echo '%s' | passwd --stdin '%s'" % (username, password, username))
|
|
||||||
gen_ssh_key(username, ssh_key_pwd)
|
|
||||||
|
|
||||||
|
|
||||||
def server_del_user(username):
|
|
||||||
bash('userdel -r %s' % username)
|
|
||||||
|
|
||||||
|
|
||||||
def ldap_add_user(username, ldap_pwd):
|
|
||||||
user_dn = "uid=%s,ou=People,%s" % (username, LDAP_BASE_DN)
|
|
||||||
password_sha512 = gen_sha512(gen_rand_pwd(6), ldap_pwd)
|
|
||||||
user = User.objects.filter(username=username)
|
|
||||||
if user:
|
|
||||||
user = user[0]
|
|
||||||
else:
|
|
||||||
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):
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
|
||||||
def dept_add(request):
|
def dept_add(request):
|
||||||
header_title, path1, path2 = '添加部门', '用户管理', '添加部门'
|
header_title, path1, path2 = '添加部门', '用户管理', '添加部门'
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
@ -192,7 +33,7 @@ def dept_add(request):
|
||||||
return render_to_response('juser/dept_add.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/dept_add.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def dept_list(request):
|
def dept_list(request):
|
||||||
header_title, path1, path2 = '查看部门', '用户管理', '查看部门'
|
header_title, path1, path2 = '查看部门', '用户管理', '查看部门'
|
||||||
keyword = request.GET.get('search')
|
keyword = request.GET.get('search')
|
||||||
|
@ -206,7 +47,7 @@ def dept_list(request):
|
||||||
return render_to_response('juser/dept_list.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/dept_list.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def dept_list_adm(request):
|
def dept_list_adm(request):
|
||||||
header_title, path1, path2 = '查看部门', '用户管理', '查看部门'
|
header_title, path1, path2 = '查看部门', '用户管理', '查看部门'
|
||||||
user, dept = get_session_user_dept(request)
|
user, dept = get_session_user_dept(request)
|
||||||
|
@ -226,7 +67,7 @@ def chg_role(request):
|
||||||
return HttpResponseRedirect('/')
|
return HttpResponseRedirect('/')
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def dept_detail(request):
|
def dept_detail(request):
|
||||||
dept_id = request.GET.get('id', None)
|
dept_id = request.GET.get('id', None)
|
||||||
if not dept_id:
|
if not dept_id:
|
||||||
|
@ -238,7 +79,7 @@ def dept_detail(request):
|
||||||
return render_to_response('juser/dept_detail.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/dept_detail.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def dept_del(request):
|
def dept_del(request):
|
||||||
dept_id = request.GET.get('id', None)
|
dept_id = request.GET.get('id', None)
|
||||||
if not dept_id or dept_id in ['1', '2']:
|
if not dept_id or dept_id in ['1', '2']:
|
||||||
|
@ -276,7 +117,7 @@ def dept_member_update(dept, users_id_list):
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def dept_del_ajax(request):
|
def dept_del_ajax(request):
|
||||||
dept_ids = request.POST.get('dept_ids')
|
dept_ids = request.POST.get('dept_ids')
|
||||||
for dept_id in dept_ids.split(','):
|
for dept_id in dept_ids.split(','):
|
||||||
|
@ -285,7 +126,7 @@ def dept_del_ajax(request):
|
||||||
return HttpResponse("删除成功")
|
return HttpResponse("删除成功")
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def dept_edit(request):
|
def dept_edit(request):
|
||||||
header_title, path1, path2 = '部门编辑', '用户管理', '部门编辑'
|
header_title, path1, path2 = '部门编辑', '用户管理', '部门编辑'
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
|
@ -331,7 +172,7 @@ def dept_user_ajax(request):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def group_add(request):
|
def group_add(request):
|
||||||
error = ''
|
error = ''
|
||||||
msg = ''
|
msg = ''
|
||||||
|
@ -372,7 +213,7 @@ def group_add(request):
|
||||||
return render_to_response('juser/group_add.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/group_add.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def group_add_adm(request):
|
def group_add_adm(request):
|
||||||
error = ''
|
error = ''
|
||||||
msg = ''
|
msg = ''
|
||||||
|
@ -403,7 +244,7 @@ def group_add_adm(request):
|
||||||
return render_to_response('juser/group_add.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/group_add.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def group_list(request):
|
def group_list(request):
|
||||||
header_title, path1, path2 = '查看小组', '用户管理', '查看小组'
|
header_title, path1, path2 = '查看小组', '用户管理', '查看小组'
|
||||||
keyword = request.GET.get('search', '')
|
keyword = request.GET.get('search', '')
|
||||||
|
@ -423,7 +264,7 @@ def group_list(request):
|
||||||
return render_to_response('juser/group_list.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/group_list.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def group_list_adm(request):
|
def group_list_adm(request):
|
||||||
header_title, path1, path2 = '查看部门小组', '用户管理', '查看小组'
|
header_title, path1, path2 = '查看部门小组', '用户管理', '查看小组'
|
||||||
keyword = request.GET.get('search', '')
|
keyword = request.GET.get('search', '')
|
||||||
|
@ -438,7 +279,7 @@ def group_list_adm(request):
|
||||||
return render_to_response('juser/group_list.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/group_list.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def group_detail(request):
|
def group_detail(request):
|
||||||
group_id = request.GET.get('id', None)
|
group_id = request.GET.get('id', None)
|
||||||
if not group_id:
|
if not group_id:
|
||||||
|
@ -448,7 +289,7 @@ def group_detail(request):
|
||||||
return render_to_response('juser/group_detail.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/group_detail.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def group_del(request):
|
def group_del(request):
|
||||||
group_id = request.GET.get('id', '')
|
group_id = request.GET.get('id', '')
|
||||||
if not group_id:
|
if not group_id:
|
||||||
|
@ -457,7 +298,7 @@ def group_del(request):
|
||||||
return HttpResponseRedirect('/juser/group_list/')
|
return HttpResponseRedirect('/juser/group_list/')
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def group_del_adm(request):
|
def group_del_adm(request):
|
||||||
group_id = request.GET.get('id', '')
|
group_id = request.GET.get('id', '')
|
||||||
if not validate(request, user_group=[group_id]):
|
if not validate(request, user_group=[group_id]):
|
||||||
|
@ -468,7 +309,7 @@ def group_del_adm(request):
|
||||||
return HttpResponseRedirect('/juser/group_list/')
|
return HttpResponseRedirect('/juser/group_list/')
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def group_del_ajax(request):
|
def group_del_ajax(request):
|
||||||
group_ids = request.POST.get('group_ids')
|
group_ids = request.POST.get('group_ids')
|
||||||
group_ids = group_ids.split(',')
|
group_ids = group_ids.split(',')
|
||||||
|
@ -490,7 +331,7 @@ def group_update_member(group_id, users_id_list):
|
||||||
group.user_set.add(user)
|
group.user_set.add(user)
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def group_edit(request):
|
def group_edit(request):
|
||||||
error = ''
|
error = ''
|
||||||
msg = ''
|
msg = ''
|
||||||
|
@ -538,7 +379,7 @@ def group_edit(request):
|
||||||
return HttpResponseRedirect('/juser/group_list/')
|
return HttpResponseRedirect('/juser/group_list/')
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def group_edit_adm(request):
|
def group_edit_adm(request):
|
||||||
error = ''
|
error = ''
|
||||||
msg = ''
|
msg = ''
|
||||||
|
@ -586,7 +427,7 @@ def group_edit_adm(request):
|
||||||
return HttpResponseRedirect('/juser/group_list/')
|
return HttpResponseRedirect('/juser/group_list/')
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def user_add(request):
|
def user_add(request):
|
||||||
error = ''
|
error = ''
|
||||||
msg = ''
|
msg = ''
|
||||||
|
@ -597,15 +438,15 @@ def user_add(request):
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
username = request.POST.get('username', '')
|
username = request.POST.get('username', '')
|
||||||
password = gen_rand_pwd(16)
|
password = PyCrypt.gen_rand_pwd(16)
|
||||||
name = request.POST.get('name', '')
|
name = request.POST.get('name', '')
|
||||||
email = request.POST.get('email', '')
|
email = request.POST.get('email', '')
|
||||||
dept_id = request.POST.get('dept_id')
|
dept_id = request.POST.get('dept_id')
|
||||||
groups = request.POST.getlist('groups', [])
|
groups = request.POST.getlist('groups', [])
|
||||||
role_post = request.POST.get('role', 'CU')
|
role_post = request.POST.get('role', 'CU')
|
||||||
ssh_key_pwd = gen_rand_pwd(16)
|
ssh_key_pwd = PyCrypt.gen_rand_pwd(16)
|
||||||
is_active = True if request.POST.get('is_active', '1') == '1' else False
|
is_active = True if request.POST.get('is_active', '1') == '1' else False
|
||||||
ldap_pwd = gen_rand_pwd(16)
|
ldap_pwd = PyCrypt.gen_rand_pwd(16)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if '' in [username, password, ssh_key_pwd, name, groups, role_post, is_active]:
|
if '' in [username, password, ssh_key_pwd, name, groups, role_post, is_active]:
|
||||||
|
@ -667,7 +508,7 @@ def user_add(request):
|
||||||
return render_to_response('juser/user_add.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/user_add.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def user_add_adm(request):
|
def user_add_adm(request):
|
||||||
error = ''
|
error = ''
|
||||||
msg = ''
|
msg = ''
|
||||||
|
@ -677,13 +518,13 @@ def user_add_adm(request):
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
username = request.POST.get('username', '')
|
username = request.POST.get('username', '')
|
||||||
password = gen_rand_pwd(16)
|
password = PyCrypt.gen_rand_pwd(16)
|
||||||
name = request.POST.get('name', '')
|
name = request.POST.get('name', '')
|
||||||
email = request.POST.get('email', '')
|
email = request.POST.get('email', '')
|
||||||
groups = request.POST.getlist('groups', [])
|
groups = request.POST.getlist('groups', [])
|
||||||
ssh_key_pwd = gen_rand_pwd(16)
|
ssh_key_pwd = PyCrypt.gen_rand_pwd(16)
|
||||||
is_active = True if request.POST.get('is_active', '1') == '1' else False
|
is_active = True if request.POST.get('is_active', '1') == '1' else False
|
||||||
ldap_pwd = gen_rand_pwd(16)
|
ldap_pwd = PyCrypt.gen_rand_pwd(16)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if '' in [username, password, ssh_key_pwd, name, groups, is_active]:
|
if '' in [username, password, ssh_key_pwd, name, groups, is_active]:
|
||||||
|
@ -739,7 +580,7 @@ def user_add_adm(request):
|
||||||
return render_to_response('juser/user_add.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/user_add.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def user_list(request):
|
def user_list(request):
|
||||||
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
||||||
header_title, path1, path2 = '查看用户', '用户管理', '用户列表'
|
header_title, path1, path2 = '查看用户', '用户管理', '用户列表'
|
||||||
|
@ -768,7 +609,7 @@ def user_list(request):
|
||||||
return render_to_response('juser/user_list.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/user_list.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def user_list_adm(request):
|
def user_list_adm(request):
|
||||||
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
||||||
header_title, path1, path2 = '查看用户', '用户管理', '用户列表'
|
header_title, path1, path2 = '查看用户', '用户管理', '用户列表'
|
||||||
|
@ -793,7 +634,7 @@ def user_list_adm(request):
|
||||||
return render_to_response('juser/user_list.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/user_list.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_login
|
@require_role(role='user')
|
||||||
def user_detail(request):
|
def user_detail(request):
|
||||||
header_title, path1, path2 = '查看用户', '用户管理', '用户详情'
|
header_title, path1, path2 = '查看用户', '用户管理', '用户详情'
|
||||||
if request.session.get('role_id') == 0:
|
if request.session.get('role_id') == 0:
|
||||||
|
@ -810,7 +651,7 @@ def user_detail(request):
|
||||||
user = User.objects.filter(id=user_id)
|
user = User.objects.filter(id=user_id)
|
||||||
if user:
|
if user:
|
||||||
user = user[0]
|
user = user[0]
|
||||||
asset_group_permed = user_perm_group_api(user)
|
asset_group_permed = user.get_asset_group()
|
||||||
logs_last = Log.objects.filter(user=user.name).order_by('-start_time')[0:10]
|
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_all = Log.objects.filter(user=user.name).order_by('-start_time')
|
||||||
logs_num = len(logs_all)
|
logs_num = len(logs_all)
|
||||||
|
@ -818,7 +659,7 @@ def user_detail(request):
|
||||||
return render_to_response('juser/user_detail.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/user_detail.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def user_del(request):
|
def user_del(request):
|
||||||
user_id = request.GET.get('id', '')
|
user_id = request.GET.get('id', '')
|
||||||
if not user_id:
|
if not user_id:
|
||||||
|
@ -838,7 +679,7 @@ def user_del(request):
|
||||||
return HttpResponseRedirect('/juser/user_list/')
|
return HttpResponseRedirect('/juser/user_list/')
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def user_del_ajax(request):
|
def user_del_ajax(request):
|
||||||
user_ids = request.POST.get('ids')
|
user_ids = request.POST.get('ids')
|
||||||
user_ids = user_ids.split(',')
|
user_ids = user_ids.split(',')
|
||||||
|
@ -857,7 +698,7 @@ def user_del_ajax(request):
|
||||||
return HttpResponse('删除成功')
|
return HttpResponse('删除成功')
|
||||||
|
|
||||||
|
|
||||||
@require_super_user
|
@require_role(role='super')
|
||||||
def user_edit(request):
|
def user_edit(request):
|
||||||
header_title, path1, path2 = '编辑用户', '用户管理', '用户编辑'
|
header_title, path1, path2 = '编辑用户', '用户管理', '用户编辑'
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
|
@ -920,7 +761,7 @@ def user_edit(request):
|
||||||
return render_to_response('juser/user_edit.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/user_edit.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
@require_admin
|
@require_role(role='admin')
|
||||||
def user_edit_adm(request):
|
def user_edit_adm(request):
|
||||||
header_title, path1, path2 = '编辑用户', '用户管理', '用户编辑'
|
header_title, path1, path2 = '编辑用户', '用户管理', '用户编辑'
|
||||||
user, dept = get_session_user_dept(request)
|
user, dept = get_session_user_dept(request)
|
||||||
|
@ -1020,21 +861,18 @@ def chg_info(request):
|
||||||
return render_to_response('juser/chg_info.html', locals(), context_instance=RequestContext(request))
|
return render_to_response('juser/chg_info.html', locals(), context_instance=RequestContext(request))
|
||||||
|
|
||||||
|
|
||||||
|
@require_role(role='user')
|
||||||
|
|
||||||
|
|
||||||
@require_login
|
|
||||||
def down_key(request):
|
def down_key(request):
|
||||||
user_id = ''
|
user_id = ''
|
||||||
if is_super_user(request):
|
if is_role_request(request, 'super'):
|
||||||
user_id = request.GET.get('id')
|
user_id = request.GET.get('id')
|
||||||
|
|
||||||
if is_group_admin(request):
|
if is_role_request(request, 'admin'):
|
||||||
user_id = request.GET.get('id')
|
user_id = request.GET.get('id')
|
||||||
if not validate(request, user=[user_id]):
|
if not validate(request, user=[user_id]):
|
||||||
user_id = request.session.get('user_id')
|
user_id = request.session.get('user_id')
|
||||||
|
|
||||||
if is_common_user(request):
|
if is_role_request(request, 'user'):
|
||||||
user_id = request.session.get('user_id')
|
user_id = request.session.get('user_id')
|
||||||
|
|
||||||
if user_id:
|
if user_id:
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<link rel="shortcut icon" href="/static/img/facio.ico" type="image/x-icon">
|
<link rel="shortcut icon" href="/static/img/facio.ico" type="image/x-icon">
|
||||||
{% include 'link_css.html' %}
|
{% include 'link_css.html' %}
|
||||||
{% include 'head_script.html' %}
|
{% include 'head_script.html' %}
|
||||||
|
{% block self_head_css_js %} {% endblock %}
|
||||||
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
@ -30,4 +31,5 @@
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
{% include 'foot_script.html' %}
|
{% include 'foot_script.html' %}
|
||||||
|
{% block self_footer_js %} {% endblock %}
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -15,12 +15,7 @@
|
||||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||||
<i class="fa fa-wrench"></i>
|
<i class="fa fa-wrench"></i>
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu dropdown-user">
|
|
||||||
<li><a href="#">未启用 1</a>
|
|
||||||
</li>
|
|
||||||
<li><a href="#">未启用 2</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<a class="close-link">
|
<a class="close-link">
|
||||||
<i class="fa fa-times"></i>
|
<i class="fa fa-times"></i>
|
||||||
</a>
|
</a>
|
||||||
|
@ -38,37 +33,13 @@
|
||||||
<label for="name" class="col-sm-2 control-label">部门名称<span class="red-fonts">*</span></label>
|
<label for="name" class="col-sm-2 control-label">部门名称<span class="red-fonts">*</span></label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
{% if error %}
|
{% if error %}
|
||||||
<input id="name" name="name" placeholder="Dept name" type="text" class="form-control" value="{{ name }}">
|
<input id="name" name="name" placeholder="Department name" type="text" class="form-control" value="{{ name }}">
|
||||||
{% else %}
|
{% else %}
|
||||||
<input id="name" name="name" placeholder="Dept name" type="text" class="form-control">
|
<input id="name" name="name" placeholder="Department name" type="text" class="form-control">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# <div class="hr-line-dashed"></div>#}
|
|
||||||
{# <div class="form-group">#}
|
|
||||||
{# <label for="users" class="col-lg-2 control-label">管理员</label>#}
|
|
||||||
{# <div class="col-sm-3">#}
|
|
||||||
{# <select id="users" name="users" size="12" class="form-control m-b" multiple>#}
|
|
||||||
{# {% for user in users %}#}
|
|
||||||
{# <option value="{{ user.id }}">{{ user.name }}</option>#}
|
|
||||||
{# {% endfor %}#}
|
|
||||||
{# </select>#}
|
|
||||||
{# </div>#}
|
|
||||||
{# <div class="col-sm-1">#}
|
|
||||||
{# <div class="btn-group" style="margin-top: 50px;">#}
|
|
||||||
{# <button type="button" class="btn btn-white" onclick="move('users', 'users_selected')"><i class="fa fa-chevron-right"></i></button>#}
|
|
||||||
{# <button type="button" class="btn btn-white" onclick="move('users_selected', 'users')"><i class="fa fa-chevron-left"></i> </button>#}
|
|
||||||
{# </div>#}
|
|
||||||
{# </div>#}
|
|
||||||
{# <div class="col-sm-3">#}
|
|
||||||
{# <div>#}
|
|
||||||
{# <select id="users_selected" name="users_selected" class="form-control m-b" size="12" multiple>#}
|
|
||||||
{# </select>#}
|
|
||||||
{# </div>#}
|
|
||||||
{# </div>#}
|
|
||||||
{# </div>#}
|
|
||||||
<div class="hr-line-dashed"></div>
|
<div class="hr-line-dashed"></div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="comment" class="col-sm-2 control-label">备注</label>
|
<label for="comment" class="col-sm-2 control-label">备注</label>
|
||||||
|
@ -95,6 +66,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block self_footer_js %}
|
||||||
<script>
|
<script>
|
||||||
$('#deptForm').validator({
|
$('#deptForm').validator({
|
||||||
timely: 2,
|
timely: 2,
|
||||||
|
@ -104,7 +78,7 @@ $('#deptForm').validator({
|
||||||
rule: "required",
|
rule: "required",
|
||||||
tip: "输入部门名称",
|
tip: "输入部门名称",
|
||||||
ok: "",
|
ok: "",
|
||||||
msg: {required: "必须填写!"}
|
msg: {required: "必须填写!!"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
valid: function(form) {
|
valid: function(form) {
|
||||||
|
@ -112,13 +86,6 @@ $('#deptForm').validator({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function change_type(type){
|
|
||||||
$.post('/juser/group_add_ajax/',
|
|
||||||
{'type': type},
|
|
||||||
function(data){
|
|
||||||
$('#users').html(data)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
$("#submit_button").click(function(){
|
$("#submit_button").click(function(){
|
||||||
|
|
Loading…
Reference in New Issue