mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-12-15 08:32:48 +00:00
Compare commits
7 Commits
pr@dev@top
...
v2.4.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f70e313b4 | ||
|
|
c225fd584d | ||
|
|
8ed6a64a9e | ||
|
|
d7e97629aa | ||
|
|
2c20889540 | ||
|
|
7d325856b9 | ||
|
|
28879d9314 |
@@ -355,3 +355,4 @@ class Asset(ProtocolsMixin, NodesRelationMixin, OrgModelMixin):
|
||||
class Meta:
|
||||
unique_together = [('org_id', 'hostname')]
|
||||
verbose_name = _("Asset")
|
||||
ordering = ['-date_created']
|
||||
|
||||
@@ -140,7 +140,7 @@ def on_system_user_groups_change(instance, action, pk_set, reverse, **kwargs):
|
||||
logger.info("System user groups update signal recv: {}".format(instance))
|
||||
|
||||
users = User.objects.filter(groups__id__in=pk_set).distinct()
|
||||
instance.users.add(users)
|
||||
instance.users.add(*users)
|
||||
|
||||
|
||||
@receiver(m2m_changed, sender=Asset.nodes.through)
|
||||
|
||||
@@ -241,8 +241,8 @@ def push_system_user_a_asset_manual(system_user, asset, username=None):
|
||||
|
||||
@shared_task(queue="ansible")
|
||||
def push_system_user_to_assets(system_user, assets, username=None):
|
||||
task_name = _("Push system users to assets: {}").format(system_user.name)
|
||||
system_user = get_object_if_need(SystemUser, system_user)
|
||||
task_name = _("Push system users to assets: {}").format(system_user.name)
|
||||
assets = get_objects_if_need(Asset, assets)
|
||||
return push_system_user_util(system_user, assets, task_name, username=username)
|
||||
|
||||
|
||||
@@ -242,6 +242,9 @@ CACHES = {
|
||||
'host': CONFIG.REDIS_HOST,
|
||||
'port': CONFIG.REDIS_PORT,
|
||||
'db': CONFIG.REDIS_DB_CACHE,
|
||||
},
|
||||
'OPTIONS': {
|
||||
"REDIS_CLIENT_KWARGS": {"health_check_interval": 30}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from django.db.models import Q
|
||||
|
||||
from common.permissions import IsOrgAdmin
|
||||
from orgs.mixins.api import OrgModelViewSet
|
||||
from orgs.mixins.api import OrgBulkModelViewSet
|
||||
from common.utils import get_object_or_none
|
||||
from ..models import AssetPermission
|
||||
from ..hands import (
|
||||
@@ -17,7 +17,7 @@ __all__ = [
|
||||
]
|
||||
|
||||
|
||||
class AssetPermissionViewSet(OrgModelViewSet):
|
||||
class AssetPermissionViewSet(OrgBulkModelViewSet):
|
||||
"""
|
||||
资产授权列表的增删改查api
|
||||
"""
|
||||
|
||||
@@ -4,6 +4,7 @@ from rest_framework.request import Request
|
||||
|
||||
from common.permissions import IsOrgAdminOrAppUser, IsValidUser
|
||||
from common.utils import lazyproperty
|
||||
from orgs.utils import tmp_to_root_org
|
||||
from users.models import User
|
||||
from perms.models import UserGrantedMappingNode
|
||||
|
||||
@@ -47,6 +48,10 @@ class ForUserMixin:
|
||||
permission_classes = (IsValidUser,)
|
||||
request: Request
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
with tmp_to_root_org():
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
@lazyproperty
|
||||
def user(self):
|
||||
return self.request.user
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
from django.utils.decorators import method_decorator
|
||||
from perms.api.user_permission.mixin import UserNodeGrantStatusDispatchMixin
|
||||
from rest_framework.generics import ListAPIView
|
||||
from rest_framework.response import Response
|
||||
@@ -10,7 +9,6 @@ from assets.api.mixin import SerializeToTreeNodeMixin
|
||||
from common.utils import get_logger
|
||||
from perms.pagination import GrantedAssetLimitOffsetPagination
|
||||
from assets.models import Asset, Node, FavoriteAsset
|
||||
from orgs.utils import tmp_to_root_org
|
||||
from ... import serializers
|
||||
from ...utils.user_asset_permission import (
|
||||
get_node_all_granted_assets, get_user_direct_granted_assets,
|
||||
@@ -22,7 +20,6 @@ from .mixin import ForAdminMixin, ForUserMixin
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
@method_decorator(tmp_to_root_org(), name='list')
|
||||
class UserDirectGrantedAssetsApi(ListAPIView):
|
||||
"""
|
||||
用户直接授权的资产的列表,也就是授权规则上直接授权的资产,并非是来自节点的
|
||||
@@ -40,7 +37,6 @@ class UserDirectGrantedAssetsApi(ListAPIView):
|
||||
return assets
|
||||
|
||||
|
||||
@method_decorator(tmp_to_root_org(), name='list')
|
||||
class UserFavoriteGrantedAssetsApi(ListAPIView):
|
||||
serializer_class = serializers.AssetGrantedSerializer
|
||||
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
|
||||
@@ -55,7 +51,6 @@ class UserFavoriteGrantedAssetsApi(ListAPIView):
|
||||
return assets
|
||||
|
||||
|
||||
@method_decorator(tmp_to_root_org(), name='list')
|
||||
class AssetsAsTreeMixin(SerializeToTreeNodeMixin):
|
||||
"""
|
||||
将 资产 序列化成树的结构返回
|
||||
@@ -82,12 +77,10 @@ class MyFavoriteGrantedAssetsApi(ForUserMixin, UserFavoriteGrantedAssetsApi):
|
||||
pass
|
||||
|
||||
|
||||
@method_decorator(tmp_to_root_org(), name='list')
|
||||
class UserDirectGrantedAssetsAsTreeForAdminApi(ForAdminMixin, AssetsAsTreeMixin, UserDirectGrantedAssetsApi):
|
||||
pass
|
||||
|
||||
|
||||
@method_decorator(tmp_to_root_org(), name='list')
|
||||
class MyUngroupAssetsAsTreeApi(ForUserMixin, AssetsAsTreeMixin, UserDirectGrantedAssetsApi):
|
||||
def get_queryset(self):
|
||||
queryset = super().get_queryset()
|
||||
@@ -96,9 +89,11 @@ class MyUngroupAssetsAsTreeApi(ForUserMixin, AssetsAsTreeMixin, UserDirectGrante
|
||||
return queryset
|
||||
|
||||
|
||||
@method_decorator(tmp_to_root_org(), name='list')
|
||||
class UserAllGrantedAssetsApi(ListAPIView):
|
||||
class UserAllGrantedAssetsApi(ForAdminMixin, ListAPIView):
|
||||
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
|
||||
serializer_class = serializers.AssetGrantedSerializer
|
||||
filter_fields = ['hostname', 'ip', 'id', 'comment']
|
||||
search_fields = ['hostname', 'ip', 'comment']
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = get_user_granted_all_assets(self.user)
|
||||
@@ -106,11 +101,14 @@ class UserAllGrantedAssetsApi(ListAPIView):
|
||||
return queryset.only(*self.only_fields)
|
||||
|
||||
|
||||
class MyAllGrantedAssetsApi(ForUserMixin, UserAllGrantedAssetsApi):
|
||||
pass
|
||||
|
||||
|
||||
class MyAllAssetsAsTreeApi(ForUserMixin, AssetsAsTreeMixin, UserAllGrantedAssetsApi):
|
||||
search_fields = ['hostname', 'ip']
|
||||
|
||||
|
||||
@method_decorator(tmp_to_root_org(), name='list')
|
||||
class UserGrantedNodeAssetsApi(UserNodeGrantStatusDispatchMixin, ListAPIView):
|
||||
serializer_class = serializers.AssetGrantedSerializer
|
||||
only_fields = serializers.AssetGrantedSerializer.Meta.only_fields
|
||||
|
||||
@@ -7,7 +7,6 @@ from rest_framework.generics import (
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.request import Request
|
||||
|
||||
from orgs.utils import tmp_to_root_org
|
||||
from assets.api.mixin import SerializeToTreeNodeMixin
|
||||
from common.utils import get_logger
|
||||
from .mixin import ForAdminMixin, ForUserMixin, UserNodeGrantStatusDispatchMixin
|
||||
@@ -59,7 +58,6 @@ class NodeChildrenMixin:
|
||||
class BaseGrantedNodeApi(_GrantedNodeStructApi, metaclass=abc.ABCMeta):
|
||||
serializer_class = serializers.NodeGrantedSerializer
|
||||
|
||||
@tmp_to_root_org()
|
||||
def list(self, request, *args, **kwargs):
|
||||
rebuild_user_tree_if_need(request, self.user)
|
||||
nodes = self.get_nodes()
|
||||
@@ -72,7 +70,6 @@ class BaseNodeChildrenApi(NodeChildrenMixin, BaseGrantedNodeApi, metaclass=abc.A
|
||||
|
||||
|
||||
class BaseGrantedNodeAsTreeApi(SerializeToTreeNodeMixin, _GrantedNodeStructApi, metaclass=abc.ABCMeta):
|
||||
@tmp_to_root_org()
|
||||
def list(self, request: Request, *args, **kwargs):
|
||||
rebuild_user_tree_if_need(request, self.user)
|
||||
nodes = self.get_nodes()
|
||||
|
||||
@@ -19,7 +19,6 @@ from ...utils.user_asset_permission import (
|
||||
|
||||
from assets.models import Asset, FavoriteAsset
|
||||
from assets.api import SerializeToTreeNodeMixin
|
||||
from orgs.utils import tmp_to_root_org
|
||||
from ...hands import Node
|
||||
|
||||
logger = get_logger(__name__)
|
||||
@@ -28,7 +27,6 @@ logger = get_logger(__name__)
|
||||
class MyGrantedNodesWithAssetsAsTreeApi(SerializeToTreeNodeMixin, ListAPIView):
|
||||
permission_classes = (IsValidUser,)
|
||||
|
||||
@tmp_to_root_org()
|
||||
def list(self, request: Request, *args, **kwargs):
|
||||
"""
|
||||
此算法依赖 UserGrantedMappingNode
|
||||
@@ -102,7 +100,6 @@ class UserGrantedNodeChildrenWithAssetsAsTreeForAdminApi(ForAdminMixin, UserNode
|
||||
if node:
|
||||
return node.key
|
||||
|
||||
@tmp_to_root_org()
|
||||
def list(self, request: Request, *args, **kwargs):
|
||||
key = self.request.query_params.get('key')
|
||||
if key is None:
|
||||
|
||||
@@ -43,12 +43,14 @@ class AssetPermissionSerializer(BulkOrgResourceModelSerializer):
|
||||
model = AssetPermission
|
||||
mini_fields = ['id', 'name']
|
||||
small_fields = mini_fields + [
|
||||
'is_active', 'is_expired', 'is_valid', 'actions', 'created_by', 'date_created',
|
||||
'date_expired', 'date_start', 'comment'
|
||||
'is_active', 'is_expired', 'is_valid', 'actions',
|
||||
'created_by', 'date_created', 'date_expired',
|
||||
'date_start', 'comment'
|
||||
]
|
||||
m2m_fields = [
|
||||
'users', 'user_groups', 'assets', 'nodes', 'system_users',
|
||||
'users_amount', 'user_groups_amount', 'assets_amount', 'nodes_amount', 'system_users_amount',
|
||||
'users_amount', 'user_groups_amount', 'assets_amount',
|
||||
'nodes_amount', 'system_users_amount',
|
||||
]
|
||||
fields = small_fields + m2m_fields
|
||||
read_only_fields = ['created_by', 'date_created']
|
||||
|
||||
@@ -19,11 +19,9 @@ user_permission_urlpatterns = [
|
||||
# 直接授权:在 `AssetPermission` 中关联的对象
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# 获取用户所有直接授权的资产
|
||||
|
||||
# 以 serializer 格式返回
|
||||
path('<uuid:pk>/assets/', api.UserDirectGrantedAssetsForAdminApi.as_view(), name='user-assets'),
|
||||
path('assets/', api.MyDirectGrantedAssetsApi.as_view(), name='my-assets'),
|
||||
path('<uuid:pk>/assets/', api.UserAllGrantedAssetsApi.as_view(), name='user-assets'),
|
||||
path('assets/', api.MyAllAssetsAsTreeApi.as_view(), name='my-assets'),
|
||||
|
||||
# Tree Node 的数据格式返回
|
||||
path('<uuid:pk>/assets/tree/', api.UserDirectGrantedAssetsAsTreeForAdminApi.as_view(), name='user-assets-as-tree'),
|
||||
|
||||
@@ -55,11 +55,13 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, BulkModelViewSet):
|
||||
post_user_create.send(self.__class__, user=user)
|
||||
|
||||
@staticmethod
|
||||
def set_users_to_org(users, org_roles):
|
||||
def set_users_to_org(users, org_roles, update=False):
|
||||
# 只有真实存在的组织才真正关联用户
|
||||
if not current_org or not current_org.is_real():
|
||||
return
|
||||
for user, roles in zip(users, org_roles):
|
||||
if update and roles is None:
|
||||
continue
|
||||
if not roles:
|
||||
# 当前组织创建的用户,至少是该组织的`User`
|
||||
roles = [ORG_ROLE.USER]
|
||||
@@ -107,7 +109,7 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, BulkModelViewSet):
|
||||
users = serializer.save()
|
||||
if isinstance(users, User):
|
||||
users = [users]
|
||||
self.set_users_to_org(users, org_roles)
|
||||
self.set_users_to_org(users, org_roles, update=True)
|
||||
|
||||
def perform_bulk_update(self, serializer):
|
||||
# TODO: 需要测试
|
||||
|
||||
@@ -59,7 +59,7 @@ python-dateutil==2.6.1
|
||||
python-gssapi==0.6.4
|
||||
pytz==2018.3
|
||||
PyYAML==5.1
|
||||
redis==3.2.0
|
||||
redis==3.5.3
|
||||
requests==2.22.0
|
||||
jms-storage==0.0.34
|
||||
s3transfer==0.3.3
|
||||
|
||||
Reference in New Issue
Block a user