mirror of https://github.com/jumpserver/jumpserver
feat(perms): 添加ApplicationPermission Model 和 API(包含ViewSet和RelationViewSet)
parent
1c551b4fe8
commit
4847b7a680
|
@ -2,8 +2,10 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from .asset_permission import *
|
from .asset_permission import *
|
||||||
|
from .application_permission import *
|
||||||
from .user_permission import *
|
from .user_permission import *
|
||||||
from .asset_permission_relation import *
|
from .asset_permission_relation import *
|
||||||
|
from .application_permission_relation import *
|
||||||
from .user_group_permission import *
|
from .user_group_permission import *
|
||||||
from .remote_app_permission import *
|
from .remote_app_permission import *
|
||||||
from .remote_app_permission_relation import *
|
from .remote_app_permission_relation import *
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
|
from common.permissions import IsOrgAdmin
|
||||||
|
from orgs.mixins.api import OrgModelViewSet
|
||||||
|
from common.utils import get_object_or_none
|
||||||
|
from ..models import ApplicationPermission
|
||||||
|
from ..hands import (
|
||||||
|
User, UserGroup, Asset, Node, SystemUser,
|
||||||
|
)
|
||||||
|
from .. import serializers
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationPermissionViewSet(OrgModelViewSet):
|
||||||
|
"""
|
||||||
|
应用授权列表的增删改查API
|
||||||
|
"""
|
||||||
|
model = ApplicationPermission
|
||||||
|
serializer_class = serializers.ApplicationPermissionSerializer
|
||||||
|
filter_fields = ['name']
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super().get_queryset().prefetch_related(
|
||||||
|
"applications", "users", "user_groups", "system_users"
|
||||||
|
)
|
||||||
|
return queryset
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from rest_framework import generics
|
||||||
|
from django.db.models import F, Value
|
||||||
|
from django.db.models import Q
|
||||||
|
from django.db.models.functions import Concat
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
|
from assets.models import Node, Asset
|
||||||
|
from orgs.mixins.api import OrgRelationMixin
|
||||||
|
from orgs.mixins.api import OrgBulkModelViewSet
|
||||||
|
from orgs.utils import current_org
|
||||||
|
from common.permissions import IsOrgAdmin
|
||||||
|
from .. import serializers
|
||||||
|
from .. import models
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'ApplicationPermissionUserRelationViewSet',
|
||||||
|
'ApplicationPermissionUserGroupRelationViewSet',
|
||||||
|
'ApplicationPermissionApplicationRelationViewSet',
|
||||||
|
'ApplicationPermissionSystemUserRelationViewSet'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class RelationMixin(OrgRelationMixin, OrgBulkModelViewSet):
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super().get_queryset()
|
||||||
|
org_id = current_org.org_id()
|
||||||
|
if org_id is not None:
|
||||||
|
queryset = queryset.filter(applicationpermission__org_id=org_id)
|
||||||
|
queryset = queryset.annotate(applicationpermission_display=F('applicationpermission__name'))
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationPermissionUserRelationViewSet(RelationMixin):
|
||||||
|
serializer_class = serializers.ApplicationPermissionUserRelationSerializer
|
||||||
|
m2m_field = models.ApplicationPermission.users.field
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
filter_fields = [
|
||||||
|
'id', "user", "applicationpermission",
|
||||||
|
]
|
||||||
|
search_fields = ("user__name", "user__username", "applicationpermission__name")
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super().get_queryset()
|
||||||
|
queryset = queryset.annotate(user_display=F('user__name'))
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationPermissionUserGroupRelationViewSet(RelationMixin):
|
||||||
|
serializer_class = serializers.ApplicationPermissionUserGroupRelationSerializer
|
||||||
|
m2m_field = models.ApplicationPermission.user_groups.field
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
filter_fields = [
|
||||||
|
'id', "usergroup", "applicationpermission"
|
||||||
|
]
|
||||||
|
search_fields = ["usergroup__name", "applicationpermission__name"]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super().get_queryset()
|
||||||
|
queryset = queryset.annotate(usergroup_display=F('usergroup__name'))
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationPermissionApplicationRelationViewSet(RelationMixin):
|
||||||
|
serializer_class = serializers.ApplicationPermissionApplicationRelationSerializer
|
||||||
|
m2m_field = models.ApplicationPermission.applications.field
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
filter_fields = [
|
||||||
|
'id', 'application', 'applicationpermission',
|
||||||
|
]
|
||||||
|
search_fields = ["id", "application__name", "applicationpermission__name"]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super().get_queryset()
|
||||||
|
queryset = queryset.annotate(application_display=F('application__name'))
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationPermissionSystemUserRelationViewSet(RelationMixin):
|
||||||
|
serializer_class = serializers.ApplicationPermissionSystemUserRelationSerializer
|
||||||
|
m2m_field = models.ApplicationPermission.system_users.field
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
filter_fields = [
|
||||||
|
'id', 'systemuser', 'applicationpermission',
|
||||||
|
]
|
||||||
|
search_fields = [
|
||||||
|
"applicactionpermission__name", "systemuser__name", "systemuser__username"
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super().get_queryset()
|
||||||
|
queryset = queryset \
|
||||||
|
.annotate(systemuser_display=Concat(
|
||||||
|
F('systemuser__name'), Value('('), F('systemuser__username'),
|
||||||
|
Value(')')
|
||||||
|
))
|
||||||
|
return queryset
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Generated by Django 2.2.13 on 2020-10-21 07:14
|
||||||
|
|
||||||
|
import common.utils.django
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.utils.timezone
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('users', '0030_auto_20200819_2041'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('applications', '0006_application'),
|
||||||
|
('assets', '0057_fill_node_value_assets_amount_and_parent_key'),
|
||||||
|
('perms', '0015_auto_20200929_1728'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ApplicationPermission',
|
||||||
|
fields=[
|
||||||
|
('org_id', models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')),
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
|
||||||
|
('name', models.CharField(max_length=128, verbose_name='Name')),
|
||||||
|
('is_active', models.BooleanField(default=True, verbose_name='Active')),
|
||||||
|
('date_start', models.DateTimeField(db_index=True, default=django.utils.timezone.now, verbose_name='Date start')),
|
||||||
|
('date_expired', models.DateTimeField(db_index=True, default=common.utils.django.date_expired_default, verbose_name='Date expired')),
|
||||||
|
('created_by', models.CharField(blank=True, max_length=128, verbose_name='Created by')),
|
||||||
|
('date_created', models.DateTimeField(auto_now_add=True, verbose_name='Date created')),
|
||||||
|
('comment', models.TextField(blank=True, verbose_name='Comment')),
|
||||||
|
('applications', models.ManyToManyField(blank=True, related_name='granted_by_permissions', to='applications.Application', verbose_name='Application')),
|
||||||
|
('system_users', models.ManyToManyField(related_name='granted_by_application_permissions', to='assets.SystemUser', verbose_name='System user')),
|
||||||
|
('user_groups', models.ManyToManyField(blank=True, related_name='applicationpermissions', to='users.UserGroup', verbose_name='User group')),
|
||||||
|
('users', models.ManyToManyField(blank=True, related_name='applicationpermissions', to=settings.AUTH_USER_MODEL, verbose_name='User')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Application permission',
|
||||||
|
'ordering': ('name',),
|
||||||
|
'unique_together': {('org_id', 'name')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -2,6 +2,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from .asset_permission import *
|
from .asset_permission import *
|
||||||
|
from .application_permission import *
|
||||||
from .remote_app_permission import *
|
from .remote_app_permission import *
|
||||||
from .database_app_permission import *
|
from .database_app_permission import *
|
||||||
from .k8s_app_permission import *
|
from .k8s_app_permission import *
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
# coding: utf-8
|
||||||
|
#
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from common.utils import lazyproperty
|
||||||
|
from .base import BasePermission
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'ApplicationPermission',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationPermission(BasePermission):
|
||||||
|
applications = models.ManyToManyField('applications.Application', related_name='granted_by_permissions', blank=True, verbose_name=_("Application"))
|
||||||
|
system_users = models.ManyToManyField('assets.SystemUser', related_name='granted_by_application_permissions', verbose_name=_("System user"))
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = [('org_id', 'name')]
|
||||||
|
verbose_name = _('Application permission')
|
||||||
|
ordering = ('name',)
|
||||||
|
|
||||||
|
@lazyproperty
|
||||||
|
def users_amount(self):
|
||||||
|
return self.users.count()
|
||||||
|
|
||||||
|
@lazyproperty
|
||||||
|
def user_groups_amount(self):
|
||||||
|
return self.user_groups.count()
|
||||||
|
|
||||||
|
@lazyproperty
|
||||||
|
def applications_amount(self):
|
||||||
|
return self.applications.count()
|
||||||
|
|
||||||
|
@lazyproperty
|
||||||
|
def system_users_amount(self):
|
||||||
|
return self.system_users.count()
|
|
@ -2,10 +2,12 @@
|
||||||
#
|
#
|
||||||
from .system_user_permission import *
|
from .system_user_permission import *
|
||||||
from .asset_permission import *
|
from .asset_permission import *
|
||||||
|
from .application_permission import *
|
||||||
from .user_permission import *
|
from .user_permission import *
|
||||||
from .remote_app_permission import *
|
from .remote_app_permission import *
|
||||||
from .remote_app_permission_relation import *
|
from .remote_app_permission_relation import *
|
||||||
from .asset_permission_relation import *
|
from .asset_permission_relation import *
|
||||||
|
from .application_permission_relation import *
|
||||||
from .database_app_permission import *
|
from .database_app_permission import *
|
||||||
from .database_app_permission_relation import *
|
from .database_app_permission_relation import *
|
||||||
from .base import *
|
from .base import *
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from django.db.models import Count
|
||||||
|
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
||||||
|
from perms.models import ApplicationPermission
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'ApplicationPermissionSerializer'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationPermissionSerializer(BulkOrgResourceModelSerializer):
|
||||||
|
is_valid = serializers.BooleanField(read_only=True)
|
||||||
|
is_expired = serializers.BooleanField(read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = ApplicationPermission
|
||||||
|
mini_fields = ['id', 'name']
|
||||||
|
small_fields = mini_fields + [
|
||||||
|
'is_active', 'is_expired', 'is_valid', 'created_by', 'date_created',
|
||||||
|
'date_expired', 'date_start', 'comment'
|
||||||
|
]
|
||||||
|
m2m_fields = [
|
||||||
|
'users', 'user_groups', 'applications', 'system_users',
|
||||||
|
'users_amount', 'user_groups_amount', 'applications_amount', 'system_users_amount',
|
||||||
|
]
|
||||||
|
fields = small_fields + m2m_fields
|
||||||
|
read_only_fields = ['created_by', 'date_created']
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setup_eager_loading(cls, queryset):
|
||||||
|
""" Perform necessary eager loading of data. """
|
||||||
|
queryset = queryset.prefetch_related('users', 'user_groups', 'applications', 'system_users')
|
||||||
|
return queryset
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from common.mixins import BulkSerializerMixin
|
||||||
|
from common.serializers import AdaptedBulkListSerializer
|
||||||
|
from assets.models import Asset, Node
|
||||||
|
from ..models import ApplicationPermission
|
||||||
|
from users.models import User
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'ApplicationPermissionUserRelationSerializer',
|
||||||
|
'ApplicationPermissionUserGroupRelationSerializer',
|
||||||
|
'ApplicationPermissionApplicationRelationSerializer',
|
||||||
|
'ApplicationPermissionSystemUserRelationSerializer'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class RelationMixin(BulkSerializerMixin, serializers.Serializer):
|
||||||
|
applicationpermission_display = serializers.ReadOnlyField()
|
||||||
|
|
||||||
|
def get_field_names(self, declared_fields, info):
|
||||||
|
fields = super().get_field_names(declared_fields, info)
|
||||||
|
fields.extend(['applicationpermission', "applicationpermission_display"])
|
||||||
|
return fields
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
list_serializer_class = AdaptedBulkListSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationPermissionUserRelationSerializer(RelationMixin, serializers.ModelSerializer):
|
||||||
|
user_display = serializers.ReadOnlyField()
|
||||||
|
|
||||||
|
class Meta(RelationMixin.Meta):
|
||||||
|
model = ApplicationPermission.users.through
|
||||||
|
fields = [
|
||||||
|
'id', 'user', 'user_display',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationPermissionUserGroupRelationSerializer(RelationMixin, serializers.ModelSerializer):
|
||||||
|
usergroup_display = serializers.ReadOnlyField()
|
||||||
|
|
||||||
|
class Meta(RelationMixin.Meta):
|
||||||
|
model = ApplicationPermission.user_groups.through
|
||||||
|
fields = [
|
||||||
|
'id', 'usergroup', "usergroup_display",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationPermissionApplicationRelationSerializer(RelationMixin, serializers.ModelSerializer):
|
||||||
|
application_display = serializers.ReadOnlyField()
|
||||||
|
|
||||||
|
class Meta(RelationMixin.Meta):
|
||||||
|
model = ApplicationPermission.applications.through
|
||||||
|
fields = [
|
||||||
|
'id', "application", "application_display",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationPermissionSystemUserRelationSerializer(RelationMixin, serializers.ModelSerializer):
|
||||||
|
systemuser_display = serializers.ReadOnlyField()
|
||||||
|
|
||||||
|
class Meta(RelationMixin.Meta):
|
||||||
|
model = ApplicationPermission.system_users.through
|
||||||
|
fields = [
|
||||||
|
'id', 'systemuser', 'systemuser_display'
|
||||||
|
]
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
from django.urls import re_path
|
from django.urls import re_path
|
||||||
from common import api as capi
|
from common import api as capi
|
||||||
from .asset_permission import asset_permission_urlpatterns
|
from .asset_permission import asset_permission_urlpatterns
|
||||||
|
from .application_permission import application_permission_urlpatterns
|
||||||
from .remote_app_permission import remote_app_permission_urlpatterns
|
from .remote_app_permission import remote_app_permission_urlpatterns
|
||||||
from .database_app_permission import database_app_permission_urlpatterns
|
from .database_app_permission import database_app_permission_urlpatterns
|
||||||
from .system_user_permission import system_users_permission_urlpatterns
|
from .system_user_permission import system_users_permission_urlpatterns
|
||||||
|
@ -15,6 +16,7 @@ old_version_urlpatterns = [
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns = asset_permission_urlpatterns + \
|
urlpatterns = asset_permission_urlpatterns + \
|
||||||
|
application_permission_urlpatterns + \
|
||||||
remote_app_permission_urlpatterns + \
|
remote_app_permission_urlpatterns + \
|
||||||
database_app_permission_urlpatterns + \
|
database_app_permission_urlpatterns + \
|
||||||
k8s_app_permission_urlpatterns + \
|
k8s_app_permission_urlpatterns + \
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
# coding: utf-8
|
||||||
|
#
|
||||||
|
|
||||||
|
from django.urls import path, include
|
||||||
|
from rest_framework_bulk.routes import BulkRouter
|
||||||
|
from .. import api
|
||||||
|
|
||||||
|
|
||||||
|
router = BulkRouter()
|
||||||
|
router.register('application-permissions', api.ApplicationPermissionViewSet, 'application-permission')
|
||||||
|
router.register('application-permissions-users-relations', api.ApplicationPermissionUserRelationViewSet, 'application-permissions-users-relation')
|
||||||
|
router.register('application-permissions-user-groups-relations', api.ApplicationPermissionUserGroupRelationViewSet, 'application-permissions-user-groups-relation')
|
||||||
|
router.register('application-permissions-applications-relations', api.ApplicationPermissionApplicationRelationViewSet, 'application-permissions-application-relation')
|
||||||
|
router.register('application-permissions-system-users-relations', api.ApplicationPermissionSystemUserRelationViewSet, 'application-permissions-system-users-relation')
|
||||||
|
|
||||||
|
"""
|
||||||
|
user_permission_urlpatterns = [
|
||||||
|
path('<uuid:pk>/applications/', api.UserGrantedApplicationsApi.as_view(), name='user-applications'),
|
||||||
|
path('applications/', api.UserGrantedApplicationsApi.as_view(), name='my-applications'),
|
||||||
|
|
||||||
|
# Application as tree
|
||||||
|
path('<uuid:pk>/applications/tree/', api.UserGrantedApplicationsAsTreeApi.as_view(), name='user-applications-as-tree'),
|
||||||
|
path('applications/tree/', api.UserGrantedApplicationsAsTreeApi.as_view(), name='my-applications-as-tree'),
|
||||||
|
|
||||||
|
path('<uuid:pk>/applications/<uuid:application_id>/system-users/', api.UserGrantedApplicationSystemUsersApi.as_view(), name='user-application-system-users'),
|
||||||
|
path('applications/<uuid:application_id>/system-users/', api.UserGrantedApplicationSystemUsersApi.as_view(), name='user-application-system-users'),
|
||||||
|
]
|
||||||
|
|
||||||
|
user_group_permission_urlpatterns = [
|
||||||
|
path('<uuid:pk>/applications/', api.UserGroupGrantedApplicationsApi.as_view(), name='user-group-applications'),
|
||||||
|
]
|
||||||
|
|
||||||
|
permission_urlpatterns = [
|
||||||
|
# 授权规则中授权的用户和数据库应用
|
||||||
|
path('<uuid:pk>/applications/all/', api.ApplicationPermissionAllApplicationListApi.as_view(), name='application-permission-all-applications'),
|
||||||
|
path('<uuid:pk>/users/all/', api.ApplicationPermissionAllUserListApi.as_view(), name='application-permission-all-users'),
|
||||||
|
|
||||||
|
# 验证用户是否有某个数据库应用的权限
|
||||||
|
path('user/validate/', api.ValidateUserApplicationPermissionApi.as_view(), name='validate-user-application-permission'),
|
||||||
|
]
|
||||||
|
|
||||||
|
application_permission_urlpatterns = [
|
||||||
|
path('users/', include(user_permission_urlpatterns)),
|
||||||
|
path('user-groups/', include(user_group_permission_urlpatterns)),
|
||||||
|
path('application-permissions/', include(permission_urlpatterns))
|
||||||
|
]
|
||||||
|
|
||||||
|
application_permission_urlpatterns += router.urls
|
||||||
|
"""
|
||||||
|
application_permission_urlpatterns = router.urls
|
Loading…
Reference in New Issue