diff --git a/jperm/models.py b/jperm/models.py index 9584e8946..b86ddd433 100644 --- a/jperm/models.py +++ b/jperm/models.py @@ -11,3 +11,11 @@ class PermLog(models.Model): results = models.CharField(max_length=1000, null=True, blank=True, default='') is_success = models.BooleanField(default=False) is_finish = models.BooleanField(default=False) + + +class SysUser(models.Model): + username = models.CharField(max_length=100) + password = models.CharField(max_length=100) + comment = models.CharField(max_length=100, null=True, blank=True, default='') + + diff --git a/jperm/perm_api.py b/jperm/perm_api.py index 585fa3cbf..ccfcbb6b4 100644 --- a/jperm/perm_api.py +++ b/jperm/perm_api.py @@ -76,8 +76,8 @@ def perm_user_api(perm_info): try: new_ip = [asset.ip for asset in new_assets if isinstance(asset, Asset)] del_ip = [asset.ip for asset in del_assets if isinstance(asset, Asset)] - new_username = [user.username for user in new_users if isinstance(user, User)] - del_username = [user.username for user in del_users if isinstance(user, User)] + new_username = [user.username for user in new_users] + del_username = [user.username for user in del_users] except IndexError: raise ServerError("Error: function perm_user_api传入参数类型错误") @@ -90,7 +90,7 @@ def perm_user_api(perm_info): playbook = get_playbook(os.path.join(BASE_DIR, 'playbook', 'user_perm.yaml'), {'the_new_group': 'new', 'the_del_group': 'del', 'the_new_users': the_new_users, 'the_del_users': the_del_users, - 'the_pub_key': '/tmp/id_rsa.pub'}) + 'KEY_DIR': os.path.join(SSH_KEY_DIR, 'sysuser')}) print playbook, inventory @@ -264,6 +264,22 @@ def _public_perm_api(info): return results +def push_user(user, asset_groups_id): + assets = [] + if not user: + return {'error': '没有该用户'} + for group_id in asset_groups_id: + asset_group = get_object(AssetGroup, id=group_id) + if asset_group: + assets.extend(asset_group.asset_set.all()) + perm_info = { + 'action': 'Push user:' + user.username, + 'new': {'users': [user], 'assets': assets} + } + + results = perm_user_api(perm_info) + return results + diff --git a/jperm/urls.py b/jperm/urls.py index c95ab9684..3892407c1 100644 --- a/jperm/urls.py +++ b/jperm/urls.py @@ -2,34 +2,13 @@ from django.conf.urls import patterns, include, url from jperm.views import * urlpatterns = patterns('jperm.views', - # Examples: - (r'^user/$', perm_user_list), - (r'^perm_user_edit/$', perm_user_edit), - (r'^group/$', perm_group_list), - (r'^perm_group_edit/$', perm_group_edit), - (r'log/$', log), - # (r'^dept_perm_edit/$', 'dept_perm_edit'), - # (r'^perm_list/$', view_splitter, {'su': perm_list, 'adm': perm_list_adm}), - # (r'^dept_perm_list/$', 'dept_perm_list'), - # (r'^perm_user_detail/$', 'perm_user_detail'), - # (r'^perm_detail/$', 'perm_detail'), - # (r'^perm_del/$', 'perm_del'), - # (r'^perm_asset_detail/$', 'perm_asset_detail'), - # (r'^sudo_list/$', view_splitter, {'su': sudo_list, 'adm': sudo_list_adm}), - # (r'^sudo_del/$', 'sudo_del'), - # (r'^sudo_edit/$', view_splitter, {'su': sudo_edit, 'adm': sudo_edit_adm}), - # (r'^sudo_refresh/$', 'sudo_refresh'), - # (r'^sudo_detail/$', 'sudo_detail'), - # (r'^cmd_add/$', view_splitter, {'su': cmd_add, 'adm': cmd_add_adm}), - # (r'^cmd_list/$', 'cmd_list'), - # (r'^cmd_del/$', 'cmd_del'), - # (r'^cmd_edit/$', 'cmd_edit'), - # (r'^cmd_detail/$', 'cmd_detail'), - # (r'^apply/$', 'perm_apply'), - # (r'^apply_show/(\w+)/$', 'perm_apply_log'), - # (r'^apply_exec/$', 'perm_apply_exec'), - # (r'^apply_info/$', 'perm_apply_info'), - # (r'^apply_del/$', 'perm_apply_del'), - # (r'^apply_search/$', 'perm_apply_search'), - -) + (r'^user/$', perm_user_list), + (r'^perm_user_edit/$', perm_user_edit), + (r'^group/$', perm_group_list), + (r'^perm_group_edit/$', perm_group_edit), + (r'^log/$', log), + (r'^sys_user_add/$', sys_user_add), + (r'^sys_user_list/$', sys_user_list), + (r'^sys_user_del/$', sys_user_del), + (r'^sys_user_edit/$', sys_user_edit), + ) diff --git a/jperm/views.py b/jperm/views.py index 0fd1f1f99..2e910e025 100644 --- a/jperm/views.py +++ b/jperm/views.py @@ -1 +1 @@ -# # coding: utf-8 # import sys # # reload(sys) # sys.setdefaultencoding('utf8') # # from django.shortcuts import render_to_response # from django.template import RequestContext # from jperm.models import Perm, SudoPerm, CmdGroup, Apply from django.db.models import Q from jumpserver.api import * from jperm.perm_api import * from jperm.models import PermLog as Log @require_role('admin') def perm_user_list(request): header_title, path1, path2 = '用户授权', '授权管理', '用户授权' keyword = request.GET.get('search', '') users_list = User.objects.all() # 获取所有用户 if keyword: users_list = users_list.filter(Q(name=keyword) | Q(username=keyword)) # 搜索 users_list, p, users, page_range, current_page, show_first, show_end = pages(users_list, request) # 分页 return my_render('jperm/perm_user_list.html', locals(), request) @require_role('admin') def perm_user_edit(request): header_title, path1, path2 = '用户授权', '授权管理', '授权更改' user_id = request.GET.get('id', '') user = get_object(User, id=user_id) asset_all = Asset.objects.all() # 获取所有资产 asset_group_all = AssetGroup.objects.all() # 获取所有资产组 asset_permed = user.asset.all() # 获取授权的资产对象列表 asset_group_permed = user.asset_group.all() # 获取授权的资产组对象列表 if request.method == 'GET' and user: assets = [asset for asset in asset_all if asset not in asset_permed] # 获取没有授权的资产对象列表 asset_groups = [asset_group for asset_group in asset_group_all if asset_group not in asset_group_permed] # 同理 return my_render('jperm/perm_user_edit.html', locals(), request) elif request.method == 'POST' and user: asset_id_select = request.POST.getlist('asset_select', []) # 获取选择的资产id列表 asset_group_id_select = request.POST.getlist('asset_groups_select', []) # 获取选择的资产组id列表 asset_select = get_object_list(Asset, asset_id_select) asset_group_select = get_object_list(AssetGroup, asset_group_id_select) asset_new = list(set(asset_select) - set(asset_permed)) # 计算的得到新授权的资产对象列表 asset_del = list(set(asset_permed) - set(asset_select)) # 计算得到回收权限的资产对象列表 asset_group_new = list(set(asset_group_select) - set(asset_group_permed)) # 新授权的资产组对象列表 asset_group_del = list(set(asset_group_permed) - set(asset_group_select)) # 回收的资产组对象列表 for asset_group in asset_group_new: asset_new.extend(asset_group.asset_set.all()) for asset_group in asset_group_del: asset_del.extend(asset_group.asset_set.all()) perm_info = { 'action': 'perm user edit: ' + user.name, 'del': {'users': [user], 'assets': asset_del}, 'new': {'users': [user], 'assets': asset_new} } print perm_info try: results = perm_user_api(perm_info) # 通过API授权或回收 except ServerError, e: return HttpResponse(e) unreachable_asset = [] failures_asset = [] for ip in results.get('unreachable'): unreachable_asset.extend(filter(lambda x: x, Asset.objects.filter(ip=ip))) for ip in results.get('failures'): failures_asset.extend(filter(lambda x: x, Asset.objects.filter(ip=ip))) failures_asset.extend(unreachable_asset) # 失败的授权要统计 for asset in failures_asset: if asset in asset_select: asset_select.remove(asset) else: asset_select.append(asset) user.asset = asset_select user.asset_group = asset_group_select user.save() # 保存到数据库 return HttpResponse(json.dumps(results, sort_keys=True, indent=4), content_type="application/json") else: return HttpResponse('输入错误') @require_role('admin') def perm_group_list(request): header_title, path1, path2 = '用户组授权', '授权管理', '用户组授权' keyword = request.GET.get('search', '') user_groups_list = UserGroup.objects.all() if keyword: request = user_groups_list.filter(Q(name=keyword) | Q(comment=keyword)) user_groups_list, p, user_groups, page_range, current_page, show_first, show_end = pages(user_groups_list, request) return my_render('jperm/perm_group_list.html', locals(), request) @require_role('admin') def perm_group_edit(request): header_title, path1, path2 = '用户组授权', '授权管理', '授权更改' user_group_id = request.GET.get('id', '') user_group = get_object(UserGroup, id=user_group_id) asset_all = Asset.objects.all() asset_group_all = AssetGroup.objects.all() asset_permed = user_group.asset.all() # 获取授权的资产对象列表 asset_group_permed = user_group.asset_group.all() # 获取授权的资产组对象列表 if request.method == 'GET' and user_group: assets = [asset for asset in asset_all if asset not in asset_permed] asset_groups = [asset_group for asset_group in asset_group_all if asset_group not in asset_group_permed] return my_render('jperm/perm_group_edit.html', locals(), request) elif request.method == 'POST' and user_group: asset_id_select = request.POST.getlist('asset_select', []) asset_group_id_select = request.POST.getlist('asset_groups_select', []) asset_select = get_object_list(Asset, asset_id_select) asset_group_select = get_object_list(AssetGroup, asset_group_id_select) asset_new = list(set(asset_select) - set(asset_permed)) # 计算的得到新授权的资产对象列表 asset_del = list(set(asset_permed) - set(asset_select)) # 计算得到回收权限的资产对象列表 asset_group_new = list(set(asset_group_select) - set(asset_group_permed)) # 新授权的资产组对象列表 asset_group_del = list(set(asset_group_permed) - set(asset_group_select)) # 回收的资产组对象列表 users = user_group.user_set.all() perm_info = { 'action': 'perm group edit: ' + user_group.name, 'del': {'users': users, 'assets': asset_del}, 'new': {'users': users, 'assets': asset_new} } results = perm_user_api(perm_info) unreachable_asset = [] failures_asset = [] for ip in results.get('unreachable'): unreachable_asset.extend(filter(lambda x: x, Asset.objects.filter(ip=ip))) for ip in results.get('failures'): failures_asset.extend(filter(lambda x: x, Asset.objects.filter(ip=ip))) failures_asset.extend(unreachable_asset) # 失败的授权要统计 for asset in failures_asset: if asset in asset_select: asset_select.remove(asset) else: asset_select.append(asset) user_group.asset = asset_select user_group.asset_group = asset_group_select user_group.save() # 保存到数据库 return HttpResponse(json.dumps(results, sort_keys=True, indent=4), content_type="application/json") else: return HttpResponse('输入错误') def log(request): header_title, path1, path2 = '授权记录', '授权管理', '授权记录' log_all = Log.objects.all().order_by('-datetime') log_all, p, logs, page_range, current_page, show_first, show_end = pages(log_all, request) return my_render('jperm/perm_log.html', locals(), request) \ No newline at end of file +# # coding: utf-8 # import sysuser # # reload(sysuser) # sysuser.setdefaultencoding('utf8') # # from django.shortcuts import render_to_response # from django.template import RequestContext # from jperm.models import Perm, SudoPerm, CmdGroup, Apply from django.db.models import Q from jumpserver.api import * from jperm.perm_api import * from jperm.models import PermLog as Log from jperm.models import SysUser from juser.user_api import gen_ssh_key @require_role('admin') def perm_user_list(request): header_title, path1, path2 = '用户授权', '授权管理', '用户授权' keyword = request.GET.get('search', '') users_list = User.objects.all() # 获取所有用户 if keyword: users_list = users_list.filter(Q(name=keyword) | Q(username=keyword)) # 搜索 users_list, p, users, page_range, current_page, show_first, show_end = pages(users_list, request) # 分页 return my_render('jperm/perm_user_list.html', locals(), request) @require_role('admin') def perm_user_edit(request): header_title, path1, path2 = '用户授权', '授权管理', '授权更改' user_id = request.GET.get('id', '') user = get_object(User, id=user_id) asset_all = Asset.objects.all() # 获取所有资产 asset_group_all = AssetGroup.objects.all() # 获取所有资产组 asset_permed = user.asset.all() # 获取授权的资产对象列表 asset_group_permed = user.asset_group.all() # 获取授权的资产组对象列表 if request.method == 'GET' and user: assets = [asset for asset in asset_all if asset not in asset_permed] # 获取没有授权的资产对象列表 asset_groups = [asset_group for asset_group in asset_group_all if asset_group not in asset_group_permed] # 同理 return my_render('jperm/perm_user_edit.html', locals(), request) elif request.method == 'POST' and user: asset_id_select = request.POST.getlist('asset_select', []) # 获取选择的资产id列表 asset_group_id_select = request.POST.getlist('asset_groups_select', []) # 获取选择的资产组id列表 asset_select = get_object_list(Asset, asset_id_select) asset_group_select = get_object_list(AssetGroup, asset_group_id_select) asset_new = list(set(asset_select) - set(asset_permed)) # 计算的得到新授权的资产对象列表 asset_del = list(set(asset_permed) - set(asset_select)) # 计算得到回收权限的资产对象列表 asset_group_new = list(set(asset_group_select) - set(asset_group_permed)) # 新授权的资产组对象列表 asset_group_del = list(set(asset_group_permed) - set(asset_group_select)) # 回收的资产组对象列表 for asset_group in asset_group_new: asset_new.extend(asset_group.asset_set.all()) for asset_group in asset_group_del: asset_del.extend(asset_group.asset_set.all()) perm_info = { 'action': 'perm user edit: ' + user.name, 'del': {'users': [user], 'assets': asset_del}, 'new': {'users': [user], 'assets': asset_new} } print perm_info try: results = perm_user_api(perm_info) # 通过API授权或回收 except ServerError, e: return HttpResponse(e) unreachable_asset = [] failures_asset = [] for ip in results.get('unreachable'): unreachable_asset.extend(filter(lambda x: x, Asset.objects.filter(ip=ip))) for ip in results.get('failures'): failures_asset.extend(filter(lambda x: x, Asset.objects.filter(ip=ip))) failures_asset.extend(unreachable_asset) # 失败的授权要统计 for asset in failures_asset: if asset in asset_select: asset_select.remove(asset) else: asset_select.append(asset) user.asset = asset_select user.asset_group = asset_group_select user.save() # 保存到数据库 return HttpResponse(json.dumps(results, sort_keys=True, indent=4), content_type="application/json") else: return HttpResponse('输入错误') @require_role('admin') def perm_group_list(request): header_title, path1, path2 = '用户组授权', '授权管理', '用户组授权' keyword = request.GET.get('search', '') user_groups_list = UserGroup.objects.all() if keyword: request = user_groups_list.filter(Q(name=keyword) | Q(comment=keyword)) user_groups_list, p, user_groups, page_range, current_page, show_first, show_end = pages(user_groups_list, request) return my_render('jperm/perm_group_list.html', locals(), request) @require_role('admin') def perm_group_edit(request): header_title, path1, path2 = '用户组授权', '授权管理', '授权更改' user_group_id = request.GET.get('id', '') user_group = get_object(UserGroup, id=user_group_id) asset_all = Asset.objects.all() asset_group_all = AssetGroup.objects.all() asset_permed = user_group.asset.all() # 获取授权的资产对象列表 asset_group_permed = user_group.asset_group.all() # 获取授权的资产组对象列表 if request.method == 'GET' and user_group: assets = [asset for asset in asset_all if asset not in asset_permed] asset_groups = [asset_group for asset_group in asset_group_all if asset_group not in asset_group_permed] return my_render('jperm/perm_group_edit.html', locals(), request) elif request.method == 'POST' and user_group: asset_id_select = request.POST.getlist('asset_select', []) asset_group_id_select = request.POST.getlist('asset_groups_select', []) asset_select = get_object_list(Asset, asset_id_select) asset_group_select = get_object_list(AssetGroup, asset_group_id_select) asset_new = list(set(asset_select) - set(asset_permed)) # 计算的得到新授权的资产对象列表 asset_del = list(set(asset_permed) - set(asset_select)) # 计算得到回收权限的资产对象列表 asset_group_new = list(set(asset_group_select) - set(asset_group_permed)) # 新授权的资产组对象列表 asset_group_del = list(set(asset_group_permed) - set(asset_group_select)) # 回收的资产组对象列表 users = user_group.user_set.all() perm_info = { 'action': 'perm group edit: ' + user_group.name, 'del': {'users': users, 'assets': asset_del}, 'new': {'users': users, 'assets': asset_new} } results = perm_user_api(perm_info) unreachable_asset = [] failures_asset = [] for ip in results.get('unreachable'): unreachable_asset.extend(filter(lambda x: x, Asset.objects.filter(ip=ip))) for ip in results.get('failures'): failures_asset.extend(filter(lambda x: x, Asset.objects.filter(ip=ip))) failures_asset.extend(unreachable_asset) # 失败的授权要统计 for asset in failures_asset: if asset in asset_select: asset_select.remove(asset) else: asset_select.append(asset) user_group.asset = asset_select user_group.asset_group = asset_group_select user_group.save() # 保存到数据库 return HttpResponse(json.dumps(results, sort_keys=True, indent=4), content_type="application/json") else: return HttpResponse('输入错误') def log(request): header_title, path1, path2 = '授权记录', '授权管理', '授权记录' log_all = Log.objects.all().order_by('-datetime') log_all, p, logs, page_range, current_page, show_first, show_end = pages(log_all, request) return my_render('jperm/perm_log.html', locals(), request) def sys_user_add(request): asset_group_all = AssetGroup.objects.all() if request.method == 'POST': username = request.POST.get('username', '') password = request.POST.get('password', '') asset_groups_id = request.POST.getlist('asset_groups_select', []) comment = request.POST.get('comment') sys_user = SysUser(username=username, password=password, comment=comment) sys_user.save() gen_ssh_key(username, key_dir=os.path.join(SSH_KEY_DIR, 'sysuser'), authorized_keys=False) results = push_user(sys_user, asset_groups_id) return HttpResponse(json.dumps(results, sort_keys=True, indent=4), content_type="application/json") return my_render('jperm/sys_user_add.html', locals(), request) def sys_user_list(request): users_list = SysUser.objects.all() users_list, p, users, page_range, current_page, show_first, show_end = pages(users_list, request) return my_render('jperm/sys_user_list.html', locals(), request) def sys_user_edit(request): pass def sys_user_del(request): pass \ No newline at end of file diff --git a/jumpserver/tasks.py b/jumpserver/tasks.py index 54726eb10..22fd514ef 100644 --- a/jumpserver/tasks.py +++ b/jumpserver/tasks.py @@ -32,6 +32,7 @@ def playbook_run(inventory, playbook, default_user=None, default_port=None, defa become=True, become_user='root') results = playbook.run() + print results results_r = {'unreachable': [], 'failures': [], 'success': []} for hostname, result in results.items(): if result.get('unreachable', 2): diff --git a/juser/user_api.py b/juser/user_api.py index 04a638a0f..2354b663f 100644 --- a/juser/user_api.py +++ b/juser/user_api.py @@ -1,6 +1,7 @@ # coding: utf-8 from Crypto.PublicKey import RSA +from subprocess import call from juser.models import AdminGroup from jumpserver.api import * @@ -115,30 +116,27 @@ def db_del_user(username): user.delete() -def gen_ssh_key(username, password=None, length=2048): +def gen_ssh_key(username, password='', + key_dir=os.path.join(BASE_DIR, 'keys/user/'), + authorized_keys=True, home="/home", length=2048): """ generate a user ssh key in a property dir 生成一个用户ssh密钥对 """ - print "gen_ssh_key" + str(time.time()) - private_key_dir = os.path.join(BASE_DIR, 'keys/jumpserver/') - private_key_file = os.path.join(private_key_dir, username+".pem") - public_key_dir = '/home/%s/.ssh/' % username - public_key_file = os.path.join(public_key_dir, 'authorized_keys') - is_dir(private_key_dir) - is_dir(public_key_dir, username, mode=0700) + private_key_file = os.path.join(key_dir, username) + if os.path.isfile(private_key_file): + os.unlink(private_key_file) + ret = bash('ssh-keygen -t rsa -f %s -b %s -P "%s"' % (private_key_file, length, password)) - key = RSA.generate(length) - with open(private_key_file, 'w') as pri_f: - pri_f.write(key.exportKey('PEM', password)) - os.chmod(private_key_file, 0600) - print "gen_ssh_pub_key" + str(time.time()) - pub_key = key.publickey() - with open(public_key_file, 'w') as pub_f: - pub_f.write(pub_key.exportKey('OpenSSH')) - os.chmod(public_key_file, 0600) - bash('chown %s:%s %s' % (username, username, public_key_file)) - print "gen_ssh_key_end" + str(time.time()) + if authorized_keys: + auth_key_dir = os.path.join(home, username, '.ssh') + is_dir(auth_key_dir, username, mode=0700) + authorized_key_file = os.path.join(auth_key_dir, 'authorized_keys') + with open(private_key_file+'.pub') as pub_f: + with open(authorized_key_file, 'w') as auth_f: + auth_f.write(pub_f.read()) + os.chmod(authorized_key_file, 0600) + bash('chown %s:%s %s' % (username, username, authorized_key_file)) def server_add_user(username, password, ssh_key_pwd, ssh_key_login_need): diff --git a/playbook/user_perm.yaml b/playbook/user_perm.yaml index 6310249d4..4bcfd72e6 100644 --- a/playbook/user_perm.yaml +++ b/playbook/user_perm.yaml @@ -13,5 +13,5 @@ file: name=/home/{{ item }}/.ssh mode=700 owner={{ item }} group={{ item }} state=directory with_items: [ the_new_users ] - name: set authorizied_file - copy: src=the_pub_key dest=/home/{{ item }}/.ssh/authorizied_keys owner={{ item }} group={{ item }} mode=600 + copy: src=KEY_DIR/{{ item }}.pub dest=/home/{{ item }}/.ssh/authorizied_keys owner={{ item }} group={{ item }} mode=600 with_items: [ the_new_users ] diff --git a/templates/jperm/sys_user_add.html b/templates/jperm/sys_user_add.html new file mode 100644 index 000000000..ac4fd2db1 --- /dev/null +++ b/templates/jperm/sys_user_add.html @@ -0,0 +1,130 @@ +{% extends 'base.html' %} +{% load mytags %} +{% block content %} + {% include 'nav_cat_bar.html' %} +