From 00e4c3cd07132f4551f5078dd6096b0d20553980 Mon Sep 17 00:00:00 2001 From: Bai Date: Fri, 11 Jun 2021 11:05:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E7=94=A8=E6=88=B7API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/applications/api/__init__.py | 1 + apps/applications/api/application.py | 37 ++----------- apps/applications/api/application_user.py | 55 ++++++++++++++++++++ apps/applications/hands.py | 2 +- apps/applications/models/application.py | 7 ++- apps/applications/serializers/application.py | 42 ++++++++++++++- apps/applications/urls/api_urls.py | 3 +- 7 files changed, 109 insertions(+), 38 deletions(-) create mode 100644 apps/applications/api/application_user.py diff --git a/apps/applications/api/__init__.py b/apps/applications/api/__init__.py index 68f0d1803..a11b4966a 100644 --- a/apps/applications/api/__init__.py +++ b/apps/applications/api/__init__.py @@ -1,3 +1,4 @@ from .application import * +from .application_user import * from .mixin import * from .remote_app import * diff --git a/apps/applications/api/application.py b/apps/applications/api/application.py index 84426b6b2..867a8ddd3 100644 --- a/apps/applications/api/application.py +++ b/apps/applications/api/application.py @@ -2,18 +2,13 @@ # from orgs.mixins.api import OrgBulkModelViewSet -from rest_framework import generics -from ..hands import IsOrgAdminOrAppUser, IsOrgAdmin -from .. import models, serializers +from ..hands import IsOrgAdminOrAppUser +from .. import serializers from ..models import Application -from assets.models import SystemUser -from assets.serializers import SystemUserListSerializer -from perms.models import ApplicationPermission -from ..const import ApplicationCategoryChoices -__all__ = ['ApplicationViewSet', 'ApplicationUserListApi'] +__all__ = ['ApplicationViewSet'] class ApplicationViewSet(OrgBulkModelViewSet): @@ -22,29 +17,3 @@ class ApplicationViewSet(OrgBulkModelViewSet): search_fields = filterset_fields permission_classes = (IsOrgAdminOrAppUser,) serializer_class = serializers.ApplicationSerializer - - -class ApplicationUserListApi(generics.ListAPIView): - permission_classes = (IsOrgAdmin, ) - filterset_fields = ('name', 'username') - search_fields = filterset_fields - serializer_class = SystemUserListSerializer - - def get_application(self): - application = None - app_id = self.request.query_params.get('application_id') - if app_id: - application = Application.objects.get(id=app_id) - return application - - def get_queryset(self): - queryset = SystemUser.objects.none() - application = self.get_application() - if not application: - return queryset - system_user_ids = ApplicationPermission.objects.filter(applications=application)\ - .values_list('system_users', flat=True) - if not system_user_ids: - return queryset - queryset = SystemUser.objects.filter(id__in=system_user_ids) - return queryset diff --git a/apps/applications/api/application_user.py b/apps/applications/api/application_user.py new file mode 100644 index 000000000..93bbc29a5 --- /dev/null +++ b/apps/applications/api/application_user.py @@ -0,0 +1,55 @@ +# coding: utf-8 +# + +from rest_framework import generics +from django.conf import settings + +from ..hands import IsOrgAdminOrAppUser, IsOrgAdmin, NeedMFAVerify +from .. import serializers +from ..models import Application, ApplicationUser +from perms.models import ApplicationPermission + + +class ApplicationUserListApi(generics.ListAPIView): + permission_classes = (IsOrgAdmin, ) + filterset_fields = ('name', 'username') + search_fields = filterset_fields + serializer_class = serializers.ApplicationUserSerializer + _application = None + + @property + def application(self): + if self._application is None: + app_id = self.request.query_params.get('application_id') + if app_id: + self._application = Application.objects.get(id=app_id) + return self._application + + def get_serializer_context(self): + context = super().get_serializer_context() + context.update({ + 'application': self.application + }) + return context + + def get_queryset(self): + queryset = ApplicationUser.objects.none() + if not self.application: + return queryset + system_user_ids = ApplicationPermission.objects.filter(applications=self.application)\ + .values_list('system_users', flat=True) + if not system_user_ids: + return queryset + queryset = ApplicationUser.objects.filter(id__in=system_user_ids) + return queryset + + +class ApplicationUserAuthInfoListApi(ApplicationUserListApi): + serializer_class = serializers.ApplicationUserWithAuthInfoSerializer + http_method_names = ['get'] + permission_classes = [IsOrgAdminOrAppUser] + + def get_permissions(self): + if settings.SECURITY_VIEW_AUTH_NEED_MFA: + self.permission_classes = [IsOrgAdminOrAppUser, NeedMFAVerify] + return super().get_permissions() diff --git a/apps/applications/hands.py b/apps/applications/hands.py index ee13e589e..4987d5948 100644 --- a/apps/applications/hands.py +++ b/apps/applications/hands.py @@ -11,5 +11,5 @@ """ -from common.permissions import IsAppUser, IsOrgAdmin, IsValidUser, IsOrgAdminOrAppUser +from common.permissions import IsAppUser, IsOrgAdmin, IsValidUser, IsOrgAdminOrAppUser, NeedMFAVerify from users.models import User, UserGroup diff --git a/apps/applications/models/application.py b/apps/applications/models/application.py index f7b541580..c9374181d 100644 --- a/apps/applications/models/application.py +++ b/apps/applications/models/application.py @@ -3,7 +3,7 @@ from django.utils.translation import ugettext_lazy as _ from orgs.mixins.models import OrgModelMixin from common.mixins import CommonModelMixin -from assets.models import Asset +from assets.models import Asset, SystemUser from .. import const @@ -68,3 +68,8 @@ class Application(CommonModelMixin, OrgModelMixin): raise ValueError("Remote App not has asset attr") asset = Asset.objects.filter(id=asset_id).first() return asset + + +class ApplicationUser(SystemUser): + class Meta: + proxy = True diff --git a/apps/applications/serializers/application.py b/apps/applications/serializers/application.py index bff8c270a..94c55c1a8 100644 --- a/apps/applications/serializers/application.py +++ b/apps/applications/serializers/application.py @@ -6,11 +6,12 @@ from django.utils.translation import ugettext_lazy as _ from orgs.mixins.serializers import BulkOrgResourceModelSerializer from common.drf.serializers import MethodSerializer from .attrs import category_serializer_classes_mapping, type_serializer_classes_mapping - +from assets.serializers import SystemUserSerializer from .. import models __all__ = [ 'ApplicationSerializer', 'ApplicationSerializerMixin', + 'ApplicationUserSerializer', 'ApplicationUserWithAuthInfoSerializer' ] @@ -66,3 +67,42 @@ class ApplicationSerializer(ApplicationSerializerMixin, BulkOrgResourceModelSeri _attrs.update(attrs) return _attrs + +class ApplicationUserSerializer(SystemUserSerializer): + application_name = serializers.SerializerMethodField(label=_('Application name')) + application_category = serializers.SerializerMethodField(label=_('Application category')) + application_type = serializers.SerializerMethodField(label=_('Application type')) + + class Meta(SystemUserSerializer.Meta): + model = models.ApplicationUser + fields_mini = [ + 'id', 'application_name', 'application_category', 'application_type', 'name', 'username' + ] + fields_small = fields_mini + [ + 'protocol', 'login_mode', 'login_mode_display', 'priority', + "username_same_with_user", 'comment', + ] + fields = fields_small + extra_kwargs = { + 'login_mode_display': {'label': _('Login mode display')}, + 'created_by': {'read_only': True}, + } + + @property + def application(self): + return self.context['application'] + + def get_application_name(self, obj): + return self.application.name + + def get_application_category(self, obj): + return self.application.get_category_display() + + def get_application_type(self, obj): + return self.application.get_type_display() + + +class ApplicationUserWithAuthInfoSerializer(ApplicationUserSerializer): + + class Meta(ApplicationUserSerializer.Meta): + fields = ApplicationUserSerializer.Meta.fields + ['password'] diff --git a/apps/applications/urls/api_urls.py b/apps/applications/urls/api_urls.py index 9ca50d32c..fb5d08228 100644 --- a/apps/applications/urls/api_urls.py +++ b/apps/applications/urls/api_urls.py @@ -14,7 +14,8 @@ router.register(r'applications', api.ApplicationViewSet, 'application') urlpatterns = [ path('remote-apps//connection-info/', api.RemoteAppConnectionInfoApi.as_view(), name='remote-app-connection-info'), - path('application-users/', api.ApplicationUserListApi.as_view(), name='application-user') + path('application-users/', api.ApplicationUserListApi.as_view(), name='application-user'), + path('application-user-auth-infos/', api.ApplicationUserAuthInfoListApi.as_view(), name='application-user-auth-info') ]