Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: adds creation of user account and user profile through migrat… #197

Merged
merged 2 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 55 additions & 4 deletions backendAPI/src/core/databases.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
from sqlalchemy.orm import sessionmaker
from sqlmodel import create_engine
from sqlmodel.ext.asyncio.session import AsyncSession

from core.config import config
from sqlmodel import select
from models.identity import User, UserAccount, UserProfile
from models.access import IdentifierTypeLink, IdentityType

# from sqlmodel import SQLmodel # noqa: F401

Expand All @@ -20,8 +21,58 @@ async def get_async_session() -> AsyncSession:
return async_session()


engine = create_engine(config.POSTGRES_URL.unicode_string())
SynchronSession = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# Run extraordinary migrations:
# Comment when propagated all the way into production!
async def run_migrations():
session = await get_async_session()
# async with get_async_session() as session:
response = await session.exec(select(User))
users = response.unique().fetchall()
for user in users:
# # The settings in user account and user profile cannot be changed, before the user is created.
try:
query = select(UserAccount, UserProfile).where(
UserAccount.user_id == user.id, UserProfile.user_id == user.id
)
response = await session.exec(query)
existing_account_and_profile = response.unique().fetchall()
print("=== existing_account_and_profile ===")
print(existing_account_and_profile)
if not existing_account_and_profile:
print("== no account or profile found - trying to generate it ===")
user_account = UserAccount(user_id=user.id)
user_profile = UserProfile(user_id=user.id)
account_type_link = IdentifierTypeLink(
id=user_account.id, type=IdentityType.user_account
)
profile_type_link = IdentifierTypeLink(
id=user_profile.id, type=IdentityType.user_profile
)
user_account = UserAccount.model_validate(user_account)
user_profile = UserProfile.model_validate(user_profile)
user.user_account_id = user_account.id
user.user_profile_id = user_profile.id

session.add(user_account)
session.add(user_profile)
session.add(account_type_link)
session.add(profile_type_link)
session.add(user)
await session.commit()
await session.refresh(user_account)
await session.refresh(user_profile)
await session.refresh(account_type_link)
await session.refresh(profile_type_link)
await session.refresh(user)
except Exception as error:
print("Error in run_migrations:")
print(error)
await session.rollback()
await session.close()


# engine = create_engine(config.POSTGRES_URL.unicode_string())
# SynchronSession = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# # This is handled by __aenter__ and __aexit__ in BaseCRUD
# # in case a session is required elsewhere, use this function!
Expand Down
4 changes: 2 additions & 2 deletions backendAPI/src/crud/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,10 @@ async def create_azure_user_and_groups_if_not_exist(
session.add(user_profile)
# session.add(database_user)
await session.commit()
# await session.refresh(user_account)
await session.refresh(user_account)
await session.refresh(user_profile)

# database_user.user_account_id = user_account.id
database_user.user_account_id = user_account.id
database_user.user_profile_id = user_profile.id
session.add(database_user)
await session.commit()
Expand Down
3 changes: 3 additions & 0 deletions backendAPI/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
from fastapi.exception_handlers import http_exception_handler
from fastapi.middleware.cors import CORSMiddleware
from socketio import ASGIApp
import asyncio

from core.databases import run_migrations
from core.config import config
from core.security import CurrentAccessTokenHasRole, CurrentAccessTokenHasScope
from routers.api.v1.access import router as access_router
Expand Down Expand Up @@ -48,6 +50,7 @@ async def lifespan(app: FastAPI):
# configure_logging()# TBD: add logging configuration
# Don't do that: use Sessions instead!
# await postgres.connect()
asyncio.create_task(run_migrations())
yield # this is where the FastAPI runs - when its done, it comes back here and closes down
# await postgres.disconnect()
logger.info("Application shutdown")
Expand Down
5 changes: 5 additions & 0 deletions backendAPI/src/models/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ class UserCreate(SQLModel):
class User(UserCreate, table=True):
"""Schema for a user in the database."""

# Rules of thumb:
# - if other users are supposed to see it, it should be in the user model.
# - if the user never sees it in the user interface, it should be in the user account.
# - if the user sees it in the user interface, it should be in the user profile.

id: Optional[uuid.UUID] = Field(
default_factory=uuid.uuid4,
foreign_key="identifiertypelink.id",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { PageServerLoad } from './$types';
import { microsoftGraph, type MicrosoftTeamBasic } from '$lib/server/apis';
import { microsoftGraph} from '$lib/server/apis';
import type { MicrosoftTeamBasic } from '$lib/types';
// const getAllMicrosoftTeams = async (sessionId: string, azureGroups: string[]) => {

// }
Expand Down Expand Up @@ -44,10 +45,10 @@ export const load: PageServerLoad = async ({ locals }) => {
);
}

console.log(
'=== src - routes - %28layout%29 - %28protected%29 - protected - identities - %2Bpage.server.ts - myTeams ==='
);
console.log(myTeams);
// console.log(
// '=== src - routes - %28layout%29 - %28protected%29 - protected - identities - %2Bpage.server.ts - myTeams ==='
// );
// console.log(myTeams);

return {
microsoftTeams: myTeams
Expand Down