Skip to content

Commit e0e8efc

Browse files
authored
Merge pull request #2890 from fractal-analytics-platform/2889-drop-self-registration-and-review-user-creation-procedure
Drop self-registration, drop UserSettings
2 parents 6739f8d + a94265f commit e0e8efc

File tree

105 files changed

+1457
-1660
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+1457
-1660
lines changed

.github/workflows/benchmarks.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
export JWT_EXPIRE_SECONDS=84600
4545
cd benchmarks/
4646
poetry run fractalctl set-db
47-
poetry run fractalctl init-db-data --resource default --profile default --admin-email [email protected] --admin-pwd 1234
47+
poetry run fractalctl init-db-data --resource default --profile default --admin-email [email protected] --admin-pwd 1234 --admin-project-dir "$(pwd)/project-dir"
4848
poetry run python populate_db/populate_db_script.py
4949
poetry run sh serve.sh
5050

.github/workflows/oauth.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,10 @@ jobs:
7575
FRACTAL_EMAIL_USE_STARTTLS: false
7676
FRACTAL_EMAIL_USE_LOGIN: true
7777
FRACTAL_EMAIL_PASSWORD: fakepassword
78+
FRACTAL_HELP_URL: https://example.org/info
7879
run: |
7980
fractalctl set-db
80-
fractalctl init-db-data --resource default --profile default --admin-email [email protected] --admin-pwd 1234
81+
fractalctl init-db-data --resource default --profile default --admin-email [email protected] --admin-pwd 1234 --admin-project-dir /fake
8182
fractalctl start --port 8001 &
8283
sleep 2
8384

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ TBD
1414
\#2895, \#2898 (remove email-password encryption)
1515

1616

17+
\#2890 (oauth self-registration)
18+
1719
# 2.16.6
1820

1921
* API:

benchmarks/populate_db/populate_db_script.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ def _create_user_client(
3737
) -> FractalClient:
3838
email = f"{user_identifier}@example.org"
3939
password = f"{user_identifier}-pwd"
40-
slurm_user = f"{user_identifier}-slurm"
40+
project_dir = f"/fake/{user_identifier}"
4141
_user = _admin.add_user(
4242
UserCreate(
4343
email=email,
4444
password=password,
45-
slurm_user=slurm_user,
45+
project_dir=project_dir,
4646
)
4747
)
4848
_admin.associate_user_with_profile(user_id=_user.id)

example/run_fractal_server.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set -e
55
# Create and init db
66
createdb fractal-example-test
77
poetry run fractalctl set-db
8-
poetry run fractalctl init-db-data --resource default --profile default --admin-email [email protected] --admin-pwd 1234
8+
poetry run fractalctl init-db-data --resource default --profile default --admin-email [email protected] --admin-pwd 1234 --project-dir "$(pwd)/project-dir"
99

1010
# Start the server
1111
poetry run gunicorn fractal_server.main:app \

fractal_server/__main__.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,20 @@
7474
init_db_data_parser.add_argument(
7575
"--admin-email",
7676
type=str,
77-
help="Email of the first admin user to create.",
77+
help="Email of the first admin user.",
7878
required=False,
7979
)
8080
init_db_data_parser.add_argument(
8181
"--admin-pwd",
8282
type=str,
83-
help="Password of the first admin user to create.",
83+
help="Password for the first admin user.",
84+
required=False,
85+
)
86+
87+
init_db_data_parser.add_argument(
88+
"--admin-project-dir",
89+
type=str,
90+
help="Project_dir for the first admin user.",
8491
required=False,
8592
)
8693

@@ -127,10 +134,12 @@ def set_db():
127134

128135

129136
def init_db_data(
137+
*,
130138
resource: str | None = None,
131139
profile: str | None = None,
132140
admin_email: str | None = None,
133141
admin_password: str | None = None,
142+
admin_project_dir: str | None = None,
134143
) -> None:
135144
from fractal_server.app.security import _create_first_user
136145
from fractal_server.app.security import _create_first_group
@@ -147,14 +156,22 @@ def init_db_data(
147156
print()
148157

149158
# Create admin user if requested
150-
if (admin_email is None) != (admin_password is None):
151-
print("You must provide both --admin-email and --admin-pwd. Exit.")
159+
if not (
160+
(admin_email is None)
161+
== (admin_password is None)
162+
== (admin_project_dir is None)
163+
):
164+
print(
165+
"You must provide either or or none of `--admin-email`, "
166+
"`--admin-pwd` and `--admin-project-dir`. Exit."
167+
)
152168
sys.exit(1)
153169
if admin_password and admin_email:
154170
asyncio.run(
155171
_create_first_user(
156172
email=admin_email,
157173
password=admin_password,
174+
project_dir=admin_project_dir,
158175
is_superuser=True,
159176
is_verified=True,
160177
)
@@ -329,6 +346,7 @@ def run():
329346
profile=args.profile,
330347
admin_email=args.admin_email,
331348
admin_password=args.admin_pwd,
349+
admin_project_dir=args.admin_project_dir,
332350
)
333351
elif args.cmd == "update-db-data":
334352
update_db_data()

fractal_server/app/models/security.py

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,17 @@
1-
# This is based on fastapi_users_db_sqlmodel
2-
# <https://github.com/fastapi-users/fastapi-users-db-sqlmodel>
3-
# Original Copyright
4-
# Copyright 2022 François Voron
5-
# License: MIT
6-
#
7-
# Modified by:
8-
# Tommaso Comparin <[email protected]>
9-
#
10-
# Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
11-
# University of Zurich
121
from datetime import datetime
132
from typing import Optional
143

154
from pydantic import ConfigDict
165
from pydantic import EmailStr
176
from sqlalchemy import Column
7+
from sqlalchemy import String
8+
from sqlalchemy.dialects.postgresql import ARRAY
189
from sqlalchemy.dialects.postgresql import JSONB
1910
from sqlalchemy.types import DateTime
2011
from sqlmodel import Field
2112
from sqlmodel import Relationship
2213
from sqlmodel import SQLModel
2314

24-
from .user_settings import UserSettings
2515
from fractal_server.utils import get_timestamp
2616

2717

@@ -74,17 +64,20 @@ class UserOAuth(SQLModel, table=True):
7464
is_superuser:
7565
is_verified:
7666
oauth_accounts:
77-
user_settings_id:
7867
profile_id:
79-
settings:
68+
project_dir:
69+
slurm_accounts:
8070
"""
8171

72+
model_config = ConfigDict(from_attributes=True)
73+
8274
__tablename__ = "user_oauth"
8375

8476
id: int | None = Field(default=None, primary_key=True)
8577

8678
email: EmailStr = Field(
87-
sa_column_kwargs={"unique": True, "index": True}, nullable=False
79+
sa_column_kwargs={"unique": True, "index": True},
80+
nullable=False,
8881
)
8982
hashed_password: str
9083
is_active: bool = Field(default=True, nullable=False)
@@ -96,18 +89,23 @@ class UserOAuth(SQLModel, table=True):
9689
sa_relationship_kwargs={"lazy": "joined", "cascade": "all, delete"},
9790
)
9891

99-
user_settings_id: int | None = Field(
100-
foreign_key="user_settings.id", default=None
101-
)
10292
profile_id: int | None = Field(
10393
foreign_key="profile.id",
10494
default=None,
10595
ondelete="SET NULL",
10696
)
107-
settings: UserSettings | None = Relationship(
108-
sa_relationship_kwargs=dict(lazy="selectin", cascade="all, delete")
97+
98+
# TODO-2.17.1: update to `project_dir: str`
99+
project_dir: str = Field(
100+
sa_column=Column(
101+
String,
102+
server_default="/PLACEHOLDER",
103+
nullable=False,
104+
)
105+
)
106+
slurm_accounts: list[str] = Field(
107+
sa_column=Column(ARRAY(String), server_default="{}"),
109108
)
110-
model_config = ConfigDict(from_attributes=True)
111109

112110

113111
class UserGroup(SQLModel, table=True):

fractal_server/app/models/user_settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from sqlmodel import SQLModel
55

66

7+
# TODO-2.17.1: Drop `UserSettings`
78
class UserSettings(SQLModel, table=True):
89
"""
910
Comprehensive list of user settings.

fractal_server/app/routes/admin/v2/accounting.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from fractal_server.app.models import UserOAuth
1414
from fractal_server.app.models.v2 import AccountingRecord
1515
from fractal_server.app.models.v2 import AccountingRecordSlurm
16-
from fractal_server.app.routes.auth import current_active_superuser
16+
from fractal_server.app.routes.auth import current_superuser_act
1717
from fractal_server.app.routes.pagination import get_pagination_params
1818
from fractal_server.app.routes.pagination import PaginationRequest
1919
from fractal_server.app.routes.pagination import PaginationResponse
@@ -34,7 +34,7 @@ async def query_accounting(
3434
query: AccountingQuery,
3535
# Dependencies
3636
pagination: PaginationRequest = Depends(get_pagination_params),
37-
superuser: UserOAuth = Depends(current_active_superuser),
37+
superuser: UserOAuth = Depends(current_superuser_act),
3838
db: AsyncSession = Depends(get_async_db),
3939
) -> PaginationResponse[AccountingRecordRead]:
4040
page = pagination.page
@@ -79,7 +79,7 @@ async def query_accounting(
7979
async def query_accounting_slurm(
8080
query: AccountingQuery,
8181
# dependencies
82-
superuser: UserOAuth = Depends(current_active_superuser),
82+
superuser: UserOAuth = Depends(current_superuser_act),
8383
db: AsyncSession = Depends(get_async_db),
8484
) -> JSONResponse:
8585
stm = select(AccountingRecordSlurm.slurm_job_ids)

fractal_server/app/routes/admin/v2/impersonate.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from fractal_server.app.db import AsyncSession
77
from fractal_server.app.db import get_async_db
88
from fractal_server.app.models import UserOAuth
9-
from fractal_server.app.routes.auth import current_active_superuser
9+
from fractal_server.app.routes.auth import current_superuser_act
1010
from fractal_server.app.routes.auth._aux_auth import _user_or_404
1111
from fractal_server.config import get_settings
1212
from fractal_server.syringe import Inject
@@ -17,7 +17,7 @@
1717
@router.get("/{user_id}/")
1818
async def impersonate_user(
1919
user_id: int,
20-
superuser: UserOAuth = Depends(current_active_superuser),
20+
superuser: UserOAuth = Depends(current_superuser_act),
2121
db: AsyncSession = Depends(get_async_db),
2222
) -> JSONResponse:
2323
user = await _user_or_404(user_id, db)

0 commit comments

Comments
 (0)