Commit 2a645747 authored by root's avatar root

Merge in 20150131

parents a8991bfb deb55d3b
...@@ -26,6 +26,7 @@ django.setup() ...@@ -26,6 +26,7 @@ django.setup()
from juser.models import User from juser.models import User
from jasset.models import Asset from jasset.models import Asset
from jlog.models import Log from jlog.models import Log
from jperm.views import perm_user_asset
try: try:
import termios import termios
...@@ -208,14 +209,9 @@ def posix_shell(chan, username, host): ...@@ -208,14 +209,9 @@ def posix_shell(chan, username, host):
def get_user_host(username): def get_user_host(username):
"""Get the hosts of under the user control.""" """Get the hosts of under the user control."""
hosts_attr = {} hosts_attr = {}
try: asset_all = perm_user_asset(username=username)
user = User.objects.get(username=username) for asset in asset_all:
except ObjectDoesNotExist: hosts_attr[asset.ip] = [asset.id, asset.comment]
raise ServerError("Username \033[1;31m%s\033[0m doesn't exist on Jumpserver." % username)
else:
perm_all = user.permission_set.all()
for perm in perm_all:
hosts_attr[perm.asset.ip] = [perm.asset.id, perm.asset.comment]
return hosts_attr return hosts_attr
...@@ -235,34 +231,18 @@ def get_connect_item(username, ip): ...@@ -235,34 +231,18 @@ def get_connect_item(username, ip):
login_type_dict = { login_type_dict = {
'L': user.ldap_pwd, 'L': user.ldap_pwd,
'S': user.ssh_key_pwd2,
'P': user.ssh_pwd, 'P': user.ssh_pwd,
} }
if asset.login_type in login_type_dict: if asset.login_type in login_type_dict:
password = cryptor.decrypt(login_type_dict[asset.login_type]) password = cryptor.decrypt(login_type_dict[asset.login_type])
return username, password, ip, port return username, password, ip, port
elif asset.login_type == 'M': elif asset.login_type == 'M':
perms = asset.permission_set.filter(user=user) username = asset.username
if perms: password = cryptor.decrypt(asset.password)
perm = perms[0] return username, password, ip, port
else:
raise ServerError('Permission %s to %s does not exist.' % (username, ip))
if perm.role == 'SU':
username_super = asset.username_super
password_super = cryptor.decrypt(asset.password_super)
return username_super, password_super, ip, port
elif perm.role == 'CU':
username_common = asset.username_common
password_common = asset.password_common
return username_common, password_common, ip, port
else:
raise ServerError('Perm in %s for %s map role is not in ["SU", "CU"].' % (ip, username))
else: else:
raise ServerError('Login type is not in ["L", "S", "P", "M"]') raise ServerError('Login type is not in ["L", "S", "P", "M"]')
......
...@@ -37,10 +37,8 @@ class Asset(models.Model): ...@@ -37,10 +37,8 @@ class Asset(models.Model):
user_group = models.ManyToManyField(UserGroup) user_group = models.ManyToManyField(UserGroup)
bis_group = models.ManyToManyField(BisGroup) bis_group = models.ManyToManyField(BisGroup)
login_type = models.CharField(max_length=1, choices=LOGIN_TYPE_CHOICES, default='L') login_type = models.CharField(max_length=1, choices=LOGIN_TYPE_CHOICES, default='L')
username_common = models.CharField(max_length=20, blank=True, null=True) username = models.CharField(max_length=20, blank=True, null=True)
password_common = models.CharField(max_length=80, blank=True, null=True) password = models.CharField(max_length=80, blank=True, null=True)
username_super = models.CharField(max_length=20, blank=True, null=True)
password_super = models.CharField(max_length=80, blank=True, null=True)
date_added = models.DateTimeField(auto_now=True, default=datetime.datetime.now(), null=True) date_added = models.DateTimeField(auto_now=True, default=datetime.datetime.now(), null=True)
is_active = models.BooleanField(default=True) is_active = models.BooleanField(default=True)
comment = models.CharField(max_length=100, blank=True, null=True) comment = models.CharField(max_length=100, blank=True, null=True)
......
...@@ -8,6 +8,7 @@ from models import IDC, Asset, BisGroup ...@@ -8,6 +8,7 @@ from models import IDC, Asset, BisGroup
from juser.models import UserGroup from juser.models import UserGroup
from connect import PyCrypt, KEY from connect import PyCrypt, KEY
from jumpserver.views import jasset_group_add, jasset_host_edit from jumpserver.views import jasset_group_add, jasset_host_edit
from jperm.models import Perm
cryptor = PyCrypt(KEY) cryptor = PyCrypt(KEY)
......
from django.db import models
from juser.models import User, UserGroup
from jasset.models import Asset, BisGroup
class Perm(models.Model):
user_group = models.ForeignKey(UserGroup)
asset_group = models.ForeignKey(BisGroup)
def __unicode__(self):
return '%s_%s' % (self.user_group.name, self.asset_group.name)
\ No newline at end of file
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
urlpatterns = patterns('jpermission.views', urlpatterns = patterns('jperm.views',
# Examples: # Examples:
# url(r'^$', 'jumpserver.views.home', name='home'), # url(r'^$', 'jumpserver.views.home', name='home'),
# url(r'^blog/', include('blog.urls')), # url(r'^blog/', include('blog.urls')),
(r'^perm_user_list/$', 'perm_user_list'), (r'^perm_edit/$', 'perm_edit'),
(r'^perm_add/$', 'perm_add'),
(r'^perm_user_show/$', 'perm_user_show'),
(r'^perm_list/$', 'perm_list'), (r'^perm_list/$', 'perm_list'),
(r'^perm_detail/$', 'perm_detail'),
(r'^perm_del/$', 'perm_del'),
(r'^perm_asset_detail/$', 'perm_asset_detail'),
) )
# coding: utf-8
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from juser.models import User, UserGroup
from jasset.models import Asset, BisGroup
from jperm.models import Perm
from django.core.paginator import Paginator, EmptyPage, InvalidPage
def perm_group_update(user_group_name='', user_group_id='', asset_groups_name='', asset_groups_id=''):
if user_group_name:
user_group = UserGroup.objects.get(name=user_group_name)
else:
user_group = UserGroup.objects.get(id=user_group_id)
Perm.objects.filter(user_group=user_group).delete()
if asset_groups_name:
for asset_group_name in asset_groups_name:
asset_group = BisGroup.objects.get(name=asset_group_name)
Perm(user_group=user_group, asset_group=asset_group).save()
else:
for asset_group_id in asset_groups_id:
asset_group = BisGroup.objects.get(id=asset_group_id)
Perm(user_group=user_group, asset_group=asset_group).save()
def perm_user_asset(user_id=None, username=None):
if user_id:
user = User.objects.get(id=user_id)
else:
user = User.objects.get(username=username)
user_groups = user.user_group.all()
perms = []
assets = []
for user_group in user_groups:
perm = user_group.perm_set.all()
perms.extend(perm)
asset_groups = [perm.asset_group for perm in perms]
for asset_group in asset_groups:
assets.extend(list(asset_group.asset_set.all()))
return list(set(assets))
def perm_list(request):
header_title, path1, path2 = u'主机授权 | Perm Host Detail.', u'jperm', u'perm_list'
groups = contact_list = UserGroup.objects.all().order_by('type')
users = contact_list2 = User.objects.all().order_by('id')
p = paginator = Paginator(contact_list, 10)
p2 = paginator2 = Paginator(contact_list2, 10)
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
try:
contacts = paginator.page(page)
contacts2 = paginator2.page(page)
except (EmptyPage, InvalidPage):
contacts = paginator.page(paginator.num_pages)
contacts2 = paginator2.page(paginator2.num_pages)
return render_to_response('jperm/perm_list.html', locals())
def perm_edit(request):
if request.method == 'GET':
header_title, path1, path2 = u'编辑授权 | Perm Host Edit.', u'jperm', u'perm_edit'
user_group_id = request.GET.get('id')
user_group = UserGroup.objects.get(id=user_group_id)
asset_groups = BisGroup.objects.all()
asset_groups_permed = [perm.asset_group for perm in user_group.perm_set.all()]
asset_groups_unperm = [asset_group for asset_group in asset_groups if asset_group not in asset_groups_permed]
return render_to_response('jperm/perm_edit.html', locals())
else:
user_group_name = request.POST.get('user_group_name')
asset_groups_selected = request.POST.getlist('asset_group_permed')
perm_group_update(user_group_name=user_group_name, asset_groups_id=asset_groups_selected)
return HttpResponseRedirect('/jperm/perm_list/')
def perm_detail(request):
user_group_id = request.GET.get('id')
user_group = UserGroup.objects.get(id=user_group_id)
asset_groups = [perm.asset_group for perm in user_group.perm_set.all()]
return render_to_response('jperm/perm_detail.html', locals())
def perm_del(request):
user_group_id = request.GET.get('id')
user_group = UserGroup.objects.get(id=user_group_id)
Perm.objects.filter(user_group=user_group).delete()
return HttpResponseRedirect('/jperm/perm_list/')
def perm_asset_detail(request):
user_id = request.GET.get('id')
user = User.objects.get(id=user_id)
assets = perm_user_asset(user_id)
return render_to_response('jperm/perm_asset_detail.html', locals())
from django.db import models
from juser.models import User
from jasset.models import Asset
class Permission(models.Model):
USER_ROLE_CHOICES = (
('SU', 'SuperUser'),
('CU', 'CommonUser'),
)
user = models.ForeignKey(User)
asset = models.ForeignKey(Asset)
role = models.CharField(choices=USER_ROLE_CHOICES,
max_length=2,
blank=True,
null=True)
def __unicode__(self):
return '%s_%s' % (self.user.username, self.asset.ip)
\ No newline at end of file
# coding: utf-8
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from juser.models import User
from jasset.models import Asset
from jpermission.models import Permission
def perm_user_list(request):
header_title, path1, path2 = u'查看授权用户 | Perm User Detail.', u'授权管理', u'用户详情'
users = User.objects.all()
return render_to_response('jperm/perm_user_list.html', locals(),)
def perm_add(request):
header_title, path1, path2 = u'添加授权 | Add User perm.', u'授权管理', u'添加授权'
if request.method == 'GET':
username = request.GET.get('username', None)
if not username:
return HttpResponseRedirect('/')
user = User.objects.get(username=username)
permed_hosts = []
for perm in user.permission_set.all():
permed_hosts.append(perm.asset)
hosts_all = Asset.objects.all()
hosts = list(set(hosts_all) - set(permed_hosts))
else:
username = request.POST.get('username', None)
host_ids = request.POST.getlist('host_ids', None)
user = User.objects.get(username=username)
for id in host_ids:
asset = Asset.objects.get(id=id)
perm = Permission(user=user, asset=asset)
perm.save()
msg = u'添加成功'
return render_to_response('jperm/perm_add.html', locals())
def perm_user_show(request):
header_title, path1, path2 = u'查看授权用户 | Perm User Detail.', u'授权管理', u'用户详情'
users = User.objects.all()
return render_to_response('jperm/perm_user_show.html', locals(),)
def perm_list(request):
header_title, path1, path2 = u'查看用户授权 | Perm User Detail.', u'授权管理', u'用户详情'
username = request.GET.get('username', None)
if not username:
return HttpResponseRedirect('/')
user = User.objects.get(username=username)
hosts = []
for perm in user.permission_set.all():
hosts.append(perm.asset)
return render_to_response('jperm/perm_list.html', locals())
...@@ -8,11 +8,7 @@ password = mysql234 ...@@ -8,11 +8,7 @@ password = mysql234
database = jumpserver database = jumpserver
[ldap] [ldap]
host_url = ldap://192.168.8.60:389 ldap_enable = 1
base_dn = dc=fengxing,dc=org
root_dn = cn=admin,dc=fengxing,dc=org
root_pw = 123456
ldap_enable = 0
host_url = ldap://127.0.0.1:389 host_url = ldap://127.0.0.1:389
base_dn = dc=jumpserver,dc=org base_dn = dc=jumpserver,dc=org
root_dn = cn=admin,dc=jumpserver,dc=org root_dn = cn=admin,dc=jumpserver,dc=org
......
...@@ -49,7 +49,7 @@ INSTALLED_APPS = ( ...@@ -49,7 +49,7 @@ INSTALLED_APPS = (
'jumpserver', 'jumpserver',
'juser', 'juser',
'jasset', 'jasset',
'jpermission', 'jperm',
'jlog', 'jlog',
) )
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
import time import time
from django import template from django import template
from juser.models import User from django.db.models import Q
from juser.models import User, UserGroup
from jperm.views import perm_user_asset
register = template.Library() register = template.Library()
...@@ -24,16 +26,20 @@ def int2str(value): ...@@ -24,16 +26,20 @@ def int2str(value):
def get_role(user_id): def get_role(user_id):
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'} user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
user = User.objects.get(id=user_id) user = User.objects.get(id=user_id)
return user_role.get(user.role) return user_role.get(str(user.role))
@register.filter(name='groups_str') @register.filter(name='groups_str')
def groups_str(username): def groups_str(username):
groups = [] groups = []
user = User.objects.get(username=username) user = User.objects.get(username=username)
for group in user.user_group.all(): for group in user.user_group.filter(Q(type='A') | Q(type='M')):
groups.append(group.name) groups.append(group.name)
return ','.join(groups) if len(groups) < 4:
return ' '.join(groups)
else:
return "%s ..." % ' '.join(groups[0:3])
@register.filter(name='get_item') @register.filter(name='get_item')
def get_item(dictionary, key): def get_item(dictionary, key):
...@@ -46,3 +52,29 @@ def bool2str(value): ...@@ -46,3 +52,29 @@ def bool2str(value):
return u'是' return u'是'
else: else:
return u'否' return u'否'
@register.filter(name='member_count')
def member_count(group_id):
group = UserGroup.objects.get(id=group_id)
return group.user_set.count()
@register.filter(name='perm_count')
def perm_count(group_id):
group = UserGroup.objects.get(id=group_id)
return group.perm_set.count()
@register.filter(name='group_type_to_str')
def group_type_to_str(type_name):
group_types = {
'P': '私有组',
'M': '管理组',
'A': '授权组',
}
return group_types.get(type_name)
@register.filter(name='perm_asset_count')
def perm_asset_count(user_id):
return len(perm_user_asset(user_id))
...@@ -5,11 +5,13 @@ urlpatterns = patterns('', ...@@ -5,11 +5,13 @@ urlpatterns = patterns('',
# Examples: # Examples:
# url(r'^$', 'jumpserver.views.home', name='home'), # url(r'^$', 'jumpserver.views.home', name='home'),
# url(r'^blog/', include('blog.urls')), # url(r'^blog/', include('blog.urls')),
(r'^$', 'jumpserver.views.base'),
(r'^skin_config/$', 'jumpserver.views.skin_config'), (r'^skin_config/$', 'jumpserver.views.skin_config'),
(r'^base/$', 'jumpserver.views.base'), (r'^base/$', 'jumpserver.views.base'),
(r'^login/$', 'jumpserver.views.login'),
(r'^logout/$', 'jumpserver.views.logout'),
(r'^juser/', include('juser.urls')), (r'^juser/', include('juser.urls')),
(r'^jperm/', include('jpermission.urls')),
(r'^jasset/', include('jasset.urls')), (r'^jasset/', include('jasset.urls')),
(r'^jlog/', include('jlog.urls')), (r'^jlog/', include('jlog.urls')),
(r'^jperm/', include('jperm.urls')),
) )
#coding: utf-8 #coding: utf-8
import hashlib
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from juser.models import User
from connect import PyCrypt, KEY from connect import PyCrypt, KEY
from jasset.models import Asset, BisGroup, IDC from jasset.models import Asset, BisGroup, IDC
from django.shortcuts import render_to_response
def md5_crypt(string):
return hashlib.new("md5", string).hexdigest()
def base(request): def base(request):
...@@ -12,6 +23,7 @@ def skin_config(request): ...@@ -12,6 +23,7 @@ def skin_config(request):
return render_to_response('skin_config.html') return render_to_response('skin_config.html')
<<<<<<< HEAD
def jasset_group_add(name, comment, type): def jasset_group_add(name, comment, type):
if BisGroup.objects.filter(name=name): if BisGroup.objects.filter(name=name):
emg = u'该业务组已存在!' emg = u'该业务组已存在!'
...@@ -52,3 +64,38 @@ def jasset_host_edit(j_ip, j_idc, j_port, j_type, j_group, j_active, j_comment): ...@@ -52,3 +64,38 @@ def jasset_host_edit(j_ip, j_idc, j_port, j_type, j_group, j_active, j_comment):
a.save() a.save()
a.bis_group = groups a.bis_group = groups
a.save() a.save()
=======
def login(request):
"""登录界面"""
if request.session.get('username'):
return HttpResponseRedirect('/')
if request.method == 'GET':
return render_to_response('login.html')
else:
username = request.POST.get('username')
password = request.POST.get('password')
user = User.objects.filter(username=username)
if user:
user = user[0]
if md5_crypt(password) == user.password:
request.session['username'] = username
if user.role == 'SU':
request.session['role'] = 2
elif user.role == 'GA':
request.session['role'] = 1
else:
request.session['role'] = 0
return HttpResponseRedirect('/')
else:
error = '密码错误,请重新输入。'
else:
error = '用户不存在。'
return render_to_response('login.html', {'error': error})
def logout(request):
request.session.delete()
return HttpResponseRedirect('/login/')
>>>>>>> guanghongwei
...@@ -2,7 +2,14 @@ from django.db import models ...@@ -2,7 +2,14 @@ from django.db import models
class UserGroup(models.Model): class UserGroup(models.Model):
GROUP_TYPE_CHOICES = (
('P', 'PrivateGroup'),
('M', 'ManageGroup'),
('A', 'AuthorizeGroup'),
)
name = models.CharField(max_length=80, unique=True) name = models.CharField(max_length=80, unique=True)
type = models.CharField(max_length=1, choices=GROUP_TYPE_CHOICES, default='P')
comment = models.CharField(max_length=160, blank=True, null=True) comment = models.CharField(max_length=160, blank=True, null=True)
def __unicode__(self): def __unicode__(self):
...@@ -22,8 +29,7 @@ class User(models.Model): ...@@ -22,8 +29,7 @@ class User(models.Model):
role = models.CharField(max_length=2, choices=USER_ROLE_CHOICES, default='CU') role = models.CharField(max_length=2, choices=USER_ROLE_CHOICES, default='CU')
user_group = models.ManyToManyField(UserGroup) user_group = models.ManyToManyField(UserGroup)
ldap_pwd = models.CharField(max_length=100) ldap_pwd = models.CharField(max_length=100)
ssh_key_pwd1 = models.CharField(max_length=100) ssh_key_pwd = models.CharField(max_length=100)
ssh_key_pwd2 = models.CharField(max_length=100)
ssh_pwd = models.CharField(max_length=100) ssh_pwd = models.CharField(max_length=100)
is_active = models.BooleanField(default=True) is_active = models.BooleanField(default=True)
last_login = models.IntegerField(default=0) last_login = models.IntegerField(default=0)
......
...@@ -15,6 +15,8 @@ from django.http import HttpResponseRedirect ...@@ -15,6 +15,8 @@ from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
from django.http import HttpResponse
from juser.models import UserGroup, User from juser.models import UserGroup, User
from connect import PyCrypt, KEY from connect import PyCrypt, KEY
...@@ -31,10 +33,6 @@ if LDAP_ENABLE: ...@@ -31,10 +33,6 @@ if LDAP_ENABLE:
LDAP_ROOT_PW = CONF.get('ldap', 'root_pw') LDAP_ROOT_PW = CONF.get('ldap', 'root_pw')
def md5_crypt(string):
return hashlib.new("md5", string).hexdigest()
def gen_rand_pwd(num): def gen_rand_pwd(num):
"""生成随机密码""" """生成随机密码"""
seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
...@@ -113,33 +111,176 @@ def gen_sha512(salt, password): ...@@ -113,33 +111,176 @@ def gen_sha512(salt, password):
return crypt.crypt(password, '$6$%s$' % salt) return crypt.crypt(password, '$6$%s$' % salt)
def group_db_add(**kwargs):
group_name = kwargs.get('name')
group = UserGroup.objects.filter(name=group_name)
if group:
raise AddError('Group %s have been exist .' % group_name)
UserGroup.objects.create(**kwargs)
def group_add_user(group_name, user_id=None, username=None):
try:
if user_id:
user = User.objects.get(id=user_id)
else:
user = User.objects.get(username=username)
except ObjectDoesNotExist:
raise AddError('用户获取失败')
else:
group = UserGroup.objects.get(name=group_name)
group.user_set.add(user)
def group_update_user(group_id, users_id):
group = UserGroup.objects.get(id=group_id)
group.user_set.clear()
for user_id in users_id:
user = User.objects.get(id=user_id)
group.user_set.add(user)
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_update_user(**kwargs):
groups_post = kwargs.pop('groups')
username = kwargs.get('username')
user = User.objects.filter(username=username)
user.update(**kwargs)
user = User.objects.get(username=username)
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_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.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_HOST_URL, LDAP_BASE_DN, LDAP_ROOT_DN, LDAP_ROOT_PW)
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_HOST_URL, LDAP_BASE_DN, LDAP_ROOT_DN, LDAP_ROOT_PW)
ldap_conn.delete(user_dn)
ldap_conn.delete(group_dn)
ldap_conn.delete(sudo_dn)
def group_add(request): def group_add(request):
error = '' error = ''
msg = '' msg = ''
header_title, path1, path2 = '添加属组 | Add Group', 'juser', 'group_add' header_title, path1, path2 = '添加属组 | Add Group', 'juser', 'group_add'
group_types = {
# 'P': '私有组',
'M': '管理组',
'A': '授权组',
}
users = User.objects.all()
if request.method == 'POST': if request.method == 'POST':
group_name = request.POST.get('group_name', None) group_name = request.POST.get('group_name', '')
comment = request.POST.get('comment', None) group_type = request.POST.get('group_type', 'A')
users_selected = request.POST.getlist('users_selected', '')
comment = request.POST.get('comment', '')
try: try:
if not group_name: if not group_name:
error = u'组名不能为空' error = u'组名不能为空'
raise AddError raise AddError
group_db_add(name=group_name, comment=comment, type=group_type)
for user_id in users_selected:
group_add_user(group_name, user_id=user_id)
group = UserGroup.objects.filter(name=group_name)
if group:
error = u'组 %s 已存在' % group_name
raise AddError
group = UserGroup(name=group_name, comment=comment)
group.save()
except AddError: except AddError:
pass pass
except TypeError: except TypeError:
error = u'保存用户失败' error = u'保存用户组失败'
else: else:
msg = u'添加组 %s 成功' % group_name msg = u'添加组 %s 成功' % group_name
...@@ -148,7 +289,7 @@ def group_add(request): ...@@ -148,7 +289,7 @@ def group_add(request):
def group_list(request): def group_list(request):
header_title, path1, path2 = '查看属组 | Show Group', 'juser', 'group_list' header_title, path1, path2 = '查看属组 | Show Group', 'juser', 'group_list'
groups = contact_list = UserGroup.objects.all().order_by('id') groups = contact_list = UserGroup.objects.filter(Q(type='M') | Q(type='A')).order_by('id')
p = paginator = Paginator(contact_list, 10) p = paginator = Paginator(contact_list, 10)
try: try:
...@@ -168,6 +309,7 @@ def group_detail(request): ...@@ -168,6 +309,7 @@ def group_detail(request):
if not group_id: if not group_id:
return HttpResponseRedirect('/') return HttpResponseRedirect('/')
group = UserGroup.objects.get(id=group_id) group = UserGroup.objects.get(id=group_id)
users = group.user_set.all()
return render_to_response('juser/group_detail.html', locals()) return render_to_response('juser/group_detail.html', locals())
...@@ -184,19 +326,32 @@ def group_edit(request): ...@@ -184,19 +326,32 @@ def group_edit(request):
error = '' error = ''
msg = '' msg = ''
header_title, path1, path2 = '修改属组 | Edit Group', 'juser', 'group_edit' header_title, path1, path2 = '修改属组 | Edit Group', 'juser', 'group_edit'
group_types = {
# 'P': '私有组',
'M': '管理组',
'A': '授权组',
}
if request.method == 'GET': if request.method == 'GET':
group_id = request.GET.get('id', None) group_id = request.GET.get('id', None)
group = UserGroup.objects.get(id=group_id) group = UserGroup.objects.get(id=group_id)
group_name = group.name group_name = group.name
comment = group.comment comment = group.comment
group_type = group.type
users_all = User.objects.all()
users_selected = group.user_set.all()
users = [user for user in users_all if user not in users_selected]
return render_to_response('juser/group_add.html', locals()) return render_to_response('juser/group_add.html', locals())
else: else:
group_id = request.POST.get('group_id', None) group_id = request.POST.get('group_id', None)
group_name = request.POST.get('group_name', None) group_name = request.POST.get('group_name', None)
comment = request.POST.get('comment', '') comment = request.POST.get('comment', '')
users_selected = request.POST.getlist('users_selected')
group_type = request.POST.get('group_type')
group = UserGroup.objects.filter(id=group_id) group = UserGroup.objects.filter(id=group_id)
group.update(name=group_name, comment=comment) # return HttpResponse(group_type)
group.update(name=group_name, comment=comment, type=group_type)
group_update_user(group_id, users_selected)
return HttpResponseRedirect('/juser/group_list/') return HttpResponseRedirect('/juser/group_list/')
...@@ -233,6 +388,10 @@ def user_del(request): ...@@ -233,6 +388,10 @@ def user_del(request):
return HttpResponseRedirect('/') return HttpResponseRedirect('/')
user = User.objects.get(id=user_id) user = User.objects.get(id=user_id)
user.delete() user.delete()
group = UserGroup.objects.get(name=user.username)
group.delete()
server_del_user(user.username)
ldap_del_user(user.username)
return HttpResponseRedirect('/juser/user_list/', locals()) return HttpResponseRedirect('/juser/user_list/', locals())
...@@ -246,10 +405,10 @@ def user_edit(request): ...@@ -246,10 +405,10 @@ def user_edit(request):
user = User.objects.get(id=user_id) user = User.objects.get(id=user_id)
username = user.username username = user.username
password = user.password password = user.password
ssh_key_pwd1 = user.ssh_key_pwd1 ssh_key_pwd = user.ssh_key_pwd
name = user.name name = user.name
all_group = UserGroup.objects.all() all_group = UserGroup.objects.filter(Q(type='M') | Q(type='A'))
groups = user.user_group.all() groups = user.user_group.filter(Q(type='M') | Q(type='A'))
groups_str = ' '.join([str(group.id) for group in groups]) groups_str = ' '.join([str(group.id) for group in groups])
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'} user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
role_post = user.role role_post = user.role
...@@ -265,10 +424,10 @@ def user_edit(request): ...@@ -265,10 +424,10 @@ def user_edit(request):
groups_str = ' '.join(groups) groups_str = ' '.join(groups)
role_post = request.POST.get('role', None) role_post = request.POST.get('role', None)
ssh_pwd = request.POST.get('ssh_pwd', None) ssh_pwd = request.POST.get('ssh_pwd', None)
ssh_key_pwd1 = request.POST.get('ssh_key_pwd1', None) ssh_key_pwd = request.POST.get('ssh_key_pwd', None)
is_active = request.POST.get('is_active', '1') is_active = request.POST.get('is_active', '1')
ldap_pwd = gen_rand_pwd(16) ldap_pwd = gen_rand_pwd(16)
all_group = UserGroup.objects.all() all_group = UserGroup.objects.filter(Q(type='M') | Q(type='A'))
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'} user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
if username: if username:
...@@ -282,8 +441,8 @@ def user_edit(request): ...@@ -282,8 +441,8 @@ def user_edit(request):
if ssh_pwd != user.ssh_pwd: if ssh_pwd != user.ssh_pwd:
ssh_pwd = CRYPTOR.encrypt(ssh_pwd) ssh_pwd = CRYPTOR.encrypt(ssh_pwd)
if ssh_key_pwd1 != user.ssh_key_pwd1: if ssh_key_pwd != user.ssh_key_pwd:
ssh_key_pwd1 = CRYPTOR.encrypt(ssh_key_pwd1) ssh_key_pwd = CRYPTOR.encrypt(ssh_key_pwd)
db_update_user(username=username, db_update_user(username=username,
password=password, password=password,
...@@ -292,7 +451,7 @@ def user_edit(request): ...@@ -292,7 +451,7 @@ def user_edit(request):
groups=groups, groups=groups,
role=role_post, role=role_post,
ssh_pwd=ssh_pwd, ssh_pwd=ssh_pwd,
ssh_key_pwd1=ssh_key_pwd1) ssh_key_pwd=ssh_key_pwd)
msg = u'修改用户成功' msg = u'修改用户成功'
return HttpResponseRedirect('/juser/user_list/') return HttpResponseRedirect('/juser/user_list/')
...@@ -300,140 +459,27 @@ def user_edit(request): ...@@ -300,140 +459,27 @@ def user_edit(request):
return render_to_response('juser/user_add.html', locals()) return render_to_response('juser/user_add.html', locals())
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_update_user(**kwargs):
groups_post = kwargs.pop('groups')
username = kwargs.get('username')
user = User.objects.filter(username=username)
user.update(**kwargs)
user = User.objects.get(username=username)
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_HOST_URL, LDAP_BASE_DN, LDAP_ROOT_DN, LDAP_ROOT_PW)
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_HOST_URL, LDAP_BASE_DN, LDAP_ROOT_DN, LDAP_ROOT_PW)
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' header_title, path1, path2 = '添加用户 | Add User', 'juser', 'user_add'
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'} user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
all_group = UserGroup.objects.all() all_group = UserGroup.objects.filter(Q(type='M') | Q(type='A')).order_by('-type')
if request.method == 'POST': if request.method == 'POST':
username = request.POST.get('username', None) username = request.POST.get('username', None)
password = request.POST.get('password', None) password = request.POST.get('password', '')
name = request.POST.get('name', None) name = request.POST.get('name', None)
email = request.POST.get('email', '') email = request.POST.get('email', '')
groups = request.POST.getlist('groups', None) groups = request.POST.getlist('groups', None)
groups_str = ' '.join(groups) groups_str = ' '.join(groups)
role_post = request.POST.get('role', None) role_post = request.POST.get('role', 'CU')
ssh_pwd = request.POST.get('ssh_pwd', None) ssh_pwd = request.POST.get('ssh_pwd', '')
ssh_key_pwd1 = request.POST.get('ssh_key_pwd1', None) ssh_key_pwd = request.POST.get('ssh_key_pwd', '')
is_active = request.POST.get('is_active', '1') is_active = request.POST.get('is_active', '1')
ldap_pwd = gen_rand_pwd(16) ldap_pwd = gen_rand_pwd(16)
try: try:
if None in [username, password, ssh_key_pwd1, name, groups, role_post, is_active]: if None in [username, password, ssh_key_pwd, name, groups, role_post, is_active]:
error = u'带*内容不能为空' error = u'带*内容不能为空'
raise AddError raise AddError
user = User.objects.filter(username=username) user = User.objects.filter(username=username)
...@@ -450,17 +496,18 @@ def user_add(request): ...@@ -450,17 +496,18 @@ def user_add(request):
password=md5_crypt(password), password=md5_crypt(password),
name=name, email=email, name=name, email=email,
groups=groups, role=role_post, groups=groups, role=role_post,
ssh_pwd=CRYPTOR.encrypt(ssh_pwd), ssh_pwd=CRYPTOR.encrypt(ssh_pwd) if ssh_pwd else '',
ssh_key_pwd1=CRYPTOR.encrypt(ssh_key_pwd1), ssh_key_pwd=CRYPTOR.encrypt(ssh_key_pwd),
ldap_pwd=CRYPTOR.encrypt(ldap_pwd), ldap_pwd=CRYPTOR.encrypt(ldap_pwd),
is_active=is_active, is_active=is_active,
date_joined=time_now) date_joined=time_now)
server_add_user(username, password, ssh_key_pwd1) server_add_user(username, password, ssh_key_pwd)
group_db_add(name=username, comment=username, type='P')
group_add_user(group_name=username, username=username)
if LDAP_ENABLE: if LDAP_ENABLE:
ldap_add_user(username, ldap_pwd) ldap_add_user(username, ldap_pwd)
msg = u'添加用户 %s 成功!' % username msg = u'添加用户 %s 成功!' % username
# locals = lambda: {}
except Exception, e: except Exception, e:
error = u'添加用户 %s 失败 %s ' % (username, e) error = u'添加用户 %s 失败 %s ' % (username, e)
......
...@@ -2577,7 +2577,7 @@ a.forum-item-title:hover { ...@@ -2577,7 +2577,7 @@ a.forum-item-title:hover {
padding-right: 20px !important; padding-right: 20px !important;
} }
body { body {
font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif; font-family: "open sans", "Helvetica Neue", Helvetica, Arial, "微软雅黑", sans-serif;
background-color: #2f4050; background-color: #2f4050;
font-size: 13px; font-size: 13px;
color: #676a6c; color: #676a6c;
...@@ -2623,6 +2623,9 @@ a:focus { ...@@ -2623,6 +2623,9 @@ a:focus {
.b-r { .b-r {
border-right: 1px solid #e7eaec; border-right: 1px solid #e7eaec;
} }
.b-l {
border-left: 1px solid #e7eaec;
}
.hr-line-dashed { .hr-line-dashed {
border-top: 1px dashed #e7eaec; border-top: 1px dashed #e7eaec;
color: #ffffff; color: #ffffff;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<link rel="shortcut icon" href="/static/img/facio.ico" type="image/x-icon"> <link rel="shortcut icon" href="/static/img/facio.ico" type="image/x-icon">
{% include 'link_css.html' %} {% include 'link_css.html' %}
{% include 'script.html' %}
</head> </head>
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
</div> </div>
</div> </div>
<!--{% include 'script.html' %}--> {# <!--{% include 'script.html' %}-->#}
</body> </body>
{% include 'script.html' %}
</html> </html>
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/font-awesome/css/font-awesome.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/style.css" rel="stylesheet">
<link href="/static/css/colorbox.css" rel="stylesheet">
<!-- Mainly scripts -->
<script src="/static/js/jquery-2.1.1.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<script src="/static/js/plugins/metisMenu/jquery.metisMenu.js"></script>
<script src="/static/js/plugins/slimscroll/jquery.slimscroll.min.js"></script>
<!-- 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>
<!-- iCheck -->
<script src="/static/js/plugins/iCheck/icheck.min.js"></script>
<!-- Peity -->
<script src="/static/js/demo/peity-demo.js"></script>
<!-- pop windows -->
<script src="/static/js/jquery.colorbox.js"></script>
<script>
$(document).ready(function(){
$(".iframe").colorbox({iframe:true, width:"90%", height:"90%"});
});
</script>
\ No newline at end of file
{% load mytags %}
<html>
<head>
{% include 'link_css.html' %}
<style type="text/css">
body
{
background: #FFFFFF;
}
</style>
</head>
<body>
<div class="row">
<div class="contact-box">
<h2 class="text-center">{{ user.name }} 授权详情</h2>
<div class="ibox-content">
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr>
<th class="text-center">主机</th>
<th class="text-center">端口</th>
<th class="text-center">登录方式</th>
</tr>
</thead>
<tbody>
{% for asset in assets %}
<tr class="gradeX">
<td class="text-center">{{ asset.ip }}</td>
<td class="text-center">{{ asset.port }}</td>
<td class="text-center">{{ asset.login_type }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</body>
</html>
\ No newline at end of file
{% load mytags %}
<html>
<head>
{% include 'link_css.html' %}
<style type="text/css">
body
{
background: #FFFFFF;
}
</style>
</head>
<body>
<div class="row">
<div class="contact-box">
<h2 class="text-center">{{ group.name }} 授权详情</h2>
<div class="ibox-content">
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr>
<th class="text-center">ID</th>
<th class="text-center">主机组</th>
<th class="text-center">主机数量</th>
</tr>
</thead>
<tbody>
{% for asset_group in asset_groups %}
<tr class="gradeX">
<td class="text-center">{{ asset_group.id }}</td>
<td class="text-center">{{ asset_group.name }}</td>
<td class="text-center">{{ asset_group.asset_set.count }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</body>
</html>
\ No newline at end of file
{% extends 'base.html' %}
{% load mytags %}
{% block content %}
<script type="text/javascript">
function search_host(text){
$("#asset_group_unperm").children().each(function(){$(this).remove();});
var permArray = [];
$("#asset_group_permed").children().each(function(){
permArray.push($(this).text());
});
$("#asset_groups").children().each(function(){
if ($(this).text().search(text) != -1 && permArray.indexOf($(this).text()) == -1) {
$("#asset_group_unperm").append($(this).clone())
}
});
}
</script>
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-10">
<div class="ibox float-e-margins">
<!-- title -->
<div class="ibox-title">
<h5>授权编辑表单 <small>Edit perm of Group</small></h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">Config option 1</a>
</li>
<li><a href="#">Config option 2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<!-- end title -->
<div class="ibox-content">
<div class="row">
<div class="col-sm-5 ">
<div class="form-group">
<label></label>
<input type="text" id="group_filter" placeholder="Search" class="form-control" value="" oninput="search_host(this.value)">
</div>
</div>
<div class="col-sm-1 ">
<div class="form-group">
<label></label>
</div>
</div>
<div class="col-sm-5 ">
<div class="form-group">
<label></label>
<input type="text" class="form-control" value="{{ user_group.name }}" readonly>
</div>
</div>
</div>
<form method="post" action="">
<input type="text" name="user_group_name" class="form-control" value="{{ user_group.name }}" style="display: none">
<div class="row">
<div class="col-sm-5"><h4>未授权主机组</h4>
<div>
<select id="asset_groups" name="asset_groups" class="form-control" size="10" multiple style="display: none">
{% for asset_group in asset_groups %}
<option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
{% endfor %}
</select>
<select id="asset_group_unperm" name="asset_group_unperm" class="form-control m-b" size="12" multiple>
{% for asset_group in asset_groups_unperm %}
<option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-sm-1">
<div class="btn-group" style="margin-top: 50px;">
<button type="button" class="btn btn-white" onclick="move('asset_group_unperm', 'asset_group_permed')"><i class="fa fa-chevron-right"></i></button>
<button type="button" class="btn btn-white" onclick="move('asset_group_permed', 'asset_group_unperm')"><i class="fa fa-chevron-left"></i> </button>
</div>
</div>
<div class="col-sm-5"><h4>授权主机</h4>
<div>
<select id="asset_group_permed" name="asset_group_permed" class="form-control m-b" size="12" multiple>
{% for asset_group in asset_groups_permed %}
<option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="submit">取消</button>
<button class="btn btn-primary" type="submit" onclick="javascript: (function(){$('#asset_group_permed option').each(function(){$(this).prop('selected', true)})})()">确认保存</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
var str = document.location.pathname.split("/")[1];
var str1 = document.location.pathname.split("/")[2];
$("#"+str).addClass('active');
$("#"+str1).addClass('active');
</script>
{# <script type="text/javascript">#}
{# $("#asset_group_permed").children().each(function(){#}
{# $("#asset_groups").append($(this).clone());#}
{##}
{# if ($(this).prop("selected") == false) {#}
{# $("#asset_group_unperm").append(this);#}
{# }#}
{##}
{# $("#asset_groups").children().each(function(){$(this).prop("selected", false)});#}
{# });#}
{# </script>#}
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %} {% extends 'base.html' %}
{% load mytags %}
{% block content %} {% block content %}
{% include 'nav_cat_bar.html' %} {% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row"> <div class="row">
<div class="col-lg-10"> <div class="col-lg-10">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>权限主机 {{ user.username }} <small> show perm host info.</small></h5> <h5> 用户组授权 <small> show host perm info.</small> </h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
<i class="fa fa-chevron-up"></i> <i class="fa fa-chevron-up"></i>
...@@ -26,34 +27,171 @@ ...@@ -26,34 +27,171 @@
</a> </a>
</div> </div>
</div> </div>
<div class="ibox-content" style="display: block;">
<form method="post" action=""> <div class="ibox-content">
<table class="table table-hover"> <div class="panel blank-panel">
<div class="panel-heading">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#tab-1">授权编辑</a></li>
<li class=""><a data-toggle="tab" href="#tab-2">查看授权</a></li>
</ul>
</div>
</div>
<div class="panel-body">
<div class="tab-content">
<div id="tab-1" class="tab-pane active">
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead> <thead>
<tr> <tr>
<th>ID</th> <th class="text-center">组名</th>
<th>IP</th> <th class="text-center">类型</th>
<th class="text-center">成员数量</th>
<th class="text-center">授权数量</th>
<th class="text-center">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for host in hosts %} {% for group in contacts.object_list %}
<tr class="gradeX">
<td class="text-center"> {{ group.name }} </td>
<td class="text-center"> {{ group.type|group_type_to_str }} </td>
<td class="text-center"> {{ group.id|member_count }} </td>
<td class="text-center"> {{ group.id|perm_count }} </td>
<td class="text-center">
<a href="../perm_detail/?id={{ group.id }}" class="iframe btn btn-xs btn-primary">详情</a>
<a href="../perm_edit/?id={{ group.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="../perm_del/?id={{ group.id }}" class="btn btn-xs btn-danger">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
<div class="dataTables_info" id="editable_info" role="status" aria-live="polite">
Showing {{ contacts.start_index }} to {{ contacts.end_index }} of {{ p.count }} entries
</div>
</div>
<div class="col-sm-6">
<div class="dataTables_paginate paging_simple_numbers" id="editable_paginate">
<ul class="pagination" style="margin-top: 0; float: right">
{% if contacts.has_previous %}
<li class="paginate_button previous" aria-controls="editable" tabindex="0" id="editable_previous">
<a href="?page={{ contacts.previous_page_number }}">Previous</a>
</li>
{% else %}
<li class="paginate_button previous disabled" aria-controls="editable" tabindex="0" id="editable_previous">
<a href="#">Previous</a>
</li>
{% endif %}
{% for page in p.page_range %}
{% ifequal offset1 page %}
<li class="paginate_button active" aria-controls="editable" tabindex="0"><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
{% else %}
<li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
{% endifequal %}
{% endfor %}
{% if contacts.has_next %}
<li class="paginate_button next" aria-controls="editable" tabindex="0" id="editable_next">
<a href="?page={{ contacts.next_page_number }}">Next</a>
</li>
{% else %}
<li class="paginate_button next disabled" aria-controls="editable" tabindex="0" id="editable_next">
<a href="#">Next</a>
</li>
{% endif %}
</ul>
</div>
</div>
</div>
</div>
<div id="tab-2" class="tab-pane">
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr> <tr>
<td>{{ host.id }}</td> <th class="text-center">用户</th>
<td>{{ host.ip }}</td> <th class="text-center">角色</th>
<th class="text-center">属组</th>
<th class="text-center">主机数量</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
{% for user in contacts2.object_list %}
<tr class="gradeX">
<td class="text-center"> {{ user.name }} </td>
<td class="text-center"> {{ user.id | get_role }} </td>
<td class="text-center"> {{ user.username | groups_str }} </td>
<td class="text-center"> {{ user.id | perm_asset_count }} </td>
<td class="text-center">
<a href="../perm_asset_detail/?id={{ user.id }}" class="iframe btn btn-xs btn-primary">详情</a>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="form-group"> <div class="row">
<div class="col-sm-4 col-sm-offset-2"> <div class="col-sm-6">
<button class="btn btn-white" type="submit">取消</button> <div class="dataTables_info" id="editable_info" role="status" aria-live="polite">
<button id="submit_button" class="btn btn-primary" type="submit">确认删除</button> Showing {{ contacts2.start_index }} to {{ contacts2.end_index }} of {{ p2.count }} entries
</div> </div>
</div> </div>
</form> <div class="col-sm-6">
<div class="dataTables_paginate paging_simple_numbers" id="editable_paginate">
<ul class="pagination" style="margin-top: 0; float: right">
{% if contacts2.has_previous %}
<li class="paginate_button previous" aria-controls="editable" tabindex="0" id="editable_previous">
<a href="?page={{ contacts2.previous_page_number }}">Previous</a>
</li>
{% else %}
<li class="paginate_button previous disabled" aria-controls="editable" tabindex="0" id="editable_previous">
<a href="#">Previous</a>
</li>
{% endif %}
{% for page in p2.page_range %}
{% ifequal offset1 page %}
<li class="paginate_button active" aria-controls="editable" tabindex="0"><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
{% else %}
<li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?page={{ page }}" title="第{{ page }}页">{{ page }}</a></li>
{% endifequal %}
{% endfor %}
{% if contacts2.has_next %}
<li class="paginate_button next" aria-controls="editable" tabindex="0" id="editable_next">
<a href="?page={{ contacts2.next_page_number }}">Next</a>
</li>
{% else %}
<li class="paginate_button next disabled" aria-controls="editable" tabindex="0" id="editable_next">
<a href="#">Next</a>
</li>
{% endif %}
</ul>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function(){
$(".iframe").colorbox({iframe:true, width:"70%", height:"70%"});
});
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-10">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>用户信息 <small> show user info.</small></h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<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>
</div>
</div>
<div class="ibox-content" style="display: block;">
<form method="post" action="">
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>添加授权</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.username }}</td>
<td><a href="../perm_add/?username={{ user.username }}">添加权限</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="submit">取消</button>
<button id="submit_button" class="btn btn-primary" type="submit">确认删除</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-10">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>用户信息 <small> show user info.</small></h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<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>
</div>
</div>
<div class="ibox-content" style="display: block;">
<form method="post" action="">
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>添加授权</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.username }}</td>
<td><a href="../perm_list/?username={{ user.username }}">查看权限</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="submit">取消</button>
<button id="submit_button" class="btn btn-primary" type="submit">确认删除</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
\ No newline at end of file
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<form method="post" class="form-horizontal" action=""> <form id="groupForm" method="post" class="form-horizontal" action="">
{% if error %} {% if error %}
<div class="alert alert-warning text-center">{{ error }}</div> <div class="alert alert-warning text-center">{{ error }}</div>
{% endif %} {% endif %}
...@@ -47,6 +47,47 @@ ...@@ -47,6 +47,47 @@
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group">
<label for="group_type" class="col-sm-2 control-label">类型<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<select id="group_type" name="group_type" class="form-control m-b">
{% for t, type_name in group_types.items %}
{% ifequal t group_type %}
<option value="{{ t }}" selected>{{ type_name }}</option>
{% else %}
<option value="{{ t }}">{{ type_name }}</option>
{% endifequal %}
{% endfor %}
</select>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="groups" 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>
{% for user in users_selected %}
<option value="{{ user.id }}">{{ user.name }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="comment" class="col-sm-2 control-label">备注</label> <label for="comment" class="col-sm-2 control-label">备注</label>
<div class="col-sm-8"> <div class="col-sm-8">
...@@ -58,7 +99,7 @@ ...@@ -58,7 +99,7 @@
<div class="form-group"> <div class="form-group">
<div class="col-sm-4 col-sm-offset-2"> <div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="submit">取消</button> <button class="btn btn-white" type="submit">取消</button>
<button class="btn btn-primary" type="submit">确认保存</button> <button class="btn btn-primary" type="submit" onclick="javascript: (function(){$('#users_selected option').each(function(){$(this).prop('selected', true)})})()">确认保存</button>
</div> </div>
</div> </div>
</form> </form>
...@@ -67,4 +108,28 @@ ...@@ -67,4 +108,28 @@
</div> </div>
</div> </div>
</div> </div>
<script>
$('#groupForm').validator({
timely: 2,
theme: "yellow_right_effect",
fields: {
"group_name": {
rule: "required",
tip: "输入组名",
ok: "",
msg: {required: "必须填写!"}
},
"group_type": {
rule: "checked",
tip: "选择组类型",
ok: "",
msg: {required: "至少选择一个组!"}
}
},
valid: function(form) {
form.submit();
}
});
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -20,23 +20,22 @@ ...@@ -20,23 +20,22 @@
<table class="table table-striped table-bordered table-hover " id="editable" > <table class="table table-striped table-bordered table-hover " id="editable" >
<thead> <thead>
<tr> <tr>
<th class="text-center">属组</th> <th class="text-center">用户名</th>
<th class="text-center">详情</th> <th class="text-center">姓名</th>
<th class="text-center">角色</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for user in users %}
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center">ID</td> <td class="text-center">{{ user.username }}</td>
<td class="text-center">{{ group.id }}</td> <td class="text-center">{{ user.name }}</td>
</tr> <td class="text-center">{{ user.id|get_role }}</td>
<tr class="gradeX">
<td class="text-center">组名</td>
<td class="text-center">{{ group.name }}</td>
</tr>
<tr class="gradeX">
<td class="text-center">备注</td>
<td class="text-center">{{ group_comment }}</td>
</tr> </tr>
{% endfor %}
</tbody>
</tbody>
</table> </table>
</div> </div>
</div> </div>
......
...@@ -36,9 +36,10 @@ ...@@ -36,9 +36,10 @@
<table class="table table-striped table-bordered table-hover " id="editable" > <table class="table table-striped table-bordered table-hover " id="editable" >
<thead> <thead>
<tr> <tr>
<th class="text-center"><input type="checkbox" class="i-checks" name=""></th>
<th class="text-center">ID</th> <th class="text-center">ID</th>
<th class="text-center">组名</th> <th class="text-center">组名</th>
<th class="text-center">类型</th>
<th class="text-center">成员数量</th>
<th class="text-center">备注</th> <th class="text-center">备注</th>
<th class="text-center">操作</th> <th class="text-center">操作</th>
</tr> </tr>
...@@ -46,12 +47,13 @@ ...@@ -46,12 +47,13 @@
<tbody> <tbody>
{% for group in contacts.object_list %} {% for group in contacts.object_list %}
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center"><input type="checkbox" class="i-checks" name=""></td>
<td class="text-center"> {{ group.id }} </td> <td class="text-center"> {{ group.id }} </td>
<td class="text-center"> {{ group.name }} </td> <td class="text-center"> {{ group.name }} </td>
<td class="text-center"> {{ group.type|group_type_to_str }} </td>
<td class="text-center"> {{ group.id|member_count }} </td>
<td class="text-center"> {{ group.comment }} </td> <td class="text-center"> {{ group.comment }} </td>
<td class="text-center"> <td class="text-center">
<a href="../group_detail/?id={{ group.id }}" class="iframe btn btn-xs btn-primary">详情</a> <a href="../group_detail/?id={{ group.id }}" class="iframe btn btn-xs btn-primary">成员</a>
<a href="../group_edit/?id={{ group.id }}" class="btn btn-xs btn-info">编辑</a> <a href="../group_edit/?id={{ group.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="../group_del/?id={{ group.id }}" class="btn btn-xs btn-danger">删除</a> <a href="../group_del/?id={{ group.id }}" class="btn btn-xs btn-danger">删除</a>
</td> </td>
......
{% extends 'base.html' %} {% extends 'base.html' %}
{% load mytags %} {% load mytags %}
{% block content %} {% block content %}
{% include 'nav_cat_bar.html' %} {% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight"> <div class="wrapper wrapper-content animated fadeInRight">
...@@ -28,7 +29,7 @@ ...@@ -28,7 +29,7 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<form method="post" class="form-horizontal" action=""> <form method="post" id="userForm" class="form-horizontal" action="">
{% if error %} {% if error %}
<div class="alert alert-warning text-center">{{ error }}</div> <div class="alert alert-warning text-center">{{ error }}</div>
{% endif %} {% endif %}
...@@ -53,9 +54,9 @@ ...@@ -53,9 +54,9 @@
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="ssh_key_pwd1" class="col-sm-2 control-label">密钥密码<span class="red-fonts">*</span></label> <label for="ssh_key_pwd" class="col-sm-2 control-label">密钥密码<span class="red-fonts">*</span></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="ssh_key_pwd1" name="ssh_key_pwd1" placeholder="SSH Key Password" type="password" class="form-control" value="{{ ssh_key_pwd1 }}"> <input id="ssh_key_pwd" name="ssh_key_pwd" placeholder="SSH Key Password" type="password" class="form-control" value="{{ ssh_key_pwd }}">
<span class="help-block m-b-none"> <span class="help-block m-b-none">
登陆 Jumpserver 使用的SSH密钥的密码 登陆 Jumpserver 使用的SSH密钥的密码
</span> </span>
...@@ -72,19 +73,19 @@ ...@@ -72,19 +73,19 @@
<div class="form-group"> <div class="form-group">
<label for="groups" 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="groups" name="groups" class="form-control m-b" multiple> <select id="groups" name="groups" class="form-control m-b" multiple size="10">
{% for group in all_group %} {% for group in all_group %}
{% if groups_str %} {% if groups_str %}
{% if group.id|int2str in groups_str %} {% if group.id|int2str in groups_str %}
<option value="{{ group.id }}" selected>{{ group.name }}</option> <option value="{{ group.id }}" selected>{{ group.name }} --- {{ group.type|group_type_to_str }}</option>
{% else %} {% else %}
<option value="{{ group.id }}">{{ group.name }}</option> <option value="{{ group.id }}">{{ group.name }} --- {{ group.type|group_type_to_str }}</option>
{% endif %} {% endif %}
{% else %} {% else %}
{% if forloop.first %} {% if forloop.first %}
<option value="{{ group.id }}" selected>{{ group.name }}</option> <option value="{{ group.id }}" selected>{{ group.name }} --- {{ group.type|group_type_to_str }}</option>
{% else %} {% else %}
<option value="{{ group.id }}">{{ group.name }}</option> <option value="{{ group.id }}">{{ group.name }} --- {{ group.type|group_type_to_str }}</option>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
...@@ -118,7 +119,7 @@ ...@@ -118,7 +119,7 @@
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="email" class="col-sm-2 control-label">Email</label> <label for="email" class="col-sm-2 control-label">Email<span class="red-fonts">*</span></label>
<div class="col-sm-8"> <div class="col-sm-8">
<input id="email" name="email" type="email" placeholder="Email" class="form-control" value="{{ email }}"> <input id="email" name="email" type="email" placeholder="Email" class="form-control" value="{{ email }}">
</div> </div>
...@@ -148,4 +149,67 @@ ...@@ -148,4 +149,67 @@
</div> </div>
</div> </div>
<script>
$('#userForm').validator({
timely: 2,
theme: "yellow_right_effect",
rules: {
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}$/, '端口号不正确'],
type_m: function(element){
return $("#M").is(":checked");
}
},
fields: {
"username": {
rule: "required",
tip: "输入用户名",
ok: "",
msg: {required: "必须填写!"}
},
"password": {
rule: "required;length[6~50]",
tip: "输入密码",
ok: "",
msg: {required: "必须填写!"}
},
"ssh_key_pwd": {
rule: "required;length[6~50]",
tip: "ssh私钥密码",
ok: "",
msg: {required: "必须填写"}
},
"groups": {
rule: "checked",
tip: "选择用户组",
ok: "",
msg: {checked: "至少选择一个组"}
},
"name": {
rule: "required",
tip: "姓名",
ok: "",
msg: {required: "必须填写"}
},
"email": {
rule: "required",
tip: "Email",
ok: "",
msg: {required: "必须填写"}
},
"role": {
rule: "checked",
tip: "角色",
ok: "",
msg: {required: "选择一个"}
}
},
valid: function(form) {
form.submit();
}
});
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -16,9 +16,6 @@ ...@@ -16,9 +16,6 @@
<div class="contact-box"> <div class="contact-box">
<h2 class="text-center">{{ user.name }} 用户详情</h2> <h2 class="text-center">{{ user.name }} 用户详情</h2>
<div class="ibox-content"> <div class="ibox-content">
<div class="">
<a target="_blank" href="/juser/user_add/" class="btn btn-sm btn-primary "> 添加 </a>
</div>
<table class="table table-striped table-bordered table-hover " id="editable" > <table class="table table-striped table-bordered table-hover " id="editable" >
<thead> <thead>
...@@ -46,7 +43,11 @@ ...@@ -46,7 +43,11 @@
</tr> </tr>
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center">属组</td> <td class="text-center">属组</td>
<td class="text-center">{{ user.username|groups_str }}</td> <td class="text-center">
{% for group in user.user_group.all %}
{{ group.name }}
{% endfor %}
</td>
</tr> </tr>
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center">Email</td> <td class="text-center">Email</td>
...@@ -58,7 +59,7 @@ ...@@ -58,7 +59,7 @@
</tr> </tr>
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center">添加时间</td> <td class="text-center">添加时间</td>
<td class="text-center">{{ user.joined }}</td> <td class="text-center">{{ user.date_joined|stamp2str }}</td>
</tr> </tr>
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center">最后登录</td> <td class="text-center">最后登录</td>
......
...@@ -36,13 +36,14 @@ ...@@ -36,13 +36,14 @@
<table class="table table-striped table-bordered table-hover " id="editable" > <table class="table table-striped table-bordered table-hover " id="editable" >
<thead> <thead>
<tr> <tr>
<th class="text-center"><input type="checkbox" class="i-checks" name=""></th> <th class="text-center">
<input type="checkbox" id="select_all" onclick="selectAll()" name="select_all">
</th>
<th class="text-center">ID</th> <th class="text-center">ID</th>
<th class="text-center">用户名</th> <th class="text-center">用户名</th>
<th class="text-center">姓名</th> <th class="text-center">姓名</th>
<th class="text-center">属组</th> <th class="text-center">属组</th>
<th class="text-center">角色</th> <th class="text-center">角色</th>
<th class="text-center">Email</th>
<th class="text-center">激活</th> <th class="text-center">激活</th>
<th class="text-center">操作</th> <th class="text-center">操作</th>
</tr> </tr>
...@@ -50,13 +51,14 @@ ...@@ -50,13 +51,14 @@
<tbody> <tbody>
{% for user in contacts.object_list %} {% for user in contacts.object_list %}
<tr class="gradeX"> <tr class="gradeX">
<td class="text-center"><input type="checkbox" class="i-checks" name=""></td> <td class="text-center">
<input type="checkbox" name="selected" value="{{ user.id }}">
</td>
<td class="text-center"> {{ user.id }} </td> <td class="text-center"> {{ user.id }} </td>
<td class="text-center"> {{ user.username }} </td> <td class="text-center"> {{ user.username }} </td>
<td class="text-center"> {{ user.name }} </td> <td class="text-center"> {{ user.name }} </td>
<td class="text-center"> {{ user.username|groups_str }}</td> <td class="text-center"> {{ user.username|groups_str }}</td>
<td class="text-center">{{ user.id|get_role }}</td> <td class="text-center">{{ user.id|get_role }}</td>
<td class="text-center">{{ user.email }}</td>
<td class="text-center">{{ user.is_active|bool2str }}</td> <td class="text-center">{{ user.is_active|bool2str }}</td>
<td class="text-center"> <td class="text-center">
<a href="../user_detail/?id={{ user.id }}" class="iframe btn btn-xs btn-primary">详情</a> <a href="../user_detail/?id={{ user.id }}" class="iframe btn btn-xs btn-primary">详情</a>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JumpServer | Login</title> <title>JumpServer | Login</title>
<link rel="shortcut icon" href="/static/img/facio.ico" type="image/x-icon">
<link href="/static/css/bootstrap.min.css" rel="stylesheet"> <link href="/static/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet"> <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
...@@ -22,22 +22,25 @@ ...@@ -22,22 +22,25 @@
<div> <div>
<div> <div>
<h1 class="logo-name">JumpServer</h1> <h1 class="logo-name"><img src="/static/img/logo.png"></h1>
</div> </div>
<h3>Welcome to JumpServer</h3> {% if error %}
<form class="m-t" role="form" method="post" action="/login/"> <div class="alert alert-danger text-center">{{ error }}</div>
{% endif %}
<h2>Welcome to JumpServer</h2>
<form class="m-t" role="form" method="post" action="">
<div class="form-group"> <div class="form-group">
<input type="email" class="form-control" placeholder="Username" required=""> <input type="text" name="username" class="form-control" placeholder="Username" required="length[6~50]">
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" placeholder="Password" required=""> <input type="password" name="password" class="form-control" placeholder="Password" required="">
</div> </div>
<button type="submit" class="btn btn-primary block full-width m-b">Login</button> <button type="submit" class="btn btn-primary block full-width m-b">Login</button>
<a href="#"><small>Forgot password?</small></a> <a href="#"><small>Forgot password?</small></a>
</form> </form>
<p class="m-t"> <small>Inspinia we app framework base on Bootstrap 3 &copy; 2014</small> </p> <p class="m-t"> <small><b>Copyright</b> Jumpserver.org Organization © 2014-2015</small> </p>
</div> </div>
</div> </div>
......
...@@ -32,10 +32,8 @@ ...@@ -32,10 +32,8 @@
<li id="jperm"> <li id="jperm">
<a href="#"><i class="fa fa-edit"></i> <span class="nav-label">授权管理</span><span class="fa arrow"></span></a> <a href="#"><i class="fa fa-edit"></i> <span class="nav-label">授权管理</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li><a href="/jperm/perm_user_show/">查看授权</a></li> <li id="perm_list"><a href="/jperm/perm_list/">主机授权</a></li>
<li><a href="/jperm/perm_user_list/">添加授权</a></li> <li id="perm_sudo"><a href="/jperm/perm_sudo/">Sudo授权</a></li>
<li><a href="/jperm/showlist/">查看sudo</a></li>
<li><a href="/jperm/add/">添加sudo</a></li>
</ul> </ul>
</li> </li>
<li id="jlog"> <li id="jlog">
......
...@@ -108,7 +108,7 @@ ...@@ -108,7 +108,7 @@
</li> </li>
<li> <li>
<a href="login.html"> <a href="/logout/">
<i class="fa fa-sign-out"></i> Log out <i class="fa fa-sign-out"></i> Log out
</a> </a>
</li> </li>
......
...@@ -10,10 +10,11 @@ ...@@ -10,10 +10,11 @@
<li><a href="contacts.html">Contacts</a></li> <li><a href="contacts.html">Contacts</a></li>
<li><a href="mailbox.html">Mailbox</a></li> <li><a href="mailbox.html">Mailbox</a></li>
<li class="divider"></li> <li class="divider"></li>
<li><a href="login.html">Logout</a></li> <li><a href="/logout/">Logout</a></li>
</ul> </ul>
</div> </div>
<div class="logo-element"> <div class="logo-element">
JS+ JS+
</div> </div>
</li> </li>
...@@ -7,28 +7,63 @@ ...@@ -7,28 +7,63 @@
<script src="/static/js/mindmup-editabletable.js"></script> <script src="/static/js/mindmup-editabletable.js"></script>
<script src="/static/js/base.js"></script> <script src="/static/js/base.js"></script>
<!-- Peity -->
<script src="/static/js/plugins/peity/jquery.peity.min.js"></script>
<!-- Custom and plugin javascript --> <!-- Custom and plugin javascript -->
<script src="/static/js/inspinia.js"></script> <script src="/static/js/inspinia.js"></script>
<script src="/static/js/plugins/pace/pace.min.js"></script> <script src="/static/js/plugins/pace/pace.min.js"></script>
<!-- iCheck --> <!-- iCheck box -->
<script src="/static/js/plugins/iCheck/icheck.min.js"></script> <script src="/static/js/plugins/iCheck/icheck.min.js"></script>
<!-- Peity -->
<script src="/static/js/plugins/peity/jquery.peity.min.js"></script>
<!-- Peity --> <!-- Peity -->
<script src="/static/js/demo/peity-demo.js"></script> <script src="/static/js/demo/peity-demo.js"></script>
<!--<script>--> <script>
<!--$(document).ready(function(){--> $(document).ready(function(){
<!--$('.i-checks').iCheck({--> $('.i-checks').iCheck({
<!--checkboxClass: 'icheckbox_square-green',--> checkboxClass: 'icheckbox_square-green',
<!--radioClass: 'iradio_square-green',--> radioClass: 'iradio_square-green'
<!--});--> });
<!--});--> });
function selectAll(){
var checklist = document.getElementsByName ("selected");
if(document.getElementById("select_all").checked)
{
for(var i=0;i<checklist.length;i++)
{
checklist[i].checked = 1;
}
}else{
for(var j=0;j<checklist.length;j++)
{
checklist[j].checked = 0;
}
}
}
function move(from, to) {
$("#"+from+" option").each(function(){
if ( $(this).prop("selected") == true ) {
$("#"+to).append(this);
}
});
}
function move_all(from, to){
$("#"+from).children().each(function(){
$("#"+to).append(this);
});
}
</script>
<!--</script>-->
<!-- pop windows --> <!-- pop windows -->
<script src="/static/js/jquery.colorbox.js"></script> <script src="/static/js/jquery.colorbox.js"></script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment