fractal-server 2.3.10__py3-none-any.whl → 2.4.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.
- fractal_server/__init__.py +1 -1
- fractal_server/__main__.py +25 -2
- fractal_server/app/models/__init__.py +11 -5
- fractal_server/app/models/linkusergroup.py +11 -0
- fractal_server/app/models/security.py +24 -3
- fractal_server/app/models/v1/project.py +1 -1
- fractal_server/app/models/v2/project.py +3 -3
- fractal_server/app/routes/admin/v1.py +14 -14
- fractal_server/app/routes/admin/v2.py +12 -12
- fractal_server/app/routes/api/__init__.py +2 -2
- fractal_server/app/routes/api/v1/_aux_functions.py +2 -2
- fractal_server/app/routes/api/v1/dataset.py +17 -15
- fractal_server/app/routes/api/v1/job.py +11 -9
- fractal_server/app/routes/api/v1/project.py +9 -9
- fractal_server/app/routes/api/v1/task.py +8 -8
- fractal_server/app/routes/api/v1/task_collection.py +5 -5
- fractal_server/app/routes/api/v1/workflow.py +13 -11
- fractal_server/app/routes/api/v1/workflowtask.py +6 -6
- fractal_server/app/routes/api/v2/_aux_functions.py +2 -2
- fractal_server/app/routes/api/v2/dataset.py +11 -11
- fractal_server/app/routes/api/v2/images.py +6 -6
- fractal_server/app/routes/api/v2/job.py +9 -9
- fractal_server/app/routes/api/v2/project.py +7 -7
- fractal_server/app/routes/api/v2/status.py +3 -3
- fractal_server/app/routes/api/v2/submit.py +3 -3
- fractal_server/app/routes/api/v2/task.py +8 -8
- fractal_server/app/routes/api/v2/task_collection.py +5 -5
- fractal_server/app/routes/api/v2/task_collection_custom.py +3 -3
- fractal_server/app/routes/api/v2/task_legacy.py +9 -9
- fractal_server/app/routes/api/v2/workflow.py +11 -11
- fractal_server/app/routes/api/v2/workflowtask.py +6 -6
- fractal_server/app/routes/auth/__init__.py +55 -0
- fractal_server/app/routes/auth/_aux_auth.py +107 -0
- fractal_server/app/routes/auth/current_user.py +60 -0
- fractal_server/app/routes/auth/group.py +176 -0
- fractal_server/app/routes/auth/group_names.py +34 -0
- fractal_server/app/routes/auth/login.py +25 -0
- fractal_server/app/routes/auth/oauth.py +63 -0
- fractal_server/app/routes/auth/register.py +23 -0
- fractal_server/app/routes/auth/router.py +19 -0
- fractal_server/app/routes/auth/users.py +192 -0
- fractal_server/app/runner/v2/__init__.py +1 -5
- fractal_server/app/runner/v2/_slurm_ssh/__init__.py +17 -0
- fractal_server/app/schemas/user.py +11 -0
- fractal_server/app/schemas/user_group.py +65 -0
- fractal_server/app/security/__init__.py +72 -75
- fractal_server/data_migrations/2_4_0.py +61 -0
- fractal_server/main.py +1 -9
- fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +53 -0
- {fractal_server-2.3.10.dist-info → fractal_server-2.4.0.dist-info}/METADATA +1 -1
- {fractal_server-2.3.10.dist-info → fractal_server-2.4.0.dist-info}/RECORD +54 -41
- fractal_server/app/routes/auth.py +0 -165
- {fractal_server-2.3.10.dist-info → fractal_server-2.4.0.dist-info}/LICENSE +0 -0
- {fractal_server-2.3.10.dist-info → fractal_server-2.4.0.dist-info}/WHEEL +0 -0
- {fractal_server-2.3.10.dist-info → fractal_server-2.4.0.dist-info}/entry_points.txt +0 -0
@@ -1,165 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Definition of `/auth` routes.
|
3
|
-
"""
|
4
|
-
from fastapi import APIRouter
|
5
|
-
from fastapi import Depends
|
6
|
-
from fastapi import HTTPException
|
7
|
-
from fastapi import status
|
8
|
-
from fastapi_users import exceptions
|
9
|
-
from fastapi_users import schemas
|
10
|
-
from fastapi_users.router.common import ErrorCode
|
11
|
-
from sqlalchemy.ext.asyncio import AsyncSession
|
12
|
-
from sqlmodel import select
|
13
|
-
|
14
|
-
from ...config import get_settings
|
15
|
-
from ...syringe import Inject
|
16
|
-
from ..db import get_async_db
|
17
|
-
from ..models.security import UserOAuth as User
|
18
|
-
from ..schemas.user import UserCreate
|
19
|
-
from ..schemas.user import UserRead
|
20
|
-
from ..schemas.user import UserUpdate
|
21
|
-
from ..schemas.user import UserUpdateStrict
|
22
|
-
from ..security import cookie_backend
|
23
|
-
from ..security import current_active_superuser
|
24
|
-
from ..security import current_active_user
|
25
|
-
from ..security import fastapi_users
|
26
|
-
from ..security import get_user_manager
|
27
|
-
from ..security import token_backend
|
28
|
-
from ..security import UserManager
|
29
|
-
|
30
|
-
router_auth = APIRouter()
|
31
|
-
|
32
|
-
router_auth.include_router(
|
33
|
-
fastapi_users.get_auth_router(token_backend),
|
34
|
-
prefix="/token",
|
35
|
-
)
|
36
|
-
router_auth.include_router(
|
37
|
-
fastapi_users.get_auth_router(cookie_backend),
|
38
|
-
)
|
39
|
-
router_auth.include_router(
|
40
|
-
fastapi_users.get_register_router(UserRead, UserCreate),
|
41
|
-
dependencies=[Depends(current_active_superuser)],
|
42
|
-
)
|
43
|
-
|
44
|
-
users_router = fastapi_users.get_users_router(UserRead, UserUpdate)
|
45
|
-
|
46
|
-
# We remove `/auth/users/me` endpoints to implement our own
|
47
|
-
# at `/auth/current-user/`.
|
48
|
-
# We also remove `DELETE /auth/users/{user_id}`
|
49
|
-
# (ref https://github.com/fastapi-users/fastapi-users/discussions/606)
|
50
|
-
users_router.routes = [
|
51
|
-
route
|
52
|
-
for route in users_router.routes
|
53
|
-
if route.name
|
54
|
-
not in [
|
55
|
-
"users:current_user",
|
56
|
-
"users:delete_user",
|
57
|
-
"users:patch_current_user",
|
58
|
-
]
|
59
|
-
]
|
60
|
-
router_auth.include_router(
|
61
|
-
users_router,
|
62
|
-
prefix="/users",
|
63
|
-
dependencies=[Depends(current_active_superuser)],
|
64
|
-
)
|
65
|
-
|
66
|
-
|
67
|
-
@router_auth.patch("/current-user/", response_model=UserRead)
|
68
|
-
async def patch_current_user(
|
69
|
-
user_update: UserUpdateStrict,
|
70
|
-
current_user: User = Depends(current_active_user),
|
71
|
-
user_manager: UserManager = Depends(get_user_manager),
|
72
|
-
):
|
73
|
-
|
74
|
-
update = UserUpdate(**user_update.dict(exclude_unset=True))
|
75
|
-
|
76
|
-
try:
|
77
|
-
user = await user_manager.update(update, current_user, safe=True)
|
78
|
-
except exceptions.InvalidPasswordException as e:
|
79
|
-
raise HTTPException(
|
80
|
-
status_code=status.HTTP_400_BAD_REQUEST,
|
81
|
-
detail={
|
82
|
-
"code": ErrorCode.UPDATE_USER_INVALID_PASSWORD,
|
83
|
-
"reason": e.reason,
|
84
|
-
},
|
85
|
-
)
|
86
|
-
return schemas.model_validate(User, user)
|
87
|
-
|
88
|
-
|
89
|
-
@router_auth.get("/current-user/", response_model=UserRead)
|
90
|
-
async def get_current_user(user: User = Depends(current_active_user)):
|
91
|
-
"""
|
92
|
-
Return current user
|
93
|
-
"""
|
94
|
-
return user
|
95
|
-
|
96
|
-
|
97
|
-
@router_auth.get("/users/", response_model=list[UserRead])
|
98
|
-
async def list_users(
|
99
|
-
user: User = Depends(current_active_superuser),
|
100
|
-
db: AsyncSession = Depends(get_async_db),
|
101
|
-
):
|
102
|
-
"""
|
103
|
-
Return list of all users
|
104
|
-
"""
|
105
|
-
stm = select(User)
|
106
|
-
res = await db.execute(stm)
|
107
|
-
user_list = res.scalars().unique().all()
|
108
|
-
await db.close()
|
109
|
-
return user_list
|
110
|
-
|
111
|
-
|
112
|
-
# OAUTH CLIENTS
|
113
|
-
|
114
|
-
# NOTE: settings.OAUTH_CLIENTS are collected by
|
115
|
-
# Settings.collect_oauth_clients(). If no specific client is specified in the
|
116
|
-
# environment variables (e.g. by setting OAUTH_FOO_CLIENT_ID and
|
117
|
-
# OAUTH_FOO_CLIENT_SECRET), this list is empty
|
118
|
-
|
119
|
-
# FIXME:Dependency injection should be wrapped within a function call to make
|
120
|
-
# it truly lazy. This function could then be called on startup of the FastAPI
|
121
|
-
# app (cf. fractal_server.main)
|
122
|
-
settings = Inject(get_settings)
|
123
|
-
|
124
|
-
for client_config in settings.OAUTH_CLIENTS_CONFIG:
|
125
|
-
|
126
|
-
client_name = client_config.CLIENT_NAME.lower()
|
127
|
-
|
128
|
-
if client_name == "google":
|
129
|
-
from httpx_oauth.clients.google import GoogleOAuth2
|
130
|
-
|
131
|
-
client = GoogleOAuth2(
|
132
|
-
client_config.CLIENT_ID, client_config.CLIENT_SECRET
|
133
|
-
)
|
134
|
-
elif client_name == "github":
|
135
|
-
from httpx_oauth.clients.github import GitHubOAuth2
|
136
|
-
|
137
|
-
client = GitHubOAuth2(
|
138
|
-
client_config.CLIENT_ID, client_config.CLIENT_SECRET
|
139
|
-
)
|
140
|
-
else:
|
141
|
-
from httpx_oauth.clients.openid import OpenID
|
142
|
-
|
143
|
-
client = OpenID(
|
144
|
-
client_config.CLIENT_ID,
|
145
|
-
client_config.CLIENT_SECRET,
|
146
|
-
client_config.OIDC_CONFIGURATION_ENDPOINT,
|
147
|
-
)
|
148
|
-
|
149
|
-
router_auth.include_router(
|
150
|
-
fastapi_users.get_oauth_router(
|
151
|
-
client,
|
152
|
-
cookie_backend,
|
153
|
-
settings.JWT_SECRET_KEY,
|
154
|
-
is_verified_by_default=False,
|
155
|
-
associate_by_email=True,
|
156
|
-
redirect_url=client_config.REDIRECT_URL,
|
157
|
-
),
|
158
|
-
prefix=f"/{client_name}",
|
159
|
-
)
|
160
|
-
|
161
|
-
|
162
|
-
# Add trailing slash to all routes' paths
|
163
|
-
for route in router_auth.routes:
|
164
|
-
if not route.path.endswith("/"):
|
165
|
-
route.path = f"{route.path}/"
|
File without changes
|
File without changes
|
File without changes
|