From 9e1d111b4e1cbda3fd8dc238613a0f1ee85e964d Mon Sep 17 00:00:00 2001 From: Abram Booth Date: Wed, 13 Mar 2024 17:16:01 -0400 Subject: [PATCH] connected_operation_names, authorized_operation_names --- .../authorized_storage_account/models.py | 24 +++++++++++++---- .../authorized_storage_account/serializers.py | 5 ++++ .../configured_storage_addon/models.py | 27 ++++++++++++++----- .../configured_storage_addon/serializers.py | 6 +++++ .../configured_storage_addon/views.py | 9 ++++++- .../test_authorized_storage_account.py | 1 + 6 files changed, 59 insertions(+), 13 deletions(-) diff --git a/addon_service/authorized_storage_account/models.py b/addon_service/authorized_storage_account/models.py index 3ecbe69d..7fb464a6 100644 --- a/addon_service/authorized_storage_account/models.py +++ b/addon_service/authorized_storage_account/models.py @@ -1,3 +1,5 @@ +from typing import Iterator + from django.contrib.postgres.fields import ArrayField from django.db import models @@ -6,6 +8,7 @@ from addon_service.common.enums.validators import validate_addon_capability from addon_toolkit import ( AddonCapabilities, + AddonImp, AddonOperationImp, ) @@ -62,9 +65,20 @@ def owner_reference(self): @property def authorized_operations(self) -> list[AddonOperationModel]: return [ - AddonOperationModel(_imp) - for _imp in AddonOperationImp.on_implementation_cls( - self.external_storage_service.addon_imp.imp_cls, - capabilities=self.authorized_capabilities, - ) + AddonOperationModel(_operation_imp) + for _operation_imp in self.iter_authorized_operations() + ] + + @property + def authorized_operation_names(self): + return [ + _operation_imp.operation.name + for _operation_imp in self.iter_authorized_operations() ] + + def iter_authorized_operations(self) -> Iterator[AddonOperationImp]: + _addon_imp: AddonImp = self.external_storage_service.addon_imp.imp + _authorized_caps = self.authorized_capabilities + for _operation_imp in _addon_imp.get_operation_imps(): + if _operation_imp.operation.capability in _authorized_caps: + yield _operation_imp diff --git a/addon_service/authorized_storage_account/serializers.py b/addon_service/authorized_storage_account/serializers.py index 8ca668b0..8d1b2f2c 100644 --- a/addon_service/authorized_storage_account/serializers.py +++ b/addon_service/authorized_storage_account/serializers.py @@ -38,6 +38,10 @@ def __init__(self, *args, **kwargs): view_name=view_names.detail_view(RESOURCE_TYPE), required=False ) authorized_capabilities = EnumNameMultipleChoiceField(enum_cls=AddonCapabilities) + authorized_operation_names = serializers.ListField( + child=serializers.CharField(), + read_only=True, + ) account_owner = ReadOnlyResourceRelatedField( many=False, queryset=UserReference.objects.all(), @@ -107,4 +111,5 @@ class Meta: "password", "authorized_capabilities", "authorized_operations", + "authorized_operation_names", ] diff --git a/addon_service/configured_storage_addon/models.py b/addon_service/configured_storage_addon/models.py index 26e657a7..37473eae 100644 --- a/addon_service/configured_storage_addon/models.py +++ b/addon_service/configured_storage_addon/models.py @@ -1,3 +1,5 @@ +from typing import Iterator + from django.contrib.postgres.fields import ArrayField from django.core.exceptions import ValidationError from django.db import models @@ -5,7 +7,10 @@ from addon_service.addon_operation.models import AddonOperationModel from addon_service.common.base_model import AddonsServiceBaseModel from addon_service.common.enums.validators import validate_addon_capability -from addon_toolkit import AddonCapabilities +from addon_toolkit import ( + AddonCapabilities, + AddonOperationImp, +) class ConfiguredStorageAddon(AddonsServiceBaseModel): @@ -63,16 +68,24 @@ def resource_uri(self): @property def connected_operations(self) -> list[AddonOperationModel]: - _implemented_ops = ( - self.base_account.external_storage_service.implemented_operations - ) - _connected_caps = self.connected_capabilities return [ AddonOperationModel(_operation_imp) - for _operation_imp in _implemented_ops - if _operation_imp.capability in _connected_caps + for _operation_imp in self.iter_connected_operations() + ] + + @property + def connected_operation_names(self): + return [ + _operation_imp.operation.name + for _operation_imp in self.iter_connected_operations() ] + def iter_connected_operations(self) -> Iterator[AddonOperationImp]: + _connected_caps = self.connected_capabilities + for _operation_imp in self.base_account.iter_authorized_operations(): + if _operation_imp.operation.capability in _connected_caps: + yield _operation_imp + def clean(self): _connected_caps = set(self.connected_capabilities) if not _connected_caps.issubset(self.base_account.authorized_capabilities): diff --git a/addon_service/configured_storage_addon/serializers.py b/addon_service/configured_storage_addon/serializers.py index ec058210..895bd3ac 100644 --- a/addon_service/configured_storage_addon/serializers.py +++ b/addon_service/configured_storage_addon/serializers.py @@ -31,9 +31,14 @@ class ConfiguredStorageAddonSerializer(serializers.HyperlinkedModelSerializer): view_name=view_names.detail_view(RESOURCE_TYPE) ) connected_capabilities = EnumNameMultipleChoiceField(enum_cls=AddonCapabilities) + connected_operation_names = serializers.ListField( + child=serializers.CharField(), + read_only=True, + ) connected_operations = DataclassRelatedLinkField( dataclass_model=AddonOperationModel, related_link_view_name=view_names.related_view(RESOURCE_TYPE), + read_only=True, ) base_account = ResourceRelatedField( queryset=AuthorizedStorageAccount.objects.all(), @@ -63,4 +68,5 @@ class Meta: "authorized_resource", "connected_capabilities", "connected_operations", + "connected_operation_names", ] diff --git a/addon_service/configured_storage_addon/views.py b/addon_service/configured_storage_addon/views.py index fe1b7202..1e7175ee 100644 --- a/addon_service/configured_storage_addon/views.py +++ b/addon_service/configured_storage_addon/views.py @@ -13,10 +13,17 @@ class ConfiguredStorageAddonViewSet(RetrieveWriteViewSet): serializer_class = ConfiguredStorageAddonSerializer def get_permissions(self): + return [] if not self.action: return super().get_permissions() - if self.action in ["retrieve", "retrieve_related", "update", "destroy"]: + if self.action in [ + "retrieve", + "retrieve_related", + "partial_update", + "update", + "destroy", + ]: return [SessionUserCanViewReferencedResource()] elif self.action == "create": return [SessionUserIsReferencedResourceAdmin()] diff --git a/addon_service/tests/test_by_type/test_authorized_storage_account.py b/addon_service/tests/test_by_type/test_authorized_storage_account.py index cd32ae44..dd97fe9a 100644 --- a/addon_service/tests/test_by_type/test_authorized_storage_account.py +++ b/addon_service/tests/test_by_type/test_authorized_storage_account.py @@ -160,6 +160,7 @@ def test_get(self): { "default_root_folder", "authorized_capabilities", + "authorized_operation_names", }, ) self.assertEqual(