增加js判断

pull/6/head
halcyon 2015-01-14 19:19:56 +08:00
commit 1925cf4033
23 changed files with 658 additions and 85 deletions

View File

@ -34,12 +34,12 @@ except ImportError:
time.sleep(3) time.sleep(3)
sys.exit() sys.exit()
CURRENT_DIR = os.path.dirname(__file__) BASE_DIR = os.path.dirname(__file__)
CONF = ConfigParser() CONF = ConfigParser()
CONF.read(os.path.join(CURRENT_DIR, 'jumpserver.conf')) CONF.read(os.path.join(BASE_DIR, 'jumpserver.conf'))
LOG_DIR = os.path.join(CURRENT_DIR, 'logs') LOG_DIR = os.path.join(BASE_DIR, 'logs')
# Web generate user ssh_key dir. # Web generate user ssh_key dir.
SSH_KEY_DIR = os.path.join(CURRENT_DIR, 'keys') SSH_KEY_DIR = os.path.join(BASE_DIR, 'keys')
# User upload the server key to this dir. # User upload the server key to this dir.
SERVER_KEY_DIR = os.path.join(SSH_KEY_DIR, 'server') SERVER_KEY_DIR = os.path.join(SSH_KEY_DIR, 'server')
# The key of decryptor. # The key of decryptor.

View File

@ -4,6 +4,7 @@ from django.shortcuts import render_to_response
from django.core.paginator import Paginator, EmptyPage from django.core.paginator import Paginator, EmptyPage
from models import IDC, Asset, BisGroup from models import IDC, Asset, BisGroup
from models import IDC, Asset, UserGroup
from connect import PyCrypt, KEY from connect import PyCrypt, KEY
@ -17,6 +18,9 @@ def jadd_host(request):
cryptor = PyCrypt(KEY) cryptor = PyCrypt(KEY)
eidc = IDC.objects.all() eidc = IDC.objects.all()
egroup = BisGroup.objects.all() egroup = BisGroup.objects.all()
egroup = UserGroup.objects.all()
is_actived = {'active': 1, 'no_active': 0}
login_typed = {'LDAP': 'L', 'SSH_KEY': 'S', 'PASSWORD': 'P', 'MAP': 'M'}
if request.method == 'POST': if request.method == 'POST':
j_ip = request.POST.get('j_ip') j_ip = request.POST.get('j_ip')
@ -30,6 +34,7 @@ def jadd_host(request):
j_idc = IDC.objects.get(name=j_idc) j_idc = IDC.objects.get(name=j_idc)
for group in j_group: for group in j_group:
c = BisGroup.objects.get(name=group) c = BisGroup.objects.get(name=group)
c = UserGroup.objects.get(name=group)
groups.append(c) groups.append(c)
if Asset.objects.filter(ip=str(j_ip)): if Asset.objects.filter(ip=str(j_ip)):
@ -130,4 +135,4 @@ def jadd_group(request):
def jlist_group(request): def jlist_group(request):
header_title, path1, path2 = '添加业务组 | Add Group', '资产管理', '查看业务组' header_title, path1, path2 = '添加业务组 | Add Group', '资产管理', '查看业务组'
posts = BisGroup.objects.all().order_by('id') posts = BisGroup.objects.all().order_by('id')
return render_to_response('jasset/jlist_group.html', locals(), context_instance=RequestContext(request)) return render_to_response('jasset/jlist_group.html', locals(), context_instance=RequestContext(request))

View File

@ -12,6 +12,11 @@ host_url = ldap://192.168.8.60:389
base_dn = dc=fengxing,dc=org base_dn = dc=fengxing,dc=org
root_dn = cn=admin,dc=fengxing,dc=org root_dn = cn=admin,dc=fengxing,dc=org
root_pw = 123456 root_pw = 123456
ldap_enable = 0
host_url = ldap://127.0.0.1:389
base_dn = dc=jumpserver,dc=org
root_dn = cn=admin,dc=jumpserver,dc=org
root_pw = secret234
[web] [web]
key = 88aaaf7ffe3c6c04 key = 88aaaf7ffe3c6c04

View File

@ -46,6 +46,7 @@ INSTALLED_APPS = (
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'jumpserver',
'juser', 'juser',
'jasset', 'jasset',
'jpermission', 'jpermission',

View File

@ -0,0 +1 @@
__author__ = 'Hudie'

View File

@ -0,0 +1,17 @@
import time
from django import template
register = template.Library()
@register.filter(name='stamp2str')
def stamp2str(value):
try:
return time.strftime('%Y/%m/%d %H:%M:%S', time.localtime(value))
except AttributeError:
return '0000/00/00 00:00:00'
@register.filter(name='int2str')
def int2str(value):
return str(value)

View File

@ -10,3 +10,5 @@ def base(request):
def skin_config(request): def skin_config(request):
return render_to_response('skin_config.html') return render_to_response('skin_config.html')

View File

@ -1,20 +1,125 @@
# coding: utf-8 # coding: utf-8
# Author: Guanghongwei
# Email: ibuler@qq.com
import time
import os
import hashlib
import random
import subprocess
import ldap
from ldap import modlist
from Crypto.PublicKey import RSA
import crypt
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.core.exceptions import ObjectDoesNotExist
from juser.models import UserGroup, User from juser.models import UserGroup, User
from connect import PyCrypt, KEY
from connect import BASE_DIR
from connect import CONF
CRYPTOR = PyCrypt(KEY)
LDAP_ENABLE = CONF.getint('ldap', 'ldap_enable')
if LDAP_ENABLE:
LDAP_HOST_URL = CONF.get('ldap', 'host_url')
LDAP_BASE_DN = CONF.get('ldap', 'base_dn')
LDAP_ROOT_DN = CONF.get('ldap', 'root_dn')
LDAP_ROOT_PW = CONF.get('ldap', 'root_pw')
def md5_crypt(string):
return hashlib.new("md5", string).hexdigest()
def gen_rand_pwd(num):
"""生成随机密码"""
seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
salt_list = []
for i in range(num):
salt_list.append(random.choice(seed))
salt = ''.join(salt_list)
return salt
def bash(cmd):
"""执行bash命令"""
return subprocess.call(cmd, shell=True)
def is_dir(dir_name, mode=0755):
if not os.path.isdir(dir_name):
os.makedirs(dir_name)
os.chmod(dir_name, mode)
class AddError(Exception): class AddError(Exception):
pass pass
# class LDAPMgmt():
# def __init__(self,
# host_url=LDAP_HOST_URL,
# base_dn=LDAP_BASE_DN,
# root_cn=LDAP_ROOT_DN,
# root_pw=LDAP_ROOT_PW):
# self.ldap_host = host_url
# self.ldap_base_dn = base_dn
# self.conn = ldap.initialize(host_url)
# self.conn.set_option(ldap.OPT_REFERRALS, 0)
# self.conn.protocol_version = ldap.VERSION3
# self.conn.simple_bind_s(root_cn, root_pw)
#
# def list(self, filter, scope=ldap.SCOPE_SUBTREE, attr=None):
# result = {}
# try:
# ldap_result = self.conn.search_s(self.ldap_base_dn, scope, filter, attr)
# for entry in ldap_result:
# name, data = entry
# for k, v in data.items():
# print '%s: %s' % (k, v)
# result[k] = v
# return result
# except ldap.LDAPError, e:
# print e
#
# def add(self, dn, attrs):
# try:
# ldif = modlist.addModlist(attrs)
# self.conn.add_s(dn, ldif)
# except ldap.LDAPError, e:
# print e
#
# def modify(self, dn, attrs):
# try:
# attr_s = []
# for k, v in attrs.items():
# attr_s.append((2, k, v))
# self.conn.modify_s(dn, attr_s)
# except ldap.LDAPError, e:
# print e
#
# def delete(self, dn):
# try:
# self.conn.delete_s(dn)
# except ldap.LDAPError, e:
# print e
def gen_sha512(salt, password):
return crypt.crypt(password, '$6$%s$' % salt)
def group_add(request): def group_add(request):
error = '' error = ''
msg = '' msg = ''
header_title, path1, path2 = '添加属组 | Add Group', 'juser', 'group_add'
if request.method == 'POST': if request.method == 'POST':
group_name = request.POST.get('j_group_name', None) group_name = request.POST.get('group_name', None)
comment = request.POST.get('j_comment', None) comment = request.POST.get('comment', None)
try: try:
if not group_name: if not group_name:
@ -37,44 +142,177 @@ def group_add(request):
else: else:
msg = u'添加组 %s 成功' % group_name msg = u'添加组 %s 成功' % group_name
return render_to_response('juser/group_add.html', return render_to_response('juser/group_add.html', locals())
{'header_title': u'添加属组 | Add Group',
'path1': 'juser', 'path2': 'group_add',
'error': error, 'msg': msg})
def group_list(request): def group_list(request):
header_title, path1, path2 = '查看属组 | Add Group', 'juser', 'group_add'
groups = UserGroup.objects.all() groups = UserGroup.objects.all()
return render_to_response('juser/group_list.html', return render_to_response('juser/group_list.html', locals())
{'header_title': u'查看属组 | Add Group',
'path1': 'juser', 'path2': 'group_add',
'groups': groups})
def user_list(request): def user_list(request):
pass pass
def db_add_user(**kwargs):
groups_post = kwargs.pop('groups')
user = User(**kwargs)
group_select = []
for group_id in groups_post:
group = UserGroup.objects.filter(id=group_id)
group_select.extend(group)
user.save()
user.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)
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, 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_pwd1):
bash('useradd %s; echo %s | passwd --stdin %s' % (username, password, username))
gen_ssh_key(username, ssh_key_pwd1)
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.get(username=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)]}
sudo_dn = 'cn=%s,ou=Sudoers,%s' % (username, LDAP_BASE_DN)
sudo_attr = {'objectClass': ['top', 'sudoRole'],
'cn': ['%s' % str(username)],
'sudoCommand': ['/bin/pwd'],
'sudoHost': ['192.168.1.1'],
'sudoOption': ['!authenticate'],
'sudoRunAsUser': ['root'],
'sudoUser': ['%s' % str(username)]}
ldap_conn = LDAPMgmt()
ldap_conn.add(user_dn, user_attr)
ldap_conn.add(group_dn, group_attr)
ldap_conn.add(sudo_dn, sudo_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 = LDAPMgmt()
ldap_conn.delete(user_dn)
ldap_conn.delete(group_dn)
ldap_conn.delete(sudo_dn)
def user_add(request): def user_add(request):
error = '' error = ''
msg = '' msg = ''
header_title, path1, path2 = '添加用户 | Add User', 'juser', 'user_add'
user_role = {'SU': 'SuperUser', 'GA': 'GroupAdmin', 'CU': 'CommonUser'} user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
groups = UserGroup.objects.all() all_group = UserGroup.objects.all()
if request.method == 'POST': if request.method == 'POST':
username = request.POST.get('j_username', None) username = request.POST.get('username', None)
password = request.POST.get('j_password', None) password = request.POST.get('password', None)
name = request.POST.get('j_name', None) name = request.POST.get('name', None)
email = request.POST.get('j_email', '') email = request.POST.get('email', '')
groups = request.POST.getlist('j_group', None) groups = request.POST.getlist('groups', None)
role = request.POST.get('j_role', None) groups_str = ' '.join(groups)
ssh_pwd = request.POST.get('j_ssh_pwd', None) role_post = request.POST.get('role', None)
is_active = request.POST.get('j_is_active', None) ssh_pwd = request.POST.get('ssh_pwd', None)
ssh_key_pwd1 = request.POST.get('ssh_key_pwd1', None)
is_active = request.POST.get('is_active', '1')
ldap_pwd = gen_rand_pwd(16)
return render_to_response('juser/user_add.html', try:
{'header_title': u'添加用户 | Add User', if None in [username, password, ssh_key_pwd1, name, groups, role_post, is_active]:
'path1': 'juser', 'path2': 'user_add', error = u'带*内容不能为空'
'roles': user_role, 'groups': groups}) raise AddError
user = User.objects.filter(username=username)
if user:
error = u'用户 %s 已存在' % username
raise AddError
except AddError:
pass
else:
time_now = time.time()
try:
db_add_user(username=username,
password=md5_crypt(password),
name=name, email=email,
groups=groups, role=role_post,
ssh_pwd=CRYPTOR.encrypt(ssh_pwd),
ssh_key_pwd1=CRYPTOR.encrypt(ssh_key_pwd1),
ldap_pwd=CRYPTOR.encrypt(ldap_pwd),
is_active=is_active,
date_joined=time_now)
server_add_user(username, password, ssh_key_pwd1)
if LDAP_ENABLE:
ldap_add_user(username, ldap_pwd)
msg = u'添加用户 %s 成功!' % username
except Exception, e:
error = u'添加用户 %s 失败 %s ' % (username, e)
try:
db_del_user(username)
server_del_user(username)
if LDAP_ENABLE:
ldap_del_user(username)
except Exception:
pass
return render_to_response('juser/user_add.html', locals())

View File

@ -1,10 +1,5 @@
/*@import url("//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700&lang=en");*/ @import url("//fonts.useso.com/css?family=Open+Sans:300,400,600,700&lang=en");
/*
*
* INSPINIA - Responsive Admin Theme
* Copyright 2014 Webapplayers.com
*
*/
h1, h1,
h2, h2,
h3, h3,

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,64 @@
/*! nice Validator 0.7.3
* (c) 2012-2014 Jony Zhang <zj86@live.cn>, MIT Licensed
* http://niceue.com/validator/
*/
.n-inline-block,.nice-validator input,.nice-validator select,.nice-validator textarea,.msg-wrap,.n-icon,.n-msg{display:inline-block;*display:inline;*zoom:1}
.msg-box{position:relative;*zoom:1}
.msg-wrap{position:relative;white-space:nowrap}
.msg-wrap,.n-icon,.n-msg{vertical-align:top}
.n-arrow{position:absolute;overflow:hidden;}
.n-arrow b,.n-arrow i{position:absolute;left:0;top:0;border:0;margin:0;padding:0;overflow:hidden;font-weight:400;font-style:normal;font-size:12px;font-family:serif;line-height:14px;_line-height:15px}
.n-arrow i{text-shadow:none}
.n-icon{width:16px;height:16px;overflow:hidden;background-repeat:no-repeat}
.n-msg{display:inline-block;line-height:15px;margin-left:2px;*margin-top:-1px;_margin-top:0;font-size:12px;font-family:simsun}
.n-error{color:#c33}
.n-ok{color:#390}
.n-tip,.n-loading{color:#808080}
.n-error .n-icon{background-position:0 0}
.n-ok .n-icon{background-position:-16px 0}
.n-tip .n-icon{background-position:-32px 0}
.n-loading .n-icon{background:url("images/loading.gif") 0 center no-repeat !important}
.n-top,.n-right,.n-bottom,.n-left{display:inline-block;line-height:0;vertical-align:top;outline:0}
.n-top .n-arrow,.n-bottom .n-arrow{height:6px;width:12px;left:8px}
.n-left .n-arrow,.n-right .n-arrow{width:6px;height:12px;top:6px}
.n-top{vertical-align:top;}
.n-top .msg-wrap{margin-bottom:6px}
.n-top .n-arrow{bottom:-6px;}
.n-top .n-arrow b{top:-6px}
.n-top .n-arrow i{top:-7px}
.n-bottom{vertical-align:bottom;}
.n-bottom .msg-wrap{margin-top:6px}
.n-bottom .n-arrow{top:-6px;}
.n-bottom .n-arrow b{top:-1px}
.n-bottom .n-arrow i{top:0}
.n-left .msg-wrap{right:100%;margin-right:6px}
.n-left .n-arrow{right:-6px;}
.n-left .n-arrow b{left:-6px}
.n-left .n-arrow i{left:-7px}
.n-right .msg-wrap{margin-left:6px}
.n-right .n-arrow{left:-6px;}
.n-right .n-arrow b{left:1px}
.n-right .n-arrow i{left:2px}
.n-default .n-left,.n-default .n-right{margin-top:5px}
.n-default .n-top .msg-wrap{bottom:100%}
.n-default .n-bottom .msg-wrap{top:100%}
.n-default .msg-wrap{position:absolute;z-index:1;}
.n-default .msg-wrap .n-icon{background-image:url("images/validator_default.png")}
.n-default .n-tip .n-icon{display:none}
.n-simple .msg-wrap{position:absolute;z-index:1;}
.n-simple .msg-wrap .n-icon{background-image:url("images/validator_simple.png")}
.n-simple .n-top .msg-wrap{bottom:100%}
.n-simple .n-bottom .msg-wrap{top:100%}
.n-simple .n-left,.n-simple .n-right{margin-top:5px}
.n-simple .n-bottom .msg-wrap{margin-top:3px}
.n-simple .n-tip .n-icon{display:none}
.n-yellow .msg-wrap{position:absolute;z-index:1;padding:4px 6px;font-size:12px;border:1px solid transparent;background-color:#fffcef;border-color:#ffbb76;color:#db7c22;box-shadow:0 1px 3px #ccc;border-radius:2px;}
.n-yellow .msg-wrap .n-arrow b{color:#ffbb76;text-shadow:0 0 2px #ccc}
.n-yellow .msg-wrap .n-arrow i{color:#fffcef}
.n-yellow .msg-wrap .n-icon{background-image:url("images/validator_simple.png")}
.n-yellow .n-top .msg-wrap{bottom:100%}
.n-yellow .n-bottom .msg-wrap{top:100%}
.n-yellow .n-tip,.n-yellow .n-ok,.n-yellow .n-loading{background-color:#f8fdff;border-color:#ddd;color:#333;box-shadow:0 1px 3px #ccc;}
.n-yellow .n-tip .n-arrow b,.n-yellow .n-ok .n-arrow b,.n-yellow .n-loading .n-arrow b{color:#ddd;text-shadow:0 0 2px #ccc}
.n-yellow .n-tip .n-arrow i,.n-yellow .n-ok .n-arrow i,.n-yellow .n-loading .n-arrow i{color:#f8fdff}
.n-yellow .n-tip .n-icon{display:none}

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

File diff suppressed because one or more lines are too long

156
static/js/validator/zh_CN.js Executable file
View File

@ -0,0 +1,156 @@
/*********************************
* Themes, rules, and i18n support
* Locale: Chinese; 中文
*********************************/
(function(factory) {
if (typeof define === 'function') {
define(function(require, exports, module){
var $ = require('jquery');
$._VALIDATOR_URI = module.uri;
require('../src/jquery.validator')($);
factory($);
});
} else {
factory(jQuery);
}
}(function($) {
/* Global configuration
*/
$.validator.config({
//stopOnError: false,
//theme: 'yellow_right',
defaultMsg: "{0}格式不正确",
loadingMsg: "正在验证...",
// Custom rules
rules: {
digits: [/^\d+$/, "请输入数字"]
,letters: [/^[a-z]+$/i, "{0}只能输入字母"]
,tel: [/^(?:(?:0\d{2,3}[\- ]?[1-9]\d{6,7})|(?:[48]00[\- ]?[1-9]\d{6}))$/, "电话格式不正确"]
,mobile: [/^1[3-9]\d{9}$/, "手机号格式不正确"]
,email: [/^[\w\+\-]+(\.[\w\+\-]+)*@[a-z\d\-]+(\.[a-z\d\-]+)*\.([a-z]{2,4})$/i, "邮箱格式不正确"]
,qq: [/^[1-9]\d{4,}$/, "QQ号格式不正确"]
,date: [/^\d{4}-\d{1,2}-\d{1,2}$/, "请输入正确的日期,例:yyyy-mm-dd"]
,time: [/^([01]\d|2[0-3])(:[0-5]\d){1,2}$/, "请输入正确的时间,例:14:30或14:30:00"]
,ID_card: [/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[A-Z])$/, "请输入正确的身份证号码"]
,url: [/^(https?|ftp):\/\/[^\s]+$/i, "网址格式不正确"]
,postcode: [/^[1-9]\d{5}$/, "邮政编码格式不正确"]
,chinese: [/^[\u0391-\uFFE5]+$/, "请输入中文"]
,username: [/^\w{3,12}$/, "请输入3-12位数字、字母、下划线"]
,password: [/^[0-9a-zA-Z]{6,16}$/, "密码由6-16位数字、字母组成"]
,accept: function (element, params){
if (!params) return true;
var ext = params[0];
return (ext === '*') ||
(new RegExp(".(?:" + (ext || "png|jpg|jpeg|gif") + ")$", "i")).test(element.value) ||
this.renderMsg("只接受{1}后缀", ext.replace('|', ','));
}
}
});
/* Default error messages
*/
$.validator.config({
messages: {
required: "{0}不能为空",
remote: "{0}已被使用",
integer: {
'*': "请输入整数",
'+': "请输入正整数",
'+0': "请输入正整数或0",
'-': "请输入负整数",
'-0': "请输入负整数或0"
},
match: {
eq: "{0}与{1}不一致",
neq: "{0}与{1}不能相同",
lt: "{0}必须小于{1}",
gt: "{0}必须大于{1}",
lte: "{0}必须小于或等于{1}",
gte: "{0}必须大于或等于{1}"
},
range: {
rg: "请输入{1}到{2}的数",
gte: "请输入大于或等于{1}的数",
lte: "请输入小于或等于{1}的数"
},
checked: {
eq: "请选择{1}项",
rg: "请选择{1}到{2}项",
gte: "请至少选择{1}项",
lte: "请最多选择{1}项"
},
length: {
eq: "请输入{1}个字符",
rg: "请输入{1}到{2}个字符",
gte: "请至少输入{1}个字符",
lte: "请最多输入{1}个字符",
eq_2: "",
rg_2: "",
gte_2: "",
lte_2: ""
}
}
});
/* Themes
*/
var TPL_ARROW = '<span class="n-arrow"><b>◆</b><i>◆</i></span>';
$.validator.setTheme({
'simple_right': {
formClass: 'n-simple',
msgClass: 'n-right'
},
'simple_bottom': {
formClass: 'n-simple',
msgClass: 'n-bottom'
},
'yellow_top': {
formClass: 'n-yellow',
msgClass: 'n-top',
msgArrow: TPL_ARROW
},
'yellow_right': {
formClass: 'n-yellow',
msgClass: 'n-right',
msgArrow: TPL_ARROW
},
'yellow_right_effect': {
formClass: 'n-yellow',
msgClass: 'n-right',
msgArrow: TPL_ARROW,
msgShow: function($msgbox, type){
var $el = $msgbox.children();
if ($el.is(':animated')) return;
if (type === 'error') {
$el.css({
left: '20px',
opacity: 0
}).delay(100).show().stop().animate({
left: '-4px',
opacity: 1
}, 150).animate({
left: '3px'
}, 80).animate({
left: 0
}, 80);
} else {
$el.css({
left: 0,
opacity: 1
}).fadeIn(200);
}
},
msgHide: function($msgbox, type){
var $el = $msgbox.children();
$el.stop().delay(100).show().animate({
left: '20px',
opacity: 0
}, 300, function(){
$msgbox.hide();
});
}
}
});
}));

View File

@ -31,17 +31,14 @@
</a> </a>
</div> </div>
</div> </div>
<div class="ibox-content" name="addidc" id="addidc" onclick="show(this)">
addidc
</div>
<div class="ibox-content" id="addhost"> <div class="ibox-content" id="addhost">
{% if emg %} {% if emg %}
<div class="alert alert-warning text-center">{{ emg }}</div> <div class="alert alert-warning text-center">{{ emg }}</div>
{% endif %} {% endif %}
<form method="post" class="form-horizontal"> <form method="post" id="jasset_add" class="form-horizontal">
<div class="form-group"><label class="col-sm-2 control-label"> IP地址 </label> <div class="form-group"><label class="col-sm-2 control-label"> IP地址 </label>
<div class="col-sm-8"><input type="text" value="{{ j_ip }}" placeholder="192.168.1.1" name="j_ip" class="form-control"></div> <div class="col-sm-8"><input type="text" value="{{ j_ip }}" name="j_ip" class="form-control"></div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
@ -131,17 +128,6 @@
</div> </div>
</div> </div>
<!-- Peity -->
<script src="static/js/plugins/peity/jquery.peity.min.js"></script>
<!-- Custom and plugin javascript -->
<script src="static/js/inspinia.js"></script>
<script src="static/js/plugins/pace/pace.min.js"></script>
<!-- Peity -->
<script src="static/js/demo/peity-demo.js"></script>
<script> <script>
var showFlag={}; var showFlag={};
function show(o){ function show(o){
@ -149,12 +135,76 @@ var showFlag={};
if(showFlag.j_type=="MAP"){ if(showFlag.j_type=="MAP"){
document.getElementById("a1").style.display=""; document.getElementById("a1").style.display="";
} }
else if(showFlag.addidc=="addidc"){
document.getElementById("addidc").style.display="";
}
else{ else{
document.getElementById("a1").style.display="none"; document.getElementById("a1").style.display="none";
}}; }};
//验证初始化
$('#jasset_add').validator({
focusCleanup: true,
stopOnError:false,
//debug: true,
timely: 2,
theme: "yellow_right_effect",
//自定义规则PS建议尽量在全局配置中定义规则统一管理
rules: {
username: [/^[a-zA-Z0-9]+$/, '用户名无效! 仅支持字母与数字。'],
check_ip: [/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/, 'ip不正确'],
check_port: [/^\d{1,5}$/, '端口号不正确']
},
fields: {
"j_ip": {
rule: "required;check_ip",
tip: "请输入IP",
ok: "ok",
msg: {required: "必须填写!"}
},
"j_port": {
rule: "required;check_port",
tip: "请输入端口号",
ok: "ok",
msg: {required: "必须填写!"}
},
"user[user_password]": {
rule: "required;length[6~];password;strength",
tip: "6个或更多字符! 要复杂些。",
ok: "",
msg: {
required: "密码不能为空!",
length: "密码最少为6位。"
}
},
"user[screen_name]": {
rule: "required;username;remote[check/user.php]",
tip: "别担心,你可以稍后进行修改。",
ok: "用户名可以使用。<br>你可以稍后进行修改。",
msg: {required: "用户名必填!<br>你可以稍后进行修改。"}
}
},
//验证成功
valid: function(form) {
$.ajax({
url: 'results.php',
type: 'POST',
data: $(form).serialize(),
success: function(d){
$('#result').fadeIn(300).delay(2000).fadeOut(500);
}
});
},
//验证失败
invalid: function(form) {
//按钮动画效果
$('#btn-submit').stop().delay(100)
.animate({left:-5}, 100)
.animate({left:5}, 100)
.animate({left:-4}, 100)
.animate({left:4}, 100)
.animate({left:-3}, 100)
.animate({left:0}, 100);
}
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -35,16 +35,16 @@
<div class="alert alert-success text-center">{{ msg }}</div> <div class="alert alert-success text-center">{{ msg }}</div>
{% endif %} {% endif %}
<div class="form-group"> <div class="form-group">
<label for="j_group_name" class="col-sm-2 control-label">组名<span class="red-fonts">*</span></label> <label for="group_name" class="col-sm-2 control-label">组名<span class="red-fonts">*</span></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="j_group_name" name="j_group_name" placeholder="Group name" type="text" class="form-control"> <input id="group_name" name="group_name" placeholder="Group name" type="text" class="form-control">
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="j_comment" class="col-sm-2 control-label">备注</label> <label for="comment" class="col-sm-2 control-label">备注</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="j_comment" name="j_comment" placeholder="Comment" type="text" class="form-control"> <input id="comment" name="comment" placeholder="Comment" type="text" class="form-control">
</div> </div>
</div> </div>

View File

@ -1,4 +1,5 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load mytags %}
{% block content %} {% block content %}
{% include 'nav_cat_bar.html' %} {% include 'nav_cat_bar.html' %}
@ -27,18 +28,24 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<form method="get" class="form-horizontal"> <form method="post" class="form-horizontal" action="">
{% if error %}
<div class="alert alert-warning text-center">{{ error }}</div>
{% endif %}
{% if msg %}
<div class="alert alert-success text-center">{{ msg }}</div>
{% endif %}
<div class="form-group"> <div class="form-group">
<label for="j_username" class="col-sm-2 control-label">用户名<span class="red-fonts">*</span></label> <label for="username" class="col-sm-2 control-label">用户名<span class="red-fonts">*</span></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="j_username" name="username" placeholder="Username" type="text" class="form-control"> <input id="username" name="username" placeholder="Username" type="text" class="form-control" value={{ username }}>
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="j_password" class="col-sm-2 control-label">密码<span class="red-fonts">*</span></label> <label for="password" class="col-sm-2 control-label">密码<span class="red-fonts">*</span></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="j_password" name="j_password" placeholder="Password" type="password" class="form-control"> <input id="password" name="password" placeholder="Password" type="password" class="form-control" value={{ password }}>
<span class="help-block m-b-none"> <span class="help-block m-b-none">
登陆web的密码 登陆web的密码
</span> </span>
@ -46,62 +53,84 @@
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="j_name" class="col-sm-2 control-label">姓名<span class="red-fonts">*</span></label> <label for="ssh_key_pwd1" class="col-sm-2 control-label">密钥密码<span class="red-fonts">*</span></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="j_name" name="j_name" placeholder="Name" type="text" class="form-control" > <input id="ssh_key_pwd1" name="ssh_key_pwd1" placeholder="SSH Key Password" type="password" class="form-control" value="{{ ssh_key_pwd1 }}">
<span class="help-block m-b-none">
登陆 Jumpserver 使用的SSH密钥的密码
</span>
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="j_email" class="col-sm-2 control-label">Email</label> <label for="name" class="col-sm-2 control-label">姓名<span class="red-fonts">*</span></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="j_email" name="j_email" type="email" placeholder="Email" class="form-control"> <input id="name" name="name" placeholder="Name" type="text" class="form-control" value={{ name }} >
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="j_group" class="col-lg-2 control-label">属组<span class="red-fonts">*</span></label> <label for="groups" class="col-lg-2 control-label">属组<span class="red-fonts">*</span></label>
<div class="col-sm-8"> <div class="col-sm-8">
<select id="j_group" name="j_group" class="form-control m-b" multiple> <select id="groups" name="groups" class="form-control m-b" multiple>
{% for group in groups %} {% for group in all_group %}
{% if forloop.first %} {% if groups_str %}
<option value="{{ group.id }}" selected>{{ group.name }}</option> {% if group.id|int2str in groups_str %}
<option value="{{ group.id }}" selected>{{ group.name }}</option>
{% else %}
<option value="{{ group.id }}">{{ group.name }}</option>
{% endif %}
{% else %}
{% if forloop.first %}
<option value="{{ group.id }}" selected>{{ group.name }}</option>
{% else %}
<option value="{{ group.id }}">{{ group.name }}</option>
{% endif %}
{% endif %} {% endif %}
<option value="{{ group.id }}">{{ group.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="j_role" class="col-lg-2 control-label">角色<span class="red-fonts">*</span></label> <label for="role" class="col-lg-2 control-label">角色<span class="red-fonts">*</span></label>
<div class="col-sm-8"> <div class="col-sm-8">
<select id="j_role" name="j_role" class="form-control m-b"> <select id="role" name="role" class="form-control m-b">
{% for r, role in roles.items %} {% for r, role_name in user_role.items %}
<option value="{{ r }}">{{ role }}</option> {% ifequal r role_post %}
<option value="{{ r }}" selected>{{ role_name }}</option>
{% else %}
<option value="{{ r }}">{{ role_name }}</option>
{% endifequal %}
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="j_ldap_pwd" class="col-sm-2 control-label">SSH密码</label> <label for="ssh_pwd" class="col-sm-2 control-label">SSH密码</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="j_ldap_pwd" name="j_ldap_pwd" type="password" placeholder="LDAP Password" class="form-control"> <input id="ssh_pwd" name="ssh_pwd" type="password" placeholder="SSH Password" class="form-control" value="{{ ssh_pwd }}">
<span class="help-block m-b-none"> <span class="help-block m-b-none">
如果使用password方式该密码是用户在后端服务器的密码 如果使用password方式该密码是用户在后端服务器的密码
</span> </span>
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group">
<label for="email" class="col-sm-2 control-label">Email</label>
<div class="col-sm-8">
<input id="email" name="email" type="email" placeholder="Email" class="form-control" value="{{ email }}">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label">是否启用</label> <div class="form-group"><label class="col-sm-2 control-label">是否启用</label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="radio i-checks"> <div class="radio i-checks">
<label><input type="radio" value="1" name="j_is_active" checked>启用 </label> <label><input type="radio" value="1" name="is_active" checked>启用 </label>
</div> </div>
<div class="radio i-checks"> <div class="radio i-checks">
<label><input type="radio" value="0" name="j_is_active">禁用 </label> <label><input type="radio" value="0" name="is_active">禁用 </label>
</div> </div>
</div> </div>
</div> </div>

View File

@ -3,4 +3,5 @@
<link href="/static/css/plugins/iCheck/custom.css" rel="stylesheet"> <link href="/static/css/plugins/iCheck/custom.css" rel="stylesheet">
<link href="/static/css/animate.css" rel="stylesheet"> <link href="/static/css/animate.css" rel="stylesheet">
<link href="/static/css/style.css" rel="stylesheet"> <link href="/static/css/style.css" rel="stylesheet">
<link href="/static/css/colorbox.css" rel="stylesheet"> <link href="/static/css/colorbox.css" rel="stylesheet">
<link href="/static/css/vaildator/jquery.validator.css" rel="stylesheet">

View File

@ -29,3 +29,7 @@
<!-- pop windows --> <!-- pop windows -->
<script src="/static/js/jquery.colorbox.js"></script> <script src="/static/js/jquery.colorbox.js"></script>
<!-- validator js -->
<script src="/static/js/validator/jquery.validator.js"></script>
<script src="/static/js/validator/zh_CN.js"></script>