From 8c1968ee25072cc942bde9bc571909829d63639a Mon Sep 17 00:00:00 2001 From: lleeoo Date: Tue, 24 Oct 2023 11:33:04 +0200 Subject: [PATCH] fix UserScopes + minor formatting issues --- src/ralph/api/auth/basic.py | 2 +- src/ralph/api/auth/user.py | 10 +++++++++- src/ralph/conf.py | 4 ++-- tests/api/test_statements_get.py | 10 +++------- tests/test_conf.py | 4 ++-- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/ralph/api/auth/basic.py b/src/ralph/api/auth/basic.py index b860660aa..86c524cb3 100644 --- a/src/ralph/api/auth/basic.py +++ b/src/ralph/api/auth/basic.py @@ -183,7 +183,7 @@ def get_basic_auth_user( headers={"WWW-Authenticate": "Basic"}, ) - user = AuthenticatedUser(scopes=UserScopes(user.scopes), agent=user.agent) + user = AuthenticatedUser(scopes=user.scopes, agent=dict(user.agent)) # Restrict access by scopes if settings.LRS_RESTRICT_BY_SCOPES: diff --git a/src/ralph/api/auth/user.py b/src/ralph/api/auth/user.py index 98abca620..752b02217 100644 --- a/src/ralph/api/auth/user.py +++ b/src/ralph/api/auth/user.py @@ -3,6 +3,8 @@ from functools import lru_cache from typing import Dict, FrozenSet, Literal +from ralph.conf import settings + from pydantic import BaseModel Scope = Literal[ @@ -22,7 +24,7 @@ class UserScopes(FrozenSet[Scope]): """Scopes available to users.""" - @lru_cache() + @lru_cache(maxsize=1024) def is_authorized(self, requested_scope: Scope): """Check if the requested scope can be accessed based on user scopes.""" expanded_scopes = { @@ -54,6 +56,12 @@ def is_authorized(self, requested_scope: Scope): return requested_scope in expanded_user_scopes + @classmethod + def __get_validators__(cls): # noqa: D105 + def validate(value: FrozenSet[Scope]) -> UserScopes: + """Transform value to an instance of UserScopes.""" + return cls(value) + yield validate class AuthenticatedUser(BaseModel): """Pydantic model for user authentication. diff --git a/src/ralph/conf.py b/src/ralph/conf.py index 220c34b7c..ad91785ae 100644 --- a/src/ralph/conf.py +++ b/src/ralph/conf.py @@ -221,8 +221,8 @@ def check_restriction_compatibility(cls, values): "LRS_RESTRICT_BY_AUTHORITY" ): raise ConfigurationException( - "`LRS_RESTRICT_BY_AUTHORITY` must be set to `True` if using " - "`LRS_RESTRICT_BY_SCOPES=True`" + "LRS_RESTRICT_BY_AUTHORITY must be set to True if using " + "LRS_RESTRICT_BY_SCOPES=True" ) return values diff --git a/tests/api/test_statements_get.py b/tests/api/test_statements_get.py index d4f2acb94..a56323c56 100644 --- a/tests/api/test_statements_get.py +++ b/tests/api/test_statements_get.py @@ -84,12 +84,11 @@ def insert_clickhouse_statements(statements): @pytest.fixture(params=["es", "mongo", "clickhouse"]) -# pylint: disable=unused-argument def insert_statements_and_monkeypatch_backend( request, es, mongo, clickhouse, monkeypatch ): """(Security) Return a function that inserts statements into each backend.""" - # pylint: disable=invalid-name + # pylint: disable=invalid-name,unused-argument def _insert_statements_and_monkeypatch_backend(statements): """Inserts statements once into each backend.""" @@ -126,8 +125,7 @@ def test_api_statements_get_mine( """(Security) Test that the get statements API route, given a "mine=True" query parameter returns a list of statements filtered by authority. """ - # pylint: disable=redefined-outer-name - # pylint: disable=invalid-name + # pylint: disable=redefined-outer-name,invalid-name # Create two distinct agents if ifi == "account_same_home_page": @@ -770,9 +768,7 @@ def test_api_statements_get_scopes( monkeypatch, fs, es, auth_method, scopes, is_authorized ): """Test that getting statements behaves properly according to user scopes.""" - # pylint: disable=invalid-name - # pylint: disable=too-many-locals - # pylint: disable=too-many-arguments + # pylint: disable=invalid-name,too-many-locals,too-many-arguments monkeypatch.setattr( "ralph.api.routers.statements.settings.LRS_RESTRICT_BY_SCOPES", True diff --git a/tests/test_conf.py b/tests/test_conf.py index bc1171853..e9c681d79 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -86,8 +86,8 @@ def test_conf_forbidden_scopes_without_authority(monkeypatch): with pytest.raises( ConfigurationException, match=( - "`LRS_RESTRICT_BY_AUTHORITY` must be set to `True` if using " - "`LRS_RESTRICT_BY_SCOPES=True`" + "LRS_RESTRICT_BY_AUTHORITY must be set to True if using " + "LRS_RESTRICT_BY_SCOPES=True" ), ): reload(conf)