Commit 44d33f70 authored by 老广's avatar 老广 Committed by BaiJiangJie

[Update] 修改授权树显示策略 (#2784)

* [Update] 修改授权树显示策略

* [Update] 是否允许用户执行批量命令

* [Update] 优化授权节点构建

* [Update] 修改节点大小判断

* [Update] 修改节点大小判断
parent 0574b439
...@@ -40,8 +40,10 @@ class Node(OrgModelMixin): ...@@ -40,8 +40,10 @@ class Node(OrgModelMixin):
return self.key == other.key return self.key == other.key
def __gt__(self, other): def __gt__(self, other):
if self.is_root(): if self.is_root() and not other.is_root():
return True return True
elif not self.is_root() and other.is_root():
return False
self_key = [int(k) for k in self.key.split(':')] self_key = [int(k) for k in self.key.split(':')]
other_key = [int(k) for k in other.key.split(':')] other_key = [int(k) for k in other.key.split(':')]
self_parent_key = self_key[:-1] self_parent_key = self_key[:-1]
...@@ -49,6 +51,10 @@ class Node(OrgModelMixin): ...@@ -49,6 +51,10 @@ class Node(OrgModelMixin):
if self_parent_key == other_parent_key: if self_parent_key == other_parent_key:
return self.name > other.name return self.name > other.name
if len(self_parent_key) < len(other_parent_key):
return True
elif len(self_parent_key) > len(other_parent_key):
return False
return self_key > other_key return self_key > other_key
def __lt__(self, other): def __lt__(self, other):
......
...@@ -15,7 +15,8 @@ def jumpserver_processor(request): ...@@ -15,7 +15,8 @@ def jumpserver_processor(request):
'FAVICON_URL': static('img/facio.ico'), 'FAVICON_URL': static('img/facio.ico'),
'JMS_TITLE': 'Jumpserver', 'JMS_TITLE': 'Jumpserver',
'VERSION': settings.VERSION, 'VERSION': settings.VERSION,
'COPYRIGHT': 'FIT2CLOUD 飞致云' + ' © 2014-2019' 'COPYRIGHT': 'FIT2CLOUD 飞致云' + ' © 2014-2019',
'SECURITY_COMMAND_EXECUTION': settings.SECURITY_COMMAND_EXECUTION,
} }
return context return context
......
...@@ -546,6 +546,7 @@ TERMINAL_REPLAY_STORAGE = { ...@@ -546,6 +546,7 @@ TERMINAL_REPLAY_STORAGE = {
SECURITY_MFA_AUTH = False SECURITY_MFA_AUTH = False
SECURITY_COMMAND_EXECUTION = True
SECURITY_LOGIN_LIMIT_COUNT = 7 SECURITY_LOGIN_LIMIT_COUNT = 7
SECURITY_LOGIN_LIMIT_TIME = 30 # Unit: minute SECURITY_LOGIN_LIMIT_TIME = 30 # Unit: minute
SECURITY_MAX_IDLE_TIME = 30 # Unit: minute SECURITY_MAX_IDLE_TIME = 30 # Unit: minute
......
This diff is collapsed.
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# #
from rest_framework import viewsets from rest_framework import viewsets
from django.db import transaction from django.db import transaction
from django.conf import settings
from common.permissions import IsValidUser from common.permissions import IsValidUser
from ..models import CommandExecution from ..models import CommandExecution
...@@ -18,6 +19,11 @@ class CommandExecutionViewSet(viewsets.ModelViewSet): ...@@ -18,6 +19,11 @@ class CommandExecutionViewSet(viewsets.ModelViewSet):
user_id=str(self.request.user.id) user_id=str(self.request.user.id)
) )
def check_permissions(self, request):
if not settings.SECURITY_COMMAND_EXECUTION:
return self.permission_denied(request, "Command execution disabled")
return super().check_permissions(request)
def perform_create(self, serializer): def perform_create(self, serializer):
instance = serializer.save() instance = serializer.save()
instance.user = self.request.user instance.user = self.request.user
......
...@@ -37,9 +37,21 @@ class GenerateTree: ...@@ -37,9 +37,21 @@ class GenerateTree:
def add_asset(self, asset, system_users): def add_asset(self, asset, system_users):
nodes = asset.nodes.all() nodes = asset.nodes.all()
self.add_nodes(nodes) in_nodes = False
for node in nodes: for node in nodes:
if node not in self.nodes:
continue
self.nodes[node][asset].update(system_users) self.nodes[node][asset].update(system_users)
in_nodes = True
if not in_nodes:
all_nodes = self.nodes.keys()
# 如果没有授权节点,就放到默认的根节点下
if not all_nodes:
root_node = Node.root()
self.add_node(root_node)
else:
root_node = max(all_nodes)
self.nodes[root_node][asset].update(system_users)
def get_nodes(self): def get_nodes(self):
for node in self.nodes: for node in self.nodes:
...@@ -50,6 +62,7 @@ class GenerateTree: ...@@ -50,6 +62,7 @@ class GenerateTree:
node.assets_amount = len(assets) node.assets_amount = len(assets)
return self.nodes return self.nodes
# 添加节点时,追溯到根节点
def add_node(self, node): def add_node(self, node):
if node in self.nodes: if node in self.nodes:
return return
...@@ -62,9 +75,11 @@ class GenerateTree: ...@@ -62,9 +75,11 @@ class GenerateTree:
self.add_node(n) self.add_node(n)
break break
# 添加树节点
def add_nodes(self, nodes): def add_nodes(self, nodes):
for node in nodes: for node in nodes:
self.add_node(node) self.add_node(node)
self.add_nodes(node.get_all_children(with_self=False))
def get_user_permissions(user, include_group=True): def get_user_permissions(user, include_group=True):
...@@ -123,6 +138,7 @@ class AssetPermissionUtil: ...@@ -123,6 +138,7 @@ class AssetPermissionUtil:
self._assets = None self._assets = None
self._filter_id = 'None' # 当通过filter更改 permission是标记 self._filter_id = 'None' # 当通过filter更改 permission是标记
self.cache_policy = cache_policy self.cache_policy = cache_policy
self.tree = GenerateTree()
@classmethod @classmethod
def is_not_using_cache(cls, cache_policy): def is_not_using_cache(cls, cache_policy):
...@@ -181,6 +197,7 @@ class AssetPermissionUtil: ...@@ -181,6 +197,7 @@ class AssetPermissionUtil:
permissions = self.permissions.prefetch_related('nodes', 'system_users') permissions = self.permissions.prefetch_related('nodes', 'system_users')
for perm in permissions: for perm in permissions:
actions = perm.actions.all() actions = perm.actions.all()
self.tree.add_nodes(perm.nodes.all())
for node in perm.nodes.all(): for node in perm.nodes.all():
system_users = perm.system_users.all() system_users = perm.system_users.all()
system_users = self._structured_system_user(system_users, actions) system_users = self._structured_system_user(system_users, actions)
...@@ -275,10 +292,9 @@ class AssetPermissionUtil: ...@@ -275,10 +292,9 @@ class AssetPermissionUtil:
:return: :return:
""" """
assets = self.get_assets_without_cache() assets = self.get_assets_without_cache()
tree = GenerateTree()
for asset, system_users in assets.items(): for asset, system_users in assets.items():
tree.add_asset(asset, system_users) self.tree.add_asset(asset, system_users)
return tree.get_nodes() return self.tree.get_nodes()
def get_nodes_with_assets_from_cache(self): def get_nodes_with_assets_from_cache(self):
cached = cache.get(self.node_key) cached = cache.get(self.node_key)
......
...@@ -180,6 +180,11 @@ class SecuritySettingForm(BaseForm): ...@@ -180,6 +180,11 @@ class SecuritySettingForm(BaseForm):
'authentication (valid for all users, including administrators)' 'authentication (valid for all users, including administrators)'
) )
) )
# Execute commands for user
SECURITY_COMMAND_EXECUTION = forms.BooleanField(
required=False, label=_("Batch execute commands"),
help_text=_("Allow user batch execute commands")
)
# limit login count # limit login count
SECURITY_LOGIN_LIMIT_COUNT = forms.IntegerField( SECURITY_LOGIN_LIMIT_COUNT = forms.IntegerField(
min_value=3, max_value=99999, min_value=3, max_value=99999,
......
...@@ -16,11 +16,13 @@ ...@@ -16,11 +16,13 @@
</li> </li>
</ul> </ul>
</li> </li>
{% if SECURITY_COMMAND_EXECUTION %}
<li id="ops"> <li id="ops">
<a href="{% url 'ops:command-execution-start' %}"> <a href="{% url 'ops:command-execution-start' %}">
<i class="fa fa-terminal" style="width: 14px"></i> <span class="nav-label">{% trans 'Command execution' %}</span><span class="label label-info pull-right"></span> <i class="fa fa-terminal" style="width: 14px"></i> <span class="nav-label">{% trans 'Command execution' %}</span><span class="label label-info pull-right"></span>
</a> </a>
</li> </li>
{% endif %}
<li id="users"> <li id="users">
<a href="{% url 'users:user-profile' %}"> <a href="{% url 'users:user-profile' %}">
<i class="fa fa-user" style="width: 14px"></i> <span class="nav-label">{% trans 'Profile' %}</span><span class="label label-info pull-right"></span> <i class="fa fa-user" style="width: 14px"></i> <span class="nav-label">{% trans 'Profile' %}</span><span class="label label-info pull-right"></span>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment