Skip to content

Commit

Permalink
feat: add FieldNotAllowedError
Browse files Browse the repository at this point in the history
Refs HP-2319
  • Loading branch information
nicobav committed Apr 29, 2024
1 parent 2f1965c commit 2d78114
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 0 deletions.
1 change: 1 addition & 0 deletions open_city_profile/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
PROFILE_ALREADY_EXISTS_FOR_USER_ERROR = "PROFILE_ALREADY_EXISTS_FOR_USER_ERROR"
PROFILE_MUST_HAVE_PRIMARY_EMAIL = "PROFILE_MUST_HAVE_PRIMARY_EMAIL"
INSUFFICIENT_LOA_ERROR = "INSUFFICIENT_LOA_ERROR"
FIELD_NOT_ALLOWED_ERROR = "FIELD_NOT_ALLOWED_ERROR"

# Service specific GDPR errors
SERVICE_GDPR_API_REQUEST_ERROR = "SERVICE_GDPR_API_REQUEST_ERROR"
Expand Down
4 changes: 4 additions & 0 deletions open_city_profile/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,7 @@ class TokenExchangeError(Exception):

class InsufficientLoaError(ProfileGraphQLError):
"""The requester has insufficient level of authentication to retrieve this data"""


class FieldNotAllowedError(ProfileGraphQLError):
"""Field are not allowed for the service"""
25 changes: 25 additions & 0 deletions open_city_profile/graphene.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
from django.conf import settings
from django.forms import MultipleChoiceField
from django_filters import MultipleChoiceFilter
from graphene.utils.str_converters import to_snake_case
from graphene_django import DjangoObjectType
from graphene_django.forms.converter import convert_form_field
from graphene_django.types import ALL_FIELDS
from graphql_sync_dataloaders import SyncDataLoader
from parler.models import TranslatableModel

from open_city_profile.exceptions import FieldNotAllowedError, ServiceNotIdentifiedError
from profiles.loaders import (
addresses_by_profile_id_loader,
emails_by_profile_id_loader,
Expand Down Expand Up @@ -178,3 +180,26 @@ def __init_subclass_with_meta__(
_meta=_meta,
**options,
)


class AllowedDataFieldsMiddleware:
def resolve(self, next, root, info, **args):
try:
is_my_profile = (
info.operation.selection_set.selections[0].name.value == "myProfile"
)
node = info.parent_type.graphene_type
except AttributeError:
is_my_profile = False
node = None

if is_my_profile and getattr(node, "check_allowed_data_fields", False):
field_name = to_snake_case(getattr(info, "field_name", ""))

if not getattr(info.context, "service", False):
raise ServiceNotIdentifiedError("Service not identified")

if not node.is_field_allowed_for_service(field_name, info.context.service):
raise FieldNotAllowedError("Field is not allowed for service.")

return next(root, info, **args)
3 changes: 3 additions & 0 deletions open_city_profile/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
CONNECTED_SERVICE_DELETION_FAILED_ERROR,
CONNECTED_SERVICE_DELETION_NOT_ALLOWED_ERROR,
DATA_CONFLICT_ERROR,
FIELD_NOT_ALLOWED_ERROR,
GENERAL_ERROR,
INSUFFICIENT_LOA_ERROR,
INVALID_EMAIL_FORMAT_ERROR,
Expand All @@ -34,6 +35,7 @@
ConnectedServiceDeletionFailedError,
ConnectedServiceDeletionNotAllowedError,
DataConflictError,
FieldNotAllowedError,
InsufficientLoaError,
InvalidEmailFormatError,
MissingGDPRApiTokenError,
Expand Down Expand Up @@ -74,6 +76,7 @@
ServiceConnectionDoesNotExist: SERVICE_CONNECTION_DOES_NOT_EXIST_ERROR,
ServiceNotIdentifiedError: SERVICE_NOT_IDENTIFIED_ERROR,
InsufficientLoaError: INSUFFICIENT_LOA_ERROR,
FieldNotAllowedError: FIELD_NOT_ALLOWED_ERROR,
}

sentry_ignored_errors = (
Expand Down

0 comments on commit 2d78114

Please sign in to comment.