API - update OAuth2 scopes
This commit is contained in:
@ -494,6 +494,38 @@ class TestUserProfile(ApiTestCaseMixin):
|
||||
assert data['status'] == 'success'
|
||||
assert data['data'] == jsonify_dict(user_1.serialize(user_1))
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'client_scope, can_access',
|
||||
[
|
||||
('application:write', False),
|
||||
('profile:read', True),
|
||||
('profile:write', False),
|
||||
('users:read', False),
|
||||
('users:write', False),
|
||||
('workouts:read', False),
|
||||
('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/auth/profile',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {access_token}'),
|
||||
)
|
||||
|
||||
self.assert_response_scope(response, can_access)
|
||||
|
||||
|
||||
class TestUserProfileUpdate(ApiTestCaseMixin):
|
||||
def test_it_returns_error_if_payload_is_empty(
|
||||
@ -559,6 +591,42 @@ class TestUserProfileUpdate(ApiTestCaseMixin):
|
||||
assert data['message'] == 'user profile updated'
|
||||
assert data['data'] == jsonify_dict(user_1.serialize(user_1))
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'client_scope, can_access',
|
||||
[
|
||||
('application:write', False),
|
||||
('profile:read', False),
|
||||
('profile:write', True),
|
||||
('users:read', False),
|
||||
('users:write', False),
|
||||
('workouts:read', False),
|
||||
('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.post(
|
||||
'/api/auth/profile/edit',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {access_token}'),
|
||||
)
|
||||
|
||||
self.assert_response_scope(response, can_access)
|
||||
|
||||
|
||||
class TestUserAccountUpdate(ApiTestCaseMixin):
|
||||
@staticmethod
|
||||
@ -1193,6 +1261,42 @@ class TestUserAccountUpdate(ApiTestCaseMixin):
|
||||
password_change_email_mock,
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'client_scope, can_access',
|
||||
[
|
||||
('application:write', False),
|
||||
('profile:read', False),
|
||||
('profile:write', True),
|
||||
('users:read', False),
|
||||
('users:write', False),
|
||||
('workouts:read', False),
|
||||
('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.patch(
|
||||
'/api/auth/profile/edit/account',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {access_token}'),
|
||||
)
|
||||
|
||||
self.assert_response_scope(response, can_access)
|
||||
|
||||
|
||||
class TestUserPreferencesUpdate(ApiTestCaseMixin):
|
||||
def test_it_returns_error_if_payload_is_empty(
|
||||
@ -1254,6 +1358,42 @@ class TestUserPreferencesUpdate(ApiTestCaseMixin):
|
||||
assert data['message'] == 'user preferences updated'
|
||||
assert data['data'] == jsonify_dict(user_1.serialize(user_1))
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'client_scope, can_access',
|
||||
[
|
||||
('application:write', False),
|
||||
('profile:read', False),
|
||||
('profile:write', True),
|
||||
('users:read', False),
|
||||
('users:write', False),
|
||||
('workouts:read', False),
|
||||
('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.post(
|
||||
'/api/auth/profile/edit/preferences',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {access_token}'),
|
||||
)
|
||||
|
||||
self.assert_response_scope(response, can_access)
|
||||
|
||||
|
||||
class TestUserSportPreferencesUpdate(ApiTestCaseMixin):
|
||||
def test_it_returns_error_if_payload_is_empty(
|
||||
@ -1436,6 +1576,42 @@ class TestUserSportPreferencesUpdate(ApiTestCaseMixin):
|
||||
assert data['data']['is_active']
|
||||
assert data['data']['stopped_speed_threshold'] == 0.5
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'client_scope, can_access',
|
||||
[
|
||||
('application:write', False),
|
||||
('profile:read', False),
|
||||
('profile:write', True),
|
||||
('users:read', False),
|
||||
('users:write', False),
|
||||
('workouts:read', False),
|
||||
('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.post(
|
||||
'/api/auth/profile/edit/sports',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {access_token}'),
|
||||
)
|
||||
|
||||
self.assert_response_scope(response, can_access)
|
||||
|
||||
|
||||
class TestUserSportPreferencesReset(ApiTestCaseMixin):
|
||||
def test_it_returns_error_if_sport_does_not_exist(
|
||||
@ -1491,6 +1667,44 @@ class TestUserSportPreferencesReset(ApiTestCaseMixin):
|
||||
|
||||
assert response.status_code == 204
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'client_scope, can_access',
|
||||
[
|
||||
('application:write', False),
|
||||
('profile:read', False),
|
||||
('profile:write', True),
|
||||
('users:read', False),
|
||||
('users:write', False),
|
||||
('workouts:read', False),
|
||||
('workouts:write', False),
|
||||
],
|
||||
)
|
||||
def test_expected_scopes_are_defined(
|
||||
self,
|
||||
app: Flask,
|
||||
user_1: User,
|
||||
client_scope: str,
|
||||
can_access: bool,
|
||||
sport_1_cycling: Sport,
|
||||
user_sport_1_preference: UserSportPreference,
|
||||
) -> None:
|
||||
(
|
||||
client,
|
||||
oauth_client,
|
||||
access_token,
|
||||
_,
|
||||
) = self.create_oauth_client_and_issue_token(
|
||||
app, user_1, scope=client_scope
|
||||
)
|
||||
|
||||
response = client.delete(
|
||||
f'/api/auth/profile/reset/sports/{sport_1_cycling.id}',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {access_token}'),
|
||||
)
|
||||
|
||||
self.assert_response_scope(response, can_access)
|
||||
|
||||
|
||||
class TestUserPicture(ApiTestCaseMixin):
|
||||
def test_it_returns_error_if_file_is_missing(
|
||||
@ -1620,6 +1834,42 @@ class TestUserPicture(ApiTestCaseMixin):
|
||||
assert 'avatar.png' not in user_1.picture
|
||||
assert 'avatar2.png' in user_1.picture
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'client_scope, can_access',
|
||||
[
|
||||
('application:write', False),
|
||||
('profile:read', False),
|
||||
('profile:write', True),
|
||||
('users:read', False),
|
||||
('users:write', False),
|
||||
('workouts:read', False),
|
||||
('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.post(
|
||||
'/api/auth/picture',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {access_token}'),
|
||||
)
|
||||
|
||||
self.assert_response_scope(response, can_access)
|
||||
|
||||
|
||||
class TestRegistrationConfiguration(ApiTestCaseMixin):
|
||||
def test_it_returns_error_if_it_exceeds_max_users(
|
||||
|
@ -3,6 +3,7 @@ from datetime import datetime, timedelta
|
||||
from io import BytesIO
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from flask import Flask
|
||||
|
||||
from fittrackee.users.models import User, UserSportPreference
|
||||
@ -131,6 +132,42 @@ class TestGetUser(ApiTestCaseMixin):
|
||||
|
||||
self.assert_404_with_entity(response, 'user')
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'client_scope, can_access',
|
||||
[
|
||||
('application:write', False),
|
||||
('profile:read', False),
|
||||
('profile:write', False),
|
||||
('users:read', True),
|
||||
('users:write', False),
|
||||
('workouts:read', False),
|
||||
('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/users/not_existing',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {access_token}'),
|
||||
)
|
||||
|
||||
self.assert_response_scope(response, can_access)
|
||||
|
||||
|
||||
class TestGetUsers(ApiTestCaseMixin):
|
||||
def test_it_returns_error_if_user_has_no_admin_rights(
|
||||
@ -885,6 +922,42 @@ class TestGetUsers(ApiTestCaseMixin):
|
||||
'total': 3,
|
||||
}
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'client_scope, can_access',
|
||||
[
|
||||
('application:write', False),
|
||||
('profile:read', False),
|
||||
('profile:write', False),
|
||||
('users:read', True),
|
||||
('users:write', False),
|
||||
('workouts:read', False),
|
||||
('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/users',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {access_token}'),
|
||||
)
|
||||
|
||||
self.assert_response_scope(response, can_access)
|
||||
|
||||
|
||||
class TestGetUserPicture(ApiTestCaseMixin):
|
||||
def test_it_return_error_if_user_has_no_picture(
|
||||
@ -1360,6 +1433,43 @@ class TestUpdateUser(ApiTestCaseMixin):
|
||||
assert user['is_active'] is True
|
||||
assert user_2.confirmation_token is None
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'client_scope, can_access',
|
||||
[
|
||||
('application:write', False),
|
||||
('profile:read', False),
|
||||
('profile:write', False),
|
||||
('users:read', False),
|
||||
('users:write', True),
|
||||
('workouts:read', False),
|
||||
('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.patch(
|
||||
f'/api/users/{user_2.username}',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {access_token}'),
|
||||
)
|
||||
|
||||
self.assert_response_scope(response, can_access)
|
||||
|
||||
|
||||
class TestDeleteUser(ApiTestCaseMixin):
|
||||
def test_user_can_delete_its_own_account(
|
||||
@ -1573,3 +1683,40 @@ class TestDeleteUser(ApiTestCaseMixin):
|
||||
)
|
||||
|
||||
self.assert_403(response, 'error, registration is disabled')
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'client_scope, can_access',
|
||||
[
|
||||
('application:write', False),
|
||||
('profile:read', False),
|
||||
('profile:write', False),
|
||||
('users:read', False),
|
||||
('users:write', True),
|
||||
('workouts:read', False),
|
||||
('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.delete(
|
||||
f'/api/users/{user_2.username}',
|
||||
content_type='application/json',
|
||||
headers=dict(Authorization=f'Bearer {access_token}'),
|
||||
)
|
||||
|
||||
self.assert_response_scope(response, can_access)
|
||||
|
Reference in New Issue
Block a user