mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-06-28 15:57:23 +00:00
Merge in 20150131
This commit is contained in:
commit
2a645747de
34
connect.py
34
connect.py
@ -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):
|
|||||||
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):
|
|||||||
|
|
||||||
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):
|
|||||||
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
|
|||||||
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)
|
||||||
|
|
||||||
|
11
jperm/models.py
Normal file
11
jperm/models.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
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)
|
@ -1,13 +1,14 @@
|
|||||||
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'),
|
||||||
)
|
)
|
104
jperm/views.py
Normal file
104
jperm/views.py
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
# 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())
|
||||||
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
|||||||
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)
|
|
@ -1,62 +0,0 @@
|
|||||||
# 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
|
|||||||
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 = (
|
|||||||
'jumpserver',
|
'jumpserver',
|
||||||
'juser',
|
'juser',
|
||||||
'jasset',
|
'jasset',
|
||||||
'jpermission',
|
'jperm',
|
||||||
'jlog',
|
'jlog',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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):
|
|||||||
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):
|
|||||||
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('',
|
|||||||
# 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')),
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
#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):
|
|||||||
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):
|
|||||||
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
|
|||||||
|
|
||||||
|
|
||||||
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):
|
|||||||
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)
|
||||||
|
427
juser/views.py
427
juser/views.py
@ -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:
|
|||||||
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,191 +111,33 @@ def gen_sha512(salt, password):
|
|||||||
return crypt.crypt(password, '$6$%s$' % salt)
|
return crypt.crypt(password, '$6$%s$' % salt)
|
||||||
|
|
||||||
|
|
||||||
def group_add(request):
|
def group_db_add(**kwargs):
|
||||||
error = ''
|
group_name = kwargs.get('name')
|
||||||
msg = ''
|
|
||||||
header_title, path1, path2 = '添加属组 | Add Group', 'juser', 'group_add'
|
|
||||||
|
|
||||||
if request.method == 'POST':
|
|
||||||
group_name = request.POST.get('group_name', None)
|
|
||||||
comment = request.POST.get('comment', None)
|
|
||||||
|
|
||||||
try:
|
|
||||||
if not group_name:
|
|
||||||
error = u'组名不能为空'
|
|
||||||
raise AddError
|
|
||||||
|
|
||||||
group = UserGroup.objects.filter(name=group_name)
|
group = UserGroup.objects.filter(name=group_name)
|
||||||
if group:
|
if group:
|
||||||
error = u'组 %s 已存在' % group_name
|
raise AddError('Group %s have been exist .' % group_name)
|
||||||
raise AddError
|
UserGroup.objects.create(**kwargs)
|
||||||
|
|
||||||
group = UserGroup(name=group_name, comment=comment)
|
|
||||||
group.save()
|
|
||||||
except AddError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
except TypeError:
|
|
||||||
error = u'保存用户失败'
|
|
||||||
|
|
||||||
else:
|
|
||||||
msg = u'添加组 %s 成功' % group_name
|
|
||||||
|
|
||||||
return render_to_response('juser/group_add.html', locals())
|
|
||||||
|
|
||||||
|
|
||||||
def group_list(request):
|
def group_add_user(group_name, user_id=None, username=None):
|
||||||
header_title, path1, path2 = '查看属组 | Show Group', 'juser', 'group_list'
|
|
||||||
groups = contact_list = UserGroup.objects.all().order_by('id')
|
|
||||||
p = paginator = Paginator(contact_list, 10)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
page = int(request.GET.get('page', '1'))
|
if user_id:
|
||||||
except ValueError:
|
|
||||||
page = 1
|
|
||||||
|
|
||||||
try:
|
|
||||||
contacts = paginator.page(page)
|
|
||||||
except (EmptyPage, InvalidPage):
|
|
||||||
contacts = paginator.page(paginator.num_pages)
|
|
||||||
return render_to_response('juser/group_list.html', locals())
|
|
||||||
|
|
||||||
|
|
||||||
def group_detail(request):
|
|
||||||
group_id = request.GET.get('id', None)
|
|
||||||
if not group_id:
|
|
||||||
return HttpResponseRedirect('/')
|
|
||||||
group = UserGroup.objects.get(id=group_id)
|
|
||||||
return render_to_response('juser/group_detail.html', locals())
|
|
||||||
|
|
||||||
|
|
||||||
def group_del(request):
|
|
||||||
group_id = request.GET.get('id', None)
|
|
||||||
if not group_id:
|
|
||||||
return HttpResponseRedirect('/')
|
|
||||||
group = UserGroup.objects.get(id=group_id)
|
|
||||||
group.delete()
|
|
||||||
return HttpResponseRedirect('/juser/group_list/', locals())
|
|
||||||
|
|
||||||
|
|
||||||
def group_edit(request):
|
|
||||||
error = ''
|
|
||||||
msg = ''
|
|
||||||
header_title, path1, path2 = '修改属组 | Edit Group', 'juser', 'group_edit'
|
|
||||||
if request.method == 'GET':
|
|
||||||
group_id = request.GET.get('id', None)
|
|
||||||
group = UserGroup.objects.get(id=group_id)
|
|
||||||
group_name = group.name
|
|
||||||
comment = group.comment
|
|
||||||
|
|
||||||
return render_to_response('juser/group_add.html', locals())
|
|
||||||
else:
|
|
||||||
group_id = request.POST.get('group_id', None)
|
|
||||||
group_name = request.POST.get('group_name', None)
|
|
||||||
comment = request.POST.get('comment', '')
|
|
||||||
group = UserGroup.objects.filter(id=group_id)
|
|
||||||
group.update(name=group_name, comment=comment)
|
|
||||||
|
|
||||||
return HttpResponseRedirect('/juser/group_list/')
|
|
||||||
|
|
||||||
|
|
||||||
def user_list(request):
|
|
||||||
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
|
||||||
header_title, path1, path2 = '查看用户 | Show User', 'juser', 'user_list'
|
|
||||||
users = contact_list = User.objects.all().order_by('id')
|
|
||||||
p = paginator = Paginator(contact_list, 10)
|
|
||||||
|
|
||||||
try:
|
|
||||||
page = int(request.GET.get('page', '1'))
|
|
||||||
except ValueError:
|
|
||||||
page = 1
|
|
||||||
|
|
||||||
try:
|
|
||||||
contacts = paginator.page(page)
|
|
||||||
except (EmptyPage, InvalidPage):
|
|
||||||
contacts = paginator.page(paginator.num_pages)
|
|
||||||
return render_to_response('juser/user_list.html', locals())
|
|
||||||
|
|
||||||
|
|
||||||
def user_detail(request):
|
|
||||||
user_id = request.GET.get('id', None)
|
|
||||||
if not user_id:
|
|
||||||
return HttpResponseRedirect('/')
|
|
||||||
user = User.objects.get(id=user_id)
|
user = User.objects.get(id=user_id)
|
||||||
return render_to_response('juser/user_detail.html', locals())
|
|
||||||
|
|
||||||
|
|
||||||
def user_del(request):
|
|
||||||
user_id = request.GET.get('id', None)
|
|
||||||
if not user_id:
|
|
||||||
return HttpResponseRedirect('/')
|
|
||||||
user = User.objects.get(id=user_id)
|
|
||||||
user.delete()
|
|
||||||
return HttpResponseRedirect('/juser/user_list/', locals())
|
|
||||||
|
|
||||||
|
|
||||||
def user_edit(request):
|
|
||||||
header_title, path1, path2 = '编辑用户 | Edit User', 'juser', 'user_edit'
|
|
||||||
readonly = "readonly"
|
|
||||||
if request.method == 'GET':
|
|
||||||
user_id = request.GET.get('id', None)
|
|
||||||
if not user_id:
|
|
||||||
return HttpResponseRedirect('/')
|
|
||||||
user = User.objects.get(id=user_id)
|
|
||||||
username = user.username
|
|
||||||
password = user.password
|
|
||||||
ssh_key_pwd1 = user.ssh_key_pwd1
|
|
||||||
name = user.name
|
|
||||||
all_group = UserGroup.objects.all()
|
|
||||||
groups = user.user_group.all()
|
|
||||||
groups_str = ' '.join([str(group.id) for group in groups])
|
|
||||||
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
|
||||||
role_post = user.role
|
|
||||||
ssh_pwd = user.ssh_pwd
|
|
||||||
email = user.email
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
username = request.POST.get('username', None)
|
|
||||||
password = request.POST.get('password', None)
|
|
||||||
name = request.POST.get('name', None)
|
|
||||||
email = request.POST.get('email', '')
|
|
||||||
groups = request.POST.getlist('groups', None)
|
|
||||||
groups_str = ' '.join(groups)
|
|
||||||
role_post = request.POST.get('role', 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)
|
|
||||||
all_group = UserGroup.objects.all()
|
|
||||||
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
|
||||||
|
|
||||||
if username:
|
|
||||||
user = User.objects.get(username=username)
|
user = User.objects.get(username=username)
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
raise AddError('用户获取失败')
|
||||||
else:
|
else:
|
||||||
return HttpResponseRedirect('/')
|
group = UserGroup.objects.get(name=group_name)
|
||||||
|
group.user_set.add(user)
|
||||||
|
|
||||||
if password != user.password:
|
|
||||||
password = md5_crypt(password)
|
|
||||||
|
|
||||||
if ssh_pwd != user.ssh_pwd:
|
def group_update_user(group_id, users_id):
|
||||||
ssh_pwd = CRYPTOR.encrypt(ssh_pwd)
|
group = UserGroup.objects.get(id=group_id)
|
||||||
|
group.user_set.clear()
|
||||||
if ssh_key_pwd1 != user.ssh_key_pwd1:
|
for user_id in users_id:
|
||||||
ssh_key_pwd1 = CRYPTOR.encrypt(ssh_key_pwd1)
|
user = User.objects.get(id=user_id)
|
||||||
|
group.user_set.add(user)
|
||||||
db_update_user(username=username,
|
|
||||||
password=password,
|
|
||||||
name=name,
|
|
||||||
email=email,
|
|
||||||
groups=groups,
|
|
||||||
role=role_post,
|
|
||||||
ssh_pwd=ssh_pwd,
|
|
||||||
ssh_key_pwd1=ssh_key_pwd1)
|
|
||||||
msg = u'修改用户成功'
|
|
||||||
|
|
||||||
return HttpResponseRedirect('/juser/user_list/')
|
|
||||||
|
|
||||||
return render_to_response('juser/user_add.html', locals())
|
|
||||||
|
|
||||||
|
|
||||||
def db_add_user(**kwargs):
|
def db_add_user(**kwargs):
|
||||||
@ -353,9 +193,9 @@ def gen_ssh_key(username, password=None, length=2048):
|
|||||||
bash('chown %s:%s %s' % (username, username, public_key_file))
|
bash('chown %s:%s %s' % (username, username, public_key_file))
|
||||||
|
|
||||||
|
|
||||||
def server_add_user(username, password, ssh_key_pwd1):
|
def server_add_user(username, password, ssh_key_pwd):
|
||||||
bash('useradd %s; echo %s | passwd --stdin %s' % (username, password, username))
|
bash('useradd %s; echo %s | passwd --stdin %s' % (username, password, username))
|
||||||
gen_ssh_key(username, ssh_key_pwd1)
|
gen_ssh_key(username, ssh_key_pwd)
|
||||||
|
|
||||||
|
|
||||||
def server_del_user(username):
|
def server_del_user(username):
|
||||||
@ -413,13 +253,169 @@ def ldap_del_user(username):
|
|||||||
ldap_conn.delete(sudo_dn)
|
ldap_conn.delete(sudo_dn)
|
||||||
|
|
||||||
|
|
||||||
def user_add(request):
|
def group_add(request):
|
||||||
error = ''
|
error = ''
|
||||||
msg = ''
|
msg = ''
|
||||||
header_title, path1, path2 = '添加用户 | Add User', 'juser', 'user_add'
|
header_title, path1, path2 = '添加属组 | Add Group', 'juser', 'group_add'
|
||||||
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
group_types = {
|
||||||
all_group = UserGroup.objects.all()
|
# 'P': '私有组',
|
||||||
|
'M': '管理组',
|
||||||
|
'A': '授权组',
|
||||||
|
}
|
||||||
|
users = User.objects.all()
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
group_name = request.POST.get('group_name', '')
|
||||||
|
group_type = request.POST.get('group_type', 'A')
|
||||||
|
users_selected = request.POST.getlist('users_selected', '')
|
||||||
|
comment = request.POST.get('comment', '')
|
||||||
|
|
||||||
|
try:
|
||||||
|
if not group_name:
|
||||||
|
error = u'组名不能为空'
|
||||||
|
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)
|
||||||
|
|
||||||
|
except AddError:
|
||||||
|
pass
|
||||||
|
except TypeError:
|
||||||
|
error = u'保存用户组失败'
|
||||||
|
else:
|
||||||
|
msg = u'添加组 %s 成功' % group_name
|
||||||
|
|
||||||
|
return render_to_response('juser/group_add.html', locals())
|
||||||
|
|
||||||
|
|
||||||
|
def group_list(request):
|
||||||
|
header_title, path1, path2 = '查看属组 | Show Group', 'juser', 'group_list'
|
||||||
|
groups = contact_list = UserGroup.objects.filter(Q(type='M') | Q(type='A')).order_by('id')
|
||||||
|
p = paginator = Paginator(contact_list, 10)
|
||||||
|
|
||||||
|
try:
|
||||||
|
page = int(request.GET.get('page', '1'))
|
||||||
|
except ValueError:
|
||||||
|
page = 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
contacts = paginator.page(page)
|
||||||
|
except (EmptyPage, InvalidPage):
|
||||||
|
contacts = paginator.page(paginator.num_pages)
|
||||||
|
return render_to_response('juser/group_list.html', locals())
|
||||||
|
|
||||||
|
|
||||||
|
def group_detail(request):
|
||||||
|
group_id = request.GET.get('id', None)
|
||||||
|
if not group_id:
|
||||||
|
return HttpResponseRedirect('/')
|
||||||
|
group = UserGroup.objects.get(id=group_id)
|
||||||
|
users = group.user_set.all()
|
||||||
|
return render_to_response('juser/group_detail.html', locals())
|
||||||
|
|
||||||
|
|
||||||
|
def group_del(request):
|
||||||
|
group_id = request.GET.get('id', None)
|
||||||
|
if not group_id:
|
||||||
|
return HttpResponseRedirect('/')
|
||||||
|
group = UserGroup.objects.get(id=group_id)
|
||||||
|
group.delete()
|
||||||
|
return HttpResponseRedirect('/juser/group_list/', locals())
|
||||||
|
|
||||||
|
|
||||||
|
def group_edit(request):
|
||||||
|
error = ''
|
||||||
|
msg = ''
|
||||||
|
header_title, path1, path2 = '修改属组 | Edit Group', 'juser', 'group_edit'
|
||||||
|
group_types = {
|
||||||
|
# 'P': '私有组',
|
||||||
|
'M': '管理组',
|
||||||
|
'A': '授权组',
|
||||||
|
}
|
||||||
|
if request.method == 'GET':
|
||||||
|
group_id = request.GET.get('id', None)
|
||||||
|
group = UserGroup.objects.get(id=group_id)
|
||||||
|
group_name = group.name
|
||||||
|
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())
|
||||||
|
else:
|
||||||
|
group_id = request.POST.get('group_id', None)
|
||||||
|
group_name = request.POST.get('group_name', None)
|
||||||
|
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)
|
||||||
|
# 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/')
|
||||||
|
|
||||||
|
|
||||||
|
def user_list(request):
|
||||||
|
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
||||||
|
header_title, path1, path2 = '查看用户 | Show User', 'juser', 'user_list'
|
||||||
|
users = contact_list = User.objects.all().order_by('id')
|
||||||
|
p = paginator = Paginator(contact_list, 10)
|
||||||
|
|
||||||
|
try:
|
||||||
|
page = int(request.GET.get('page', '1'))
|
||||||
|
except ValueError:
|
||||||
|
page = 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
contacts = paginator.page(page)
|
||||||
|
except (EmptyPage, InvalidPage):
|
||||||
|
contacts = paginator.page(paginator.num_pages)
|
||||||
|
return render_to_response('juser/user_list.html', locals())
|
||||||
|
|
||||||
|
|
||||||
|
def user_detail(request):
|
||||||
|
user_id = request.GET.get('id', None)
|
||||||
|
if not user_id:
|
||||||
|
return HttpResponseRedirect('/')
|
||||||
|
user = User.objects.get(id=user_id)
|
||||||
|
return render_to_response('juser/user_detail.html', locals())
|
||||||
|
|
||||||
|
|
||||||
|
def user_del(request):
|
||||||
|
user_id = request.GET.get('id', None)
|
||||||
|
if not user_id:
|
||||||
|
return HttpResponseRedirect('/')
|
||||||
|
user = User.objects.get(id=user_id)
|
||||||
|
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())
|
||||||
|
|
||||||
|
|
||||||
|
def user_edit(request):
|
||||||
|
header_title, path1, path2 = '编辑用户 | Edit User', 'juser', 'user_edit'
|
||||||
|
readonly = "readonly"
|
||||||
|
if request.method == 'GET':
|
||||||
|
user_id = request.GET.get('id', None)
|
||||||
|
if not user_id:
|
||||||
|
return HttpResponseRedirect('/')
|
||||||
|
user = User.objects.get(id=user_id)
|
||||||
|
username = user.username
|
||||||
|
password = user.password
|
||||||
|
ssh_key_pwd = user.ssh_key_pwd
|
||||||
|
name = user.name
|
||||||
|
all_group = UserGroup.objects.filter(Q(type='M') | Q(type='A'))
|
||||||
|
groups = user.user_group.filter(Q(type='M') | Q(type='A'))
|
||||||
|
groups_str = ' '.join([str(group.id) for group in groups])
|
||||||
|
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
||||||
|
role_post = user.role
|
||||||
|
ssh_pwd = user.ssh_pwd
|
||||||
|
email = user.email
|
||||||
|
|
||||||
|
else:
|
||||||
username = request.POST.get('username', None)
|
username = request.POST.get('username', None)
|
||||||
password = request.POST.get('password', None)
|
password = request.POST.get('password', None)
|
||||||
name = request.POST.get('name', None)
|
name = request.POST.get('name', None)
|
||||||
@ -428,12 +424,62 @@ def user_add(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')
|
||||||
|
ldap_pwd = gen_rand_pwd(16)
|
||||||
|
all_group = UserGroup.objects.filter(Q(type='M') | Q(type='A'))
|
||||||
|
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
||||||
|
|
||||||
|
if username:
|
||||||
|
user = User.objects.get(username=username)
|
||||||
|
else:
|
||||||
|
return HttpResponseRedirect('/')
|
||||||
|
|
||||||
|
if password != user.password:
|
||||||
|
password = md5_crypt(password)
|
||||||
|
|
||||||
|
if ssh_pwd != user.ssh_pwd:
|
||||||
|
ssh_pwd = CRYPTOR.encrypt(ssh_pwd)
|
||||||
|
|
||||||
|
if ssh_key_pwd != user.ssh_key_pwd:
|
||||||
|
ssh_key_pwd = CRYPTOR.encrypt(ssh_key_pwd)
|
||||||
|
|
||||||
|
db_update_user(username=username,
|
||||||
|
password=password,
|
||||||
|
name=name,
|
||||||
|
email=email,
|
||||||
|
groups=groups,
|
||||||
|
role=role_post,
|
||||||
|
ssh_pwd=ssh_pwd,
|
||||||
|
ssh_key_pwd=ssh_key_pwd)
|
||||||
|
msg = u'修改用户成功'
|
||||||
|
|
||||||
|
return HttpResponseRedirect('/juser/user_list/')
|
||||||
|
|
||||||
|
return render_to_response('juser/user_add.html', locals())
|
||||||
|
|
||||||
|
|
||||||
|
def user_add(request):
|
||||||
|
error = ''
|
||||||
|
msg = ''
|
||||||
|
header_title, path1, path2 = '添加用户 | Add User', 'juser', 'user_add'
|
||||||
|
user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'}
|
||||||
|
all_group = UserGroup.objects.filter(Q(type='M') | Q(type='A')).order_by('-type')
|
||||||
|
if request.method == 'POST':
|
||||||
|
username = request.POST.get('username', None)
|
||||||
|
password = request.POST.get('password', '')
|
||||||
|
name = request.POST.get('name', None)
|
||||||
|
email = request.POST.get('email', '')
|
||||||
|
groups = request.POST.getlist('groups', None)
|
||||||
|
groups_str = ' '.join(groups)
|
||||||
|
role_post = request.POST.get('role', 'CU')
|
||||||
|
ssh_pwd = request.POST.get('ssh_pwd', '')
|
||||||
|
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):
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
.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;
|
||||||
|
BIN
static/img/logo.png
Normal file
BIN
static/img/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
@ -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 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--{% include 'script.html' %}-->
|
{# <!--{% include 'script.html' %}-->#}
|
||||||
</body>
|
</body>
|
||||||
|
{% include 'script.html' %}
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
<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>
|
|
41
templates/jperm/perm_asset_detail.html
Normal file
41
templates/jperm/perm_asset_detail.html
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{% 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>
|
41
templates/jperm/perm_detail.html
Normal file
41
templates/jperm/perm_detail.html
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{% 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>
|
138
templates/jperm/perm_edit.html
Normal file
138
templates/jperm/perm_edit.html
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
{% 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 %}
|
@ -1,13 +1,14 @@
|
|||||||
{% 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 @@
|
|||||||
</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>
|
<tr class="gradeX">
|
||||||
<td>{{ host.id }}</td>
|
<td class="text-center"> {{ group.name }} </td>
|
||||||
<td>{{ host.ip }}</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>
|
</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 {{ contacts.start_index }} to {{ contacts.end_index }} of {{ p.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 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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="tab-2" class="tab-pane">
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="dataTables_info" id="editable_info" role="status" aria-live="polite">
|
||||||
|
Showing {{ contacts2.start_index }} to {{ contacts2.end_index }} of {{ p2.count }} entries
|
||||||
</div>
|
</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 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>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$(".iframe").colorbox({iframe:true, width:"70%", height:"70%"});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -1,61 +0,0 @@
|
|||||||
{% 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 %}
|
|
@ -1,61 +0,0 @@
|
|||||||
{% 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 %}
|
|
@ -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 @@
|
|||||||
</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 @@
|
|||||||
<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 @@
|
|||||||
</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 %}
|
@ -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 @@
|
|||||||
<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 @@
|
|||||||
<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>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{% 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 @@
|
|||||||
</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 @@
|
|||||||
</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 @@
|
|||||||
<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 @@
|
|||||||
</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 @@
|
|||||||
</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 %}
|
@ -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 @@
|
|||||||
</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 @@
|
|||||||
</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 @@
|
|||||||
<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 @@
|
|||||||
<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 @@
|
|||||||
<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 @@
|
|||||||
<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 © 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 @@
|
|||||||
<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 @@
|
|||||||
</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 @@
|
|||||||
<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 @@
|
|||||||
<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>
|
||||||
|
Loading…
Reference in New Issue
Block a user