From 458394fa533a24447acb7ffa8aceed052128fc96 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 7 Jun 2022 08:40:50 +0200 Subject: [PATCH] API - get oauth client by id or client_id --- fittrackee/oauth2/routes.py | 31 ++++-- fittrackee/tests/oauth2/test_oauth2_routes.py | 100 +++++++++++++++++- 2 files changed, 120 insertions(+), 11 deletions(-) diff --git a/fittrackee/oauth2/routes.py b/fittrackee/oauth2/routes.py index 6f388d7b..a17224cc 100644 --- a/fittrackee/oauth2/routes.py +++ b/fittrackee/oauth2/routes.py @@ -1,4 +1,4 @@ -from typing import Dict, Tuple, Union +from typing import Dict, Optional, Tuple, Union from flask import Blueprint, Response, request @@ -89,12 +89,15 @@ def create_client(auth_user: User) -> Union[HttpResponse, Tuple[Dict, int]]: ) -@oauth_blueprint.route('/oauth/apps/', methods=['GET']) -@require_auth() -def get_client(auth_user: User, client_id: str) -> Union[Dict, HttpResponse]: +def get_client( + auth_user: User, + client_id: Optional[int], + client_client_id: Optional[str], +) -> Union[Dict, HttpResponse]: + key = 'id' if client_id else 'client_id' + value = client_id if client_id else client_client_id client = OAuth2Client.query.filter_by( - id=client_id, - user_id=auth_user.id, + **{key: value, 'user_id': auth_user.id} ).first() if not client: @@ -106,6 +109,22 @@ def get_client(auth_user: User, client_id: str) -> Union[Dict, HttpResponse]: } +@oauth_blueprint.route('/oauth/apps/', methods=['GET']) +@require_auth() +def get_client_by_client_id( + auth_user: User, client_id: str +) -> Union[Dict, HttpResponse]: + return get_client(auth_user, client_id=None, client_client_id=client_id) + + +@oauth_blueprint.route('/oauth/apps//by_id', methods=['GET']) +@require_auth() +def get_client_by_id( + auth_user: User, client_id: int +) -> Union[Dict, HttpResponse]: + return get_client(auth_user, client_id=client_id, client_client_id=None) + + @oauth_blueprint.route('/oauth/apps/', methods=['DELETE']) @require_auth() def delete_client( diff --git a/fittrackee/tests/oauth2/test_oauth2_routes.py b/fittrackee/tests/oauth2/test_oauth2_routes.py index 9c156e58..28da480e 100644 --- a/fittrackee/tests/oauth2/test_oauth2_routes.py +++ b/fittrackee/tests/oauth2/test_oauth2_routes.py @@ -549,8 +549,8 @@ class TestOAuthGetClients(ApiTestCaseMixin): assert data['data']['clients'] == [] -class TestOAuthGetClient(ApiTestCaseMixin): - route = '/api/oauth/apps/{client_id}' +class TestOAuthGetClientById(ApiTestCaseMixin): + route = '/api/oauth/apps/{client_id}/by_id' def test_it_returns_error_when_not_authenticated( self, app: Flask, user_1: User @@ -630,10 +630,100 @@ class TestOAuthGetClient(ApiTestCaseMixin): app, user_1.email ) oauth_client = self.create_oauth_client(user_2) - client_id = oauth_client.id - response = client.delete( - self.route.format(client_id=client_id), + response = client.get( + self.route.format(client_id=oauth_client.id), + content_type='application/json', + headers=dict(Authorization=f'Bearer {auth_token}'), + ) + + self.assert_404_with_message(response, 'OAuth client not found') + + +class TestOAuthGetClientByClientId(ApiTestCaseMixin): + route = '/api/oauth/apps/{client_id}' + + def test_it_returns_error_when_not_authenticated( + self, app: Flask, user_1: User + ) -> None: + client = app.test_client() + + response = client.get( + self.route.format(client_id=self.random_string()), + content_type='application/json', + ) + + self.assert_401(response) + + def test_it_returns_error_when_client_not_found( + self, app: Flask, user_1: User + ) -> None: + client, auth_token = self.get_test_client_and_auth_token( + app, user_1.email + ) + + response = client.get( + self.route.format(client_id=self.random_string()), + content_type='application/json', + headers=dict(Authorization=f'Bearer {auth_token}'), + ) + + self.assert_404_with_message(response, 'OAuth client not found') + + def test_it_returns_user_oauth_client( + self, app: Flask, user_1: User + ) -> None: + client, auth_token = self.get_test_client_and_auth_token( + app, user_1.email + ) + client_description = self.random_string() + oauth_client = self.create_oauth_client( + user_1, + metadata={ + **TEST_OAUTH_CLIENT_METADATA, + 'client_description': client_description, + }, + ) + client_id = oauth_client.id + client_client_id = oauth_client.client_id + + response = client.get( + self.route.format(client_id=client_client_id), + content_type='application/json', + headers=dict(Authorization=f'Bearer {auth_token}'), + ) + + assert response.status_code == 200 + data = json.loads(response.data.decode()) + assert data['data']['client']['client_id'] == client_client_id + assert 'client_secret' not in data['data']['client'] + assert ( + data['data']['client']['client_description'] == client_description + ) + assert data['data']['client']['id'] == client_id + assert ( + data['data']['client']['name'] + == TEST_OAUTH_CLIENT_METADATA['client_name'] + ) + assert ( + data['data']['client']['redirect_uris'] + == TEST_OAUTH_CLIENT_METADATA['redirect_uris'] + ) + assert ( + data['data']['client']['website'] + == TEST_OAUTH_CLIENT_METADATA['client_uri'] + ) + + def test_it_does_not_return_oauth_client_from_another_user( + self, app: Flask, user_1: User, user_2: User + ) -> None: + client, auth_token = self.get_test_client_and_auth_token( + app, user_1.email + ) + oauth_client = self.create_oauth_client(user_2) + + response = client.get( + self.route.format(client_id=oauth_client.client_id), content_type='application/json', headers=dict(Authorization=f'Bearer {auth_token}'), )