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