mirror of https://github.com/jumpserver/jumpserver
1. rule operations list add delete edit info page compeleted
2. rule operations list add delete edit info page compeletedpull/26/head
parent
6d5d279f61
commit
f6bc03324f
|
@ -21,17 +21,25 @@ class SysUser(models.Model):
|
|||
|
||||
class PermRole(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
comment = models.CharField(max_length=100)
|
||||
comment = models.CharField(max_length=100, null=True, blank=True, default='')
|
||||
password = models.CharField(max_length=100)
|
||||
key_path = models.CharField(max_length=100)
|
||||
date_added = models.DateTimeField(auto_now=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class PermRule(models.Model):
|
||||
date_added = models.DateTimeField(auto_now=True)
|
||||
name = models.CharField(max_length=100)
|
||||
comment = models.CharField(max_length=100)
|
||||
asset = models.ManyToManyField(Asset)
|
||||
asset_group = models.ManyToManyField(AssetGroup)
|
||||
user = models.ManyToManyField(User)
|
||||
user_group = models.ManyToManyField(UserGroup)
|
||||
role = models.ManyToManyField(PermRole)
|
||||
asset = models.ManyToManyField(Asset, related_name='perm_rule')
|
||||
asset_group = models.ManyToManyField(AssetGroup, related_name='perm_rule')
|
||||
user = models.ManyToManyField(User, related_name='perm_rule')
|
||||
user_group = models.ManyToManyField(UserGroup, related_name='perm_rule')
|
||||
role = models.ManyToManyField(PermRole, related_name='perm_rule')
|
||||
ssh_type = models.BooleanField()
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
|
@ -1,6 +1,6 @@
|
|||
# coding: utf-8
|
||||
|
||||
from jasset.models import *
|
||||
|
||||
from jumpserver.api import *
|
||||
import uuid
|
||||
import re
|
||||
|
@ -9,6 +9,8 @@ from jumpserver.tasks import playbook_run
|
|||
from jumpserver.models import Setting
|
||||
from jperm.models import PermLog
|
||||
|
||||
from jperm.models import PermRole
|
||||
|
||||
|
||||
def get_object_list(model, id_list):
|
||||
"""根据id列表获取对象列表"""
|
||||
|
@ -281,8 +283,62 @@ def push_user(user, asset_groups_id):
|
|||
return results
|
||||
|
||||
|
||||
|
||||
|
||||
def get_role_info(role_id, type="all"):
|
||||
"""
|
||||
获取role对应的一些信息
|
||||
:return: 返回值 均为对象列表
|
||||
"""
|
||||
# 获取role对应的授权规则
|
||||
role_obj = PermRole.objects.get(id=role_id)
|
||||
rules_obj = role_obj.perm_rule.all()
|
||||
# 获取role 对应的用户 和 用户组
|
||||
# 获取role 对应的主机 和主机组
|
||||
users_obj = []
|
||||
assets_obj = []
|
||||
user_groups_obj = []
|
||||
group_users_obj = []
|
||||
asset_groups_obj = []
|
||||
group_assets_obj = []
|
||||
for rule in rules_obj:
|
||||
for user in rule.user.all():
|
||||
users_obj.append(user)
|
||||
for asset in rule.asset.all():
|
||||
assets_obj.append(asset)
|
||||
for user_group in rule.user_group.all():
|
||||
user_groups_obj.append(user_group)
|
||||
for user in user_group.user_set.all():
|
||||
group_users_obj.append(user)
|
||||
for asset_group in rule.asset_group.all():
|
||||
asset_groups_obj.append(asset_group)
|
||||
for asset in asset_group.asset_set.all():
|
||||
group_assets_obj.append(asset)
|
||||
|
||||
calc_users = set(users_obj) | set(group_users_obj)
|
||||
calc_assets = set(assets_obj) | set(group_assets_obj)
|
||||
|
||||
if type == "all":
|
||||
return {"rules": rules_obj,
|
||||
"users": list(calc_users),
|
||||
"user_groups": user_groups_obj,
|
||||
"assets": list(calc_assets),
|
||||
"asset_groups": asset_groups_obj,
|
||||
}
|
||||
elif type == "rule":
|
||||
return rules_obj
|
||||
elif type == "user":
|
||||
return calc_users
|
||||
elif type == "user_group":
|
||||
return user_groups_obj
|
||||
elif type == "asset":
|
||||
return calc_assets
|
||||
elif type == "asset_group":
|
||||
return asset_groups_obj
|
||||
else:
|
||||
return u"不支持的查询"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print get_role_info(1)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -2,16 +2,21 @@ from django.conf.urls import patterns, include, url
|
|||
from jperm.views import *
|
||||
|
||||
urlpatterns = patterns('jperm.views',
|
||||
(r'^rule/$', perm_rules),
|
||||
(r'^rule/$', perm_rule_list),
|
||||
(r'^perm_rule_add/$', perm_rule_add),
|
||||
(r'^perm_rule_detail/$', perm_rule_detail),
|
||||
(r'^perm_rule_edit/$', perm_rule_edit),
|
||||
(r'^perm_rule_delete/$', perm_rule_delete),
|
||||
(r'^group/$', perm_group_list),
|
||||
(r'^perm_group_edit/$', perm_group_edit),
|
||||
(r'^role/$', perm_role_list),
|
||||
(r'^role/perm_role_add/$', perm_role_add),
|
||||
(r'^role/perm_role_delete/$', perm_role_delete),
|
||||
(r'^role/perm_role_detail/$', perm_role_detail),
|
||||
(r'^role/perm_role_edit/$', perm_role_edit),
|
||||
|
||||
|
||||
(r'^log/$', log),
|
||||
(r'^sys_user_add/$', sys_user_add),
|
||||
(r'^sys_user_list/$', sys_user_list),
|
||||
(r'^perm_user_list/$', sys_user_list),
|
||||
(r'^sys_user_del/$', sys_user_del),
|
||||
(r'^sys_user_edit/$', sys_user_edit),
|
||||
)
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import random
|
||||
import os.path
|
||||
|
||||
from Crypto.PublicKey import RSA
|
||||
from os import chmod, mkdir
|
||||
from uuid import uuid4
|
||||
|
||||
PERM_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
KEY_DIR = os.path.join(PERM_DIR, 'role_keys')
|
||||
|
||||
|
||||
def get_rand_pass():
|
||||
"""
|
||||
|
@ -19,6 +28,7 @@ def get_rand_pass():
|
|||
password = ''.join(pass_list)
|
||||
return password
|
||||
|
||||
|
||||
def updates_dict(*args):
|
||||
"""
|
||||
surport update multi dict
|
||||
|
@ -29,8 +39,30 @@ def updates_dict(*args):
|
|||
return result
|
||||
|
||||
|
||||
def gen_keys():
|
||||
"""
|
||||
在KEY_DIR下创建一个 uuid命名的目录,
|
||||
并且在该目录下 生产一对秘钥
|
||||
:return: 返回目录名(uuid)
|
||||
"""
|
||||
key_basename = "keys-" + uuid4().hex
|
||||
key_path_dir = os.path.join(KEY_DIR, key_basename)
|
||||
mkdir(key_path_dir, 0700)
|
||||
|
||||
key = RSA.generate(4096)
|
||||
private_key = os.path.join(key_path_dir, 'id_rsa')
|
||||
public_key = os.path.join(key_path_dir, 'id_rsa.pub')
|
||||
with open(private_key, 'w') as content_file:
|
||||
content_file.write(key.exportKey('PEM'))
|
||||
with open(public_key, 'w') as content_file:
|
||||
content_file.write(key.publickey().exportKey('OpenSSH'))
|
||||
|
||||
return key_path_dir
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
print gen_keys()
|
||||
|
||||
|
||||
|
|
136
jperm/views.py
136
jperm/views.py
|
@ -13,14 +13,16 @@ from juser.models import User, UserGroup
|
|||
from jasset.models import Asset, AssetGroup
|
||||
from jperm.models import PermRole, PermRule
|
||||
|
||||
from jperm.utils import updates_dict
|
||||
from jperm.utils import updates_dict, gen_keys, get_rand_pass
|
||||
from jperm.ansible_api import Tasks
|
||||
from jperm.perm_api import get_role_info
|
||||
|
||||
from jumpserver.api import my_render, get_object
|
||||
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
def perm_rules(request):
|
||||
def perm_rule_list(request):
|
||||
"""
|
||||
用户授权视图:
|
||||
该视图的模板包含2部分:
|
||||
|
@ -45,7 +47,7 @@ def perm_rules(request):
|
|||
|
||||
render_data = updates_dict(data_nav, data_content)
|
||||
|
||||
return my_render('jperm/perm_rules.html', render_data, request)
|
||||
return my_render('jperm/perm_rule_list.html', render_data, request)
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
|
@ -175,15 +177,15 @@ def perm_rule_edit(request):
|
|||
|
||||
if request.method == 'GET' and rule_id:
|
||||
# 获取所有的rule对象
|
||||
users = rule_obj.user.all()
|
||||
user_groups = rule_obj.user_group.all()
|
||||
assets = rule_obj.asset.all()
|
||||
asset_groups = rule_obj.asset_group.all()
|
||||
roles = rule_obj.role.all()
|
||||
users_obj = rule_obj.user.all()
|
||||
user_groups_obj = rule_obj.user_group.all()
|
||||
assets_obj = rule_obj.asset.all()
|
||||
asset_groups_obj = rule_obj.asset_group.all()
|
||||
roles_obj = rule_obj.role.all()
|
||||
|
||||
data_content = {"users": users, "user_groups": user_groups,
|
||||
"assets": assets, "asset_groups": asset_groups,
|
||||
"roles": roles}
|
||||
data_content = {"users": users_obj, "user_groups": user_groups_obj,
|
||||
"assets": assets_obj, "asset_groups": asset_groups_obj,
|
||||
"roles": roles_obj, "rule": rule_obj}
|
||||
render_data = updates_dict(data_nav, data_content)
|
||||
return my_render('jperm/perm_rule_edit.html', render_data, request)
|
||||
|
||||
|
@ -210,6 +212,118 @@ def perm_rule_delete(request):
|
|||
return HttpResponse(u"不支持该操作")
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
def perm_role_list(request):
|
||||
"""
|
||||
用户授权视图:
|
||||
该视图的模板包含2部分:
|
||||
1. block 部分:{% block content %}
|
||||
rander_content 为渲染数据
|
||||
2. include 部分:{% include 'nav_cat_bar.html' %}
|
||||
rander_nav 为渲染数据
|
||||
"""
|
||||
data_nav = {"header_title": "系统角色", "path1": "角色管理", "path2": "查看角色"}
|
||||
|
||||
# 获取所有系统角色
|
||||
roles_list = PermRole.objects.all()
|
||||
|
||||
|
||||
# TODO: 搜索和分页
|
||||
keyword = request.GET.get('search', '')
|
||||
if keyword:
|
||||
roles_list = roles_list.filter(Q(name=keyword))
|
||||
|
||||
roles_list, p, roles, page_range, current_page, show_first, show_end = pages(roles_list, request)
|
||||
data_content = {"roles": roles_list}
|
||||
|
||||
render_data = updates_dict(data_nav, data_content)
|
||||
|
||||
return my_render('jperm/perm_role_list.html', render_data, request)
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
def perm_role_add(request):
|
||||
"""
|
||||
用户授权视图:
|
||||
该视图的模板包含2部分:
|
||||
1. block 部分:{% block content %}
|
||||
rander_content 为渲染数据
|
||||
2. include 部分:{% include 'nav_cat_bar.html' %}
|
||||
rander_nav 为渲染数据
|
||||
"""
|
||||
data_nav = {"header_title": "系统角色", "path1": "角色管理", "path2": "添加角色"}
|
||||
|
||||
if request.method == "GET":
|
||||
return my_render('jperm/perm_role_add.html', data_nav, request)
|
||||
|
||||
elif request.method == "POST":
|
||||
# 获取参数: name, comment
|
||||
name = request.POST.get("role_name")
|
||||
comment = request.POST.get("role_comment")
|
||||
# 生成随机密码,生成秘钥对
|
||||
password = get_rand_pass()
|
||||
key_path = gen_keys()
|
||||
role = PermRole(name=name, comment=comment, password=password, key_path=key_path)
|
||||
role.save()
|
||||
return HttpResponse(u"添加角色: %s" % name)
|
||||
else:
|
||||
return HttpResponse(u"不支持该操作")
|
||||
|
||||
@require_role('admin')
|
||||
def perm_role_delete(request):
|
||||
"""
|
||||
用户授权视图:
|
||||
该视图的模板包含2部分:
|
||||
1. block 部分:{% block content %}
|
||||
rander_content 为渲染数据
|
||||
2. include 部分:{% include 'nav_cat_bar.html' %}
|
||||
rander_nav 为渲染数据
|
||||
"""
|
||||
if request.method == "POST":
|
||||
# 获取参数删除的role对象
|
||||
role_id = request.POST.get("id")
|
||||
role = PermRole.objects.get(id=role_id)
|
||||
role.delete()
|
||||
return HttpResponse(u"删除角色: %s" % role.name)
|
||||
else:
|
||||
return HttpResponse(u"不支持该操作")
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
def perm_role_detail(request):
|
||||
"""
|
||||
the role_info data like:
|
||||
{'asset_groups': [],
|
||||
'assets': [<Asset: 192.168.10.148>],
|
||||
'rules': [<PermRule: PermRule object>],
|
||||
'user_groups': [],
|
||||
'users': [<User: user1>]}
|
||||
"""
|
||||
data_nav = {"header_title": "系统角色", "path1": "角色管理", "path2": "角色详情"}
|
||||
|
||||
if request.method == "GET":
|
||||
role_id = request.GET.get("id")
|
||||
role_info = get_role_info(role_id)
|
||||
render_data = updates_dict(data_nav, role_info)
|
||||
return my_render('jperm/perm_role_detail.html', render_data, request)
|
||||
|
||||
@require_role('admin')
|
||||
def perm_role_edit(request):
|
||||
"""
|
||||
|
||||
:param request:
|
||||
:return:
|
||||
"""
|
||||
data_nav = {"header_title": "系统角色", "path1": "角色管理", "path2": "角色编辑"}
|
||||
|
||||
if request.method == "GET":
|
||||
role_id = request.GET.get("id")
|
||||
data_content = {"role": PermRole.objects.get(id=role_id)}
|
||||
render_data = updates_dict(data_nav, data_content)
|
||||
return my_render('jperm/perm_role_edit.html', render_data, request)
|
||||
|
||||
if request.method == "POST":
|
||||
return HttpResponse(u"未实现")
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
|
|
|
@ -19,6 +19,7 @@ config = ConfigParser.ConfigParser()
|
|||
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||
config.read(os.path.join(BASE_DIR, 'jumpserver.conf'))
|
||||
|
||||
|
||||
DB_HOST = config.get('db', 'host')
|
||||
DB_PORT = config.getint('db', 'port')
|
||||
DB_USER = config.get('db', 'user')
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
<div class="form-group">
|
||||
<label for="username" class="col-sm-2 control-label">授权名称<span class="red-fonts">*</span></label>
|
||||
<div class="col-sm-8">
|
||||
<input id="rulename" name="rulename" placeholder="RuleName" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
|
||||
<input id="rulename" name="rulename" placeholder="Rule Name" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
@ -139,7 +139,7 @@
|
|||
<div class="form-group">
|
||||
<label for="comment" class="col-sm-2 control-label">备注</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="comment" name="comment" placeholder="Comment" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
|
||||
<input id="comment" name="comment" placeholder="Rule Comment" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">时间</td>
|
||||
<td>{{ rule.date_added }}</td>
|
||||
<td>{{ rule.date_added | date:"Y-m-d H:i:s"}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">角色</td>
|
||||
|
@ -60,15 +60,32 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<h5>授权用户/用户组</h5>
|
||||
<span class="label label-primary"><b>授权用户/用户组</b></span>
|
||||
<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="#"></a>
|
||||
</li>
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<div>
|
||||
<div class="text-left">
|
||||
<table class="table table-striped table-bordered table-hover " id="editable" >
|
||||
<table class="table table-striped" id="ugedit" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">用户</th>
|
||||
|
@ -88,19 +105,33 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content inspinia-timeline">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<h5>授权主机/主机组</h5>
|
||||
<span class="label label-primary"><b>授权主机/主机组</b></span>
|
||||
<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="#"></a>
|
||||
</li>
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<div>
|
||||
<div class="text-left">
|
||||
<table class="table table-striped table-bordered table-hover " id="editable" >
|
||||
<table class="table table-striped" id="agedit" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">主机</th>
|
||||
|
@ -120,11 +151,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content inspinia-timeline">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
<div class="form-group">
|
||||
<label for="username" class="col-sm-2 control-label">授权名称<span class="red-fonts">*</span></label>
|
||||
<div class="col-sm-8">
|
||||
<input id="rulename" name="rulename" placeholder="RuleName" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
|
||||
<input id="rulename" name="rulename" placeholder="RuleName" type="text" class="form-control" value="{{ rule.name }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
|
|
@ -31,16 +31,12 @@
|
|||
<a href="/jperm/rule/">授权规则</a>
|
||||
</li>
|
||||
|
||||
<li class="perm_list perm_edit perm_detail">
|
||||
<a href="/jperm/group/">用户组授权</a>
|
||||
</li>
|
||||
|
||||
<li class="sudo_list sudo_edit sudo_add cmd_list cmd_edit cmd_add sudo_detail">
|
||||
<a href="/jperm/sys_user_list/">系统用户</a>
|
||||
<a href="/jperm/role/">系统角色</a>
|
||||
</li>
|
||||
<li class="apply_show online"><a href="/jperm/apply_show/online/">权限审批</a></li>
|
||||
<li class="apply_show online"><a href="/jperm/log/">授权记录</a></li>
|
||||
</ul>d
|
||||
</ul>
|
||||
</li>
|
||||
<li id="jlog">
|
||||
<a href="/jlog/log_list/online/"><i class="fa fa-files-o"></i> <span class="nav-label">日志审计</span><span class="label label-info pull-right"></span></a>
|
||||
|
|
Loading…
Reference in New Issue