diff --git a/apps/applications/api/application.py b/apps/applications/api/application.py index 9bc3bc752..c65f3b879 100644 --- a/apps/applications/api/application.py +++ b/apps/applications/api/application.py @@ -3,6 +3,7 @@ from orgs.mixins.api import OrgBulkModelViewSet +from common.exceptions import JMSException from .. import models from .. import serializers from ..hands import IsOrgAdminOrAppUser @@ -14,7 +15,29 @@ __all__ = [ class ApplicationViewSet(OrgBulkModelViewSet): model = models.Application - filter_fields = ('name',) + filter_fields = ('name', 'type', 'category') search_fields = filter_fields permission_classes = (IsOrgAdminOrAppUser,) serializer_class = serializers.ApplicationSerializer + + def get_serializer_class(self): + serializer_class = super().get_serializer_class() + app_type = self.request.query_params.get('type') + app_category = self.request.query_params.get('category') + + # TODO: app_type invalid + # TODO: app_category invalid + + attrs_cls = None + if app_type: + attrs_cls = models.Category.get_type_serializer_cls(app_type) + elif self.request.method.lower() in ['get', 'option', 'head']: + if app_category: + attrs_cls = models.Category.get_category_serializer_cls(app_category) + else: + attrs_cls = serializers.CommonCategorySerializer + + if not attrs_cls: + raise JMSException(detail='Please bring the query parameter Category or Type') + + return type('ApplicationDynamicSerializer', (serializer_class,), {'attrs': attrs_cls()}) diff --git a/apps/applications/models/application.py b/apps/applications/models/application.py index 9984bd914..1d9483e42 100644 --- a/apps/applications/models/application.py +++ b/apps/applications/models/application.py @@ -98,6 +98,16 @@ class Category(ChoiceSet): mapper = cls.get_all_type_serializer_mapper() return mapper.get(tp, None) + @classmethod + def get_category_serializer_cls(cls, cg): + from ..serializers import remote_app, database_app, k8s_app + mapper = { + cls.db: database_app.DatabaseCategorySerializer, + cls.remote_app: remote_app.RemmoteAppCategorySerializer, + cls.cloud: k8s_app.CloudCategorySerializer, + } + return mapper.get(cg, None) + class Application(CommonModelMixin, OrgModelMixin): name = models.CharField(max_length=128, verbose_name=_('Name')) diff --git a/apps/applications/serializers/__init__.py b/apps/applications/serializers/__init__.py index b232a1ece..272b91982 100644 --- a/apps/applications/serializers/__init__.py +++ b/apps/applications/serializers/__init__.py @@ -2,3 +2,4 @@ from .application import * from .remote_app import * from .database_app import * from .k8s_app import * +from .common import * diff --git a/apps/applications/serializers/application.py b/apps/applications/serializers/application.py index 8c00b9e6b..2c8038e60 100644 --- a/apps/applications/serializers/application.py +++ b/apps/applications/serializers/application.py @@ -11,7 +11,6 @@ __all__ = [ class ApplicationSerializer(BulkOrgResourceModelSerializer): - class Meta: model = models.Application fields = [ diff --git a/apps/applications/serializers/common.py b/apps/applications/serializers/common.py new file mode 100644 index 000000000..07a67551d --- /dev/null +++ b/apps/applications/serializers/common.py @@ -0,0 +1,11 @@ +from rest_framework import serializers + + +class CommonCategorySerializer(serializers.JSONField): + def to_representation(self, value): + new_value = {} + for k, v in value.items(): + if 'password' not in k: + new_value[k] = v + return new_value + diff --git a/apps/applications/serializers/database_app.py b/apps/applications/serializers/database_app.py index 9cbc286ef..ac460ad8d 100644 --- a/apps/applications/serializers/database_app.py +++ b/apps/applications/serializers/database_app.py @@ -9,12 +9,16 @@ from common.serializers import AdaptedBulkListSerializer from .. import models -class DatabaseAttrsSerializer(serializers.Serializer): +class DatabaseCategorySerializer(serializers.Serializer): host = serializers.CharField() port = serializers.IntegerField() database = serializers.CharField(allow_blank=True, allow_null=True) +class DatabaseAttrsSerializer(DatabaseCategorySerializer): + pass + + class MySQLAttrsSerializer(DatabaseAttrsSerializer): port = serializers.IntegerField(default=3306, label=_('Port')) diff --git a/apps/applications/serializers/k8s_app.py b/apps/applications/serializers/k8s_app.py index d6327906d..0296e221b 100644 --- a/apps/applications/serializers/k8s_app.py +++ b/apps/applications/serializers/k8s_app.py @@ -5,10 +5,14 @@ from orgs.mixins.serializers import BulkOrgResourceModelSerializer from .. import models -class K8sAttrsSerializer(serializers.Serializer): +class CloudCategorySerializer(serializers.Serializer): cluster = serializers.CharField(label=_('Cluster')) +class K8sAttrsSerializer(CloudCategorySerializer): + pass + + class K8sAppSerializer(BulkOrgResourceModelSerializer): type_display = serializers.CharField(source='get_type_display', read_only=True) diff --git a/apps/applications/serializers/remote_app.py b/apps/applications/serializers/remote_app.py index 6a2161867..20eb3402a 100644 --- a/apps/applications/serializers/remote_app.py +++ b/apps/applications/serializers/remote_app.py @@ -14,8 +14,11 @@ from .. import const from ..models import RemoteApp -class RemoteAppAttrsSerializer(serializers.Serializer): +class RemmoteAppCategorySerializer(serializers.Serializer): asset = serializers.CharField(max_length=36, label=_('Assets')) + + +class RemoteAppAttrsSerializer(RemmoteAppCategorySerializer): path = serializers.CharField(label=_('Remote App path')) diff --git a/apps/perms/utils/database_app_permission.py b/apps/perms/utils/database_app_permission.py index 9a2897160..dd51ca458 100644 --- a/apps/perms/utils/database_app_permission.py +++ b/apps/perms/utils/database_app_permission.py @@ -29,7 +29,7 @@ def get_user_database_app_permissions(user, include_group=True): def get_user_group_database_app_permission(user_group): return DatabaseAppPermission.objects.all().valid().filter( - user_group=user_group + user_groups=user_group )