feat(perms): 添加ApplicationPermission Model 和 API(包含ViewSet和RelationViewSet)

pull/4886/head
Bai 2020-10-21 19:32:27 +08:00 committed by 老广
parent 1c551b4fe8
commit 4847b7a680
11 changed files with 373 additions and 0 deletions

View File

@ -2,8 +2,10 @@
#
from .asset_permission import *
from .application_permission import *
from .user_permission import *
from .asset_permission_relation import *
from .application_permission_relation import *
from .user_group_permission import *
from .remote_app_permission import *
from .remote_app_permission_relation import *

View File

@ -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

View File

@ -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

View File

@ -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')},
},
),
]

View File

@ -2,6 +2,7 @@
#
from .asset_permission import *
from .application_permission import *
from .remote_app_permission import *
from .database_app_permission import *
from .k8s_app_permission import *

View File

@ -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()

View File

@ -2,10 +2,12 @@
#
from .system_user_permission import *
from .asset_permission import *
from .application_permission import *
from .user_permission import *
from .remote_app_permission import *
from .remote_app_permission_relation import *
from .asset_permission_relation import *
from .application_permission_relation import *
from .database_app_permission import *
from .database_app_permission_relation import *
from .base import *

View File

@ -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

View File

@ -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'
]

View File

@ -3,6 +3,7 @@
from django.urls import re_path
from common import api as capi
from .asset_permission import asset_permission_urlpatterns
from .application_permission import application_permission_urlpatterns
from .remote_app_permission import remote_app_permission_urlpatterns
from .database_app_permission import database_app_permission_urlpatterns
from .system_user_permission import system_users_permission_urlpatterns
@ -15,6 +16,7 @@ old_version_urlpatterns = [
]
urlpatterns = asset_permission_urlpatterns + \
application_permission_urlpatterns + \
remote_app_permission_urlpatterns + \
database_app_permission_urlpatterns + \
k8s_app_permission_urlpatterns + \

View File

@ -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