zrb 1.0.0a21__py3-none-any.whl → 1.0.0b2__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.
- zrb/__init__.py +2 -1
- zrb/__main__.py +0 -3
- zrb/builtin/__init__.py +3 -0
- zrb/builtin/group.py +1 -0
- zrb/builtin/llm/llm_chat.py +2 -2
- zrb/builtin/llm/tool/web.py +1 -1
- zrb/builtin/project/add/fastapp/fastapp_task.py +2 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/config.py +5 -2
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py +80 -20
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_util.py +150 -42
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_service.py +113 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_service_factory.py +9 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/my_entity_db_repository.py +0 -10
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/my_entity_repository.py +37 -16
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/repository/{factory.py → my_entity_repository_factory.py} +2 -2
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/schema/my_entity.py +16 -6
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/client_method.py +57 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/gateway_subroute.py +72 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/format_task.py +1 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/input.py +13 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_task.py +23 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/add_module_util.py +42 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/gateway/subroute/my_module.py +7 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_api_client.py +6 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/{any_client.py → my_module_client.py} +1 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_client_factory.py +11 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/my_module_direct_client.py +5 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/route.py +11 -11
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/module_task_definition.py +2 -2
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/task.py +8 -8
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/util.py +47 -20
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/app_factory.py +29 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_db_repository.py +185 -101
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_service.py +236 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/{db_engine.py → db_engine_factory.py} +1 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/error.py +12 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/logger_factory.py +10 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/parser_factory.py +7 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/app.py +47 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/parser.py +105 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/user_agent.py +58 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/util/view.py +37 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/config.py +25 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/main.py +1 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_api_client.py +16 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_client.py +163 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_client_factory.py +9 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_direct_client.py +15 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/versions/3093c7336477_add_auth_tables.py +160 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration_metadata.py +18 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py +7 -3
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service.py +117 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service_factory.py +11 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_db_repository.py +26 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_repository.py +61 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/repository/permission_repository_factory.py +13 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_db_repository.py +75 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository.py +59 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_repository_factory.py +13 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service.py +105 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service_factory.py +7 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_db_repository.py +42 -13
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository.py +38 -17
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository_factory.py +2 -2
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service.py +105 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service_factory.py +7 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py +43 -14
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +198 -28
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/util/view.py +74 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/error.html +6 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/content/homepage.html +6 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/android-chrome-192x192.png +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/android-chrome-512x512.png +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/images/favicon-32x32.png +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.amber.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.blue.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.cyan.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.fuchsia.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.green.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.grey.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.indigo.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.jade.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.lime.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.orange.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.pink.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.pumpkin.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.purple.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.red.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.sand.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.slate.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.violet.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.yellow.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/static/pico-css/pico.zinc.min.css +4 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/view/template/default.html +34 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/requirements.txt +1 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/permission.py +17 -5
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/role.py +50 -4
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/session.py +52 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/user.py +30 -5
- zrb/builtin/python.py +1 -1
- zrb/builtin/random.py +61 -0
- zrb/cmd/cmd_val.py +6 -5
- zrb/content_transformer/any_content_transformer.py +7 -0
- zrb/content_transformer/content_transformer.py +6 -0
- zrb/runner/cli.py +14 -7
- zrb/runner/web_app.py +28 -280
- zrb/runner/web_config/config.py +91 -0
- zrb/runner/web_config/config_factory.py +26 -0
- zrb/runner/web_route/docs_route.py +17 -0
- zrb/runner/web_route/error_page/serve_default_404.py +28 -0
- zrb/runner/{web_controller/error_page/controller.py → web_route/error_page/show_error_page.py} +2 -2
- zrb/runner/{web_controller → web_route}/error_page/view.html +5 -0
- zrb/runner/web_route/home_page/home_page_route.py +51 -0
- zrb/runner/web_route/login_api_route.py +31 -0
- zrb/runner/web_route/login_page/login_page_route.py +39 -0
- zrb/runner/web_route/logout_api_route.py +18 -0
- zrb/runner/web_route/logout_page/logout_page_route.py +40 -0
- zrb/runner/{web_controller/group_info_page/controller.py → web_route/node_page/group/show_group_page.py} +3 -3
- zrb/runner/web_route/node_page/node_page_route.py +50 -0
- zrb/runner/{web_controller/session_page/controller.py → web_route/node_page/task/show_task_page.py} +3 -3
- zrb/runner/web_route/refresh_token_api_route.py +38 -0
- zrb/runner/web_route/static/static_route.py +44 -0
- zrb/runner/web_route/task_input_api_route.py +47 -0
- zrb/runner/web_route/task_session_api_route.py +102 -0
- zrb/runner/web_schema/session.py +5 -0
- zrb/runner/web_schema/token.py +11 -0
- zrb/runner/web_schema/user.py +32 -0
- zrb/runner/web_util/cookie.py +29 -0
- zrb/runner/{web_util.py → web_util/html.py} +1 -23
- zrb/runner/web_util/token.py +72 -0
- zrb/runner/web_util/user.py +63 -0
- zrb/session/session.py +6 -4
- zrb/session_state_logger/{default_session_state_logger.py → session_state_logger_factory.py} +1 -1
- zrb/task/base_task.py +53 -6
- zrb/task/base_trigger.py +2 -0
- zrb/task/cmd_task.py +9 -5
- zrb/task/http_check.py +2 -0
- zrb/task/llm_task.py +2 -0
- zrb/task/make_task.py +2 -0
- zrb/task/rsync_task.py +2 -0
- zrb/task/scaffolder.py +8 -5
- zrb/task/scheduler.py +2 -0
- zrb/task/tcp_check.py +2 -0
- zrb/task_status/task_status.py +4 -3
- zrb/util/cmd/command.py +1 -0
- zrb/util/file.py +7 -1
- {zrb-1.0.0a21.dist-info → zrb-1.0.0b2.dist-info}/METADATA +1 -1
- zrb-1.0.0b2.dist-info/RECORD +307 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/any_client_method.py +0 -27
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_usecase.py +0 -65
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/api_client.py +0 -6
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/direct_client.py +0 -6
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/client/factory.py +0 -9
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/app.py +0 -20
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_usecase.py +0 -245
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/any_client.py +0 -33
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py +0 -7
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py +0 -6
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/factory.py +0 -9
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/versions/3093c7336477_add_user_table.py +0 -37
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase.py +0 -53
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase_factory.py +0 -6
- zrb/runner/web_config.py +0 -274
- zrb/runner/web_controller/home_page/controller.py +0 -33
- zrb/runner/web_controller/login_page/controller.py +0 -25
- zrb/runner/web_controller/logout_page/controller.py +0 -26
- zrb-1.0.0a21.dist-info/RECORD +0 -244
- /zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/column/{create_column_task.py → add_column_task.py} +0 -0
- /zrb/{runner/web_controller → builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission}/__init__.py +0 -0
- /zrb/{runner/web_controller/group_info_page → builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role}/__init__.py +0 -0
- /zrb/runner/{web_controller/home_page → web_route}/__init__.py +0 -0
- /zrb/runner/{web_controller/session_page → web_route/home_page}/__init__.py +0 -0
- /zrb/runner/{web_controller → web_route}/home_page/view.html +0 -0
- /zrb/runner/{web_controller → web_route}/login_page/view.html +0 -0
- /zrb/runner/{web_controller → web_route}/logout_page/view.html +0 -0
- /zrb/runner/{web_controller/group_info_page → web_route/node_page/group}/view.html +0 -0
- /zrb/runner/{web_controller/session_page → web_route/node_page/task}/partial/input.html +0 -0
- /zrb/runner/{web_controller/session_page → web_route/node_page/task}/view.html +0 -0
- /zrb/runner/{refresh-token.template.js → web_route/static/refresh-token.template.js} +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/common.css +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/favicon-32x32.png +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/login/event.js +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/logout/event.js +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/pico.min.css +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/session/common-util.js +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/session/current-session.js +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/session/event.js +0 -0
- /zrb/runner/{web_controller/static → web_route/static/resources}/session/past-session.js +0 -0
- {zrb-1.0.0a21.dist-info → zrb-1.0.0b2.dist-info}/WHEEL +0 -0
- {zrb-1.0.0a21.dist-info → zrb-1.0.0b2.dist-info}/entry_points.txt +0 -0
@@ -1,245 +0,0 @@
|
|
1
|
-
from enum import Enum
|
2
|
-
from functools import partial, wraps
|
3
|
-
from typing import Any, Callable, Sequence
|
4
|
-
|
5
|
-
import httpx
|
6
|
-
from fastapi import APIRouter, params
|
7
|
-
from fastapi.routing import APIRoute
|
8
|
-
from fastapi.types import IncEx
|
9
|
-
from fastapi.utils import generate_unique_id
|
10
|
-
from starlette.responses import JSONResponse, Response
|
11
|
-
|
12
|
-
|
13
|
-
class RouteParam:
|
14
|
-
def __init__(
|
15
|
-
self,
|
16
|
-
path: str,
|
17
|
-
response_model: Any,
|
18
|
-
status_code: int | None = None,
|
19
|
-
tags: list[str | Enum] | None = None,
|
20
|
-
dependencies: Sequence[params.Depends] | None = None,
|
21
|
-
summary: str | None = None,
|
22
|
-
description: str = "",
|
23
|
-
response_description: str = "",
|
24
|
-
responses: dict[int | str, dict[str, Any]] | None = None,
|
25
|
-
deprecated: bool | None = None,
|
26
|
-
methods: set[str] | list[str] | None = None,
|
27
|
-
operation_id: str | None = None,
|
28
|
-
response_model_include: IncEx | None = None,
|
29
|
-
response_model_exclude: IncEx | None = None,
|
30
|
-
response_model_by_alias: bool = True,
|
31
|
-
response_model_exclude_unset: bool = False,
|
32
|
-
response_model_exclude_defaults: bool = False,
|
33
|
-
response_model_exclude_none: bool = False,
|
34
|
-
include_in_schema: bool = True,
|
35
|
-
response_class: type[Response] = Response,
|
36
|
-
name: str | None = None,
|
37
|
-
openapi_extra: dict[str, Any] | None = None,
|
38
|
-
generate_unique_id_function: Callable[[APIRoute], str] | None = None,
|
39
|
-
func: Callable | None = None,
|
40
|
-
):
|
41
|
-
self.path = path
|
42
|
-
self.response_model = response_model
|
43
|
-
self.status_code = status_code
|
44
|
-
self.tags = tags
|
45
|
-
self.dependencies = dependencies
|
46
|
-
self.summary = summary
|
47
|
-
self.description = description
|
48
|
-
self.response_description = response_description
|
49
|
-
self.responses = responses
|
50
|
-
self.deprecated = deprecated
|
51
|
-
self.methods = methods
|
52
|
-
self.operation_id = operation_id
|
53
|
-
self.response_model_include = response_model_include
|
54
|
-
self.response_model_exclude = response_model_exclude
|
55
|
-
self.response_model_by_alias = response_model_by_alias
|
56
|
-
self.response_model_exclude_unset = response_model_exclude_unset
|
57
|
-
self.response_model_exclude_defaults = response_model_exclude_defaults
|
58
|
-
self.response_model_exclude_none = response_model_exclude_none
|
59
|
-
self.include_in_schema = include_in_schema
|
60
|
-
self.response_class = response_class
|
61
|
-
self.name = name
|
62
|
-
self.openapi_extra = openapi_extra
|
63
|
-
self.generate_unique_id_function = generate_unique_id_function
|
64
|
-
self.func = func
|
65
|
-
|
66
|
-
|
67
|
-
class BaseUsecase:
|
68
|
-
_route_params: dict[str, RouteParam] = {}
|
69
|
-
|
70
|
-
def __init__(self):
|
71
|
-
self._route_params: dict[str, RouteParam] = {}
|
72
|
-
for name, method in self.__class__.__dict__.items():
|
73
|
-
if hasattr(method, "__route_param__"):
|
74
|
-
self._route_params[name] = getattr(method, "__route_param__")
|
75
|
-
|
76
|
-
@classmethod
|
77
|
-
def route(
|
78
|
-
cls,
|
79
|
-
path: str,
|
80
|
-
*,
|
81
|
-
response_model: Any = None,
|
82
|
-
status_code: int | None = None,
|
83
|
-
tags: list[str | Enum] | None = None,
|
84
|
-
dependencies: Sequence[params.Depends] | None = None,
|
85
|
-
summary: str | None = None,
|
86
|
-
description: str = None,
|
87
|
-
response_description: str = "Successful Response",
|
88
|
-
responses: dict[int | str, dict[str, Any]] | None = None,
|
89
|
-
deprecated: bool | None = None,
|
90
|
-
methods: set[str] | list[str] | None = None,
|
91
|
-
operation_id: str | None = None,
|
92
|
-
response_model_include: IncEx | None = None,
|
93
|
-
response_model_exclude: IncEx | None = None,
|
94
|
-
response_model_by_alias: bool = True,
|
95
|
-
response_model_exclude_unset: bool = False,
|
96
|
-
response_model_exclude_defaults: bool = False,
|
97
|
-
response_model_exclude_none: bool = False,
|
98
|
-
include_in_schema: bool = True,
|
99
|
-
response_class: type[Response] = JSONResponse,
|
100
|
-
name: str | None = None,
|
101
|
-
openapi_extra: dict[str, Any] | None = None,
|
102
|
-
generate_unique_id_function: Callable[[APIRoute], str] = generate_unique_id,
|
103
|
-
):
|
104
|
-
"""
|
105
|
-
Decorator to register a method with its HTTP details.
|
106
|
-
"""
|
107
|
-
|
108
|
-
def decorator(func: Callable):
|
109
|
-
@wraps(func)
|
110
|
-
async def wrapped(*args, **kwargs):
|
111
|
-
return await func(*args, **kwargs)
|
112
|
-
|
113
|
-
# Inject __route_param__ property to the method
|
114
|
-
# Method with __route_param__ property will automatically
|
115
|
-
# registered to self._route_param and will be automatically exposed
|
116
|
-
# into DirectClient and APIClient
|
117
|
-
wrapped.__route_param__ = RouteParam(
|
118
|
-
path=path,
|
119
|
-
response_model=response_model,
|
120
|
-
status_code=status_code,
|
121
|
-
tags=tags,
|
122
|
-
dependencies=dependencies,
|
123
|
-
summary=summary,
|
124
|
-
description=description,
|
125
|
-
response_description=response_description,
|
126
|
-
responses=responses,
|
127
|
-
deprecated=deprecated,
|
128
|
-
methods=methods,
|
129
|
-
operation_id=operation_id,
|
130
|
-
response_model_include=response_model_include,
|
131
|
-
response_model_exclude=response_model_exclude,
|
132
|
-
response_model_by_alias=response_model_by_alias,
|
133
|
-
response_model_exclude_unset=response_model_exclude_unset,
|
134
|
-
response_model_exclude_defaults=response_model_exclude_defaults,
|
135
|
-
response_model_exclude_none=response_model_exclude_none,
|
136
|
-
include_in_schema=include_in_schema,
|
137
|
-
response_class=response_class,
|
138
|
-
name=name,
|
139
|
-
openapi_extra=openapi_extra,
|
140
|
-
generate_unique_id_function=generate_unique_id_function,
|
141
|
-
func=func,
|
142
|
-
)
|
143
|
-
return wrapped
|
144
|
-
|
145
|
-
return decorator
|
146
|
-
|
147
|
-
def as_direct_client(self):
|
148
|
-
"""
|
149
|
-
Dynamically create a direct client class.
|
150
|
-
"""
|
151
|
-
_methods = self._route_params
|
152
|
-
DirectClient = create_client_class("DirectClient")
|
153
|
-
for name, details in _methods.items():
|
154
|
-
func = details.func
|
155
|
-
client_method = create_direct_client_method(func, self)
|
156
|
-
# Use __get__ to make a bounded method,
|
157
|
-
# ensuring that client_method use DirectClient as `self`
|
158
|
-
setattr(DirectClient, name, client_method.__get__(DirectClient))
|
159
|
-
return DirectClient
|
160
|
-
|
161
|
-
def as_api_client(self, base_url: str):
|
162
|
-
"""
|
163
|
-
Dynamically create an API client class.
|
164
|
-
"""
|
165
|
-
_methods = self._route_params
|
166
|
-
APIClient = create_client_class("APIClient")
|
167
|
-
# Dynamically generate methods
|
168
|
-
for name, param in _methods.items():
|
169
|
-
client_method = create_api_client_method(param, base_url)
|
170
|
-
# Use __get__ to make a bounded method,
|
171
|
-
# ensuring that client_method use APIClient as `self`
|
172
|
-
setattr(APIClient, name, client_method.__get__(APIClient))
|
173
|
-
return APIClient
|
174
|
-
|
175
|
-
def serve_route(self, app: APIRouter):
|
176
|
-
"""
|
177
|
-
Dynamically add routes to FastAPI.
|
178
|
-
"""
|
179
|
-
for _, route_param in self._route_params.items():
|
180
|
-
bound_func = partial(route_param.func, self)
|
181
|
-
bound_func.__name__ = route_param.func.__name__
|
182
|
-
bound_func.__doc__ = route_param.func.__doc__
|
183
|
-
app.add_api_route(
|
184
|
-
path=route_param.path,
|
185
|
-
endpoint=bound_func,
|
186
|
-
response_model=route_param.response_model,
|
187
|
-
status_code=route_param.status_code,
|
188
|
-
tags=route_param.tags,
|
189
|
-
dependencies=route_param.dependencies,
|
190
|
-
summary=route_param.summary,
|
191
|
-
description=route_param.description,
|
192
|
-
response_description=route_param.response_description,
|
193
|
-
responses=route_param.responses,
|
194
|
-
deprecated=route_param.deprecated,
|
195
|
-
methods=route_param.methods,
|
196
|
-
operation_id=route_param.operation_id,
|
197
|
-
response_model_include=route_param.response_model_include,
|
198
|
-
response_model_exclude=route_param.response_model_exclude,
|
199
|
-
response_model_by_alias=route_param.response_model_by_alias,
|
200
|
-
response_model_exclude_unset=route_param.response_model_exclude_unset,
|
201
|
-
response_model_exclude_defaults=route_param.response_model_exclude_defaults,
|
202
|
-
response_model_exclude_none=route_param.response_model_exclude_none,
|
203
|
-
include_in_schema=route_param.include_in_schema,
|
204
|
-
response_class=route_param.response_class,
|
205
|
-
name=route_param.name,
|
206
|
-
openapi_extra=route_param.openapi_extra,
|
207
|
-
generate_unique_id_function=route_param.generate_unique_id_function,
|
208
|
-
)
|
209
|
-
|
210
|
-
|
211
|
-
def create_client_class(name):
|
212
|
-
class Client:
|
213
|
-
pass
|
214
|
-
|
215
|
-
Client.__name__ = name
|
216
|
-
return Client
|
217
|
-
|
218
|
-
|
219
|
-
def create_direct_client_method(func: Callable, usecase: BaseUsecase):
|
220
|
-
async def client_method(self, *args, **kwargs):
|
221
|
-
return await func(usecase, *args, **kwargs)
|
222
|
-
|
223
|
-
return client_method
|
224
|
-
|
225
|
-
|
226
|
-
def create_api_client_method(param: RouteParam, base_url: str):
|
227
|
-
_url = param.path
|
228
|
-
_methods = [method.lower() for method in param.methods]
|
229
|
-
|
230
|
-
async def client_method(self, *args, **kwargs):
|
231
|
-
async with httpx.AsyncClient() as client:
|
232
|
-
url = base_url + _url.format(**kwargs)
|
233
|
-
if "post" in _methods:
|
234
|
-
response = await client.post(url, json=kwargs)
|
235
|
-
elif "put" in _methods:
|
236
|
-
response = await client.put(url, json=kwargs)
|
237
|
-
elif "delete" in _methods:
|
238
|
-
response = await client.delete(url, json=kwargs)
|
239
|
-
else:
|
240
|
-
response = await client.get(url, params=kwargs)
|
241
|
-
# Add more HTTP methods as needed
|
242
|
-
response.raise_for_status()
|
243
|
-
return response.json()
|
244
|
-
|
245
|
-
return client_method
|
zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/any_client.py
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
from abc import ABC, abstractmethod
|
2
|
-
|
3
|
-
from my_app_name.schema.user import (
|
4
|
-
UserCreateWithAudit,
|
5
|
-
UserResponse,
|
6
|
-
UserUpdateWithAudit,
|
7
|
-
)
|
8
|
-
|
9
|
-
|
10
|
-
class AnyClient(ABC):
|
11
|
-
@abstractmethod
|
12
|
-
async def get_user_by_id(self, user_id: str) -> UserResponse:
|
13
|
-
pass
|
14
|
-
|
15
|
-
@abstractmethod
|
16
|
-
async def get_all_users(self) -> list[UserResponse]:
|
17
|
-
pass
|
18
|
-
|
19
|
-
@abstractmethod
|
20
|
-
async def create_user(
|
21
|
-
self, data: UserCreateWithAudit | list[UserCreateWithAudit]
|
22
|
-
) -> UserResponse | list[UserResponse]:
|
23
|
-
pass
|
24
|
-
|
25
|
-
@abstractmethod
|
26
|
-
async def update_user(
|
27
|
-
self, user_id: str, data: UserUpdateWithAudit
|
28
|
-
) -> UserResponse:
|
29
|
-
pass
|
30
|
-
|
31
|
-
@abstractmethod
|
32
|
-
async def delete_user(self, user_id: str) -> UserResponse:
|
33
|
-
pass
|
zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
from my_app_name.config import APP_AUTH_BASE_URL
|
2
|
-
from my_app_name.module.auth.client.any_client import AnyClient
|
3
|
-
from my_app_name.module.auth.service.user.user_usecase_factory import user_usecase
|
4
|
-
|
5
|
-
|
6
|
-
class APIClient(user_usecase.as_api_client(base_url=APP_AUTH_BASE_URL), AnyClient):
|
7
|
-
pass
|
@@ -1,9 +0,0 @@
|
|
1
|
-
from my_app_name.config import APP_COMMUNICATION
|
2
|
-
from my_app_name.module.auth.client.any_client import AnyClient
|
3
|
-
from my_app_name.module.auth.client.api_client import APIClient
|
4
|
-
from my_app_name.module.auth.client.direct_client import DirectClient
|
5
|
-
|
6
|
-
if APP_COMMUNICATION == "direct":
|
7
|
-
client: AnyClient = DirectClient()
|
8
|
-
elif APP_COMMUNICATION == "api":
|
9
|
-
client: AnyClient = APIClient()
|
@@ -1,37 +0,0 @@
|
|
1
|
-
"""Add user table
|
2
|
-
|
3
|
-
Revision ID: 3093c7336477
|
4
|
-
Revises:
|
5
|
-
Create Date: 2024-11-20 05:57:01.684118
|
6
|
-
|
7
|
-
"""
|
8
|
-
|
9
|
-
from typing import Sequence, Union
|
10
|
-
|
11
|
-
import sqlalchemy as sa
|
12
|
-
import sqlmodel
|
13
|
-
from alembic import op
|
14
|
-
|
15
|
-
# revision identifiers, used by Alembic.
|
16
|
-
revision: str = "3093c7336477"
|
17
|
-
down_revision: Union[str, None] = None
|
18
|
-
branch_labels: Union[str, Sequence[str], None] = None
|
19
|
-
depends_on: Union[str, Sequence[str], None] = None
|
20
|
-
|
21
|
-
|
22
|
-
def upgrade() -> None:
|
23
|
-
# ### commands auto generated by Alembic - please adjust! ###
|
24
|
-
op.create_table(
|
25
|
-
"user",
|
26
|
-
sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
27
|
-
sa.Column("username", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
28
|
-
sa.Column("password", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
29
|
-
sa.PrimaryKeyConstraint("id"),
|
30
|
-
)
|
31
|
-
# ### end Alembic commands ###
|
32
|
-
|
33
|
-
|
34
|
-
def downgrade() -> None:
|
35
|
-
# ### commands auto generated by Alembic - please adjust! ###
|
36
|
-
op.drop_table("user")
|
37
|
-
# ### end Alembic commands ###
|
@@ -1,53 +0,0 @@
|
|
1
|
-
from my_app_name.common.base_usecase import BaseUsecase
|
2
|
-
from my_app_name.module.auth.service.user.repository.user_repository import (
|
3
|
-
UserRepository,
|
4
|
-
)
|
5
|
-
from my_app_name.schema.user import (
|
6
|
-
UserCreateWithAudit,
|
7
|
-
UserResponse,
|
8
|
-
UserUpdateWithAudit,
|
9
|
-
)
|
10
|
-
|
11
|
-
|
12
|
-
class UserUsecase(BaseUsecase):
|
13
|
-
def __init__(self, user_repository: UserRepository):
|
14
|
-
super().__init__()
|
15
|
-
self.user_repository = user_repository
|
16
|
-
|
17
|
-
@BaseUsecase.route(
|
18
|
-
"/api/v1/users/{user_id}", methods=["get"], response_model=UserResponse
|
19
|
-
)
|
20
|
-
async def get_user_by_id(self, user_id: str) -> UserResponse:
|
21
|
-
return await self.user_repository.get_by_id(user_id)
|
22
|
-
|
23
|
-
@BaseUsecase.route(
|
24
|
-
"/api/v1/users", methods=["get"], response_model=list[UserResponse]
|
25
|
-
)
|
26
|
-
async def get_all_users(self) -> list[UserResponse]:
|
27
|
-
return await self.user_repository.get_all()
|
28
|
-
|
29
|
-
@BaseUsecase.route(
|
30
|
-
"/api/v1/users",
|
31
|
-
methods=["post"],
|
32
|
-
response_model=UserResponse | list[UserResponse],
|
33
|
-
)
|
34
|
-
async def create_user(
|
35
|
-
self, data: UserCreateWithAudit | list[UserCreateWithAudit]
|
36
|
-
) -> UserResponse | list[UserResponse]:
|
37
|
-
if isinstance(data, UserCreateWithAudit):
|
38
|
-
return await self.user_repository.create(data)
|
39
|
-
return await self.user_repository.create_bulk(data)
|
40
|
-
|
41
|
-
@BaseUsecase.route(
|
42
|
-
"/api/v1/users/{user_id}", methods=["put"], response_model=UserResponse
|
43
|
-
)
|
44
|
-
async def update_user(
|
45
|
-
self, user_id: str, data: UserUpdateWithAudit
|
46
|
-
) -> UserResponse:
|
47
|
-
return await self.user_repository.update(user_id, data)
|
48
|
-
|
49
|
-
@BaseUsecase.route(
|
50
|
-
"/api/v1/users/{user_id}", methods=["delete"], response_model=UserResponse
|
51
|
-
)
|
52
|
-
async def delete_user(self, user_id: str, deleted_by: str) -> UserResponse:
|
53
|
-
return await self.user_repository.delete(user_id)
|
zrb/runner/web_config.py
DELETED
@@ -1,274 +0,0 @@
|
|
1
|
-
from datetime import datetime, timedelta
|
2
|
-
from typing import TYPE_CHECKING, Callable
|
3
|
-
|
4
|
-
from pydantic import BaseModel, ConfigDict
|
5
|
-
|
6
|
-
from zrb.config import (
|
7
|
-
WEB_ACCESS_TOKEN_COOKIE_NAME,
|
8
|
-
WEB_AUTH_ACCESS_TOKEN_EXPIRE_MINUTES,
|
9
|
-
WEB_AUTH_REFRESH_TOKEN_EXPIRE_MINUTES,
|
10
|
-
WEB_ENABLE_AUTH,
|
11
|
-
WEB_GUEST_USERNAME,
|
12
|
-
WEB_HTTP_PORT,
|
13
|
-
WEB_REFRESH_TOKEN_COOKIE_NAME,
|
14
|
-
WEB_SECRET_KEY,
|
15
|
-
WEB_SUPER_ADMIN_PASSWORD,
|
16
|
-
WEB_SUPER_ADMIN_USERNAME,
|
17
|
-
)
|
18
|
-
from zrb.group.any_group import AnyGroup
|
19
|
-
from zrb.task.any_task import AnyTask
|
20
|
-
from zrb.util.group import get_all_subtasks
|
21
|
-
|
22
|
-
if TYPE_CHECKING:
|
23
|
-
# Import Request only for type checking to reduce runtime dependencies
|
24
|
-
from fastapi import Request
|
25
|
-
|
26
|
-
|
27
|
-
class NewSessionResponse(BaseModel):
|
28
|
-
session_name: str
|
29
|
-
|
30
|
-
|
31
|
-
class RefreshTokenRequest(BaseModel):
|
32
|
-
refresh_token: str
|
33
|
-
|
34
|
-
|
35
|
-
class User(BaseModel):
|
36
|
-
model_config = ConfigDict(arbitrary_types_allowed=True)
|
37
|
-
username: str
|
38
|
-
password: str = ""
|
39
|
-
is_super_admin: bool = False
|
40
|
-
is_guest: bool = False
|
41
|
-
accessible_tasks: list[AnyTask | str] = []
|
42
|
-
|
43
|
-
def is_password_match(self, password: str) -> bool:
|
44
|
-
return self.password == password
|
45
|
-
|
46
|
-
def can_access_group(self, group: AnyGroup) -> bool:
|
47
|
-
if self.is_super_admin:
|
48
|
-
return True
|
49
|
-
all_tasks = get_all_subtasks(group, web_only=True)
|
50
|
-
if any(self.can_access_task(task) for task in all_tasks):
|
51
|
-
return True
|
52
|
-
return False
|
53
|
-
|
54
|
-
def can_access_task(self, task: AnyTask) -> bool:
|
55
|
-
if self.is_super_admin:
|
56
|
-
return True
|
57
|
-
if task.name in self.accessible_tasks or task in self.accessible_tasks:
|
58
|
-
return True
|
59
|
-
return False
|
60
|
-
|
61
|
-
|
62
|
-
class Token(BaseModel):
|
63
|
-
access_token: str
|
64
|
-
refresh_token: str
|
65
|
-
token_type: str
|
66
|
-
|
67
|
-
|
68
|
-
class WebConfig:
|
69
|
-
def __init__(
|
70
|
-
self,
|
71
|
-
port: int,
|
72
|
-
secret_key: str,
|
73
|
-
access_token_expire_minutes: int,
|
74
|
-
refresh_token_expire_minutes: int,
|
75
|
-
access_token_cookie_name: str,
|
76
|
-
refresh_token_cookie_name: str,
|
77
|
-
enable_auth: bool,
|
78
|
-
super_admin_username: str,
|
79
|
-
super_admin_password: str,
|
80
|
-
guest_username: str,
|
81
|
-
guest_accessible_tasks: list[AnyTask | str] = [],
|
82
|
-
find_user_by_username: Callable[[str], User | None] | None = None,
|
83
|
-
):
|
84
|
-
self.secret_key = secret_key
|
85
|
-
self.access_token_expire_minutes = access_token_expire_minutes
|
86
|
-
self.refresh_token_expire_minutes = refresh_token_expire_minutes
|
87
|
-
self.access_token_cookie_name = access_token_cookie_name
|
88
|
-
self.refresh_token_cookie_name = refresh_token_cookie_name
|
89
|
-
self.enable_auth = enable_auth
|
90
|
-
self.port = port
|
91
|
-
self._user_list = []
|
92
|
-
self.super_admin_username = super_admin_username
|
93
|
-
self.super_admin_password = super_admin_password
|
94
|
-
self.guest_username = guest_username
|
95
|
-
self.guest_accessible_tasks = guest_accessible_tasks
|
96
|
-
self._find_user_by_username = find_user_by_username
|
97
|
-
|
98
|
-
@property
|
99
|
-
def default_user(self) -> User:
|
100
|
-
if self.enable_auth:
|
101
|
-
return User(
|
102
|
-
username=self.guest_username,
|
103
|
-
password="",
|
104
|
-
is_guest=True,
|
105
|
-
accessible_tasks=self.guest_accessible_tasks,
|
106
|
-
)
|
107
|
-
return User(
|
108
|
-
username=self.guest_username,
|
109
|
-
password="",
|
110
|
-
is_guest=True,
|
111
|
-
is_super_admin=True,
|
112
|
-
)
|
113
|
-
|
114
|
-
@property
|
115
|
-
def super_admin(self) -> User:
|
116
|
-
return User(
|
117
|
-
username=self.super_admin_username,
|
118
|
-
password=self.super_admin_password,
|
119
|
-
is_super_admin=True,
|
120
|
-
)
|
121
|
-
|
122
|
-
@property
|
123
|
-
def user_list(self) -> list[User]:
|
124
|
-
if not self.enable_auth:
|
125
|
-
return [self.default_user]
|
126
|
-
return self._user_list + [self.super_admin, self.default_user]
|
127
|
-
|
128
|
-
def set_guest_accessible_tasks(self, tasks: list[AnyTask | str]):
|
129
|
-
self.guest_accessible_tasks = tasks
|
130
|
-
|
131
|
-
def set_find_user_by_username(
|
132
|
-
self, find_user_by_username: Callable[[str], User | None]
|
133
|
-
):
|
134
|
-
self._find_user_by_username = find_user_by_username
|
135
|
-
|
136
|
-
def append_user(self, user: User):
|
137
|
-
duplicates = [
|
138
|
-
existing_user
|
139
|
-
for existing_user in self.user_list
|
140
|
-
if existing_user.username == user.username
|
141
|
-
]
|
142
|
-
if len(duplicates) > 0:
|
143
|
-
raise ValueError(f"User already exists {user.username}")
|
144
|
-
self._user_list.append(user)
|
145
|
-
|
146
|
-
def find_user_by_username(self, username: str) -> User | None:
|
147
|
-
user = None
|
148
|
-
if self._find_user_by_username is not None:
|
149
|
-
user = self._find_user_by_username(username)
|
150
|
-
if user is None:
|
151
|
-
user = next((u for u in self.user_list if u.username == username), None)
|
152
|
-
return user
|
153
|
-
|
154
|
-
async def get_user_from_request(self, request: "Request") -> User | None:
|
155
|
-
from fastapi.security import OAuth2PasswordBearer
|
156
|
-
|
157
|
-
if not self.enable_auth:
|
158
|
-
return self.default_user
|
159
|
-
# Normally we use "Depends"
|
160
|
-
get_bearer_token = OAuth2PasswordBearer(
|
161
|
-
tokenUrl="/api/v1/login", auto_error=False
|
162
|
-
)
|
163
|
-
bearer_token = await get_bearer_token(request)
|
164
|
-
token_user = self._get_user_from_token(bearer_token)
|
165
|
-
if token_user is not None:
|
166
|
-
return token_user
|
167
|
-
cookie_user = self._get_user_from_cookie(request)
|
168
|
-
if cookie_user is not None:
|
169
|
-
return cookie_user
|
170
|
-
return self.default_user
|
171
|
-
|
172
|
-
def _get_user_from_token(self, token: str) -> User | None:
|
173
|
-
try:
|
174
|
-
from jose import jwt
|
175
|
-
|
176
|
-
payload = jwt.decode(
|
177
|
-
token,
|
178
|
-
self.secret_key,
|
179
|
-
options={"require_sub": True, "require_exp": True},
|
180
|
-
)
|
181
|
-
username: str = payload.get("sub")
|
182
|
-
if username is None:
|
183
|
-
return None
|
184
|
-
user = self.find_user_by_username(username)
|
185
|
-
if user is None:
|
186
|
-
return None
|
187
|
-
return user
|
188
|
-
except Exception:
|
189
|
-
return None
|
190
|
-
|
191
|
-
def _get_user_from_cookie(self, request: "Request") -> User | None:
|
192
|
-
token = request.cookies.get(self.access_token_cookie_name)
|
193
|
-
if token:
|
194
|
-
return self._get_user_from_token(token)
|
195
|
-
return None
|
196
|
-
|
197
|
-
def get_user_by_credentials(self, username: str, password: str) -> User | None:
|
198
|
-
user = self.find_user_by_username(username)
|
199
|
-
if user is None or not user.is_password_match(password):
|
200
|
-
return None
|
201
|
-
return user
|
202
|
-
|
203
|
-
def generate_tokens_by_credentials(
|
204
|
-
self, username: str, password: str
|
205
|
-
) -> Token | None:
|
206
|
-
if not self.enable_auth:
|
207
|
-
user = self.default_user
|
208
|
-
else:
|
209
|
-
user = self.get_user_by_credentials(username, password)
|
210
|
-
if user is None:
|
211
|
-
return None
|
212
|
-
access_token = self._generate_access_token(user.username)
|
213
|
-
refresh_token = self._generate_refresh_token(user.username)
|
214
|
-
return Token(
|
215
|
-
access_token=access_token, refresh_token=refresh_token, token_type="bearer"
|
216
|
-
)
|
217
|
-
|
218
|
-
def _generate_access_token(self, username: str) -> str:
|
219
|
-
from jose import jwt
|
220
|
-
|
221
|
-
expire = datetime.now() + timedelta(minutes=self.access_token_expire_minutes)
|
222
|
-
to_encode = {"sub": username, "exp": expire, "type": "access"}
|
223
|
-
return jwt.encode(to_encode, self.secret_key)
|
224
|
-
|
225
|
-
def _generate_refresh_token(self, username: str) -> str:
|
226
|
-
from jose import jwt
|
227
|
-
|
228
|
-
expire = datetime.now() + timedelta(minutes=self.refresh_token_expire_minutes)
|
229
|
-
to_encode = {"sub": username, "exp": expire, "type": "refresh"}
|
230
|
-
return jwt.encode(to_encode, self.secret_key)
|
231
|
-
|
232
|
-
def regenerate_tokens(self, refresh_token: str) -> Token:
|
233
|
-
from fastapi import HTTPException
|
234
|
-
from jose import jwt
|
235
|
-
|
236
|
-
# Decode and validate token
|
237
|
-
try:
|
238
|
-
payload = jwt.decode(
|
239
|
-
refresh_token,
|
240
|
-
self.secret_key,
|
241
|
-
options={"require_exp": True, "require_sub": True},
|
242
|
-
)
|
243
|
-
except Exception:
|
244
|
-
raise HTTPException(status_code=401, detail="Invalid JWT token")
|
245
|
-
if payload.get("type") != "refresh":
|
246
|
-
raise HTTPException(status_code=401, detail="Invalid token type")
|
247
|
-
username: str = payload.get("sub")
|
248
|
-
if username is None:
|
249
|
-
raise HTTPException(status_code=401, detail="Invalid refresh token")
|
250
|
-
user = self.find_user_by_username(username)
|
251
|
-
if user is None:
|
252
|
-
raise HTTPException(status_code=401, detail="User not found")
|
253
|
-
# Create new token
|
254
|
-
new_access_token = self._generate_access_token(username)
|
255
|
-
new_refresh_token = self._generate_refresh_token(username)
|
256
|
-
return Token(
|
257
|
-
access_token=new_access_token,
|
258
|
-
refresh_token=new_refresh_token,
|
259
|
-
token_type="bearer",
|
260
|
-
)
|
261
|
-
|
262
|
-
|
263
|
-
web_config = WebConfig(
|
264
|
-
port=WEB_HTTP_PORT,
|
265
|
-
secret_key=WEB_SECRET_KEY,
|
266
|
-
access_token_expire_minutes=WEB_AUTH_ACCESS_TOKEN_EXPIRE_MINUTES,
|
267
|
-
refresh_token_expire_minutes=WEB_AUTH_REFRESH_TOKEN_EXPIRE_MINUTES,
|
268
|
-
access_token_cookie_name=WEB_ACCESS_TOKEN_COOKIE_NAME,
|
269
|
-
refresh_token_cookie_name=WEB_REFRESH_TOKEN_COOKIE_NAME,
|
270
|
-
enable_auth=WEB_ENABLE_AUTH,
|
271
|
-
super_admin_username=WEB_SUPER_ADMIN_USERNAME,
|
272
|
-
super_admin_password=WEB_SUPER_ADMIN_PASSWORD,
|
273
|
-
guest_username=WEB_GUEST_USERNAME,
|
274
|
-
)
|