API - update OAuth2 scopes

This commit is contained in:
Sam
2022-06-15 19:16:14 +02:00
parent 969a92b8d4
commit 8b2543eb61
25 changed files with 1111 additions and 293 deletions

View File

@ -1,5 +1,6 @@
import json
import pytest
from flask import Flask
from fittrackee.users.models import User
@ -897,3 +898,40 @@ class TestGetRecords(ApiTestCaseMixin):
response = client.get('/api/records')
self.assert_401(response)
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', True),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1_admin: User,
user_2: User,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1_admin, scope=client_scope
)
response = client.get(
'/api/records',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)

View File

@ -1,5 +1,6 @@
import json
import pytest
from flask import Flask
from fittrackee import db
@ -138,6 +139,43 @@ class TestGetSports(ApiTestCaseMixin):
sport_2_running.serialize(is_admin=True)
)
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', True),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1, scope=client_scope
)
response = client.get(
'/api/sports',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)
class TestGetSport(ApiTestCaseMixin):
def test_it_gets_a_sport(
@ -241,6 +279,43 @@ class TestGetSport(ApiTestCaseMixin):
sport_1_cycling_inactive.serialize(is_admin=True)
)
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', True),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1, scope=client_scope
)
response = client.get(
f'/api/sports/{sport_1_cycling.id}',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)
class TestUpdateSport(ApiTestCaseMixin):
def test_it_disables_a_sport(
@ -442,3 +517,41 @@ class TestUpdateSport(ApiTestCaseMixin):
data = self.assert_404(response)
assert len(data['data']['sports']) == 0
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', False),
('workouts:write', True),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1_admin: User,
user_2: User,
sport_1_cycling: Sport,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1_admin, scope=client_scope
)
response = client.patch(
f'/api/sports/{sport_1_cycling.id}',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)

View File

@ -1,5 +1,6 @@
import json
import pytest
from flask import Flask
from fittrackee.users.models import User
@ -862,6 +863,42 @@ class TestGetStatsByTime(ApiTestCaseMixin):
}
}
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', True),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1, scope=client_scope
)
response = client.get(
f'/api/stats/{user_1.username}/by_time',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)
class TestGetStatsBySport(ApiTestCaseMixin):
def test_it_returns_error_if_user_is_not_authenticated(
@ -1007,6 +1044,42 @@ class TestGetStatsBySport(ApiTestCaseMixin):
self.assert_500(response)
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', True),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1, scope=client_scope
)
response = client.get(
f'/api/stats/{user_1.username}/by_sport',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)
class TestGetAllStats(ApiTestCaseMixin):
def test_it_returns_error_if_user_is_not_authenticated(
@ -1089,3 +1162,39 @@ class TestGetAllStats(ApiTestCaseMixin):
)
self.assert_403(response)
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', True),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1_admin: User,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1_admin, scope=client_scope
)
response = client.get(
'/api/stats/all',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)

View File

@ -3,6 +3,7 @@ from typing import List
from unittest.mock import patch
from uuid import uuid4
import pytest
from flask import Flask
from fittrackee.users.models import User
@ -101,6 +102,42 @@ class TestGetWorkouts(ApiTestCaseMixin):
self.assert_401(response, 'provide a valid auth token')
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', True),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1, scope=client_scope
)
response = client.get(
'/api/workouts',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)
class TestGetWorkoutsWithPagination(ApiTestCaseMixin):
def test_it_gets_workouts_with_default_pagination(
@ -1158,6 +1195,55 @@ class TestGetWorkout(ApiTestCaseMixin):
self.assert_404_with_message(response, 'Map does not exist')
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', True),
('workouts:write', False),
],
)
@pytest.mark.parametrize(
'endpoint',
[
'/api/workouts/{workout_short_id}',
'/api/workouts/{workout_short_id}/gpx',
'/api/workouts/{workout_short_id}/chart_data',
'/api/workouts/{workout_short_id}/gpx/segment/1',
'/api/workouts/{workout_short_id}/chart_data/segment/1',
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
workout_cycling_user_1: Workout,
client_scope: str,
can_access: bool,
endpoint: str,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1, scope=client_scope
)
response = client.get(
endpoint.format(workout_short_id=workout_cycling_user_1.short_id),
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)
class TestDownloadWorkoutGpx(ApiTestCaseMixin):
def test_it_returns_404_if_workout_does_not_exist(
@ -1242,3 +1328,41 @@ class TestDownloadWorkoutGpx(ApiTestCaseMixin):
mimetype='application/gpx+xml',
as_attachment=True,
)
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', True),
('workouts:write', False),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
workout_cycling_user_1: Workout,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1, scope=client_scope
)
response = client.get(
f'/api/workouts/{workout_cycling_user_1.short_id}/gpx/download',
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)

View File

@ -621,6 +621,45 @@ class TestPostWorkoutWithGpx(ApiTestCaseMixin, CallArgsMixin):
)
assert 'data' not in data
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', False),
('workouts:write', True),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1, scope=client_scope
)
response = client.post(
'/api/workouts',
data=dict(),
headers=dict(
content_type='multipart/form-data',
Authorization=f'Bearer {access_token}',
),
)
self.assert_response_scope(response, can_access)
class TestPostWorkoutWithoutGpx(ApiTestCaseMixin):
def test_it_returns_error_if_user_is_not_authenticated(
@ -763,6 +802,45 @@ class TestPostWorkoutWithoutGpx(ApiTestCaseMixin):
assert len(data['data']['workouts'][0]['segments']) == 0
assert len(data['data']['workouts'][0]['records']) == 0
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', False),
('workouts:write', True),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1, scope=client_scope
)
response = client.post(
'/api/workouts/no_gpx',
data=dict(),
headers=dict(
content_type='multipart/form-data',
Authorization=f'Bearer {access_token}',
),
)
self.assert_response_scope(response, can_access)
class TestPostWorkoutWithZipArchive(ApiTestCaseMixin):
def test_it_adds_workouts_with_zip_archive(

View File

@ -221,6 +221,45 @@ class TestEditWorkoutWithGpx(ApiTestCaseMixin):
self.assert_500(response)
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', False),
('workouts:write', True),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
workout_cycling_user_1: Workout,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1, scope=client_scope
)
response = client.patch(
f'/api/workouts/{workout_cycling_user_1.short_id}',
data=dict(),
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)
class TestEditWorkoutWithoutGpx(ApiTestCaseMixin):
def test_it_updates_a_workout_wo_gpx(

View File

@ -1,5 +1,6 @@
import os
import pytest
from flask import Flask
from fittrackee.files import get_absolute_file_path
@ -80,6 +81,45 @@ class TestDeleteWorkoutWithGpx(ApiTestCaseMixin):
self.assert_500(response)
@pytest.mark.parametrize(
'client_scope, can_access',
[
('application:write', False),
('profile:read', False),
('profile:write', False),
('users:read', False),
('users:write', False),
('workouts:read', False),
('workouts:write', True),
],
)
def test_expected_scopes_are_defined(
self,
app: Flask,
user_1: User,
sport_1_cycling: Sport,
workout_cycling_user_1: Workout,
client_scope: str,
can_access: bool,
) -> None:
(
client,
oauth_client,
access_token,
_,
) = self.create_oauth_client_and_issue_token(
app, user_1, scope=client_scope
)
response = client.delete(
f'/api/workouts/{workout_cycling_user_1.short_id}',
data=dict(),
content_type='application/json',
headers=dict(Authorization=f'Bearer {access_token}'),
)
self.assert_response_scope(response, can_access)
class TestDeleteWorkoutWithoutGpx(ApiTestCaseMixin):
def test_it_deletes_a_workout_wo_gpx(