feat: API to delete given social auth record for user

This commit is contained in:
Kaustav Banerjee
2025-02-03 16:04:43 +05:30
committed by Farhaan Bukhsh
parent c2eb913dcb
commit 02344c5905
3 changed files with 95 additions and 4 deletions

View File

@@ -7,6 +7,7 @@ from unittest.mock import patch
import ddt
from django.conf import settings
from django.contrib.auth import get_user_model
from django.http import QueryDict
from django.test.utils import override_settings
from django.urls import reverse
@@ -214,15 +215,43 @@ class UserViewV2APITests(UserViewsMixin, TpaAPITestCase):
Test the Third Party Auth User REST API
"""
def make_url(self, identifier):
def setUp(self): # pylint: disable=arguments-differ
""" Create users for use in the tests """
super().setUp()
admin_user = get_user_model().objects.get(username=ADMIN_USERNAME)
self.auth_token = f"JWT {generate_jwt(admin_user, is_restricted=False, scopes=None, filters=None)}"
def make_url(self, params):
"""
Return the view URL, with the identifier provided
"""
return '?'.join([
reverse('third_party_auth_users_api_v2'),
urllib.parse.urlencode(identifier)
urllib.parse.urlencode(params)
])
@ddt.data(
({}, 400, ["Must provide one of ['email', 'username']"]),
({'username': ALICE_USERNAME}, 400, ["Must provide uid"]),
(
{'username': 'invalid-user', 'uid': f'{ALICE_USERNAME}@gmail.com'},
404,
{f"Either user invalid-user or social auth record {ALICE_USERNAME}@gmail.com does not exist."}
),
(
{'username': ALICE_USERNAME, 'uid': 'invalid-uid'},
404,
{f"Either user {ALICE_USERNAME} or social auth record invalid-uid does not exist."}
),
({'username': ALICE_USERNAME, 'uid': f'{ALICE_USERNAME}@gmail.com'}, 204, None),
)
@ddt.unpack
def test_delete_social_auth_record(self, identifier, expect_code, expect_data):
url = self.make_url(identifier)
response = self.client.delete(url, HTTP_AUTHORIZATION=self.auth_token)
assert response.status_code == expect_code
assert (response.data == expect_data)
@override_settings(EDX_API_KEY=VALID_API_KEY)
@ddt.ddt

View File

@@ -65,6 +65,7 @@ class BaseUserView(APIView):
identifier_kinds = ['email', 'username']
authentication_classes = (
JwtAuthentication,
# Users may want to view/edit the providers used for authentication before they've
# activated their account, so we allow inactive users.
BearerAuthenticationAllowInactiveUser,
@@ -249,6 +250,42 @@ class UserViewV2(BaseUserView):
identifier = self.get_identifier_for_requested_user(request)
return self.do_get(request, identifier)
def delete(self, request):
"""
Delete given social auth record for a user.
Args:
request (Request): The HTTP DELETE request
Request Parameters:
email/username: Must provide one of 'email' or 'username'. If both are provided,
the username will be ignored.
uid: UID of the social auth record to delete
Return:
JSON serialized list of the providers linked to this user after the delete operation.
"""
identifier = self.get_identifier_for_requested_user(request)
uid = request.query_params.get("uid")
if not uid:
raise exceptions.ValidationError("Must provide uid")
is_unprivileged = self.is_unprivileged_query(request, identifier)
if is_unprivileged:
return Response(status=status.HTTP_403_FORBIDDEN)
try:
UserSocialAuth.objects.get(**{"user__" + identifier.kind: identifier.value}, uid=uid).delete()
except UserSocialAuth.DoesNotExist:
return Response(
data={f"Either user {identifier.value} or social auth record {uid} does not exist."},
status=status.HTTP_404_NOT_FOUND
)
return Response(status=status.HTTP_204_NO_CONTENT)
def get_identifier_for_requested_user(self, request):
"""
Return an identifier namedtuple for the requested user.

View File

@@ -8890,10 +8890,35 @@ paths:
parameters: []
responses:
'200':
description: ''
description: 'JSON serialized list of the providers linked to this user.'
tags:
- third_party_auth
parameters: []
delete:
operationId: third_party_auth_v0_users_delete
summary: Delete given social auth record for a user.
description: Allows deleting the given social auth record if it exists for a specified user.
parameters:
- name: uid
in: query
description: UID of the social auth record to delete.
required: true
type: string
responses:
'204':
description: 'No content returned if delete operation successful.'
tags:
- third_party_auth
parameters:
- name: username
in: query
description: Username of user. One of 'email' or 'username'. If both are provided, the username will be ignored.
required: false
type: string
- name: email
in: query
description: Email of user. One of 'email' or 'username'. If both are provided, the username will be ignored.
required: false
type: string
/third_party_auth/v0/users/{username}:
get:
operationId: third_party_auth_v0_users_read