mirror of https://github.com/jumpserver/jumpserver
[Update] 修改Perms
parent
0fa8287811
commit
bbaa35c773
|
@ -41,9 +41,9 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="wrapper wrapper-content">
|
<div class="wrapper wrapper-content">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-3" id="split-left">
|
<div class="col-lg-3" id="split-left" style="padding-left: 3px">
|
||||||
<div class="ibox float-e-margins">
|
<div class="ibox float-e-margins">
|
||||||
<div class="ibox-content mailbox-content" style="padding-top: 0">
|
<div class="ibox-content mailbox-content" style="padding-top: 0;padding-left: 1px">
|
||||||
<div class="file-manager ">
|
<div class="file-manager ">
|
||||||
<div id="assetTree" class="ztree">
|
<div id="assetTree" class="ztree">
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,81 +1,171 @@
|
||||||
{% extends '_base_list.html' %}
|
{% extends 'base.html' %}
|
||||||
{% load i18n %}
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block custom_head_css_js %}
|
{% block custom_head_css_js %}
|
||||||
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
<link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet">
|
||||||
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
<script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script>
|
||||||
|
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
||||||
{% endblock %}
|
|
||||||
{% block content_left_head %}{% endblock %}
|
|
||||||
|
|
||||||
{% block table_search %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block table_container %}
|
{% block content %}
|
||||||
<table class="table table-striped table-bordered table-hover " id="asset_list_table" >
|
<div class="wrapper wrapper-content">
|
||||||
<thead>
|
<div class="row">
|
||||||
<tr>
|
<div class="col-lg-3" id="split-left" style="padding-left: 3px">
|
||||||
<th class="text-center"><input type="checkbox" class="ipt_check_all"></th>
|
<div class="ibox float-e-margins">
|
||||||
<th class="text-center">{% trans 'Hostname' %}</th>
|
<div class="ibox-content mailbox-content" style="padding-top: 0;padding-left: 1px">
|
||||||
<th class="text-center">{% trans 'IP' %}</th>
|
<div class="file-manager ">
|
||||||
<th class="text-center">{% trans 'Port' %}</th>
|
<div id="assetTree" class="ztree">
|
||||||
<th class="text-center">{% trans 'Hardware' %}</th>
|
</div>
|
||||||
<th class="text-center">{% trans 'Active' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Connective' %}</th>
|
<div class="clearfix"></div>
|
||||||
</tr>
|
</div>
|
||||||
</thead>
|
</div>
|
||||||
<tbody>
|
</div>
|
||||||
</tbody>
|
</div>
|
||||||
</table>
|
<div class="col-lg-9 animated fadeInRight" id="split-right">
|
||||||
|
<div class="tree-toggle">
|
||||||
|
<div class="btn btn-sm btn-primary tree-toggle-btn" onclick="toggle()">
|
||||||
|
<i class="fa fa-angle-left fa-x" id="toggle-icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mail-box-header">
|
||||||
|
<div class="btn-group" style="float: right">
|
||||||
|
<button data-toggle="dropdown" class="btn btn-default btn-sm dropdown-toggle">{% trans 'Label' %} <span class="caret"></span></button>
|
||||||
|
<ul class="dropdown-menu labels">
|
||||||
|
{% for label in labels %}
|
||||||
|
<li><a style="font-weight: bolder">{{ label.name }}:{{ label.value }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<table class="table table-striped table-bordered table-hover " id="user_assets_table" style="width: 100%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-center"><input type="checkbox" class="ipt_check_all"></th>
|
||||||
|
<th class="text-center">{% trans 'Hostname' %}</th>
|
||||||
|
<th class="text-center">{% trans 'IP' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Active' %}</th>
|
||||||
|
<th class="text-center">{% trans 'System users' %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
<script>
|
||||||
<script type="text/javascript">
|
var zTree, rMenu, asset_table;
|
||||||
|
var inited = false;
|
||||||
|
var url;
|
||||||
function initTable() {
|
function initTable() {
|
||||||
|
if (inited){
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
inited = true;
|
||||||
|
}
|
||||||
var options = {
|
var options = {
|
||||||
ele: $('#asset_list_table'),
|
ele: $('#user_assets_table'),
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||||
{% url 'assets:asset-detail' pk=DEFAULT_PK as the_url %}
|
{% url 'assets:asset-detail' pk=DEFAULT_PK as the_url %}
|
||||||
var detail_btn = '<a href="{{ the_url }}">' + cellData + '</a>';
|
var detail_btn = '<a href="{{ the_url }}">' + cellData + '</a>';
|
||||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
||||||
}},
|
}},
|
||||||
{targets: 5, createdCell: function (td, cellData) {
|
{targets: 3, createdCell: function (td, cellData) {
|
||||||
if (!cellData) {
|
if (!cellData) {
|
||||||
$(td).html('<i class="fa fa-times text-danger"></i>')
|
$(td).html('<i class="fa fa-times text-danger"></i>')
|
||||||
} else {
|
} else {
|
||||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
$(td).html('<i class="fa fa-check text-navy"></i>')
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{targets: 6, createdCell: function (td, cellData) {
|
{targets: 4, createdCell: function (td, cellData) {
|
||||||
if (cellData == 'Unknown'){
|
var users = [];
|
||||||
$(td).html('<i class="fa fa-circle text-warning"></i>')
|
$.each(cellData, function (id, data) {
|
||||||
} else if (!cellData) {
|
users.push(data.name);
|
||||||
$(td).html('<i class="fa fa-circle text-danger"></i>')
|
});
|
||||||
} else {
|
$(td).html(users.join(', '))
|
||||||
$(td).html('<i class="fa fa-circle text-navy"></i>')
|
}}
|
||||||
}
|
|
||||||
}},
|
|
||||||
{# {targets: 9, createdCell: function (td, cellData, rowData) {#}
|
|
||||||
{# var conn_btn = '<a href="{% url "terminal:web-terminal" %}?id={{ DEFAULT_PK }}" class="btn btn-xs btn-info">{% trans "Connect" %}</a>'.replace("{{ DEFAULT_PK }}", cellData);#}
|
|
||||||
{# $(td).html(conn_btn)#}
|
|
||||||
{# }}#}
|
|
||||||
],
|
],
|
||||||
ajax_url: '{% url "api-assets:user-asset-list" %}',
|
ajax_url: url,
|
||||||
columns: [
|
columns: [
|
||||||
{data: "id"}, {data: "hostname" }, {data: "ip" }, {data: "port" },
|
{data: "id"}, {data: "hostname" }, {data: "ip" },
|
||||||
{data: "hardware_info"}, {data: "is_active" }, {data: "is_connective"}
|
{data: "is_active", orderable: false },
|
||||||
],
|
{data: "system_users_granted", orderable: false}
|
||||||
op_html: $('#actions').html()
|
]
|
||||||
};
|
};
|
||||||
return jumpserver.initDataTable(options);
|
asset_table = jumpserver.initDataTable(options);
|
||||||
|
return asset_table
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function(){
|
function onSelected(event, treeNode) {
|
||||||
|
console.log("select");
|
||||||
|
url = '{% url "api-perms:my-node-assets" node_id=DEFAULT_PK %}';
|
||||||
|
url = url.replace("{{ DEFAULT_PK }}", treeNode.id);
|
||||||
initTable();
|
initTable();
|
||||||
});
|
setCookie('node_selected', treeNode.id);
|
||||||
|
asset_table.ajax.url(url);
|
||||||
|
asset_table.ajax.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectQueryNode() {
|
||||||
|
var query_node_id = $.getUrlParam("node");
|
||||||
|
var cookie_node_id = getCookie('node_selected');
|
||||||
|
var node;
|
||||||
|
var node_id;
|
||||||
|
|
||||||
|
if (query_node_id !== null) {
|
||||||
|
node_id = query_node_id
|
||||||
|
} else if (cookie_node_id !== null) {
|
||||||
|
node_id = cookie_node_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = zTree.getNodesByParam("id", node_id, null);
|
||||||
|
if (node){
|
||||||
|
zTree.selectNode(node[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initTree() {
|
||||||
|
var setting = {
|
||||||
|
view: {
|
||||||
|
dblClickExpand: false,
|
||||||
|
showLine: true
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
simpleData: {
|
||||||
|
enable: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
callback: {
|
||||||
|
onSelected: onSelected
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var zNodes = [];
|
||||||
|
$.get("{% url 'api-perms:my-nodes' %}", function(data, status){
|
||||||
|
$.each(data, function (index, value) {
|
||||||
|
value["pId"] = value["parent"];
|
||||||
|
if (value["key"] === "0") {
|
||||||
|
value["open"] = true;
|
||||||
|
}
|
||||||
|
value["name"] = value["value"]
|
||||||
|
});
|
||||||
|
zNodes = data;
|
||||||
|
$.fn.zTree.init($("#assetTree"), setting, zNodes);
|
||||||
|
zTree = $.fn.zTree.getZTreeObj("assetTree");
|
||||||
|
rMenu = $("#rMenu");
|
||||||
|
selectQueryNode();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
initTree();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -100,33 +100,6 @@ class UserGrantedNodesApi(ListAPIView):
|
||||||
|
|
||||||
|
|
||||||
class UserGrantedNodesWithAssetsApi(ListAPIView):
|
class UserGrantedNodesWithAssetsApi(ListAPIView):
|
||||||
"""
|
|
||||||
授权用户的资产组,注:这里的资产组并非是授权列表中授权的,
|
|
||||||
而是把所有资产取出来,然后反查出所有节点,然后合并得到,
|
|
||||||
结果里也包含资产组下授权的资产
|
|
||||||
数据结构如下:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"value": "node",
|
|
||||||
... 其它属性
|
|
||||||
"assets_granted": [
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"hostname": "testserver",
|
|
||||||
"ip": "192.168.1.1",
|
|
||||||
"port": 22,
|
|
||||||
"system_users_granted": [
|
|
||||||
"id": 1,
|
|
||||||
"name": "web",
|
|
||||||
"username": "web",
|
|
||||||
"protocol": "ssh",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
"""
|
|
||||||
permission_classes = (IsSuperUserOrAppUser,)
|
permission_classes = (IsSuperUserOrAppUser,)
|
||||||
serializer_class = NodeGrantedSerializer
|
serializer_class = NodeGrantedSerializer
|
||||||
|
|
||||||
|
@ -172,6 +145,11 @@ class UserGrantedNodeAssetsApi(ListAPIView):
|
||||||
asset.system_users_granted = system_users
|
asset.system_users_granted = system_users
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
|
def get_permissions(self):
|
||||||
|
if self.kwargs.get('pk') is None:
|
||||||
|
self.permission_classes = (IsValidUser,)
|
||||||
|
return super().get_permissions()
|
||||||
|
|
||||||
|
|
||||||
class UserGroupGrantedAssetsApi(ListAPIView):
|
class UserGroupGrantedAssetsApi(ListAPIView):
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
|
@ -241,7 +241,7 @@ class User(AbstractUser):
|
||||||
def create_app_user(cls, name, comment):
|
def create_app_user(cls, name, comment):
|
||||||
app = cls.objects.create(
|
app = cls.objects.create(
|
||||||
username=name, name=name, email='{}@local.domain'.format(name),
|
username=name, name=name, email='{}@local.domain'.format(name),
|
||||||
is_active=False, role='App', enable_otp=False, comment=comment,
|
is_active=False, role='App', comment=comment,
|
||||||
is_first_login=False, created_by='System'
|
is_first_login=False, created_by='System'
|
||||||
)
|
)
|
||||||
access_key = app.create_access_key()
|
access_key = app.create_access_key()
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-navy">{% trans 'OTP' %}</td>
|
<td class="text-navy">{% trans 'OTP' %}</td>
|
||||||
<td>{{ user.enable_otp|yesno:"Yes,No,Unkown" }}</td>
|
<td>{{ user.otp_enabled|yesno:"Yes,No,Unkown" }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-navy">{% trans 'Public key' %}</td>
|
<td class="text-navy">{% trans 'Public key' %}</td>
|
||||||
|
|
|
@ -192,8 +192,6 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
|
||||||
for field in form:
|
for field in form:
|
||||||
if field.value():
|
if field.value():
|
||||||
setattr(user, field.name, field.value())
|
setattr(user, field.name, field.value())
|
||||||
if field.name == 'enable_otp':
|
|
||||||
user.enable_otp = field.value()
|
|
||||||
user.is_first_login = False
|
user.is_first_login = False
|
||||||
user.is_public_key_valid = True
|
user.is_public_key_valid = True
|
||||||
user.save()
|
user.save()
|
||||||
|
|
Loading…
Reference in New Issue