xn-auth 0.2.0__tar.gz → 0.2.2.dev1__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.
- {xn_auth-0.2.0/xn_auth.egg-info → xn_auth-0.2.2.dev1}/PKG-INFO +1 -1
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/x_auth/__init__.py +11 -7
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/x_auth/backend.py +2 -3
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/x_auth/depend.py +2 -2
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/x_auth/router.py +21 -19
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1/xn_auth.egg-info}/PKG-INFO +1 -1
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/.env.dist +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/.gitignore +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/.pre-commit-config.yaml +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/README.md +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/makefile +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/pyproject.toml +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/setup.cfg +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/x_auth/enums.py +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/x_auth/model.py +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/x_auth/pydantic.py +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/xn_auth.egg-info/SOURCES.txt +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/xn_auth.egg-info/dependency_links.txt +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/xn_auth.egg-info/requires.txt +0 -0
- {xn_auth-0.2.0 → xn_auth-0.2.2.dev1}/xn_auth.egg-info/top_level.txt +0 -0
|
@@ -2,7 +2,7 @@ import logging
|
|
|
2
2
|
from datetime import timedelta
|
|
3
3
|
|
|
4
4
|
from fastapi import HTTPException as BaseHTTPException
|
|
5
|
-
from fastapi.openapi.models import
|
|
5
|
+
from fastapi.openapi.models import HTTPBase, SecuritySchemeType
|
|
6
6
|
from fastapi.security.base import SecurityBase
|
|
7
7
|
from fastapi.security.utils import get_authorization_scheme_param
|
|
8
8
|
from jose import jwt, JWTError
|
|
@@ -46,13 +46,17 @@ class AuthException(HTTPException, AuthenticationError):
|
|
|
46
46
|
super().__init__(reason=reason, parent=parent, status_=status_, hdrs=hdrs)
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
class
|
|
50
|
-
|
|
49
|
+
class BearerModel(HTTPBase):
|
|
50
|
+
type_: SecuritySchemeType = SecuritySchemeType.http
|
|
51
|
+
scheme: str = "bearer"
|
|
52
|
+
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
class BearerSecurity(SecurityBase):
|
|
55
|
+
"""HTTP Bearer token authentication"""
|
|
53
56
|
|
|
54
|
-
def __init__(self, auto_error: bool = True,
|
|
55
|
-
self.model =
|
|
57
|
+
def __init__(self, model: BearerModel = BearerModel(), auto_error: bool = True, scheme_name: str = None):
|
|
58
|
+
self.model = model
|
|
59
|
+
self.scheme_name = scheme_name or self.__class__.__name__
|
|
56
60
|
self.auto_error = auto_error
|
|
57
61
|
|
|
58
62
|
async def __call__(self, conn: HTTPConnection) -> str | None:
|
|
@@ -63,7 +67,7 @@ class BearerBase(SecurityBase):
|
|
|
63
67
|
raise AuthException(reason=AuthFailReason.header, parent="Not authenticated")
|
|
64
68
|
else:
|
|
65
69
|
return None
|
|
66
|
-
if scheme.lower() !=
|
|
70
|
+
if scheme.lower() != self.model.scheme:
|
|
67
71
|
if self.auto_error:
|
|
68
72
|
raise AuthException(reason=AuthFailReason.scheme, parent="Not Bearer scheme")
|
|
69
73
|
else:
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from starlette.authentication import AuthenticationBackend, AuthCredentials
|
|
2
2
|
from starlette.requests import HTTPConnection
|
|
3
3
|
|
|
4
|
-
from x_auth import jwt_decode,
|
|
4
|
+
from x_auth import jwt_decode, BearerSecurity
|
|
5
5
|
from x_auth.pydantic import AuthUser
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class AuthBackend(AuthenticationBackend):
|
|
9
|
-
def __init__(self, secret: str, auth_scheme:
|
|
9
|
+
def __init__(self, secret: str, auth_scheme: BearerSecurity):
|
|
10
10
|
self.auth_scheme = auth_scheme
|
|
11
11
|
self.secret = secret
|
|
12
12
|
|
|
@@ -15,4 +15,3 @@ class AuthBackend(AuthenticationBackend):
|
|
|
15
15
|
verify_exp: bool = conn.scope["path"] != "/refresh"
|
|
16
16
|
user: AuthUser = jwt_decode(token, self.secret, verify_exp)
|
|
17
17
|
return AuthCredentials(scopes=user.role.scopes()), user
|
|
18
|
-
return None
|
|
@@ -5,11 +5,11 @@ from fastapi.security import SecurityScopes
|
|
|
5
5
|
from starlette.requests import HTTPConnection
|
|
6
6
|
|
|
7
7
|
from x_auth.enums import AuthFailReason, UserStatus, Scope
|
|
8
|
-
from x_auth import
|
|
8
|
+
from x_auth import AuthUser, AuthException, BearerSecurity
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class Depend:
|
|
12
|
-
def __init__(self, scheme:
|
|
12
|
+
def __init__(self, scheme: BearerSecurity):
|
|
13
13
|
# For Depends
|
|
14
14
|
def get_authenticated_user(conn: HTTPConnection, _: str | None = Depends(scheme)) -> AuthUser:
|
|
15
15
|
if not conn.user.is_authenticated:
|
|
@@ -4,7 +4,7 @@ from x_auth.backend import AuthBackend
|
|
|
4
4
|
|
|
5
5
|
from x_auth.depend import Depend
|
|
6
6
|
from x_auth.enums import FailReason, AuthFailReason
|
|
7
|
-
from x_auth import jwt_encode, HTTPException, AuthException,
|
|
7
|
+
from x_auth import jwt_encode, HTTPException, AuthException, BearerSecurity
|
|
8
8
|
from x_auth.model import User
|
|
9
9
|
from x_auth.pydantic import AuthUser, UserReg, Token
|
|
10
10
|
|
|
@@ -12,37 +12,39 @@ from x_auth.pydantic import AuthUser, UserReg, Token
|
|
|
12
12
|
class AuthRouter:
|
|
13
13
|
expires = timedelta(minutes=15)
|
|
14
14
|
|
|
15
|
-
def __init__(self, secret: str, db_user_model: type(User) = User, scheme:
|
|
15
|
+
def __init__(self, secret: str, db_user_model: type(User) = User, scheme: BearerSecurity = BearerSecurity()):
|
|
16
16
|
self.depend = Depend(scheme)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def _user2tok(user: AuthUser) -> Token:
|
|
20
|
-
return Token(access_token=jwt_encode(user, secret, self.expires), user=user)
|
|
21
|
-
|
|
22
|
-
# api reg endpoint
|
|
23
|
-
async def reg(user_reg_input: UserReg) -> Token:
|
|
24
|
-
data = user_reg_input.model_dump()
|
|
25
|
-
try:
|
|
26
|
-
db_user: User = await db_user_model.create(**data)
|
|
27
|
-
except IntegrityError as e:
|
|
28
|
-
raise HTTPException(FailReason.body, e)
|
|
29
|
-
user: AuthUser = AuthUser.model_validate(db_user, from_attributes=True)
|
|
30
|
-
return _user2tok(user)
|
|
17
|
+
self.secret = secret
|
|
18
|
+
self.db_user_model = db_user_model
|
|
31
19
|
|
|
32
20
|
# api refresh token
|
|
33
21
|
async def refresh(auth_user: AuthUser = self.depend.AUTHENTICATED) -> Token:
|
|
34
22
|
try:
|
|
35
|
-
db_user: User = await
|
|
23
|
+
db_user: User = await self.db_user_model[auth_user.id]
|
|
36
24
|
auth_user = AuthUser.model_validate(db_user, from_attributes=True)
|
|
37
25
|
except ConfigurationError:
|
|
38
26
|
raise AuthException(AuthFailReason.username, f"Not inicialized user model: {User})", 500)
|
|
39
27
|
except Exception:
|
|
40
28
|
raise AuthException(AuthFailReason.username, f"No user#{auth_user.id}({auth_user.username})", 404)
|
|
41
29
|
|
|
42
|
-
return _user2tok(auth_user)
|
|
30
|
+
return self._user2tok(auth_user)
|
|
43
31
|
|
|
44
32
|
self.routes: dict[str, tuple[callable, str]] = {
|
|
45
|
-
"reg": (reg, "POST"),
|
|
33
|
+
"reg": (self.reg, "POST"),
|
|
46
34
|
"refresh": (refresh, "GET"),
|
|
47
35
|
}
|
|
48
36
|
self.backend = AuthBackend(secret, scheme)
|
|
37
|
+
|
|
38
|
+
# API ENDOINTS
|
|
39
|
+
def _user2tok(self, user: AuthUser) -> Token:
|
|
40
|
+
return Token(access_token=jwt_encode(user, self.secret, self.expires), user=user)
|
|
41
|
+
|
|
42
|
+
# api reg endpoint
|
|
43
|
+
async def reg(self, user_reg_input: UserReg) -> Token:
|
|
44
|
+
data = user_reg_input.model_dump()
|
|
45
|
+
try:
|
|
46
|
+
db_user: User = await self.db_user_model.create(**data)
|
|
47
|
+
except IntegrityError as e:
|
|
48
|
+
raise HTTPException(FailReason.body, e)
|
|
49
|
+
user: AuthUser = AuthUser.model_validate(db_user, from_attributes=True)
|
|
50
|
+
return self._user2tok(user)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|