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.
Files changed (55) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/__main__.py +25 -2
  3. fractal_server/app/models/__init__.py +11 -5
  4. fractal_server/app/models/linkusergroup.py +11 -0
  5. fractal_server/app/models/security.py +24 -3
  6. fractal_server/app/models/v1/project.py +1 -1
  7. fractal_server/app/models/v2/project.py +3 -3
  8. fractal_server/app/routes/admin/v1.py +14 -14
  9. fractal_server/app/routes/admin/v2.py +12 -12
  10. fractal_server/app/routes/api/__init__.py +2 -2
  11. fractal_server/app/routes/api/v1/_aux_functions.py +2 -2
  12. fractal_server/app/routes/api/v1/dataset.py +17 -15
  13. fractal_server/app/routes/api/v1/job.py +11 -9
  14. fractal_server/app/routes/api/v1/project.py +9 -9
  15. fractal_server/app/routes/api/v1/task.py +8 -8
  16. fractal_server/app/routes/api/v1/task_collection.py +5 -5
  17. fractal_server/app/routes/api/v1/workflow.py +13 -11
  18. fractal_server/app/routes/api/v1/workflowtask.py +6 -6
  19. fractal_server/app/routes/api/v2/_aux_functions.py +2 -2
  20. fractal_server/app/routes/api/v2/dataset.py +11 -11
  21. fractal_server/app/routes/api/v2/images.py +6 -6
  22. fractal_server/app/routes/api/v2/job.py +9 -9
  23. fractal_server/app/routes/api/v2/project.py +7 -7
  24. fractal_server/app/routes/api/v2/status.py +3 -3
  25. fractal_server/app/routes/api/v2/submit.py +3 -3
  26. fractal_server/app/routes/api/v2/task.py +8 -8
  27. fractal_server/app/routes/api/v2/task_collection.py +5 -5
  28. fractal_server/app/routes/api/v2/task_collection_custom.py +3 -3
  29. fractal_server/app/routes/api/v2/task_legacy.py +9 -9
  30. fractal_server/app/routes/api/v2/workflow.py +11 -11
  31. fractal_server/app/routes/api/v2/workflowtask.py +6 -6
  32. fractal_server/app/routes/auth/__init__.py +55 -0
  33. fractal_server/app/routes/auth/_aux_auth.py +107 -0
  34. fractal_server/app/routes/auth/current_user.py +60 -0
  35. fractal_server/app/routes/auth/group.py +176 -0
  36. fractal_server/app/routes/auth/group_names.py +34 -0
  37. fractal_server/app/routes/auth/login.py +25 -0
  38. fractal_server/app/routes/auth/oauth.py +63 -0
  39. fractal_server/app/routes/auth/register.py +23 -0
  40. fractal_server/app/routes/auth/router.py +19 -0
  41. fractal_server/app/routes/auth/users.py +192 -0
  42. fractal_server/app/runner/v2/__init__.py +1 -5
  43. fractal_server/app/runner/v2/_slurm_ssh/__init__.py +17 -0
  44. fractal_server/app/schemas/user.py +11 -0
  45. fractal_server/app/schemas/user_group.py +65 -0
  46. fractal_server/app/security/__init__.py +72 -75
  47. fractal_server/data_migrations/2_4_0.py +61 -0
  48. fractal_server/main.py +1 -9
  49. fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +53 -0
  50. {fractal_server-2.3.10.dist-info → fractal_server-2.4.0.dist-info}/METADATA +1 -1
  51. {fractal_server-2.3.10.dist-info → fractal_server-2.4.0.dist-info}/RECORD +54 -41
  52. fractal_server/app/routes/auth.py +0 -165
  53. {fractal_server-2.3.10.dist-info → fractal_server-2.4.0.dist-info}/LICENSE +0 -0
  54. {fractal_server-2.3.10.dist-info → fractal_server-2.4.0.dist-info}/WHEEL +0 -0
  55. {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}/"