FastAPI-UI-Auth 0.1.1__py3-none-any.whl → 0.2.0__py3-none-any.whl
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.
- {fastapi_ui_auth-0.1.1.dist-info → fastapi_ui_auth-0.2.0.dist-info}/METADATA +34 -14
- fastapi_ui_auth-0.2.0.dist-info/RECORD +17 -0
- fastapi_ui_auth-0.2.0.dist-info/top_level.txt +1 -0
- uiauth/__init__.py +6 -0
- {fastapiauthenticator → uiauth}/endpoints.py +2 -2
- uiauth/logger.py +13 -0
- {fastapiauthenticator → uiauth}/models.py +53 -2
- {fastapiauthenticator → uiauth}/service.py +18 -14
- {fastapiauthenticator → uiauth}/templates/index.html +1 -1
- {fastapiauthenticator → uiauth}/templates/session.html +3 -3
- {fastapiauthenticator → uiauth}/templates/unauthorized.html +3 -3
- {fastapiauthenticator → uiauth}/utils.py +11 -18
- uiauth/version.py +1 -0
- fastapi_ui_auth-0.1.1.dist-info/RECORD +0 -16
- fastapi_ui_auth-0.1.1.dist-info/top_level.txt +0 -1
- fastapiauthenticator/__init__.py +0 -6
- fastapiauthenticator/version.py +0 -1
- {fastapi_ui_auth-0.1.1.dist-info → fastapi_ui_auth-0.2.0.dist-info}/WHEEL +0 -0
- {fastapi_ui_auth-0.1.1.dist-info → fastapi_ui_auth-0.2.0.dist-info}/licenses/LICENSE +0 -0
- {fastapiauthenticator → uiauth}/enums.py +0 -0
- {fastapiauthenticator → uiauth}/secure.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: FastAPI-UI-Auth
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Python module to add username and password authentication to specific FastAPI routes
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -15,7 +15,7 @@ Requires-Dist: pre-commit==4.2.*; extra == "dev"
|
|
|
15
15
|
Requires-Dist: uvicorn==0.34.*; extra == "dev"
|
|
16
16
|
Dynamic: license-file
|
|
17
17
|
|
|
18
|
-
#
|
|
18
|
+
# FastAPIUIAuth
|
|
19
19
|
|
|
20
20
|
Python module to add username and password authentication to specific FastAPI routes
|
|
21
21
|
|
|
@@ -25,20 +25,24 @@ Python module to add username and password authentication to specific FastAPI ro
|
|
|
25
25
|
|
|
26
26
|
![Platform][label-platform]
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
**Deployments**
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
repo="thevickypedia/FastAPIAuthenticator"
|
|
30
|
+
[![pypi][label-actions-pypi]][gha_pypi]
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
[![Pypi][label-pypi]][pypi]
|
|
33
|
+
[![Pypi-format][label-pypi-format]][pypi-files]
|
|
34
|
+
[![Pypi-status][label-pypi-status]][pypi]
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```shell
|
|
39
|
+
pip install FastAPI-UI-Auth
|
|
36
40
|
```
|
|
37
41
|
|
|
38
42
|
## Usage
|
|
39
43
|
|
|
40
44
|
```python
|
|
41
|
-
import
|
|
45
|
+
import uiauth
|
|
42
46
|
|
|
43
47
|
from fastapi import FastAPI
|
|
44
48
|
|
|
@@ -51,16 +55,16 @@ async def public_route():
|
|
|
51
55
|
async def private_route():
|
|
52
56
|
return {"message": "This is a private route"}
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
uiauth.protect(
|
|
55
59
|
app=app,
|
|
56
|
-
params=
|
|
60
|
+
params=uiauth.Parameters(
|
|
57
61
|
path="/private",
|
|
58
62
|
function=private_route
|
|
59
63
|
)
|
|
60
64
|
)
|
|
61
65
|
```
|
|
62
66
|
|
|
63
|
-
> `
|
|
67
|
+
> `FastAPI-UI-Auth` supports both `APIRoute` and `APIWebSocketRoute` routes.<br>
|
|
64
68
|
> Refer [samples] directory for different use-cases.
|
|
65
69
|
|
|
66
70
|
## Coding Standards
|
|
@@ -90,6 +94,11 @@ python -m pip install sphinx==5.1.1 pre-commit recommonmark
|
|
|
90
94
|
pre-commit run --all-files
|
|
91
95
|
```
|
|
92
96
|
|
|
97
|
+
## Pypi Package
|
|
98
|
+
[![pypi-module][label-pypi-package]][pypi-repo]
|
|
99
|
+
|
|
100
|
+
[https://pypi.org/project/FastAPI-UI-Auth/][pypi]
|
|
101
|
+
|
|
93
102
|
## License & copyright
|
|
94
103
|
|
|
95
104
|
© Vignesh Rao
|
|
@@ -99,12 +108,23 @@ Licensed under the [MIT License][license]
|
|
|
99
108
|
[//]: # (Labels)
|
|
100
109
|
|
|
101
110
|
[3.11]: https://docs.python.org/3/whatsnew/3.11.html
|
|
102
|
-
[license]: https://github.com/thevickypedia/
|
|
111
|
+
[license]: https://github.com/thevickypedia/FastAPI-UI-Auth/blob/main/LICENSE
|
|
103
112
|
[google-docs]: https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings
|
|
104
113
|
[pep8]: https://www.python.org/dev/peps/pep-0008/
|
|
105
114
|
[isort]: https://pycqa.github.io/isort/
|
|
106
|
-
[samples]: https://github.com/thevickypedia/
|
|
115
|
+
[samples]: https://github.com/thevickypedia/FastAPI-UI-Auth/tree/main/samples
|
|
107
116
|
|
|
117
|
+
[label-actions-pypi]: https://github.com/thevickypedia/FastAPI-UI-Auth/actions/workflows/python-publish.yml/badge.svg
|
|
118
|
+
[label-pypi]: https://img.shields.io/pypi/v/FastAPI-UI-Auth
|
|
119
|
+
[label-pypi-format]: https://img.shields.io/pypi/format/FastAPI-UI-Auth
|
|
120
|
+
[label-pypi-status]: https://img.shields.io/pypi/status/FastAPI_UI_Auth
|
|
121
|
+
[label-pypi-package]: https://img.shields.io/badge/Pypi%20Package-FastAPI_UI_Auth-blue?style=for-the-badge&logo=Python
|
|
108
122
|
[label-pyversion]: https://img.shields.io/badge/python-3.11%20%7C%203.12-blue
|
|
109
123
|
[label-platform]: https://img.shields.io/badge/Platform-Linux|macOS|Windows-1f425f.svg
|
|
110
|
-
[release-notes]: https://github.com/thevickypedia/
|
|
124
|
+
[release-notes]: https://github.com/thevickypedia/FastAPI-UI-Auth/blob/main/release_notes.rst
|
|
125
|
+
|
|
126
|
+
[gha_pypi]: https://github.com/thevickypedia/FastAPI-UI-Auth/actions/workflows/python-publish.yml
|
|
127
|
+
|
|
128
|
+
[pypi]: https://pypi.org/project/FastAPI-UI-Auth
|
|
129
|
+
[pypi-files]: https://pypi.org/project/FastAPI-UI-Auth/#files
|
|
130
|
+
[pypi-repo]: https://packaging.python.org/tutorials/packaging-projects/
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
fastapi_ui_auth-0.2.0.dist-info/licenses/LICENSE,sha256=_sOIKJWdD2o1WwwDIwYB2qTP2nlSWqT5Tyg9jr1Xa4w,1070
|
|
2
|
+
uiauth/__init__.py,sha256=s8r2Z0O9w3cuw7GcmRTOWY0NZC0KJXzBS9QsG9wUWsk,264
|
|
3
|
+
uiauth/endpoints.py,sha256=4RtabYwlNSHAqpU89zfRH8RD_ATH1AAf-lJKg4HA1RQ,2076
|
|
4
|
+
uiauth/enums.py,sha256=WO0eBv3l9HHr1I_ZXtAifCgdL-db_tZj9ka7jnjiS5k,547
|
|
5
|
+
uiauth/logger.py,sha256=z67PBMs4zWOfy-Gfm_41dj5Uulm-ChvZxB_jmYKKXeI,391
|
|
6
|
+
uiauth/models.py,sha256=lcJyy99c-VeSeUj3LahXisQZ4g3wRqdGtBVdL1oyaZI,4255
|
|
7
|
+
uiauth/secure.py,sha256=ZOH6kT4BD56VqwaKdKocX7eSE8tqZcu-tK0QOmjY58k,1089
|
|
8
|
+
uiauth/service.py,sha256=6CN3Rg8m3f83sJuLdswVzwkxkwkjptHgWa5uugxIccE,6460
|
|
9
|
+
uiauth/utils.py,sha256=DzXqxLpKHUDy1bxffg1cw0izqxcgmnCybSytywiPgbQ,6625
|
|
10
|
+
uiauth/version.py,sha256=XQVhijSHeIVMVzY2S4fY9BKxV2XHSTr9VVHsYltGPvQ,18
|
|
11
|
+
uiauth/templates/index.html,sha256=8vbONgCdhBmwe12ITeuBSjwwjp309kDS9cu2lRrrG88,9080
|
|
12
|
+
uiauth/templates/session.html,sha256=EL4gajOED3IcOnrALMiJ2SzJl2at8GFfruTuExhgOVI,3040
|
|
13
|
+
uiauth/templates/unauthorized.html,sha256=ahv78zLM04_Lu83LdX0Ua_toKeP5JZkYsTCWCrfCvHA,3002
|
|
14
|
+
fastapi_ui_auth-0.2.0.dist-info/METADATA,sha256=L10c3aWSYOwNnAQIcbVO4SzBVH7Xa6DhueQViFlmW_o,3553
|
|
15
|
+
fastapi_ui_auth-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
16
|
+
fastapi_ui_auth-0.2.0.dist-info/top_level.txt,sha256=ra3nGTbDTgQ7eChlkngJ7xGXhSCeFTWMvb_b6q8uPVA,7
|
|
17
|
+
fastapi_ui_auth-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
uiauth
|
uiauth/__init__.py
ADDED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from fastapi.requests import Request
|
|
2
2
|
from fastapi.responses import HTMLResponse
|
|
3
3
|
|
|
4
|
-
from
|
|
5
|
-
from
|
|
4
|
+
from uiauth import enums, models, utils
|
|
5
|
+
from uiauth.version import version
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def session(request: Request) -> HTMLResponse:
|
uiauth/logger.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Default logger for FastAPI-UI-Auth package."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
CUSTOM_LOGGER = logging.getLogger(__name__)
|
|
7
|
+
CUSTOM_LOGGER.setLevel(logging.DEBUG)
|
|
8
|
+
CONSOLE_HANDLER = logging.StreamHandler(sys.stdout)
|
|
9
|
+
CONSOLE_FORMATTER = logging.Formatter(
|
|
10
|
+
fmt="%(levelname)-9s %(message)s",
|
|
11
|
+
)
|
|
12
|
+
CONSOLE_HANDLER.setFormatter(fmt=CONSOLE_FORMATTER)
|
|
13
|
+
CUSTOM_LOGGER.addHandler(hdlr=CONSOLE_HANDLER)
|
|
@@ -1,15 +1,66 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import pathlib
|
|
2
3
|
from typing import Callable, Dict, List, Optional, Type
|
|
3
4
|
|
|
4
5
|
from fastapi.routing import APIRoute, APIWebSocketRoute
|
|
5
6
|
from fastapi.templating import Jinja2Templates
|
|
6
|
-
from pydantic import BaseModel, Field
|
|
7
|
+
from pydantic import BaseModel, Field, ValidationInfo, field_validator
|
|
7
8
|
|
|
8
|
-
from
|
|
9
|
+
from uiauth.enums import APIMethods
|
|
9
10
|
|
|
10
11
|
templates = Jinja2Templates(directory=pathlib.Path(__file__).parent / "templates")
|
|
11
12
|
|
|
12
13
|
|
|
14
|
+
def get_env(keys: List[str], default: Optional[str] = None) -> Optional[str]:
|
|
15
|
+
"""Get environment variable value.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
keys: List of environment variable names to check.
|
|
19
|
+
default: Default value if the environment variable is not set.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Value of the environment variable or default value.
|
|
23
|
+
"""
|
|
24
|
+
for key in keys:
|
|
25
|
+
if value := os.getenv(key):
|
|
26
|
+
return value
|
|
27
|
+
if value := os.getenv(key.upper()):
|
|
28
|
+
return value
|
|
29
|
+
if value := os.getenv(key.lower()):
|
|
30
|
+
return value
|
|
31
|
+
return default
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class EnvConfig(BaseModel):
|
|
35
|
+
"""Configuration for environment variables."""
|
|
36
|
+
|
|
37
|
+
username: str
|
|
38
|
+
password: str
|
|
39
|
+
|
|
40
|
+
# noinspection PyMethodParameters
|
|
41
|
+
@field_validator("username", "password", mode="before")
|
|
42
|
+
def load_user(cls, key: str, field: ValidationInfo) -> str | None:
|
|
43
|
+
"""Load environment variables into the configuration.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
key: Environment variable key to check.
|
|
47
|
+
field: Field information for validation.
|
|
48
|
+
|
|
49
|
+
See Also:
|
|
50
|
+
- This method checks if the environment variable is set and returns its value.
|
|
51
|
+
- If the key is not set, it attempts to get the value from the environment using a helper function.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
str | None:
|
|
55
|
+
Value of the environment variable or None if not set.
|
|
56
|
+
"""
|
|
57
|
+
if not key:
|
|
58
|
+
return get_env([field.field_name, field.field_name[:4]])
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
env = EnvConfig
|
|
62
|
+
|
|
63
|
+
|
|
13
64
|
class Parameters(BaseModel):
|
|
14
65
|
"""Parameters for the Authenticator class.
|
|
15
66
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
import os
|
|
3
2
|
from threading import Timer
|
|
4
3
|
from typing import Dict, List
|
|
5
4
|
|
|
@@ -13,18 +12,17 @@ from fastapi.responses import Response
|
|
|
13
12
|
from fastapi.routing import APIRoute, APIWebSocketRoute
|
|
14
13
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
|
15
14
|
|
|
16
|
-
from
|
|
15
|
+
from uiauth import endpoints, enums, logger, models, utils
|
|
17
16
|
|
|
18
17
|
dotenv.load_dotenv(dotenv_path=dotenv.find_dotenv(), override=True)
|
|
19
|
-
LOGGER = logging.getLogger("uvicorn.default")
|
|
20
18
|
BEARER_AUTH = HTTPBearer()
|
|
21
19
|
|
|
22
20
|
|
|
23
21
|
# noinspection PyDefaultArgument
|
|
24
|
-
class
|
|
25
|
-
"""
|
|
22
|
+
class FastAPIUIAuth:
|
|
23
|
+
"""FastAPIUIAuth is a FastAPI integration that provides authentication for secure routes.
|
|
26
24
|
|
|
27
|
-
>>>
|
|
25
|
+
>>> FastAPIUIAuth
|
|
28
26
|
|
|
29
27
|
"""
|
|
30
28
|
|
|
@@ -33,10 +31,11 @@ class Authenticator:
|
|
|
33
31
|
app: FastAPI,
|
|
34
32
|
params: models.Parameters | List[models.Parameters],
|
|
35
33
|
timeout: int = 300,
|
|
36
|
-
username: str =
|
|
37
|
-
password: str =
|
|
34
|
+
username: str = None,
|
|
35
|
+
password: str = None,
|
|
38
36
|
fallback_button: str = models.fallback.button,
|
|
39
37
|
fallback_path: str = models.fallback.path,
|
|
38
|
+
custom_logger: logging.Logger = None,
|
|
40
39
|
):
|
|
41
40
|
"""Initialize the APIAuthenticator with the FastAPI app and secure function.
|
|
42
41
|
|
|
@@ -48,8 +47,9 @@ class Authenticator:
|
|
|
48
47
|
password: Password for authentication, can be set via environment variable 'PASSWORD'.
|
|
49
48
|
fallback_button: Title for the fallback button, defaults to "LOGIN".
|
|
50
49
|
fallback_path: Fallback path to redirect to in case of session timeout or invalid session.
|
|
50
|
+
custom_logger: Custom logger instance, defaults to the custom logger.
|
|
51
51
|
"""
|
|
52
|
-
|
|
52
|
+
models.env = models.EnvConfig(username=username, password=password)
|
|
53
53
|
assert fallback_path.startswith("/"), "Fallback path must start with '/'"
|
|
54
54
|
|
|
55
55
|
self.app = app
|
|
@@ -68,11 +68,15 @@ class Authenticator:
|
|
|
68
68
|
handler=utils.redirect_exception_handler,
|
|
69
69
|
)
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
if custom_logger:
|
|
72
|
+
assert isinstance(
|
|
73
|
+
custom_logger, logging.Logger
|
|
74
|
+
), "Custom logger must be an instance of logging.Logger"
|
|
75
|
+
logger.CUSTOM_LOGGER = custom_logger
|
|
73
76
|
self.timeout = timeout
|
|
74
77
|
|
|
75
78
|
self._secure()
|
|
79
|
+
logger.CUSTOM_LOGGER.debug("Endpoints registered: %s", len(self.params))
|
|
76
80
|
|
|
77
81
|
def _verify_auth(
|
|
78
82
|
self,
|
|
@@ -94,11 +98,11 @@ class Authenticator:
|
|
|
94
98
|
session_token = utils.verify_login(
|
|
95
99
|
authorization=authorization,
|
|
96
100
|
request=request,
|
|
97
|
-
env_username=self.username,
|
|
98
|
-
env_password=self.password,
|
|
99
101
|
)
|
|
100
102
|
if destination := request.cookies.get("X-Requested-By"):
|
|
101
|
-
|
|
103
|
+
logger.CUSTOM_LOGGER.info(
|
|
104
|
+
"Setting session timeout for %s seconds", self.timeout
|
|
105
|
+
)
|
|
102
106
|
# Set session_token cookie with a timeout, to be used for session validation when redirected
|
|
103
107
|
response.set_cookie(
|
|
104
108
|
key="session_token",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<html lang="en">
|
|
4
4
|
<head>
|
|
5
5
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
6
|
-
<title>FastAPI
|
|
6
|
+
<title>FastAPI UI Authentication</title>
|
|
7
7
|
<meta property="og:type" content="Authenticator">
|
|
8
8
|
<meta name="keywords" content="Python, fastapi, JavaScript, HTML, CSS">
|
|
9
9
|
<meta name="author" content="Vignesh Rao">
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
5
|
-
<title>FastAPI
|
|
5
|
+
<title>FastAPI UI Authentication</title>
|
|
6
6
|
<meta property="og:type" content="Authenticator">
|
|
7
7
|
<meta name="keywords" content="Python, fastapi, JavaScript, HTML, CSS">
|
|
8
8
|
<meta name="author" content="Vignesh Rao">
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
</body>
|
|
80
80
|
<footer>
|
|
81
81
|
<div class="footer">
|
|
82
|
-
|
|
83
|
-
<a href="https://github.com/thevickypedia/
|
|
82
|
+
FastAPI-UI-Auth - {{ version }}<br>
|
|
83
|
+
<a href="https://github.com/thevickypedia/FastAPI-UI-Auth">https://github.com/thevickypedia/FastAPI-UI-Auth</a>
|
|
84
84
|
</div>
|
|
85
85
|
</footer>
|
|
86
86
|
</html>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
5
|
-
<title>FastAPI
|
|
5
|
+
<title>FastAPI UI Authentication</title>
|
|
6
6
|
<meta property="og:type" content="Authenticator">
|
|
7
7
|
<meta name="keywords" content="Python, fastapi, JavaScript, HTML, CSS">
|
|
8
8
|
<meta name="author" content="Vignesh Rao">
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
</body>
|
|
80
80
|
<footer>
|
|
81
81
|
<div class="footer">
|
|
82
|
-
|
|
83
|
-
<a href="https://github.com/thevickypedia/
|
|
82
|
+
FastAPI-UI-Auth - {{ version }}<br>
|
|
83
|
+
<a href="https://github.com/thevickypedia/FastAPI-UI-Auth">https://github.com/thevickypedia/FastAPI-UI-Auth</a>
|
|
84
84
|
</div>
|
|
85
85
|
</footer>
|
|
86
86
|
</html>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import logging
|
|
2
1
|
import secrets
|
|
3
2
|
from typing import List, NoReturn
|
|
4
3
|
|
|
@@ -9,9 +8,7 @@ from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse
|
|
|
9
8
|
from fastapi.security import HTTPAuthorizationCredentials
|
|
10
9
|
from fastapi.websockets import WebSocket
|
|
11
10
|
|
|
12
|
-
from
|
|
13
|
-
|
|
14
|
-
LOGGER = logging.getLogger("uvicorn.default")
|
|
11
|
+
from uiauth import enums, logger, models, secure
|
|
15
12
|
|
|
16
13
|
|
|
17
14
|
def failed_auth_counter(request: Request) -> None:
|
|
@@ -62,7 +59,7 @@ def raise_error(request: Request) -> NoReturn:
|
|
|
62
59
|
request: Request object containing client information.
|
|
63
60
|
"""
|
|
64
61
|
failed_auth_counter(request)
|
|
65
|
-
|
|
62
|
+
logger.CUSTOM_LOGGER.error(
|
|
66
63
|
"Incorrect username or password: %d",
|
|
67
64
|
models.ws_session.invalid[request.client.host],
|
|
68
65
|
)
|
|
@@ -88,16 +85,12 @@ def extract_credentials(authorization: HTTPAuthorizationCredentials) -> List[str
|
|
|
88
85
|
def verify_login(
|
|
89
86
|
authorization: HTTPAuthorizationCredentials,
|
|
90
87
|
request: Request,
|
|
91
|
-
env_username: str,
|
|
92
|
-
env_password: str,
|
|
93
88
|
) -> str | NoReturn:
|
|
94
89
|
"""Verifies authentication and generates session token for each user.
|
|
95
90
|
|
|
96
91
|
Args:
|
|
97
92
|
authorization: Authorization header from the request.
|
|
98
93
|
request: Request object containing client information.
|
|
99
|
-
env_username: Environment variable for the username.
|
|
100
|
-
env_password: Environment variable for the password.
|
|
101
94
|
|
|
102
95
|
Returns:
|
|
103
96
|
str:
|
|
@@ -107,11 +100,11 @@ def verify_login(
|
|
|
107
100
|
username, signature, timestamp = extract_credentials(authorization)
|
|
108
101
|
else:
|
|
109
102
|
raise_error(request)
|
|
110
|
-
if secrets.compare_digest(username,
|
|
111
|
-
hex_user = secure.hex_encode(
|
|
112
|
-
hex_pass = secure.hex_encode(
|
|
103
|
+
if secrets.compare_digest(username, models.env.username):
|
|
104
|
+
hex_user = secure.hex_encode(models.env.username)
|
|
105
|
+
hex_pass = secure.hex_encode(models.env.password)
|
|
113
106
|
else:
|
|
114
|
-
|
|
107
|
+
logger.CUSTOM_LOGGER.warning("User '%s' not allowed", models.env.username)
|
|
115
108
|
raise_error(request)
|
|
116
109
|
message = f"{hex_user}{hex_pass}{timestamp}"
|
|
117
110
|
expected_signature = secure.calculate_hash(message)
|
|
@@ -151,10 +144,10 @@ def verify_session(
|
|
|
151
144
|
and session_token
|
|
152
145
|
and secrets.compare_digest(session_token, stored_token)
|
|
153
146
|
):
|
|
154
|
-
|
|
147
|
+
logger.CUSTOM_LOGGER.info("Session is valid for host: %s", request.client.host)
|
|
155
148
|
return
|
|
156
149
|
elif not session_token:
|
|
157
|
-
|
|
150
|
+
logger.CUSTOM_LOGGER.warning(
|
|
158
151
|
"Session is invalid or expired for host: %s", request.client.host
|
|
159
152
|
)
|
|
160
153
|
raise models.RedirectException(
|
|
@@ -162,7 +155,7 @@ def verify_session(
|
|
|
162
155
|
destination=enums.APIEndpoints.fastapi_login,
|
|
163
156
|
)
|
|
164
157
|
else:
|
|
165
|
-
|
|
158
|
+
logger.CUSTOM_LOGGER.warning(
|
|
166
159
|
"Session token mismatch for host: %s. Expected: %s, Received: %s",
|
|
167
160
|
request.client.host,
|
|
168
161
|
stored_token,
|
|
@@ -198,6 +191,6 @@ def clear_session(host: str) -> None:
|
|
|
198
191
|
"""
|
|
199
192
|
if models.ws_session.client_auth.get(host):
|
|
200
193
|
models.ws_session.client_auth.pop(host)
|
|
201
|
-
|
|
194
|
+
logger.CUSTOM_LOGGER.info("Session cleared for host: %s", host)
|
|
202
195
|
else:
|
|
203
|
-
|
|
196
|
+
logger.CUSTOM_LOGGER.warning("No session found for host: %s", host)
|
uiauth/version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "0.2.0"
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
fastapi_ui_auth-0.1.1.dist-info/licenses/LICENSE,sha256=_sOIKJWdD2o1WwwDIwYB2qTP2nlSWqT5Tyg9jr1Xa4w,1070
|
|
2
|
-
fastapiauthenticator/__init__.py,sha256=H1tJUJp4FWweEu2JeMw5vmqjtMhMwR4kUd11ek8UmwQ,320
|
|
3
|
-
fastapiauthenticator/endpoints.py,sha256=PF2qu6XQ3MQStFEprRYYxiS6Dl6ukYaMqEkSlO-F3Ls,2104
|
|
4
|
-
fastapiauthenticator/enums.py,sha256=WO0eBv3l9HHr1I_ZXtAifCgdL-db_tZj9ka7jnjiS5k,547
|
|
5
|
-
fastapiauthenticator/models.py,sha256=GxmQfSvg70OTsvswJ3QFq_lxq-Yz1fIfzW6x8d4Sj40,2726
|
|
6
|
-
fastapiauthenticator/secure.py,sha256=ZOH6kT4BD56VqwaKdKocX7eSE8tqZcu-tK0QOmjY58k,1089
|
|
7
|
-
fastapiauthenticator/service.py,sha256=7E474kwPIDsbtZPMGJTSo0thKc2FP2n-MUogsH0ZrZI,6247
|
|
8
|
-
fastapiauthenticator/utils.py,sha256=Is7oaaHYsZ97aPmDWTcIqStW693HRIDUKtkGBdfyMVg,6731
|
|
9
|
-
fastapiauthenticator/version.py,sha256=I4WU5JcKZjfggPiNIoGDFxUDB05Ym1xFhbC3J_MjilA,18
|
|
10
|
-
fastapiauthenticator/templates/index.html,sha256=mA2R6gk6lvibq_AmPgGHBFQijYtNUD7IIfeBSJWQrM4,9078
|
|
11
|
-
fastapiauthenticator/templates/session.html,sha256=LUCvcEdQOjfIXjRZ2gPx2s5wyzNuCve4OMge0hXaBLM,3053
|
|
12
|
-
fastapiauthenticator/templates/unauthorized.html,sha256=UZo1Jt64-CFfjwWTGicUMdHVWkYkXCJBRxvit4QTiQM,3015
|
|
13
|
-
fastapi_ui_auth-0.1.1.dist-info/METADATA,sha256=cmKRN9LBPNgKnm66iKXZaAkBasddHo2vs5ISjFw9HJE,2733
|
|
14
|
-
fastapi_ui_auth-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
-
fastapi_ui_auth-0.1.1.dist-info/top_level.txt,sha256=EpDRP7uLM0f-Vd5rUtLBh4MTMAnpXzw1pr0DSknW_Ds,21
|
|
16
|
-
fastapi_ui_auth-0.1.1.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
fastapiauthenticator
|
fastapiauthenticator/__init__.py
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
from fastapiauthenticator.enums import APIEndpoints, APIMethods # noqa: F401,E402
|
|
2
|
-
from fastapiauthenticator.models import Parameters # noqa: F401,E402
|
|
3
|
-
from fastapiauthenticator.service import Authenticator # noqa: F401,E402
|
|
4
|
-
from fastapiauthenticator.version import version # noqa: F401,E402
|
|
5
|
-
|
|
6
|
-
protect = Authenticator
|
fastapiauthenticator/version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
version = "0.1.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|