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'
 | 
			
		||||
if django.get_version() != '1.6':
 | 
			
		||||
    django.setup()
 | 
			
		||||
from jumpserver.api import BASE_DIR, ServerError, User, UserGroup, Asset, Jtty, get_object
 | 
			
		||||
from jumpserver.api import CRYPTOR, logger, is_dir
 | 
			
		||||
from jumpserver.api import ServerError, User, Asset, Jtty, get_object
 | 
			
		||||
from jumpserver.api import logger
 | 
			
		||||
from jumpserver.api import BisGroup as AssetGroup
 | 
			
		||||
 | 
			
		||||
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):
 | 
			
		||||
    """
 | 
			
		||||
    Print colorful string.
 | 
			
		||||
    颜色打印
 | 
			
		||||
    颜色打印字符或者退出
 | 
			
		||||
    """
 | 
			
		||||
    color_msg = {'blue': '\033[1;36m%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):
 | 
			
		||||
    """鉴定用户是否有该主机权限 或 匹配到的ip是否唯一"""
 | 
			
		||||
    """
 | 
			
		||||
    Check user was permed or not . Check ip is unique or not.
 | 
			
		||||
    鉴定用户是否有该主机权限 或 匹配到的ip是否唯一
 | 
			
		||||
    """
 | 
			
		||||
    ip_matched = []
 | 
			
		||||
    try:
 | 
			
		||||
        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))
 | 
			
		||||
    ip_matched = list(set(ip_matched))
 | 
			
		||||
 | 
			
		||||
    if len(ip_matched) > 1:
 | 
			
		||||
    if len(ip_matched) > 1:  # 如果匹配ip不唯一
 | 
			
		||||
        ip_comment = {}
 | 
			
		||||
        for ip in ip_matched:
 | 
			
		||||
            ip_comment[ip] = assets_info[ip][2]
 | 
			
		||||
| 
						 | 
				
			
			@ -71,15 +74,19 @@ def verify_connect(user, option):
 | 
			
		|||
            else:
 | 
			
		||||
                print '%-15s' % ip
 | 
			
		||||
        print ''
 | 
			
		||||
    elif len(ip_matched) < 1:
 | 
			
		||||
    elif len(ip_matched) < 1:  # 如果没匹配到
 | 
			
		||||
        color_print('没有该主机,或者您没有该主机的权限 No Permission or No host.', 'red')
 | 
			
		||||
    else:
 | 
			
		||||
    else:  # 恰好是1个
 | 
			
		||||
        asset = get_object(Asset, ip=ip_matched[0])
 | 
			
		||||
        jtty = Jtty(user, asset)
 | 
			
		||||
        jtty.connect()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def print_prompt():
 | 
			
		||||
    """
 | 
			
		||||
    Print prompt
 | 
			
		||||
    打印提示导航
 | 
			
		||||
    """
 | 
			
		||||
    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.
 | 
			
		||||
    2) Type \033[32mP/p\033[0m To Print The Servers You Available.
 | 
			
		||||
| 
						 | 
				
			
			@ -162,6 +169,10 @@ def print_prompt():
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    """
 | 
			
		||||
    he he
 | 
			
		||||
    主程序
 | 
			
		||||
    """
 | 
			
		||||
    if not login_user:  # 判断用户是否存在
 | 
			
		||||
        color_print(u'没有该用户,或许你是以root运行的 No that user.', exits=True)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import os, sys, time
 | 
			
		|||
from ConfigParser import ConfigParser
 | 
			
		||||
import getpass
 | 
			
		||||
from Crypto.Cipher import AES
 | 
			
		||||
import crypt
 | 
			
		||||
from binascii import b2a_hex, a2b_hex
 | 
			
		||||
import ldap
 | 
			
		||||
from ldap import modlist
 | 
			
		||||
| 
						 | 
				
			
			@ -13,15 +14,18 @@ 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
 | 
			
		||||
from django.shortcuts import render_to_response
 | 
			
		||||
from django.template import RequestContext
 | 
			
		||||
from juser.models import User, UserGroup, DEPT
 | 
			
		||||
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.http import HttpResponseRedirect
 | 
			
		||||
from django.shortcuts import render_to_response
 | 
			
		||||
from django.core.mail import send_mail
 | 
			
		||||
import json
 | 
			
		||||
import logging
 | 
			
		||||
| 
						 | 
				
			
			@ -50,20 +54,29 @@ SEND_PORT = CONF.get('base', 'port')
 | 
			
		|||
MAIL_FROM = CONF.get('mail', 'email_host_user')
 | 
			
		||||
log_dir = os.path.join(BASE_DIR, 'logs')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
                       'critical': logging.CRITICAL}
 | 
			
		||||
    logger = logging.getLogger('jumpserver')
 | 
			
		||||
    logger.setLevel(logging.DEBUG)
 | 
			
		||||
    logger_f = logging.getLogger('jumpserver')
 | 
			
		||||
    logger_f.setLevel(logging.DEBUG)
 | 
			
		||||
    fh = logging.FileHandler(JLOG_FILE)
 | 
			
		||||
    fh.setLevel(log_level_total.get(level, logging.DEBUG))
 | 
			
		||||
    formatter = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s')
 | 
			
		||||
    fh.setFormatter(formatter)
 | 
			
		||||
    logger.addHandler(fh)
 | 
			
		||||
    return logger
 | 
			
		||||
    logger_f.addHandler(fh)
 | 
			
		||||
    return logger_f
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LDAPMgmt():
 | 
			
		||||
    """
 | 
			
		||||
    LDAP class for add, select, del, update
 | 
			
		||||
    LDAP 管理类,增删改查
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self,
 | 
			
		||||
                 host_url,
 | 
			
		||||
                 base_dn,
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +90,10 @@ class LDAPMgmt():
 | 
			
		|||
        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)
 | 
			
		||||
| 
						 | 
				
			
			@ -90,6 +107,10 @@ class LDAPMgmt():
 | 
			
		|||
            print e
 | 
			
		||||
 | 
			
		||||
    def add(self, dn, attrs):
 | 
			
		||||
        """
 | 
			
		||||
        add
 | 
			
		||||
        添加
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            ldif = modlist.addModlist(attrs)
 | 
			
		||||
            self.conn.add_s(dn, ldif)
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +118,10 @@ class LDAPMgmt():
 | 
			
		|||
            print e
 | 
			
		||||
 | 
			
		||||
    def modify(self, dn, attrs):
 | 
			
		||||
        """
 | 
			
		||||
        modify
 | 
			
		||||
        更改
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            attr_s = []
 | 
			
		||||
            for k, v in attrs.items():
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +131,10 @@ class LDAPMgmt():
 | 
			
		|||
            print e
 | 
			
		||||
 | 
			
		||||
    def delete(self, dn):
 | 
			
		||||
        """
 | 
			
		||||
        delete
 | 
			
		||||
        删除
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            self.conn.delete_s(dn)
 | 
			
		||||
        except ldap.LDAPError, e:
 | 
			
		||||
| 
						 | 
				
			
			@ -113,6 +142,10 @@ class LDAPMgmt():
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def page_list_return(total, current=1):
 | 
			
		||||
    """
 | 
			
		||||
    page
 | 
			
		||||
    分页,返回本次分页的最小页数到最大页数列表
 | 
			
		||||
    """
 | 
			
		||||
    min_page = current - 2 if current - 4 > 0 else 1
 | 
			
		||||
    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):
 | 
			
		||||
    """分页公用函数"""
 | 
			
		||||
    """
 | 
			
		||||
    page public function , return page's object tuple
 | 
			
		||||
    分页公用函数,返回分页的对象元组
 | 
			
		||||
    """
 | 
			
		||||
    contact_list = posts
 | 
			
		||||
    p = paginator = Paginator(contact_list, 10)
 | 
			
		||||
    try:
 | 
			
		||||
| 
						 | 
				
			
			@ -148,6 +184,10 @@ def pages(posts, r):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class Jtty(object):
 | 
			
		||||
    """
 | 
			
		||||
    A virtual tty class
 | 
			
		||||
    一个虚拟终端类,实现连接ssh和记录日志
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, user, asset):
 | 
			
		||||
        self.chan = None
 | 
			
		||||
        self.username = user.username
 | 
			
		||||
| 
						 | 
				
			
			@ -260,7 +300,10 @@ class Jtty(object):
 | 
			
		|||
            log.save()
 | 
			
		||||
 | 
			
		||||
    def get_connect_item(self):
 | 
			
		||||
        """获取连接需要的参数,也就是服务ip, 端口, 用户账号和密码"""
 | 
			
		||||
        """
 | 
			
		||||
        get args for connect: ip, port, username, passwd
 | 
			
		||||
        获取连接需要的参数,也就是服务ip, 端口, 用户账号和密码
 | 
			
		||||
        """
 | 
			
		||||
        if not self.asset.is_active:
 | 
			
		||||
            raise ServerError('该主机被禁用 Host %s is not active.' % self.ip)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -283,15 +326,13 @@ class Jtty(object):
 | 
			
		|||
        else:
 | 
			
		||||
            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()
 | 
			
		||||
        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 = paramiko.SSHClient()
 | 
			
		||||
| 
						 | 
				
			
			@ -303,6 +344,19 @@ class Jtty(object):
 | 
			
		|||
            raise ServerError('认证错误 Authentication Error.')
 | 
			
		||||
        except socket.error:
 | 
			
		||||
            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
 | 
			
		||||
        global channel
 | 
			
		||||
| 
						 | 
				
			
			@ -324,11 +378,18 @@ class Jtty(object):
 | 
			
		|||
        channel.close()
 | 
			
		||||
        ssh.close()
 | 
			
		||||
 | 
			
		||||
    def execute(self, cmd):
 | 
			
		||||
        """
 | 
			
		||||
        execute cmd on the asset
 | 
			
		||||
        执行命令
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PyCrypt(object):
 | 
			
		||||
    """
 | 
			
		||||
    This class used to encrypt and decrypt password.
 | 
			
		||||
    对称加密库
 | 
			
		||||
    加密类
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, key):
 | 
			
		||||
| 
						 | 
				
			
			@ -353,12 +414,24 @@ class PyCrypt(object):
 | 
			
		|||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def md5_crypt(string):
 | 
			
		||||
        """
 | 
			
		||||
        md5 encrypt method
 | 
			
		||||
        md5非对称加密方法
 | 
			
		||||
        """
 | 
			
		||||
        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):
 | 
			
		||||
        """
 | 
			
		||||
        encrypt gen password
 | 
			
		||||
        加密生成密码
 | 
			
		||||
        对称加密之加密生成密码
 | 
			
		||||
        """
 | 
			
		||||
        if not passwd:
 | 
			
		||||
            passwd = self.random_pass()
 | 
			
		||||
| 
						 | 
				
			
			@ -376,6 +449,10 @@ class PyCrypt(object):
 | 
			
		|||
        return b2a_hex(cipher_text)
 | 
			
		||||
 | 
			
		||||
    def decrypt(self, text):
 | 
			
		||||
        """
 | 
			
		||||
        decrypt pass base the same key
 | 
			
		||||
        对称加密之解密,同一个加密随机数
 | 
			
		||||
        """
 | 
			
		||||
        cryptor = AES.new(self.key, self.mode, b'8122ca7d906ad5e1')
 | 
			
		||||
        try:
 | 
			
		||||
            plain_text = cryptor.decrypt(a2b_hex(text))
 | 
			
		||||
| 
						 | 
				
			
			@ -386,10 +463,18 @@ class PyCrypt(object):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class ServerError(Exception):
 | 
			
		||||
    """
 | 
			
		||||
    self define exception
 | 
			
		||||
    自定义异常
 | 
			
		||||
    """
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_object(model, **kwargs):
 | 
			
		||||
    """
 | 
			
		||||
    use this function for query
 | 
			
		||||
    使用改封装函数查询数据库
 | 
			
		||||
    """
 | 
			
		||||
    try:
 | 
			
		||||
        the_object = model.objects.get(**kwargs)
 | 
			
		||||
    except ObjectDoesNotExist:
 | 
			
		||||
| 
						 | 
				
			
			@ -399,7 +484,8 @@ def get_object(model, **kwargs):
 | 
			
		|||
 | 
			
		||||
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(request, *args, **kwargs):
 | 
			
		||||
| 
						 | 
				
			
			@ -413,27 +499,30 @@ def require_role(role='user'):
 | 
			
		|||
                if request.session.get('role_id', 0) != 2:
 | 
			
		||||
                    return HttpResponseRedirect('/')
 | 
			
		||||
            return func(request, *args, **kwargs)
 | 
			
		||||
        return __deco()
 | 
			
		||||
        return __deco
 | 
			
		||||
    return _deco
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def is_role_request(request, role='user'):
 | 
			
		||||
    """
 | 
			
		||||
    :param request: 请求
 | 
			
		||||
    :param role: 角色
 | 
			
		||||
    :return: bool
 | 
			
		||||
    require this request of user is right
 | 
			
		||||
    要求请求角色正确
 | 
			
		||||
    """
 | 
			
		||||
    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
 | 
			
		||||
    else:
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role
 | 
			
		||||
def get_session_user_dept(request):
 | 
			
		||||
    """
 | 
			
		||||
    get department of the user in session
 | 
			
		||||
    获取session中用户的部门
 | 
			
		||||
    """
 | 
			
		||||
    user_id = request.session.get('user_id', 0)
 | 
			
		||||
    print '#' * 20
 | 
			
		||||
    print user_id
 | 
			
		||||
    user = User.objects.filter(id=user_id)
 | 
			
		||||
    if user:
 | 
			
		||||
        user = user[0]
 | 
			
		||||
| 
						 | 
				
			
			@ -443,6 +532,10 @@ def get_session_user_dept(request):
 | 
			
		|||
 | 
			
		||||
@require_role
 | 
			
		||||
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 = User.objects.filter(id=user_id)
 | 
			
		||||
    if user:
 | 
			
		||||
| 
						 | 
				
			
			@ -452,6 +545,10 @@ def get_session_user_info(request):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def get_user_dept(request):
 | 
			
		||||
    """
 | 
			
		||||
    get the user dept id
 | 
			
		||||
    获取用户的部门id
 | 
			
		||||
    """
 | 
			
		||||
    user_id = request.session.get('user_id')
 | 
			
		||||
    if user_id:
 | 
			
		||||
        user_dept = User.objects.get(id=user_id).dept
 | 
			
		||||
| 
						 | 
				
			
			@ -466,16 +563,24 @@ def api_user(request):
 | 
			
		|||
    return HttpResponse(json_data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# def view_splitter(request, su=None, adm=None):
 | 
			
		||||
#     if is_super_user(request):
 | 
			
		||||
#         return su(request)
 | 
			
		||||
#     elif is_group_admin(request):
 | 
			
		||||
#         return adm(request)
 | 
			
		||||
#     else:
 | 
			
		||||
#         return HttpResponseRedirect('/login/')
 | 
			
		||||
def view_splitter(request, su=None, adm=None):
 | 
			
		||||
    """
 | 
			
		||||
    for different user use different view
 | 
			
		||||
    视图分页器
 | 
			
		||||
    """
 | 
			
		||||
    if is_role_request(request, 'super'):
 | 
			
		||||
        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):
 | 
			
		||||
    """
 | 
			
		||||
    validate the user request
 | 
			
		||||
    判定用户请求是否合法
 | 
			
		||||
    """
 | 
			
		||||
    dept = get_session_user_dept(request)[1]
 | 
			
		||||
    if edept:
 | 
			
		||||
        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):
 | 
			
		||||
    """执行bash命令"""
 | 
			
		||||
    """
 | 
			
		||||
    run a bash shell command
 | 
			
		||||
    执行bash命令
 | 
			
		||||
    """
 | 
			
		||||
    return subprocess.call(cmd, shell=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def is_dir(dir_name, username='root', mode=0755):
 | 
			
		||||
    """目录存在,如果不存在就建立,并且权限正确"""
 | 
			
		||||
    """
 | 
			
		||||
    insure the dir exist and mode ok
 | 
			
		||||
    目录存在,如果不存在就建立,并且权限正确
 | 
			
		||||
    """
 | 
			
		||||
    if not os.path.isdir(dir_name):
 | 
			
		||||
        os.makedirs(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()
 | 
			
		||||
    else:
 | 
			
		||||
        user, dept = get_session_user_dept(request)
 | 
			
		||||
        print user, dept
 | 
			
		||||
        user_total_num = dept.user_set.all().count()
 | 
			
		||||
        user_active_num = dept.user_set.filter(is_active=True).count()
 | 
			
		||||
        host_total_num = dept.asset_set.all().count()
 | 
			
		||||
        host_active_num = dept.asset_set.all().filter(is_active=True).count()
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    username = User.objects.get(id=user_id).name
 | 
			
		||||
    apply_info = Apply.objects.filter(admin=username, status=0, read=0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,9 +56,9 @@ INSTALLED_APPS = (
 | 
			
		|||
    'django.contrib.humanize',
 | 
			
		||||
    'jumpserver',
 | 
			
		||||
    'juser',
 | 
			
		||||
    'jasset',
 | 
			
		||||
    'jperm',
 | 
			
		||||
    'jlog',
 | 
			
		||||
    # 'jasset',
 | 
			
		||||
    # 'jperm',
 | 
			
		||||
    # 'jlog',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
MIDDLEWARE_CLASSES = (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,9 +14,9 @@ urlpatterns = patterns('',
 | 
			
		|||
    (r'^file/download/$', 'jumpserver.views.download'),
 | 
			
		||||
    (r'^error/$', 'jumpserver.views.httperror'),
 | 
			
		||||
    (r'^juser/', include('juser.urls')),
 | 
			
		||||
    (r'^jasset/', include('jasset.urls')),
 | 
			
		||||
    (r'^jlog/', include('jlog.urls')),
 | 
			
		||||
    (r'^jperm/', include('jperm.urls')),
 | 
			
		||||
    # (r'^jasset/', include('jasset.urls')),
 | 
			
		||||
    # (r'^jlog/', include('jlog.urls')),
 | 
			
		||||
    # (r'^jperm/', include('jperm.urls')),
 | 
			
		||||
    (r'^node_auth/', 'jumpserver.views.node_auth'),
 | 
			
		||||
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,15 +1,18 @@
 | 
			
		|||
# coding: utf-8
 | 
			
		||||
 | 
			
		||||
from __future__ import division
 | 
			
		||||
import uuid
 | 
			
		||||
import urllib
 | 
			
		||||
 | 
			
		||||
from django.db.models import Count
 | 
			
		||||
from django.shortcuts import render_to_response
 | 
			
		||||
from django.template import RequestContext
 | 
			
		||||
from django.http import HttpResponseNotFound
 | 
			
		||||
from django.http import HttpResponse
 | 
			
		||||
from jperm.models import Apply
 | 
			
		||||
import paramiko
 | 
			
		||||
from jumpserver.api import *
 | 
			
		||||
import uuid
 | 
			
		||||
import urllib
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def getDaysByNum(num):
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +47,7 @@ def get_data(data, items, option):
 | 
			
		|||
    return dic
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_login
 | 
			
		||||
@require_role(role='user')
 | 
			
		||||
def index_cu(request):
 | 
			
		||||
    user_id = request.session.get('user_id')
 | 
			
		||||
    user = User.objects.filter(id=user_id)
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +56,7 @@ def index_cu(request):
 | 
			
		|||
    login_types = {'L': 'LDAP', 'M': 'MAP'}
 | 
			
		||||
    user_id = request.session.get('user_id')
 | 
			
		||||
    username = User.objects.get(id=user_id).username
 | 
			
		||||
    posts = user_perm_asset_api(username)
 | 
			
		||||
    posts = user.get_asset()
 | 
			
		||||
    host_count = len(posts)
 | 
			
		||||
    new_posts = []
 | 
			
		||||
    post_five = []
 | 
			
		||||
| 
						 | 
				
			
			@ -68,16 +71,16 @@ def index_cu(request):
 | 
			
		|||
    return render_to_response('index_cu.html', locals(), context_instance=RequestContext(request))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_login
 | 
			
		||||
@require_role(role='user')
 | 
			
		||||
def index(request):
 | 
			
		||||
    li_date, li_str = getDaysByNum(7)
 | 
			
		||||
    today = datetime.datetime.now().day
 | 
			
		||||
    from_week = datetime.datetime.now() - datetime.timedelta(days=7)
 | 
			
		||||
 | 
			
		||||
    if is_common_user(request):
 | 
			
		||||
    if is_role_request(request, 'user'):
 | 
			
		||||
        return index_cu(request)
 | 
			
		||||
 | 
			
		||||
    elif is_super_user(request):
 | 
			
		||||
    elif is_role_request(request, 'super'):
 | 
			
		||||
        users = User.objects.all()
 | 
			
		||||
        hosts = Asset.objects.all()
 | 
			
		||||
        online = Log.objects.filter(is_finished=0)
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +90,7 @@ def index(request):
 | 
			
		|||
        active_hosts = Asset.objects.filter(is_active=1)
 | 
			
		||||
        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]
 | 
			
		||||
        dept_name, dept = get_session_user_info(request)[4:]
 | 
			
		||||
        users = User.objects.filter(dept=dept)
 | 
			
		||||
| 
						 | 
				
			
			@ -205,7 +208,7 @@ def login(request):
 | 
			
		|||
        user_filter = User.objects.filter(username=username)
 | 
			
		||||
        if user_filter:
 | 
			
		||||
            user = user_filter[0]
 | 
			
		||||
            if md5_crypt(password) == user.password:
 | 
			
		||||
            if PyCrypt.md5_crypt(password) == user.password:
 | 
			
		||||
                request.session['user_id'] = user.id
 | 
			
		||||
                user_filter.update(last_login=datetime.datetime.now())
 | 
			
		||||
                if user.role == 'SU':
 | 
			
		||||
| 
						 | 
				
			
			@ -216,7 +219,7 @@ def login(request):
 | 
			
		|||
                    request.session['role_id'] = 0
 | 
			
		||||
                response = HttpResponseRedirect('/', )
 | 
			
		||||
                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
 | 
			
		||||
            else:
 | 
			
		||||
                error = '密码错误,请重新输入。'
 | 
			
		||||
| 
						 | 
				
			
			@ -248,7 +251,7 @@ def filter_ajax_api(request):
 | 
			
		|||
def install(request):
 | 
			
		||||
    from juser.models import DEPT, User
 | 
			
		||||
    if User.objects.filter(id=5000):
 | 
			
		||||
        return httperror(request, 'Jumpserver已初始化,不能重复安装!')
 | 
			
		||||
        return http_error(request, 'Jumpserver已初始化,不能重复安装!')
 | 
			
		||||
 | 
			
		||||
    dept = DEPT(id=1, name="超管部", comment="超级管理部门")
 | 
			
		||||
    dept.save()
 | 
			
		||||
| 
						 | 
				
			
			@ -257,7 +260,7 @@ def install(request):
 | 
			
		|||
    IDC(id=1, name="默认", comment="默认IDC").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()
 | 
			
		||||
    return http_success(request, u'Jumpserver初始化成功')
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -278,55 +281,56 @@ def transfer(sftp, filenames):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def upload(request):
 | 
			
		||||
    user, dept = get_session_user_dept(request)
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        hosts = request.POST.get('hosts')
 | 
			
		||||
        upload_files = request.FILES.getlist('file[]', None)
 | 
			
		||||
        upload_dir = "/tmp/%s" % user.username
 | 
			
		||||
        is_dir(upload_dir)
 | 
			
		||||
        date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
 | 
			
		||||
        hosts_list = hosts.split(',')
 | 
			
		||||
        user_hosts = get_user_host(user.username).keys()
 | 
			
		||||
        unperm_hosts = []
 | 
			
		||||
        filenames = {}
 | 
			
		||||
        for ip in hosts_list:
 | 
			
		||||
            if ip not in user_hosts:
 | 
			
		||||
                unperm_hosts.append(ip)
 | 
			
		||||
 | 
			
		||||
        if not hosts:
 | 
			
		||||
            return HttpResponseNotFound(u'地址不能为空')
 | 
			
		||||
 | 
			
		||||
        if 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)
 | 
			
		||||
            filenames[upload_file.name] = file_path
 | 
			
		||||
            f = open(file_path, 'w')
 | 
			
		||||
            for chunk in upload_file.chunks():
 | 
			
		||||
                f.write(chunk)
 | 
			
		||||
            f.close()
 | 
			
		||||
 | 
			
		||||
        sftps = []
 | 
			
		||||
        for host in hosts_list:
 | 
			
		||||
            username, password, host, port = get_connect_item(user.username, host)
 | 
			
		||||
            try:
 | 
			
		||||
                t = paramiko.Transport((host, port))
 | 
			
		||||
                t.connect(username=username, password=password)
 | 
			
		||||
                sftp = paramiko.SFTPClient.from_transport(t)
 | 
			
		||||
                sftps.append(sftp)
 | 
			
		||||
            except paramiko.AuthenticationException:
 | 
			
		||||
                return HttpResponseNotFound(u'%s 连接失败.' % host)
 | 
			
		||||
 | 
			
		||||
        # pool = Pool(processes=5)
 | 
			
		||||
        for sftp in sftps:
 | 
			
		||||
            transfer(sftp, filenames)
 | 
			
		||||
        # pool.close()
 | 
			
		||||
        # pool.join()
 | 
			
		||||
        return HttpResponse('传送成功')
 | 
			
		||||
 | 
			
		||||
    return render_to_response('upload.html', locals(), context_instance=RequestContext(request))
 | 
			
		||||
    pass
 | 
			
		||||
#     user, dept = get_session_user_dept(request)
 | 
			
		||||
#     if request.method == 'POST':
 | 
			
		||||
#         hosts = request.POST.get('hosts')
 | 
			
		||||
#         upload_files = request.FILES.getlist('file[]', None)
 | 
			
		||||
#         upload_dir = "/tmp/%s" % user.username
 | 
			
		||||
#         is_dir(upload_dir)
 | 
			
		||||
#         date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
 | 
			
		||||
#         hosts_list = hosts.split(',')
 | 
			
		||||
#         user_hosts = [asset.ip for asset in user.get_asset()]
 | 
			
		||||
#         unperm_hosts = []
 | 
			
		||||
#         filenames = {}
 | 
			
		||||
#         for ip in hosts_list:
 | 
			
		||||
#             if ip not in user_hosts:
 | 
			
		||||
#                 unperm_hosts.append(ip)
 | 
			
		||||
#
 | 
			
		||||
#         if not hosts:
 | 
			
		||||
#             return HttpResponseNotFound(u'地址不能为空')
 | 
			
		||||
#
 | 
			
		||||
#         if 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)
 | 
			
		||||
#             filenames[upload_file.name] = file_path
 | 
			
		||||
#             f = open(file_path, 'w')
 | 
			
		||||
#             for chunk in upload_file.chunks():
 | 
			
		||||
#                 f.write(chunk)
 | 
			
		||||
#             f.close()
 | 
			
		||||
#
 | 
			
		||||
#         sftps = []
 | 
			
		||||
#         for host in hosts_list:
 | 
			
		||||
#             username, password, host, port = get_connect_item(user.username, host)
 | 
			
		||||
#             try:
 | 
			
		||||
#                 t = paramiko.Transport((host, port))
 | 
			
		||||
#                 t.connect(username=username, password=password)
 | 
			
		||||
#                 sftp = paramiko.SFTPClient.from_transport(t)
 | 
			
		||||
#                 sftps.append(sftp)
 | 
			
		||||
#             except paramiko.AuthenticationException:
 | 
			
		||||
#                 return HttpResponseNotFound(u'%s 连接失败.' % host)
 | 
			
		||||
#
 | 
			
		||||
#         # pool = Pool(processes=5)
 | 
			
		||||
#         for sftp in sftps:
 | 
			
		||||
#             transfer(sftp, filenames)
 | 
			
		||||
#         # pool.close()
 | 
			
		||||
#         # pool.join()
 | 
			
		||||
#         return HttpResponse('传送成功')
 | 
			
		||||
#
 | 
			
		||||
#     return render_to_response('upload.html', locals(), context_instance=RequestContext(request))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def node_auth(request):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										238
									
								
								juser/views.py
								
								
								
								
							
							
						
						
									
										238
									
								
								juser/views.py
								
								
								
								
							| 
						 | 
				
			
			@ -4,174 +4,15 @@
 | 
			
		|||
 | 
			
		||||
import random
 | 
			
		||||
from Crypto.PublicKey import RSA
 | 
			
		||||
import crypt
 | 
			
		||||
 | 
			
		||||
from django.db.models import Q
 | 
			
		||||
from django.template import RequestContext
 | 
			
		||||
from django.db.models import ObjectDoesNotExist
 | 
			
		||||
 | 
			
		||||
from jumpserver.api import *
 | 
			
		||||
from juser.user_api import *
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def md5_crypt(string):
 | 
			
		||||
    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
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def dept_add(request):
 | 
			
		||||
    header_title, path1, path2 = '添加部门', '用户管理', '添加部门'
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_super_user
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def dept_list(request):
 | 
			
		||||
    header_title, path1, path2 = '查看部门', '用户管理', '查看部门'
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_admin
 | 
			
		||||
@require_role(role='admin')
 | 
			
		||||
def dept_list_adm(request):
 | 
			
		||||
    header_title, path1, path2 = '查看部门', '用户管理', '查看部门'
 | 
			
		||||
    user, dept = get_session_user_dept(request)
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +67,7 @@ def chg_role(request):
 | 
			
		|||
    return HttpResponseRedirect('/')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_super_user
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def dept_detail(request):
 | 
			
		||||
    dept_id = request.GET.get('id', None)
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_super_user
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def dept_del(request):
 | 
			
		||||
    dept_id = request.GET.get('id', None)
 | 
			
		||||
    if not dept_id or dept_id in ['1', '2']:
 | 
			
		||||
| 
						 | 
				
			
			@ -276,7 +117,7 @@ def dept_member_update(dept, users_id_list):
 | 
			
		|||
        user.save()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_super_user
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def dept_del_ajax(request):
 | 
			
		||||
    dept_ids = request.POST.get('dept_ids')
 | 
			
		||||
    for dept_id in dept_ids.split(','):
 | 
			
		||||
| 
						 | 
				
			
			@ -285,7 +126,7 @@ def dept_del_ajax(request):
 | 
			
		|||
    return HttpResponse("删除成功")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_super_user
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def dept_edit(request):
 | 
			
		||||
    header_title, path1, path2 = '部门编辑', '用户管理', '部门编辑'
 | 
			
		||||
    if request.method == 'GET':
 | 
			
		||||
| 
						 | 
				
			
			@ -331,7 +172,7 @@ def dept_user_ajax(request):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_super_user
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def group_add(request):
 | 
			
		||||
    error = ''
 | 
			
		||||
    msg = ''
 | 
			
		||||
| 
						 | 
				
			
			@ -372,7 +213,7 @@ def group_add(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):
 | 
			
		||||
    error = ''
 | 
			
		||||
    msg = ''
 | 
			
		||||
| 
						 | 
				
			
			@ -403,7 +244,7 @@ def group_add_adm(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):
 | 
			
		||||
    header_title, path1, path2 = '查看小组', '用户管理', '查看小组'
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_admin
 | 
			
		||||
@require_role(role='admin')
 | 
			
		||||
def group_list_adm(request):
 | 
			
		||||
    header_title, path1, path2 = '查看部门小组', '用户管理', '查看小组'
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_admin
 | 
			
		||||
@require_role(role='admin')
 | 
			
		||||
def group_detail(request):
 | 
			
		||||
    group_id = request.GET.get('id', None)
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_super_user
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def group_del(request):
 | 
			
		||||
    group_id = request.GET.get('id', '')
 | 
			
		||||
    if not group_id:
 | 
			
		||||
| 
						 | 
				
			
			@ -457,7 +298,7 @@ def group_del(request):
 | 
			
		|||
    return HttpResponseRedirect('/juser/group_list/')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_admin
 | 
			
		||||
@require_role(role='admin')
 | 
			
		||||
def group_del_adm(request):
 | 
			
		||||
    group_id = request.GET.get('id', '')
 | 
			
		||||
    if not validate(request, user_group=[group_id]):
 | 
			
		||||
| 
						 | 
				
			
			@ -468,7 +309,7 @@ def group_del_adm(request):
 | 
			
		|||
    return HttpResponseRedirect('/juser/group_list/')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_admin
 | 
			
		||||
@require_role(role='admin')
 | 
			
		||||
def group_del_ajax(request):
 | 
			
		||||
    group_ids = request.POST.get('group_ids')
 | 
			
		||||
    group_ids = group_ids.split(',')
 | 
			
		||||
| 
						 | 
				
			
			@ -490,7 +331,7 @@ def group_update_member(group_id, users_id_list):
 | 
			
		|||
            group.user_set.add(user)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_super_user
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def group_edit(request):
 | 
			
		||||
    error = ''
 | 
			
		||||
    msg = ''
 | 
			
		||||
| 
						 | 
				
			
			@ -538,7 +379,7 @@ def group_edit(request):
 | 
			
		|||
        return HttpResponseRedirect('/juser/group_list/')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_admin
 | 
			
		||||
@require_role(role='admin')
 | 
			
		||||
def group_edit_adm(request):
 | 
			
		||||
    error = ''
 | 
			
		||||
    msg = ''
 | 
			
		||||
| 
						 | 
				
			
			@ -586,7 +427,7 @@ def group_edit_adm(request):
 | 
			
		|||
        return HttpResponseRedirect('/juser/group_list/')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_super_user
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def user_add(request):
 | 
			
		||||
    error = ''
 | 
			
		||||
    msg = ''
 | 
			
		||||
| 
						 | 
				
			
			@ -597,15 +438,15 @@ def user_add(request):
 | 
			
		|||
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        username = request.POST.get('username', '')
 | 
			
		||||
        password = gen_rand_pwd(16)
 | 
			
		||||
        password = PyCrypt.gen_rand_pwd(16)
 | 
			
		||||
        name = request.POST.get('name', '')
 | 
			
		||||
        email = request.POST.get('email', '')
 | 
			
		||||
        dept_id = request.POST.get('dept_id')
 | 
			
		||||
        groups = request.POST.getlist('groups', [])
 | 
			
		||||
        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
 | 
			
		||||
        ldap_pwd = gen_rand_pwd(16)
 | 
			
		||||
        ldap_pwd = PyCrypt.gen_rand_pwd(16)
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_admin
 | 
			
		||||
@require_role(role='admin')
 | 
			
		||||
def user_add_adm(request):
 | 
			
		||||
    error = ''
 | 
			
		||||
    msg = ''
 | 
			
		||||
| 
						 | 
				
			
			@ -677,13 +518,13 @@ def user_add_adm(request):
 | 
			
		|||
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        username = request.POST.get('username', '')
 | 
			
		||||
        password = gen_rand_pwd(16)
 | 
			
		||||
        password = PyCrypt.gen_rand_pwd(16)
 | 
			
		||||
        name = request.POST.get('name', '')
 | 
			
		||||
        email = request.POST.get('email', '')
 | 
			
		||||
        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
 | 
			
		||||
        ldap_pwd = gen_rand_pwd(16)
 | 
			
		||||
        ldap_pwd = PyCrypt.gen_rand_pwd(16)
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_super_user
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def user_list(request):
 | 
			
		||||
    user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_admin
 | 
			
		||||
@require_role(role='admin')
 | 
			
		||||
def user_list_adm(request):
 | 
			
		||||
    user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_login
 | 
			
		||||
@require_role(role='user')
 | 
			
		||||
def user_detail(request):
 | 
			
		||||
    header_title, path1, path2 = '查看用户', '用户管理', '用户详情'
 | 
			
		||||
    if request.session.get('role_id') == 0:
 | 
			
		||||
| 
						 | 
				
			
			@ -810,7 +651,7 @@ def user_detail(request):
 | 
			
		|||
    user = User.objects.filter(id=user_id)
 | 
			
		||||
    if user:
 | 
			
		||||
        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_all = Log.objects.filter(user=user.name).order_by('-start_time')
 | 
			
		||||
        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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_admin
 | 
			
		||||
@require_role(role='admin')
 | 
			
		||||
def user_del(request):
 | 
			
		||||
    user_id = request.GET.get('id', '')
 | 
			
		||||
    if not user_id:
 | 
			
		||||
| 
						 | 
				
			
			@ -838,7 +679,7 @@ def user_del(request):
 | 
			
		|||
    return HttpResponseRedirect('/juser/user_list/')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_admin
 | 
			
		||||
@require_role(role='admin')
 | 
			
		||||
def user_del_ajax(request):
 | 
			
		||||
    user_ids = request.POST.get('ids')
 | 
			
		||||
    user_ids = user_ids.split(',')
 | 
			
		||||
| 
						 | 
				
			
			@ -857,7 +698,7 @@ def user_del_ajax(request):
 | 
			
		|||
    return HttpResponse('删除成功')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_super_user
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def user_edit(request):
 | 
			
		||||
    header_title, path1, path2 = '编辑用户', '用户管理', '用户编辑'
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_admin
 | 
			
		||||
@require_role(role='admin')
 | 
			
		||||
def user_edit_adm(request):
 | 
			
		||||
    header_title, path1, path2 = '编辑用户', '用户管理', '用户编辑'
 | 
			
		||||
    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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_login
 | 
			
		||||
@require_role(role='user')
 | 
			
		||||
def down_key(request):
 | 
			
		||||
    user_id = ''
 | 
			
		||||
    if is_super_user(request):
 | 
			
		||||
    if is_role_request(request, 'super'):
 | 
			
		||||
        user_id = request.GET.get('id')
 | 
			
		||||
 | 
			
		||||
    if is_group_admin(request):
 | 
			
		||||
    if is_role_request(request, 'admin'):
 | 
			
		||||
        user_id = request.GET.get('id')
 | 
			
		||||
        if not validate(request, user=[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')
 | 
			
		||||
 | 
			
		||||
    if user_id:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@
 | 
			
		|||
    <link rel="shortcut icon" href="/static/img/facio.ico" type="image/x-icon">
 | 
			
		||||
    {% include 'link_css.html' %}
 | 
			
		||||
    {% include 'head_script.html' %}
 | 
			
		||||
    {% block self_head_css_js %} {% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</head>
 | 
			
		||||
| 
						 | 
				
			
			@ -30,4 +31,5 @@
 | 
			
		|||
 | 
			
		||||
</body>
 | 
			
		||||
    {% include 'foot_script.html' %}
 | 
			
		||||
    {% block self_footer_js %} {% endblock %}
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,12 +15,7 @@
 | 
			
		|||
                            <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>
 | 
			
		||||
| 
						 | 
				
			
			@ -38,37 +33,13 @@
 | 
			
		|||
                                <label for="name" class="col-sm-2 control-label">部门名称<span class="red-fonts">*</span></label>
 | 
			
		||||
                                <div class="col-sm-8">
 | 
			
		||||
                                    {% 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 %}
 | 
			
		||||
                                        <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 %}
 | 
			
		||||
                                </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="form-group">
 | 
			
		||||
                                <label for="comment" class="col-sm-2 control-label">备注</label>
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +66,9 @@
 | 
			
		|||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block self_footer_js %}
 | 
			
		||||
<script>
 | 
			
		||||
$('#deptForm').validator({
 | 
			
		||||
    timely: 2,
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +78,7 @@ $('#deptForm').validator({
 | 
			
		|||
            rule: "required",
 | 
			
		||||
            tip: "输入部门名称",
 | 
			
		||||
            ok: "",
 | 
			
		||||
            msg: {required: "必须填写!"}
 | 
			
		||||
            msg: {required: "必须填写!!"}
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    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(){
 | 
			
		||||
    $("#submit_button").click(function(){
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue