mirror of https://github.com/jumpserver/jumpserver
Merge branch 'dev' of github.com:jumpserver/jumpserver into github_dev
commit
f9ab0abc37
|
@ -2,4 +2,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
__version__ = "1.3.0"
|
__version__ = "1.3.1"
|
||||||
|
|
|
@ -65,15 +65,25 @@ class Node(models.Model):
|
||||||
key__regex=r'^{}:[0-9]+$'.format(self.key)
|
key__regex=r'^{}:[0-9]+$'.format(self.key)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_children_with_self(self):
|
||||||
|
return self.__class__.objects.filter(
|
||||||
|
key__regex=r'^{0}$|^{0}:[0-9]+$'.format(self.key)
|
||||||
|
)
|
||||||
|
|
||||||
def get_all_children(self):
|
def get_all_children(self):
|
||||||
return self.__class__.objects.filter(
|
return self.__class__.objects.filter(
|
||||||
key__startswith='{}:'.format(self.key)
|
key__startswith='{}:'.format(self.key)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_all_children_with_self(self):
|
||||||
|
return self.__class__.objects.filter(
|
||||||
|
key__regex=r'^{0}$|^{0}:'.format(self.key)
|
||||||
|
)
|
||||||
|
|
||||||
def get_family(self):
|
def get_family(self):
|
||||||
children = list(self.get_all_children())
|
ancestor = self.ancestor
|
||||||
children.append(self)
|
children = self.get_all_children()
|
||||||
return children
|
return [*tuple(ancestor), self, *tuple(children)]
|
||||||
|
|
||||||
def get_assets(self):
|
def get_assets(self):
|
||||||
from .asset import Asset
|
from .asset import Asset
|
||||||
|
@ -88,7 +98,7 @@ class Node(models.Model):
|
||||||
if self.is_root():
|
if self.is_root():
|
||||||
assets = Asset.objects.all()
|
assets = Asset.objects.all()
|
||||||
else:
|
else:
|
||||||
nodes = self.get_family()
|
nodes = self.get_all_children_with_self()
|
||||||
assets = Asset.objects.filter(nodes__in=nodes).distinct()
|
assets = Asset.objects.filter(nodes__in=nodes).distinct()
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
|
@ -108,18 +118,15 @@ class Node(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parent(self):
|
def parent(self):
|
||||||
if self.key == "0":
|
if self.key == "0" or not self.key.startswith("0"):
|
||||||
return self.__class__.root()
|
|
||||||
elif not self.key.startswith("0"):
|
|
||||||
return self.__class__.root()
|
return self.__class__.root()
|
||||||
|
|
||||||
parent_key = ":".join(self.key.split(":")[:-1])
|
parent_key = ":".join(self.key.split(":")[:-1])
|
||||||
try:
|
try:
|
||||||
parent = self.__class__.objects.get(key=parent_key)
|
parent = self.__class__.objects.get(key=parent_key)
|
||||||
|
return parent
|
||||||
except Node.DoesNotExist:
|
except Node.DoesNotExist:
|
||||||
return self.__class__.root()
|
return self.__class__.root()
|
||||||
else:
|
|
||||||
return parent
|
|
||||||
|
|
||||||
@parent.setter
|
@parent.setter
|
||||||
def parent(self, parent):
|
def parent(self, parent):
|
||||||
|
@ -127,14 +134,20 @@ class Node(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ancestor(self):
|
def ancestor(self):
|
||||||
if self.parent == self.__class__.root():
|
_key = self.key.split(':')
|
||||||
|
ancestor_keys = []
|
||||||
|
|
||||||
|
if self.is_root():
|
||||||
return [self.__class__.root()]
|
return [self.__class__.root()]
|
||||||
else:
|
|
||||||
return [self.parent, *tuple(self.parent.ancestor)]
|
for i in range(len(_key)-1):
|
||||||
|
_key.pop()
|
||||||
|
ancestor_keys.append(':'.join(_key))
|
||||||
|
return self.__class__.objects.filter(key__in=ancestor_keys)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ancestor_with_node(self):
|
def ancestor_with_self(self):
|
||||||
ancestor = self.ancestor
|
ancestor = list(self.ancestor)
|
||||||
ancestor.insert(0, self)
|
ancestor.insert(0, self)
|
||||||
return ancestor
|
return ancestor
|
||||||
|
|
||||||
|
|
|
@ -229,7 +229,11 @@ LOGGING = {
|
||||||
'django_auth_ldap': {
|
'django_auth_ldap': {
|
||||||
'handlers': ['console', 'ansible_logs'],
|
'handlers': ['console', 'ansible_logs'],
|
||||||
'level': "INFO",
|
'level': "INFO",
|
||||||
}
|
},
|
||||||
|
# 'django.db': {
|
||||||
|
# 'handlers': ['console', 'file'],
|
||||||
|
# 'level': 'DEBUG'
|
||||||
|
# }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
|
||||||
asset = get_object_or_404(Asset, pk=asset_id)
|
asset = get_object_or_404(Asset, pk=asset_id)
|
||||||
permissions = set(queryset.filter(assets=asset))
|
permissions = set(queryset.filter(assets=asset))
|
||||||
for node in asset.nodes.all():
|
for node in asset.nodes.all():
|
||||||
inherit_nodes.update(set(node.ancestor_with_node))
|
inherit_nodes.update(set(node.ancestor_with_self))
|
||||||
elif node_id:
|
elif node_id:
|
||||||
node = get_object_or_404(Node, pk=node_id)
|
node = get_object_or_404(Node, pk=node_id)
|
||||||
permissions = set(queryset.filter(nodes=node))
|
permissions = set(queryset.filter(nodes=node))
|
||||||
|
|
|
@ -8,10 +8,35 @@ import copy
|
||||||
|
|
||||||
from common.utils import set_or_append_attr_bulk, get_logger
|
from common.utils import set_or_append_attr_bulk, get_logger
|
||||||
from .models import AssetPermission
|
from .models import AssetPermission
|
||||||
|
from .hands import Node
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
|
class Tree:
|
||||||
|
def __init__(self):
|
||||||
|
self.__all_nodes = list(Node.objects.all())
|
||||||
|
self.nodes = defaultdict(dict)
|
||||||
|
self.root = Node.root()
|
||||||
|
|
||||||
|
def add_node(self, node):
|
||||||
|
if node in self.nodes:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
self.nodes[node] = defaultdict(set)
|
||||||
|
if node.key == self.root.key:
|
||||||
|
return
|
||||||
|
parent_key = ':'.join(node.key.split(':')[:-1])
|
||||||
|
for n in self.__all_nodes:
|
||||||
|
if n.key == parent_key:
|
||||||
|
self.add_node(n)
|
||||||
|
break
|
||||||
|
|
||||||
|
def add_nodes(self, nodes):
|
||||||
|
for node in nodes:
|
||||||
|
self.add_node(node)
|
||||||
|
|
||||||
|
|
||||||
class AssetPermissionUtil:
|
class AssetPermissionUtil:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_user_permissions(user):
|
def get_user_permissions(user):
|
||||||
|
@ -181,25 +206,15 @@ class AssetPermissionUtil:
|
||||||
:param user:
|
:param user:
|
||||||
:return: {node: {asset: set(su1, su2)}}
|
:return: {node: {asset: set(su1, su2)}}
|
||||||
"""
|
"""
|
||||||
from assets.models import Node
|
tree = Tree()
|
||||||
unnode = Node(value='Unnode')
|
|
||||||
nodes = defaultdict(dict)
|
|
||||||
for _node in cls.get_user_nodes(user):
|
|
||||||
children = _node.get_family()
|
|
||||||
for node in children:
|
|
||||||
nodes[node] = defaultdict(set)
|
|
||||||
nodes[unnode] = defaultdict(set)
|
|
||||||
_assets = cls.get_user_assets(user)
|
_assets = cls.get_user_assets(user)
|
||||||
for asset, _system_users in _assets.items():
|
for asset, _system_users in _assets.items():
|
||||||
_nodes = asset.get_nodes()
|
_nodes = asset.get_nodes()
|
||||||
in_node = False
|
tree.add_nodes(_nodes)
|
||||||
|
|
||||||
for node in _nodes:
|
for node in _nodes:
|
||||||
if node in nodes:
|
tree.nodes[node][asset].update(_system_users)
|
||||||
in_node = True
|
return tree.nodes
|
||||||
nodes[node][asset].update(_system_users)
|
|
||||||
if not in_node:
|
|
||||||
nodes[unnode][asset].update(_system_users)
|
|
||||||
return nodes
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_system_user_assets(cls, system_user):
|
def get_system_user_assets(cls, system_user):
|
||||||
|
@ -254,7 +269,7 @@ class NodePermissionUtil:
|
||||||
|
|
||||||
nodes = copy.deepcopy(nodes_directed)
|
nodes = copy.deepcopy(nodes_directed)
|
||||||
for node, system_users in nodes_directed.items():
|
for node, system_users in nodes_directed.items():
|
||||||
for child in node.get_family():
|
for child in node.get_all_children_with_self():
|
||||||
nodes[child].update(system_users)
|
nodes[child].update(system_users)
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="footer fixed">
|
<div class="footer fixed">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
Version <strong>1.3.0-{% include '_build.html' %}</strong> GPLv2.
|
Version <strong>1.3.1-{% include '_build.html' %}</strong> GPLv2.
|
||||||
<img style="display: none" src="http://www.jumpserver.org/img/evaluate_avatar1.jpg">
|
<img style="display: none" src="http://www.jumpserver.org/img/evaluate_avatar1.jpg">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -109,10 +109,9 @@ class StatusViewSet(viewsets.ModelViewSet):
|
||||||
task_serializer_class = TaskSerializer
|
task_serializer_class = TaskSerializer
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
if self.request.query_params.get("from_guacamole", None):
|
from_gua = self.request.query_params.get("from_guacamole", None)
|
||||||
return Response({"msg": "From guacamole, not support now"})
|
if not from_gua:
|
||||||
|
self.handle_sessions()
|
||||||
self.handle_sessions()
|
|
||||||
super().create(request, *args, **kwargs)
|
super().create(request, *args, **kwargs)
|
||||||
tasks = self.request.user.terminal.task_set.filter(is_finished=False)
|
tasks = self.request.user.terminal.task_set.filter(is_finished=False)
|
||||||
serializer = self.task_serializer_class(tasks, many=True)
|
serializer = self.task_serializer_class(tasks, many=True)
|
||||||
|
|
|
@ -3,10 +3,10 @@ ansible==2.4.2.0
|
||||||
asn1crypto==0.24.0
|
asn1crypto==0.24.0
|
||||||
bcrypt==3.1.4
|
bcrypt==3.1.4
|
||||||
billiard==3.5.0.3
|
billiard==3.5.0.3
|
||||||
boto3==1.6.4
|
boto3==1.6.5
|
||||||
botocore==1.9.4
|
botocore==1.9.5
|
||||||
celery==4.1.0
|
celery==4.1.0
|
||||||
certifi==2017.11.5
|
certifi==2018.1.18
|
||||||
cffi==1.11.2
|
cffi==1.11.2
|
||||||
chardet==3.0.4
|
chardet==3.0.4
|
||||||
configparser==3.5.0
|
configparser==3.5.0
|
||||||
|
@ -31,7 +31,7 @@ ecdsa==0.13
|
||||||
elasticsearch==6.1.1
|
elasticsearch==6.1.1
|
||||||
enum-compat==0.0.2
|
enum-compat==0.0.2
|
||||||
ephem==3.7.6.0
|
ephem==3.7.6.0
|
||||||
eventlet==0.21.0
|
eventlet==0.22.1
|
||||||
ForgeryPy==0.1
|
ForgeryPy==0.1
|
||||||
greenlet==0.4.12
|
greenlet==0.4.12
|
||||||
gunicorn==19.7.1
|
gunicorn==19.7.1
|
||||||
|
@ -57,7 +57,7 @@ pyotp==2.2.6
|
||||||
PyNaCl==1.2.1
|
PyNaCl==1.2.1
|
||||||
python-dateutil==2.6.1
|
python-dateutil==2.6.1
|
||||||
python-gssapi==0.6.4
|
python-gssapi==0.6.4
|
||||||
pytz==2017.3
|
pytz==2018.3
|
||||||
PyYAML==3.12
|
PyYAML==3.12
|
||||||
redis==2.10.6
|
redis==2.10.6
|
||||||
requests==2.18.4
|
requests==2.18.4
|
||||||
|
|
Loading…
Reference in New Issue