wip: initiate user creation

This commit is contained in:
swve 2023-10-28 19:36:58 +02:00
parent afaf1d6dfe
commit 732b14866c
10 changed files with 126 additions and 11 deletions

View file

@ -1,7 +1,7 @@
from fastapi import FastAPI, Request from fastapi import FastAPI, Request
from config.config import LearnHouseConfig, get_learnhouse_config from config.config import LearnHouseConfig, get_learnhouse_config
from src.core.events.events import shutdown_app, startup_app from src.core.events.events import shutdown_app, startup_app
from src.router import v1_router from src.router import v1_router, rewrite
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
@ -60,6 +60,7 @@ app.mount("/content", StaticFiles(directory="content"), name="content")
# Global Routes # Global Routes
app.include_router(v1_router) app.include_router(v1_router)
app.include_router(rewrite)
# General Routes # General Routes
@app.get("/") @app.get("/")

View file

@ -1,8 +1,10 @@
fastapi==0.101.1 fastapi==0.101.1
pydantic>=1.8.0,<2.0.0 pydantic>=1.8.0,<2.0.0
sqlmodel==0.0.10
uvicorn==0.23.2 uvicorn==0.23.2
pymongo==4.3.3 pymongo==4.3.3
motor==3.1.1 motor==3.1.1
psycopg2
python-multipart python-multipart
boto3 boto3
botocore botocore

View file

@ -1,20 +1,28 @@
import logging import logging
from fastapi import FastAPI from fastapi import FastAPI
import motor.motor_asyncio import motor.motor_asyncio
from sqlmodel import Field, SQLModel, Session, create_engine
from src.rewrite.services.db import users
engine = create_engine('postgresql://learnhouse:learnhouse@db:5432/learnhouse', echo=True)
SQLModel.metadata.create_all(engine)
async def connect_to_db(app: FastAPI): async def connect_to_db(app: FastAPI):
logging.info("Connecting to database...") app.db_engine = engine # type: ignore
try: logging.info("LearnHouse database has been started.")
app.mongodb_client = motor.motor_asyncio.AsyncIOMotorClient( # type: ignore
app.learnhouse_config.database_config.mongodb_connection_string) # type: ignore
app.db = app.mongodb_client["learnhouse"] # type: ignore
logging.info("Connected to database!")
except Exception as e:
logging.error("Failed to connect to database!")
logging.error(e)
SQLModel.metadata.create_all(engine)
# mongodb
app.mongodb_client = motor.motor_asyncio.AsyncIOMotorClient( # type: ignore
app.learnhouse_config.database_config.mongodb_connection_string) # type: ignore
app.db = app.mongodb_client["learnhouse"] # type: ignore
def get_db_session():
with Session(engine) as session:
yield session
async def close_database(app: FastAPI): async def close_database(app: FastAPI):
app.mongodb_client.close() # type: ignore app.mongodb_client.close() # type: ignore
logging.info("LearnHouse has been shut down.") logging.info("LearnHouse has been shut down.")

View file

View file

@ -0,0 +1,23 @@
from fastapi import APIRouter, Depends, Request
from sqlmodel import Session
from src.core.events.database import get_db_session
from src.rewrite.services.db.users import UserCreate, UserRead
from src.rewrite.services.users.users import create_user
router = APIRouter()
@router.post("/", response_model=UserRead, tags=["users"])
async def api_create_user(
*,
request: Request,
db_session: Session = Depends(get_db_session),
user_object: UserCreate,
org_slug: str
):
"""
Create new user
"""
return await create_user(request, db_session, None, user_object, org_slug)

View file

@ -0,0 +1,32 @@
from typing import Optional
from sqlmodel import Field, Session, SQLModel, create_engine, select
class UserBase(SQLModel):
username: str
first_name: str
last_name: str
email: str
avatar_image: Optional[str] = ""
bio: Optional[str] = ""
class UserCreate(UserBase):
password: str
class UserUpdate(UserBase):
password: Optional[str] = None
class UserRead(UserBase):
id: int
class User(UserBase, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
password: str = ""
user_uuid: str = ""
email_verified: bool = False
creation_date: str = ""
update_date: str = ""

View file

@ -0,0 +1,43 @@
from datetime import datetime
from uuid import uuid4
from fastapi import Depends, Request
from sqlmodel import Session
from src.rewrite.services.db.users import User, UserCreate
from src.security.security import security_hash_password
from src.services.users.schemas.users import PublicUser
async def create_user(
request: Request,
db_session: Session,
current_user: PublicUser | None,
user_object: UserCreate,
org_slug: str,
):
user = User.from_orm(user_object)
# Complete the user object
user.user_uuid = f"user_{uuid4()}"
user.password = await security_hash_password(user_object.password)
user.email_verified = False
user.creation_date = str(datetime.now())
user.update_date = str(datetime.now())
# Verifications
#todo: add username uniqueness verification
#todo: add email uniqueness verification
#todo: add user to org as member if org is not None
# Exclude unset values
user_data = user.dict(exclude_unset=True)
for key, value in user_data.items():
setattr(user, key, value)
# Add user to database
db_session.add(user)
db_session.commit()
db_session.refresh(user)
return user

View file

@ -1,5 +1,7 @@
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from src import rewrite
from src.routers import blocks, dev, trail, users, auth, orgs, roles from src.routers import blocks, dev, trail, users, auth, orgs, roles
from src.rewrite.routers import users as rw_users
from src.routers.courses import chapters, collections, courses, activities from src.routers.courses import chapters, collections, courses, activities
from src.routers.install import install from src.routers.install import install
from src.services.dev.dev import isDevModeEnabledOrRaise from src.services.dev.dev import isDevModeEnabledOrRaise
@ -7,6 +9,7 @@ from src.services.install.install import isInstallModeEnabled
v1_router = APIRouter(prefix="/api/v1") v1_router = APIRouter(prefix="/api/v1")
rewrite = APIRouter(prefix="/api/rewrite")
# API Routes # API Routes
@ -35,3 +38,6 @@ v1_router.include_router(
tags=["install"], tags=["install"],
dependencies=[Depends(isInstallModeEnabled)], dependencies=[Depends(isInstallModeEnabled)],
) )
# Rewrite Routes
rewrite.include_router(rw_users.router, prefix="/users", tags=["users"])

View file

@ -8,7 +8,7 @@ services:
- .:/usr/learnhouse - .:/usr/learnhouse
environment: environment:
- LEARNHOUSE_COOKIE_DOMAIN=.localhost - LEARNHOUSE_COOKIE_DOMAIN=.localhost
postgresql: db:
image: postgres:16-alpine image: postgres:16-alpine
restart: always restart: always
ports: ports: