diff --git a/connect.py b/connect.py index 31a9be0f4..dc9a6ae31 100755 --- a/connect.py +++ b/connect.py @@ -26,6 +26,7 @@ django.setup() from juser.models import User from jasset.models import Asset from jlog.models import Log +from jperm.views import perm_user_asset try: import termios @@ -208,15 +209,10 @@ def posix_shell(chan, username, host): def get_user_host(username): """Get the hosts of under the user control.""" hosts_attr = {} - try: - user = User.objects.get(username=username) - except ObjectDoesNotExist: - 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 + asset_all = perm_user_asset(username=username) + for asset in asset_all: + hosts_attr[asset.ip] = [asset.id, asset.comment] + return hosts_attr def get_connect_item(username, ip): @@ -235,34 +231,18 @@ def get_connect_item(username, ip): login_type_dict = { 'L': user.ldap_pwd, - 'S': user.ssh_key_pwd2, 'P': user.ssh_pwd, } if asset.login_type in login_type_dict: password = cryptor.decrypt(login_type_dict[asset.login_type]) - return username, password, ip, port elif asset.login_type == 'M': - perms = asset.permission_set.filter(user=user) - if perms: - perm = perms[0] - else: - raise ServerError('Permission %s to %s does not exist.' % (username, ip)) + username = asset.username + password = cryptor.decrypt(asset.password) + return username, password, ip, port - 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: raise ServerError('Login type is not in ["L", "S", "P", "M"]') diff --git a/jasset/models.py b/jasset/models.py index 92fd9c1ce..d0e6cd425 100644 --- a/jasset/models.py +++ b/jasset/models.py @@ -37,10 +37,8 @@ class Asset(models.Model): user_group = models.ManyToManyField(UserGroup) bis_group = models.ManyToManyField(BisGroup) login_type = models.CharField(max_length=1, choices=LOGIN_TYPE_CHOICES, default='L') - username_common = models.CharField(max_length=20, blank=True, null=True) - password_common = 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) + username = models.CharField(max_length=20, blank=True, null=True) + password = models.CharField(max_length=80, blank=True, null=True) date_added = models.DateTimeField(auto_now=True, default=datetime.datetime.now(), null=True) is_active = models.BooleanField(default=True) comment = models.CharField(max_length=100, blank=True, null=True) diff --git a/jasset/views.py b/jasset/views.py index 706f166cd..f50f1e583 100644 --- a/jasset/views.py +++ b/jasset/views.py @@ -8,6 +8,7 @@ from models import IDC, Asset, BisGroup from juser.models import UserGroup from connect import PyCrypt, KEY from jumpserver.views import jasset_group_add, jasset_host_edit +from jperm.models import Perm cryptor = PyCrypt(KEY) @@ -237,4 +238,4 @@ def group_del(request, offset): return HttpResponseRedirect('/jasset/group_list/') def test(request): - return render_to_response('jasset/test.html', locals()) \ No newline at end of file + return render_to_response('jasset/test.html', locals()) diff --git a/jpermission/__init__.py b/jperm/__init__.py similarity index 100% rename from jpermission/__init__.py rename to jperm/__init__.py diff --git a/jpermission/admin.py b/jperm/admin.py similarity index 100% rename from jpermission/admin.py rename to jperm/admin.py diff --git a/jperm/models.py b/jperm/models.py new file mode 100644 index 000000000..75a4081f2 --- /dev/null +++ b/jperm/models.py @@ -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) \ No newline at end of file diff --git a/jpermission/tests.py b/jperm/tests.py similarity index 100% rename from jpermission/tests.py rename to jperm/tests.py diff --git a/jpermission/urls.py b/jperm/urls.py similarity index 51% rename from jpermission/urls.py rename to jperm/urls.py index 39256ca7f..80d8f8630 100644 --- a/jpermission/urls.py +++ b/jperm/urls.py @@ -1,13 +1,14 @@ from django.conf.urls import patterns, include, url -urlpatterns = patterns('jpermission.views', +urlpatterns = patterns('jperm.views', # Examples: # url(r'^$', 'jumpserver.views.home', name='home'), # url(r'^blog/', include('blog.urls')), - (r'^perm_user_list/$', 'perm_user_list'), - (r'^perm_add/$', 'perm_add'), - (r'^perm_user_show/$', 'perm_user_show'), + (r'^perm_edit/$', 'perm_edit'), (r'^perm_list/$', 'perm_list'), + (r'^perm_detail/$', 'perm_detail'), + (r'^perm_del/$', 'perm_del'), + (r'^perm_asset_detail/$', 'perm_asset_detail'), ) diff --git a/jperm/views.py b/jperm/views.py new file mode 100644 index 000000000..b9da25c6b --- /dev/null +++ b/jperm/views.py @@ -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()) + + diff --git a/jpermission/models.py b/jpermission/models.py deleted file mode 100644 index d942e337a..000000000 --- a/jpermission/models.py +++ /dev/null @@ -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) \ No newline at end of file diff --git a/jpermission/views.py b/jpermission/views.py deleted file mode 100644 index 8da55a238..000000000 --- a/jpermission/views.py +++ /dev/null @@ -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()) diff --git a/jumpserver.conf b/jumpserver.conf index 4defe0c11..743f0db43 100644 --- a/jumpserver.conf +++ b/jumpserver.conf @@ -8,11 +8,7 @@ password = mysql234 database = jumpserver [ldap] -host_url = ldap://192.168.8.60:389 -base_dn = dc=fengxing,dc=org -root_dn = cn=admin,dc=fengxing,dc=org -root_pw = 123456 -ldap_enable = 0 +ldap_enable = 1 host_url = ldap://127.0.0.1:389 base_dn = dc=jumpserver,dc=org root_dn = cn=admin,dc=jumpserver,dc=org diff --git a/jumpserver/settings.py b/jumpserver/settings.py index 5b991157f..2a20aab9d 100644 --- a/jumpserver/settings.py +++ b/jumpserver/settings.py @@ -49,7 +49,7 @@ INSTALLED_APPS = ( 'jumpserver', 'juser', 'jasset', - 'jpermission', + 'jperm', 'jlog', ) diff --git a/jumpserver/templatetags/mytags.py b/jumpserver/templatetags/mytags.py index 4c4045254..01b81d486 100644 --- a/jumpserver/templatetags/mytags.py +++ b/jumpserver/templatetags/mytags.py @@ -2,7 +2,9 @@ import time 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() @@ -24,16 +26,20 @@ def int2str(value): def get_role(user_id): user_role = {'SU': u'超级管理员', 'GA': u'组管理员', 'CU': u'普通用户'} 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') def groups_str(username): groups = [] 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) - return ','.join(groups) + if len(groups) < 4: + return ' '.join(groups) + else: + return "%s ..." % ' '.join(groups[0:3]) + @register.filter(name='get_item') def get_item(dictionary, key): @@ -45,4 +51,30 @@ def bool2str(value): if value: return u'是' else: - return u'否' \ No newline at end of file + 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)) diff --git a/jumpserver/urls.py b/jumpserver/urls.py index 23af0f8a7..9352fc543 100644 --- a/jumpserver/urls.py +++ b/jumpserver/urls.py @@ -5,11 +5,13 @@ urlpatterns = patterns('', # Examples: # url(r'^$', 'jumpserver.views.home', name='home'), # url(r'^blog/', include('blog.urls')), - + (r'^$', 'jumpserver.views.base'), (r'^skin_config/$', 'jumpserver.views.skin_config'), (r'^base/$', 'jumpserver.views.base'), + (r'^login/$', 'jumpserver.views.login'), + (r'^logout/$', 'jumpserver.views.logout'), (r'^juser/', include('juser.urls')), - (r'^jperm/', include('jpermission.urls')), (r'^jasset/', include('jasset.urls')), (r'^jlog/', include('jlog.urls')), + (r'^jperm/', include('jperm.urls')), ) diff --git a/jumpserver/views.py b/jumpserver/views.py index 57646eb5e..d2446aaf8 100644 --- a/jumpserver/views.py +++ b/jumpserver/views.py @@ -1,7 +1,18 @@ #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 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): @@ -12,6 +23,7 @@ def skin_config(request): return render_to_response('skin_config.html') +<<<<<<< HEAD def jasset_group_add(name, comment, type): if BisGroup.objects.filter(name=name): emg = u'该业务组已存在!' @@ -51,4 +63,39 @@ def jasset_host_edit(j_ip, j_idc, j_port, j_type, j_group, j_active, j_comment): a.save() a.bis_group = groups - a.save() \ No newline at end of file + 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 diff --git a/juser/models.py b/juser/models.py index 25bc2c055..67fe6de30 100644 --- a/juser/models.py +++ b/juser/models.py @@ -2,7 +2,14 @@ from django.db import models class UserGroup(models.Model): + GROUP_TYPE_CHOICES = ( + ('P', 'PrivateGroup'), + ('M', 'ManageGroup'), + ('A', 'AuthorizeGroup'), + ) + 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) def __unicode__(self): @@ -22,8 +29,7 @@ class User(models.Model): role = models.CharField(max_length=2, choices=USER_ROLE_CHOICES, default='CU') user_group = models.ManyToManyField(UserGroup) ldap_pwd = models.CharField(max_length=100) - ssh_key_pwd1 = models.CharField(max_length=100) - ssh_key_pwd2 = models.CharField(max_length=100) + ssh_key_pwd = models.CharField(max_length=100) ssh_pwd = models.CharField(max_length=100) is_active = models.BooleanField(default=True) last_login = models.IntegerField(default=0) diff --git a/juser/views.py b/juser/views.py index e090dd8ce..875754003 100644 --- a/juser/views.py +++ b/juser/views.py @@ -15,6 +15,8 @@ from django.http import HttpResponseRedirect from django.shortcuts import render_to_response from django.core.exceptions import ObjectDoesNotExist +from django.db.models import Q +from django.http import HttpResponse from juser.models import UserGroup, User from connect import PyCrypt, KEY @@ -31,10 +33,6 @@ if LDAP_ENABLE: LDAP_ROOT_PW = CONF.get('ldap', 'root_pw') -def md5_crypt(string): - return hashlib.new("md5", string).hexdigest() - - def gen_rand_pwd(num): """生成随机密码""" seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -113,191 +111,33 @@ def gen_sha512(salt, password): return crypt.crypt(password, '$6$%s$' % salt) -def group_add(request): - error = '' - msg = '' - header_title, path1, path2 = '添加属组 | Add Group', 'juser', 'group_add' +def group_db_add(**kwargs): + group_name = kwargs.get('name') + group = UserGroup.objects.filter(name=group_name) + if group: + raise AddError('Group %s have been exist .' % group_name) + UserGroup.objects.create(**kwargs) - 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) - if group: - error = u'组 %s 已存在' % group_name - raise AddError - - group = UserGroup(name=group_name, comment=comment) - group.save() - except AddError: - pass - - except TypeError: - error = u'保存用户失败' +def group_add_user(group_name, user_id=None, username=None): + try: + if user_id: + user = User.objects.get(id=user_id) 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.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/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) - 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: - 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) - else: - return HttpResponseRedirect('/') + except ObjectDoesNotExist: + raise AddError('用户获取失败') + else: + 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: - ssh_pwd = CRYPTOR.encrypt(ssh_pwd) - - if ssh_key_pwd1 != user.ssh_key_pwd1: - ssh_key_pwd1 = CRYPTOR.encrypt(ssh_key_pwd1) - - 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 group_update_user(group_id, users_id): + group = UserGroup.objects.get(id=group_id) + group.user_set.clear() + for user_id in users_id: + user = User.objects.get(id=user_id) + group.user_set.add(user) def db_add_user(**kwargs): @@ -353,9 +193,9 @@ def gen_ssh_key(username, password=None, length=2048): 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)) - gen_ssh_key(username, ssh_key_pwd1) + gen_ssh_key(username, ssh_key_pwd) def server_del_user(username): @@ -413,13 +253,169 @@ def ldap_del_user(username): ldap_conn.delete(sudo_dn) -def user_add(request): +def group_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.all() + header_title, path1, path2 = '添加属组 | Add Group', 'juser', 'group_add' + group_types = { + # 'P': '私有组', + 'M': '管理组', + 'A': '授权组', + } + users = User.objects.all() 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) password = request.POST.get('password', None) name = request.POST.get('name', None) @@ -428,12 +424,62 @@ def user_add(request): 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) + 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') ldap_pwd = gen_rand_pwd(16) 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'带*内容不能为空' raise AddError user = User.objects.filter(username=username) @@ -450,17 +496,18 @@ def user_add(request): password=md5_crypt(password), name=name, email=email, groups=groups, role=role_post, - ssh_pwd=CRYPTOR.encrypt(ssh_pwd), - ssh_key_pwd1=CRYPTOR.encrypt(ssh_key_pwd1), + ssh_pwd=CRYPTOR.encrypt(ssh_pwd) if ssh_pwd else '', + ssh_key_pwd=CRYPTOR.encrypt(ssh_key_pwd), ldap_pwd=CRYPTOR.encrypt(ldap_pwd), is_active=is_active, 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: ldap_add_user(username, ldap_pwd) msg = u'添加用户 %s 成功!' % username - # locals = lambda: {} except Exception, e: error = u'添加用户 %s 失败 %s ' % (username, e) diff --git a/static/css/style.css b/static/css/style.css index 8550c5a87..b80d0bb47 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -2577,7 +2577,7 @@ a.forum-item-title:hover { padding-right: 20px !important; } body { - font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-family: "open sans", "Helvetica Neue", Helvetica, Arial, "微软雅黑", sans-serif; background-color: #2f4050; font-size: 13px; color: #676a6c; @@ -2623,6 +2623,9 @@ a:focus { .b-r { border-right: 1px solid #e7eaec; } +.b-l { + border-left: 1px solid #e7eaec; +} .hr-line-dashed { border-top: 1px dashed #e7eaec; color: #ffffff; diff --git a/static/img/logo.png b/static/img/logo.png new file mode 100644 index 000000000..0d8ff20a6 Binary files /dev/null and b/static/img/logo.png differ diff --git a/templates/base.html b/templates/base.html index 8eb5d6e1e..95cc04d06 100644 --- a/templates/base.html +++ b/templates/base.html @@ -10,7 +10,7 @@ {% include 'link_css.html' %} - {% include 'script.html' %} + @@ -27,7 +27,7 @@ - +{# #} - + {% include 'script.html' %} diff --git a/templates/css_js.html b/templates/css_js.html deleted file mode 100644 index 9004ffc1e..000000000 --- a/templates/css_js.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/templates/jperm/perm_asset_detail.html b/templates/jperm/perm_asset_detail.html new file mode 100644 index 000000000..f469138d5 --- /dev/null +++ b/templates/jperm/perm_asset_detail.html @@ -0,0 +1,41 @@ +{% load mytags %} + + + {% include 'link_css.html' %} + + + + + +
+
+

{{ user.name }} 授权详情

+
+ + + + + + + + + + + {% for asset in assets %} + + + + + + {% endfor %} + +
主机端口登录方式
{{ asset.ip }}{{ asset.port }}{{ asset.login_type }}
+
+
+ + \ No newline at end of file diff --git a/templates/jperm/perm_detail.html b/templates/jperm/perm_detail.html new file mode 100644 index 000000000..8f5f7521a --- /dev/null +++ b/templates/jperm/perm_detail.html @@ -0,0 +1,41 @@ +{% load mytags %} + + + {% include 'link_css.html' %} + + + + + +
+
+

{{ group.name }} 授权详情

+
+ + + + + + + + + + + {% for asset_group in asset_groups %} + + + + + + {% endfor %} + +
ID主机组主机数量
{{ asset_group.id }}{{ asset_group.name }}{{ asset_group.asset_set.count }}
+
+
+ + \ No newline at end of file diff --git a/templates/jperm/perm_edit.html b/templates/jperm/perm_edit.html new file mode 100644 index 000000000..cba2d4155 --- /dev/null +++ b/templates/jperm/perm_edit.html @@ -0,0 +1,138 @@ +{% extends 'base.html' %} +{% load mytags %} + +{% block content %} + + + {% include 'nav_cat_bar.html' %} +
+
+
+
+ +
+
授权编辑表单 Edit perm of Group
+ +
+ +
+
+
+
+ + +
+
+
+
+ +
+
+
+
+ + +
+
+ +
+
+ +
+

未授权主机组

+
+ + +
+
+ +
+
+ + +
+
+ +

授权主机

+
+ +
+
+
+
+
+
+ + +
+
+
+
+ +
+
+
+
+
+ +{# #} + +{% endblock %} \ No newline at end of file diff --git a/templates/jperm/perm_list.html b/templates/jperm/perm_list.html index 6f1742bb3..dd8436d6c 100644 --- a/templates/jperm/perm_list.html +++ b/templates/jperm/perm_list.html @@ -1,59 +1,197 @@ {% extends 'base.html' %} - +{% load mytags %} {% block content %} - {% include 'nav_cat_bar.html' %} -
-
-
-
-
-
权限主机 {{ user.username }} show perm host info.
- +{% include 'nav_cat_bar.html' %} + +
+
+
+
+
+
用户组授权 show host perm info.
+ -
-
- - - - - - - - - {% for host in hosts %} - - - - - {% endfor %} - -
IDIP
{{ host.id }}{{ host.ip }}
-
-
- - +
+ +
+
+
+ +
+ +
+ +
+
+ + + + + + + + + + + + {% for group in contacts.object_list %} + + + + + + + + {% endfor %} + +
组名类型成员数量授权数量操作
{{ group.name }} {{ group.type|group_type_to_str }} {{ group.id|member_count }} {{ group.id|perm_count }} + 详情 + 编辑 + 删除 +
+
+
+
+ Showing {{ contacts.start_index }} to {{ contacts.end_index }} of {{ p.count }} entries +
+
+
+
+
    + {% if contacts.has_previous %} + + {% else %} + + {% endif %} + {% for page in p.page_range %} + {% ifequal offset1 page %} +
  • {{ page }}
  • + {% else %} +
  • {{ page }}
  • + {% endifequal %} + {% endfor %} + {% if contacts.has_next %} + + {% else %} + + {% endif %} +
+
+
+
+
+ +
+ + + + + + + + + + + + {% for user in contacts2.object_list %} + + + + + + + + {% endfor %} + +
用户角色属组主机数量操作
{{ user.name }} {{ user.id | get_role }} {{ user.username | groups_str }} {{ user.id | perm_asset_count }} + 详情 +
+
+
+
+ Showing {{ contacts2.start_index }} to {{ contacts2.end_index }} of {{ p2.count }} entries +
+
+
+
+
    + {% if contacts2.has_previous %} + + {% else %} + + {% endif %} + {% for page in p2.page_range %} + {% ifequal offset1 page %} +
  • {{ page }}
  • + {% else %} +
  • {{ page }}
  • + {% endifequal %} + {% endfor %} + {% if contacts2.has_next %} + + {% else %} + + {% endif %} +
+
+
+
+
- + +
+
+ + +
+
+ + + {% endblock %} \ No newline at end of file diff --git a/templates/jperm/perm_user_list.html b/templates/jperm/perm_user_list.html deleted file mode 100644 index 20d835726..000000000 --- a/templates/jperm/perm_user_list.html +++ /dev/null @@ -1,61 +0,0 @@ -{% extends 'base.html' %} -{% load mytags %} - -{% block content %} - {% include 'nav_cat_bar.html' %} -
-
-
-
-
-
用户信息 show user info.
- -
-
-
- - - - - - - - - {% for user in users %} - - - - - - {% endfor %} - -
ID添加授权
{{ user.id }}{{ user.username }}添加权限
-
-
- - -
-
-
-
-
-
-
-
-{% endblock %} \ No newline at end of file diff --git a/templates/jperm/perm_user_show.html b/templates/jperm/perm_user_show.html deleted file mode 100644 index 842de720b..000000000 --- a/templates/jperm/perm_user_show.html +++ /dev/null @@ -1,61 +0,0 @@ -{% extends 'base.html' %} -{% load mytags %} - -{% block content %} - {% include 'nav_cat_bar.html' %} -
-
-
-
-
-
用户信息 show user info.
- -
-
-
- - - - - - - - - {% for user in users %} - - - - - - {% endfor %} - -
ID添加授权
{{ user.id }}{{ user.username }}查看权限
-
-
- - -
-
-
-
-
-
-
-
-{% endblock %} \ No newline at end of file diff --git a/templates/juser/group_add.html b/templates/juser/group_add.html index 6e4fa6559..db20f8506 100644 --- a/templates/juser/group_add.html +++ b/templates/juser/group_add.html @@ -27,7 +27,7 @@
-
+ {% if error %}
{{ error }}
{% endif %} @@ -47,6 +47,47 @@
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ + +
+
+
+
+ +
+
+
+
@@ -58,7 +99,7 @@
- +
@@ -67,4 +108,28 @@
+ + {% endblock %} \ No newline at end of file diff --git a/templates/juser/group_detail.html b/templates/juser/group_detail.html index 9b906ccc0..46c205d07 100644 --- a/templates/juser/group_detail.html +++ b/templates/juser/group_detail.html @@ -20,23 +20,22 @@ - - + + + + {% for user in users %} - - - - - - - - - - + + + + {% endfor %} + + +
属组详情用户名姓名角色
ID{{ group.id }}
组名{{ group.name }}
备注{{ group_comment }}{{ user.username }}{{ user.name }}{{ user.id|get_role }}
diff --git a/templates/juser/group_list.html b/templates/juser/group_list.html index 086dd43d2..0a045d8f7 100644 --- a/templates/juser/group_list.html +++ b/templates/juser/group_list.html @@ -36,9 +36,10 @@ - + + @@ -46,12 +47,13 @@ {% for group in contacts.object_list %} - + + diff --git a/templates/juser/user_add.html b/templates/juser/user_add.html index 657792157..68bf3f1a5 100644 --- a/templates/juser/user_add.html +++ b/templates/juser/user_add.html @@ -1,6 +1,7 @@ {% extends 'base.html' %} {% load mytags %} + {% block content %} {% include 'nav_cat_bar.html' %}
@@ -28,7 +29,7 @@
-
+ {% if error %}
{{ error }}
{% endif %} @@ -53,9 +54,9 @@
- +
- + 登陆 Jumpserver 使用的SSH密钥的密码 @@ -72,19 +73,19 @@
- {% for group in all_group %} {% if groups_str %} {% if group.id|int2str in groups_str %} - + {% else %} - + {% endif %} {% else %} {% if forloop.first %} - + {% else %} - + {% endif %} {% endif %} {% endfor %} @@ -118,7 +119,7 @@
- +
@@ -148,4 +149,67 @@
+ + + {% endblock %} \ No newline at end of file diff --git a/templates/juser/user_detail.html b/templates/juser/user_detail.html index be846b9a5..e06247dc5 100644 --- a/templates/juser/user_detail.html +++ b/templates/juser/user_detail.html @@ -16,9 +16,6 @@

{{ user.name }} 用户详情

-
ID 组名类型成员数量 备注 操作
{{ group.id }} {{ group.name }} {{ group.type|group_type_to_str }} {{ group.id|member_count }} {{ group.comment }} - 详情 + 成员 编辑 删除
@@ -46,7 +43,11 @@ - + @@ -58,7 +59,7 @@ - + diff --git a/templates/juser/user_list.html b/templates/juser/user_list.html index f2c5596c4..4c10d996e 100644 --- a/templates/juser/user_list.html +++ b/templates/juser/user_list.html @@ -36,13 +36,14 @@
属组{{ user.username|groups_str }} + {% for group in user.user_group.all %} + {{ group.name }} + {% endfor %} +
Email
添加时间{{ user.joined }}{{ user.date_joined|stamp2str }}
最后登录
- + - @@ -50,13 +51,14 @@ {% for user in contacts.object_list %} - + -
+ + ID 用户名 姓名 属组 角色Email 激活 操作
+ + {{ user.id }} {{ user.username }} {{ user.name }} {{ user.username|groups_str }} {{ user.id|get_role }}{{ user.email }} {{ user.is_active|bool2str }} 详情 @@ -117,4 +119,4 @@ }); -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/link_css.html b/templates/link_css.html index 057f788be..37adaf59f 100644 --- a/templates/link_css.html +++ b/templates/link_css.html @@ -4,4 +4,4 @@ - \ No newline at end of file + diff --git a/templates/login.html b/templates/login.html index 263cf07e2..df3b35f2b 100644 --- a/templates/login.html +++ b/templates/login.html @@ -7,7 +7,7 @@ JumpServer | Login - + @@ -22,22 +22,25 @@
-

JumpServer

+

-

Welcome to JumpServer

- + {% if error %} +
{{ error }}
+ {% endif %} +

Welcome to JumpServer

+
- +
- +
Forgot password? -

Inspinia we app framework base on Bootstrap 3 © 2014

+

Copyright Jumpserver.org Organization © 2014-2015

diff --git a/templates/nav.html b/templates/nav.html index 7bc66fa12..bf2440b35 100644 --- a/templates/nav.html +++ b/templates/nav.html @@ -32,10 +32,8 @@
  • 授权管理
  • diff --git a/templates/nav_bar_header.html b/templates/nav_bar_header.html index 50276b70f..7d4d3bb79 100644 --- a/templates/nav_bar_header.html +++ b/templates/nav_bar_header.html @@ -108,7 +108,7 @@
  • - + Log out
  • diff --git a/templates/nav_li_profile.html b/templates/nav_li_profile.html index c19e00b3f..09811e0c8 100644 --- a/templates/nav_li_profile.html +++ b/templates/nav_li_profile.html @@ -10,10 +10,11 @@
  • Contacts
  • Mailbox
  • -
  • Logout
  • +
  • Logout
  • JS+
    + diff --git a/templates/script.html b/templates/script.html index 32e03f70c..70edc0934 100644 --- a/templates/script.html +++ b/templates/script.html @@ -7,28 +7,63 @@ - - - - + + + + - - - - - - - + + + -