11"""Basic authentication & authorization related tools for the Ralph API."""
22
33import logging
4+ import os
45from functools import lru_cache
56from pathlib import Path
67from threading import Lock
1011from cachetools import TTLCache , cached
1112from fastapi import Depends , HTTPException , status
1213from fastapi .security import HTTPBasic , HTTPBasicCredentials
13- from pydantic import BaseModel , root_validator
14+ from pydantic import RootModel , model_validator
1415from starlette .authentication import AuthenticationError
1516
1617from ralph .api .auth .user import AuthenticatedUser
@@ -40,45 +41,42 @@ class UserCredentials(AuthenticatedUser):
4041 username : str
4142
4243
43- class ServerUsersCredentials (BaseModel ):
44+ class ServerUsersCredentials (RootModel [ List [ UserCredentials ]] ):
4445 """Custom root pydantic model.
4546
4647 Describe expected list of all server users credentials as stored in
4748 the credentials file.
4849
4950 Attributes:
50- __root__ (List): Custom root consisting of the
51+ root (List): Custom root consisting of the
5152 list of all server users credentials.
5253 """
5354
54- __root__ : List [UserCredentials ]
55-
5655 def __add__ (self , other ) -> Any : # noqa: D105
57- return ServerUsersCredentials .parse_obj (self .__root__ + other .__root__ )
56+ return ServerUsersCredentials .model_validate (self .root + other .root )
5857
5958 def __getitem__ (self , item : int ) -> UserCredentials : # noqa: D105
60- return self .__root__ [item ]
59+ return self .root [item ]
6160
6261 def __len__ (self ) -> int : # noqa: D105
63- return len (self .__root__ )
62+ return len (self .root )
6463
6564 def __iter__ (self ) -> Iterator [UserCredentials ]: # noqa: D105
66- return iter (self .__root__ )
65+ return iter (self .root )
6766
68- @root_validator
69- @classmethod
70- def ensure_unique_username (cls , values : Any ) -> Any :
67+ @model_validator (mode = "after" )
68+ def ensure_unique_username (self ) -> Any :
7169 """Every username should be unique among registered users."""
72- usernames = [entry .username for entry in values . get ( "__root__" ) ]
70+ usernames = [entry .username for entry in self . root ]
7371 if len (usernames ) != len (set (usernames )):
7472 raise ValueError (
7573 "You cannot create multiple credentials with the same username"
7674 )
77- return values
75+ return self
7876
7977
8078@lru_cache ()
81- def get_stored_credentials (auth_file : Path ) -> ServerUsersCredentials :
79+ def get_stored_credentials (auth_file : os . PathLike ) -> ServerUsersCredentials :
8280 """Helper to read the credentials/scopes file.
8381
8482 Read credentials from JSON file and stored them to avoid reloading them with every
@@ -96,7 +94,9 @@ def get_stored_credentials(auth_file: Path) -> ServerUsersCredentials:
9694 msg = "Credentials file <%s> not found."
9795 logger .warning (msg , auth_file )
9896 raise AuthenticationError (msg .format (auth_file ))
99- return ServerUsersCredentials .parse_file (auth_file )
97+
98+ with open (auth_file , encoding = settings .LOCALE_ENCODING ) as f :
99+ return ServerUsersCredentials .model_validate_json (f .read ())
100100
101101
102102@cached (
0 commit comments