datatracker/ietf/person/api.py
Jennifer Richards c58490bb36
feat: django-rest-framework + Person/Email API (#8256)
* feat: django-rest-framework + Person/Email API (#8233)

* chore: djangorestframework -> requirements.txt

* chore: auth/perm/schema classes for drf

* chore: settings for drf and friends

* chore: comment that api/serializer.py is not DRF

* feat: URL router for DRF

* feat: simple api/v3/person/{id} endpoint

* fix: actually working demo endpoint

* chore: no auth for PersonViewSet

* ci: params in ci-run-tests.yml

* Revert "ci: params in ci-run-tests.yml"

This reverts commit 03808ddf94afe42b7382ddd3730959987389612b.

* feat: email addresses for person API

* feat: email update api (WIP)

* fix: working Email API endpoint

* chore: annotate address format in api schema

* chore: api adjustments

* feat: expose SpectacularAPIView

At least for now...

* chore: better schema_path_prefix

* feat: permissions for DRF API

* refactor: use permissions classes

* refactor: extract NewEmailForm validation for reuse

* refactor: ietfauth.validators module

* refactor: send new email conf req via helper

* feat: API call to issue new address request

* chore: move datatracker DRF api to /api/core/

* fix: unused import

* fix: lint

* test: drf URL names + API tests (#8248)

* refactor: better drf URL naming

* test: test person-detail view

* test: permissions

* test: add_email tests + stubs

* test: test email update

* test: test 404 vs 403

* fix: fix permissions

* test: test email partial update

* test: assert we have a nonexistent PK

* chore: disable DRF api for now

* chore: fix git inanity

* fix: lint

* test: disable tests of disabled code

* test: more lint
2024-11-27 14:54:28 -06:00

46 lines
1.9 KiB
Python

# Copyright The IETF Trust 2024, All Rights Reserved
"""DRF API Views"""
from rest_framework import mixins, viewsets
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from ietf.api.permissions import BelongsToOwnPerson, IsOwnPerson
from ietf.ietfauth.utils import send_new_email_confirmation_request
from .models import Email, Person
from .serializers import NewEmailSerializer, EmailSerializer, PersonSerializer
class EmailViewSet(mixins.UpdateModelMixin, viewsets.GenericViewSet):
"""Email viewset
Only allows updating an existing email for now.
"""
permission_classes = [IsAuthenticated & BelongsToOwnPerson]
queryset = Email.objects.all()
serializer_class = EmailSerializer
lookup_value_regex = '.+@.+' # allow @-sign in the pk
class PersonViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
"""Person viewset"""
permission_classes = [IsAuthenticated & IsOwnPerson]
queryset = Person.objects.all()
serializer_class = PersonSerializer
@action(detail=True, methods=["post"], serializer_class=NewEmailSerializer)
def email(self, request, pk=None):
"""Add an email address for this Person
Always succeeds if the email address is valid. Causes a confirmation email to be sent to the
requested address and completion of that handshake will actually add the email address. If the
address already exists, an alert will be sent instead of the confirmation email.
"""
person = self.get_object()
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
# This may or may not actually send a confirmation, but doesn't reveal that to the user.
send_new_email_confirmation_request(person, serializer.validated_data["address"])
return Response(serializer.data)