apexauthlib 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- apexauthlib-0.1.2/PKG-INFO +19 -0
- apexauthlib-0.1.2/README.md +2 -0
- apexauthlib-0.1.2/apexauthlib/entities/__init__.py +3 -0
- apexauthlib-0.1.2/apexauthlib/entities/auth.py +35 -0
- {apexauthlib-0.1.0 → apexauthlib-0.1.2}/apexauthlib/fastapi/auth.py +33 -1
- {apexauthlib-0.1.0 → apexauthlib-0.1.2}/apexauthlib/integration/api.py +6 -4
- {apexauthlib-0.1.0 → apexauthlib-0.1.2}/pyproject.toml +1 -1
- apexauthlib-0.1.0/PKG-INFO +0 -12
- apexauthlib-0.1.0/README.md +0 -2
- apexauthlib-0.1.0/apexauthlib.egg-info/PKG-INFO +0 -12
- apexauthlib-0.1.0/apexauthlib.egg-info/SOURCES.txt +0 -13
- apexauthlib-0.1.0/apexauthlib.egg-info/dependency_links.txt +0 -1
- apexauthlib-0.1.0/apexauthlib.egg-info/top_level.txt +0 -1
- apexauthlib-0.1.0/setup.cfg +0 -4
- apexauthlib-0.1.0/tests/test_api.py +0 -86
- {apexauthlib-0.1.0 → apexauthlib-0.1.2}/LICENSE +0 -0
- {apexauthlib-0.1.0 → apexauthlib-0.1.2}/apexauthlib/__init__.py +0 -0
- {apexauthlib-0.1.0 → apexauthlib-0.1.2}/apexauthlib/fastapi/__init__.py +0 -0
- {apexauthlib-0.1.0 → apexauthlib-0.1.2}/apexauthlib/integration/__init__.py +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: apexauthlib
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Apex authorization library for services
|
|
5
|
+
Author: Apex Dev
|
|
6
|
+
Author-email: dev@apex.ge
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
11
|
+
Requires-Dist: apexdevkit
|
|
12
|
+
Requires-Dist: fastapi
|
|
13
|
+
Requires-Dist: httpx
|
|
14
|
+
Requires-Dist: uvicorn
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# apexauthlib
|
|
18
|
+
Central authorization library for apex services
|
|
19
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Any
|
|
3
|
+
from uuid import uuid4
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True)
|
|
7
|
+
class User:
|
|
8
|
+
username: str
|
|
9
|
+
hashed_password: str
|
|
10
|
+
first_name: str
|
|
11
|
+
last_name: str
|
|
12
|
+
email: str
|
|
13
|
+
phone_number: str
|
|
14
|
+
|
|
15
|
+
is_admin: bool
|
|
16
|
+
|
|
17
|
+
id: str = field(default_factory=lambda: str(uuid4()))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass(frozen=True)
|
|
21
|
+
class Service:
|
|
22
|
+
service: str
|
|
23
|
+
superuser: str
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(frozen=True)
|
|
27
|
+
class ServiceMetadata:
|
|
28
|
+
user_id: str
|
|
29
|
+
metadata: dict[str, Any]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class UserMetadata:
|
|
34
|
+
service: str
|
|
35
|
+
metadata: dict[str, Any]
|
|
@@ -6,6 +6,7 @@ from fastapi import APIRouter, Depends, HTTPException
|
|
|
6
6
|
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
|
7
7
|
from starlette import status
|
|
8
8
|
|
|
9
|
+
from apexauthlib.entities import User
|
|
9
10
|
from apexauthlib.integration.api import AuthApiProvider
|
|
10
11
|
|
|
11
12
|
auth_api = APIRouter(tags=["Auth"])
|
|
@@ -22,10 +23,41 @@ TokenDependable = Annotated[str, Depends(oauth2())]
|
|
|
22
23
|
def get_user(
|
|
23
24
|
token: TokenDependable,
|
|
24
25
|
auth: AuthApiProviderDependable,
|
|
26
|
+
) -> User:
|
|
27
|
+
try:
|
|
28
|
+
api = auth.for_token(token)
|
|
29
|
+
return api.user()
|
|
30
|
+
except Exception as e:
|
|
31
|
+
raise HTTPException(
|
|
32
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
33
|
+
detail=str(e),
|
|
34
|
+
headers={"WWW-Authenticate": "Bearer"},
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_user_metadata(
|
|
39
|
+
token: TokenDependable,
|
|
40
|
+
auth: AuthApiProviderDependable,
|
|
25
41
|
) -> Any:
|
|
26
42
|
try:
|
|
27
43
|
api = auth.for_token(token)
|
|
28
|
-
return api.metadata_for(api.user())
|
|
44
|
+
return api.metadata_for(api.user().id)
|
|
45
|
+
except Exception as e:
|
|
46
|
+
raise HTTPException(
|
|
47
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
48
|
+
detail=str(e),
|
|
49
|
+
headers={"WWW-Authenticate": "Bearer"},
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_user_with_metadata(
|
|
54
|
+
token: TokenDependable,
|
|
55
|
+
auth: AuthApiProviderDependable,
|
|
56
|
+
) -> tuple[User, Any]:
|
|
57
|
+
try:
|
|
58
|
+
api = auth.for_token(token)
|
|
59
|
+
user = api.user()
|
|
60
|
+
return user, api.metadata_for(api.user().id)
|
|
29
61
|
except Exception as e:
|
|
30
62
|
raise HTTPException(
|
|
31
63
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
@@ -3,9 +3,11 @@ from __future__ import annotations
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from typing import Any, Generic, Mapping, TypeVar
|
|
5
5
|
|
|
6
|
-
from apexdevkit.formatter import Formatter
|
|
6
|
+
from apexdevkit.formatter import DataclassFormatter, Formatter
|
|
7
7
|
from apexdevkit.http import FluentHttp, JsonDict
|
|
8
8
|
|
|
9
|
+
from apexauthlib.entities import User
|
|
10
|
+
|
|
9
11
|
ItemT = TypeVar("ItemT")
|
|
10
12
|
|
|
11
13
|
|
|
@@ -46,15 +48,15 @@ class AuthApi(Generic[ItemT]):
|
|
|
46
48
|
formatter: Formatter[Mapping[str, Any], ItemT]
|
|
47
49
|
token: str
|
|
48
50
|
|
|
49
|
-
def user(self) ->
|
|
50
|
-
return
|
|
51
|
+
def user(self) -> User:
|
|
52
|
+
return DataclassFormatter(User).load(
|
|
51
53
|
(
|
|
52
54
|
self.http.with_header("Authorization", f"Bearer {self.token}")
|
|
53
55
|
.get()
|
|
54
56
|
.on_endpoint("/auth/user")
|
|
55
57
|
.on_failure(raises=RuntimeError)
|
|
56
58
|
.json()
|
|
57
|
-
)
|
|
59
|
+
)
|
|
58
60
|
)
|
|
59
61
|
|
|
60
62
|
def metadata_for(self, user_id: str) -> ItemT:
|
apexauthlib-0.1.0/PKG-INFO
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: apexauthlib
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Apex authorization library for services
|
|
5
|
-
Author-email: Apex Dev <dev@apex.ge>
|
|
6
|
-
Requires-Python: >=3.12
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Dynamic: license-file
|
|
10
|
-
|
|
11
|
-
# apexauthlib
|
|
12
|
-
Authorization library for apex services
|
apexauthlib-0.1.0/README.md
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: apexauthlib
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Apex authorization library for services
|
|
5
|
-
Author-email: Apex Dev <dev@apex.ge>
|
|
6
|
-
Requires-Python: >=3.12
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Dynamic: license-file
|
|
10
|
-
|
|
11
|
-
# apexauthlib
|
|
12
|
-
Authorization library for apex services
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
pyproject.toml
|
|
4
|
-
apexauthlib/__init__.py
|
|
5
|
-
apexauthlib.egg-info/PKG-INFO
|
|
6
|
-
apexauthlib.egg-info/SOURCES.txt
|
|
7
|
-
apexauthlib.egg-info/dependency_links.txt
|
|
8
|
-
apexauthlib.egg-info/top_level.txt
|
|
9
|
-
apexauthlib/fastapi/__init__.py
|
|
10
|
-
apexauthlib/fastapi/auth.py
|
|
11
|
-
apexauthlib/integration/__init__.py
|
|
12
|
-
apexauthlib/integration/api.py
|
|
13
|
-
tests/test_api.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
apexauthlib
|
apexauthlib-0.1.0/setup.cfg
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
|
|
3
|
-
from apexdevkit.formatter import DataclassFormatter
|
|
4
|
-
from apexdevkit.http import FakeHttp, FluentHttp, HttpMethod
|
|
5
|
-
from apexdevkit.http.fake import FakeResponse
|
|
6
|
-
from faker import Faker
|
|
7
|
-
|
|
8
|
-
from apexauthlib.integration import AuthApiProvider
|
|
9
|
-
from apexauthlib.integration.api import AuthApi
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@dataclass(frozen=True)
|
|
13
|
-
class TestPermissions:
|
|
14
|
-
role: str
|
|
15
|
-
read: bool
|
|
16
|
-
write: bool
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def test_login() -> None:
|
|
20
|
-
http = FakeHttp(FakeResponse({"access_token": "token"}))
|
|
21
|
-
service_name = Faker().text()
|
|
22
|
-
api = AuthApiProvider[TestPermissions](
|
|
23
|
-
FluentHttp(http), service_name, DataclassFormatter(TestPermissions)
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
result = api.login("user", "9")
|
|
27
|
-
|
|
28
|
-
assert result == "token"
|
|
29
|
-
|
|
30
|
-
http.intercepted(HttpMethod.post).on_endpoint("/auth/login")
|
|
31
|
-
|
|
32
|
-
assert http.data == {
|
|
33
|
-
"grant_type": "password",
|
|
34
|
-
"username": "user",
|
|
35
|
-
"password": "9",
|
|
36
|
-
"scope": "",
|
|
37
|
-
"client_id": "string",
|
|
38
|
-
"client_secret": "string",
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def test_user() -> None:
|
|
43
|
-
http = FakeHttp(FakeResponse({"id": "1"}))
|
|
44
|
-
service_name = Faker().text()
|
|
45
|
-
api = AuthApi[TestPermissions](
|
|
46
|
-
FluentHttp(http), service_name, DataclassFormatter(TestPermissions), "token"
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
result = api.user()
|
|
50
|
-
|
|
51
|
-
assert result == "1"
|
|
52
|
-
|
|
53
|
-
http.intercepted(HttpMethod.get).on_endpoint("/auth/user")
|
|
54
|
-
|
|
55
|
-
assert http.headers == {
|
|
56
|
-
"Authorization": "Bearer token",
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def test_metadata() -> None:
|
|
61
|
-
http = FakeHttp(
|
|
62
|
-
FakeResponse(
|
|
63
|
-
{
|
|
64
|
-
"data": {
|
|
65
|
-
"metadata": {
|
|
66
|
-
"metadata": {"role": "admin", "read": True, "write": True}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
)
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
service_name = Faker().text()
|
|
74
|
-
api = AuthApi[TestPermissions](
|
|
75
|
-
FluentHttp(http), service_name, DataclassFormatter(TestPermissions), "token"
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
result = api.metadata_for("1")
|
|
79
|
-
|
|
80
|
-
assert result == TestPermissions("admin", True, True)
|
|
81
|
-
|
|
82
|
-
http.intercepted(HttpMethod.get).on_endpoint(f"/services/{service_name}/metadata/1")
|
|
83
|
-
|
|
84
|
-
assert http.headers == {
|
|
85
|
-
"Authorization": "Bearer token",
|
|
86
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|