feat: init install + cleanup code

This commit is contained in:
swve 2023-11-20 22:38:49 +01:00
parent 2485285a06
commit 38288e8a57
28 changed files with 310 additions and 583 deletions

View file

@ -1,23 +1,8 @@
import logging
from fastapi import FastAPI
import motor.motor_asyncio
from sqlmodel import Field, SQLModel, Session, create_engine
from sqlmodel import SQLModel, Session, create_engine
from src.db import (
user_organizations,
users,
roles,
organization_settings,
organizations,
courses,
course_authors,
chapters,
activities,
course_chapters,
chapter_activities,
collections,
blocks,
)
engine = create_engine(
"postgresql://learnhouse:learnhouse@db:5432/learnhouse", echo=True

View file

@ -1,7 +1,6 @@
from typing import Literal, Optional
from click import Option
from typing import Optional
from sqlalchemy import JSON, Column
from sqlmodel import Field, Session, SQLModel, create_engine, select
from sqlmodel import Field, SQLModel
from enum import Enum

View file

@ -1,6 +1,5 @@
from typing import Optional
from sqlmodel import Field, SQLModel
from enum import Enum
class ChapterActivity(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)

View file

@ -1,7 +1,7 @@
from typing import List, Optional
from pydantic import BaseModel
from sqlmodel import Field, SQLModel
from src.db.activities import Activity, ActivityRead, ActivityUpdate
from src.db.activities import ActivityRead
class ChapterBase(SQLModel):

View file

@ -1,6 +1,5 @@
from typing import Optional
from sqlmodel import Field, SQLModel
from enum import Enum
class CourseChapter(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)

View file

@ -0,0 +1,31 @@
from typing import Optional
from sqlalchemy import JSON, Column
from sqlmodel import Field, SQLModel
class InstallBase(SQLModel):
step: int = Field(default=0)
data: dict = Field(default={}, sa_column=Column(JSON))
class Install(InstallBase, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
install_uuid: str = Field(default=None)
creation_date: str = ""
update_date: str = ""
class InstallCreate(InstallBase):
pass
class InstallUpdate(InstallBase):
pass
class InstallRead(InstallBase):
id: Optional[int] = Field(default=None, primary_key=True)
install_uuid: str = Field(default=None)
creation_date: str
update_date: str
pass

View file

@ -1,19 +1,46 @@
from enum import Enum
from typing import Optional
from typing import Optional, Union
from pydantic import BaseModel
from sqlalchemy import JSON, Column
from sqlmodel import Field, SQLModel
# Rights
class Permission(BaseModel):
action_create: bool
action_read: bool
action_update: bool
action_delete: bool
def __getitem__(self, item):
return getattr(self, item)
class Rights(BaseModel):
courses: Permission
users: Permission
collections: Permission
organizations: Permission
coursechapters: Permission
activities: Permission
def __getitem__(self, item):
return getattr(self, item)
# Database Models
class RoleTypeEnum(str, Enum):
TYPE_ORGANIZATION = "TYPE_ORGANIZATION"
TYPE_ORGANIZATION_API_TOKEN = "TYPE_ORGANIZATION_API_TOKEN"
TYPE_GLOBAL = "TYPE_GLOBAL"
TYPE_ORGANIZATION = "TYPE_ORGANIZATION" # Organization roles are associated with an organization, they are used to define the rights of a user in an organization
TYPE_ORGANIZATION_API_TOKEN = "TYPE_ORGANIZATION_API_TOKEN" # Organization API Token roles are associated with an organization, they are used to define the rights of an API Token in an organization
TYPE_GLOBAL = "TYPE_GLOBAL" # Global roles are not associated with an organization, they are used to define the default rights of a user
class RoleBase(SQLModel):
name: str
description: Optional[str]
rights: dict = Field(default={}, sa_column=Column(JSON))
rights: Optional[Union[Rights,dict]] = Field(default={}, sa_column=Column(JSON))
class Role(RoleBase, table=True):
@ -26,11 +53,12 @@ class Role(RoleBase, table=True):
class RoleCreate(RoleBase):
org_id: int = Field(default=None, foreign_key="organization.id")
org_id: Optional[int] = Field(default=None, foreign_key="organization.id")
class RoleUpdate(SQLModel):
role_id: int = Field(default=None, foreign_key="role.id")
name: Optional[str]
description: Optional[str]
rights: Optional[dict] = Field(default={}, sa_column=Column(JSON))
rights: Optional[Union[Rights,dict]] = Field(default={}, sa_column=Column(JSON))

View file

@ -1,10 +1,8 @@
from typing import Optional
from pydantic import BaseModel
from sqlmodel import Field, SQLModel
from enum import Enum
from src.db.trail_runs import TrailRun, TrailRunRead
from src.db.trail_runs import TrailRunRead
from src.db.trail_steps import TrailStep
class TrailBase(SQLModel):

View file

@ -5,7 +5,6 @@ from src.db.users import UserRead
from src.core.events.database import get_db_session
from config.config import get_learnhouse_config
from src.security.auth import AuthJWT, authenticate_user
from src.services.users.users import PublicUser
router = APIRouter()

View file

@ -3,7 +3,6 @@ from src.db.activities import ActivityCreate, ActivityUpdate
from src.db.users import PublicUser
from src.core.events.database import get_db_session
from src.services.courses.activities.activities import (
Activity,
create_activity,
get_activity,
get_activities,

View file

@ -4,7 +4,6 @@ from src.db.collections import CollectionCreate, CollectionUpdate
from src.security.auth import get_current_user
from src.services.users.users import PublicUser
from src.services.courses.collections import (
Collection,
create_collection,
get_collection,
get_collections,

View file

@ -2,7 +2,7 @@ from fastapi import APIRouter, Depends, UploadFile, Form, Request
from sqlmodel import Session
from src.core.events.database import get_db_session
from src.db.users import PublicUser
from src.db.courses import Course, CourseCreate, CourseUpdate
from src.db.courses import CourseCreate, CourseUpdate
from src.security.auth import get_current_user
from src.services.courses.courses import (

View file

@ -1,6 +1,5 @@
from fastapi import APIRouter, Request
from fastapi import APIRouter
from config.config import get_learnhouse_config
from src.services.dev.mocks.initial import create_initial_data
router = APIRouter()
@ -10,9 +9,3 @@ router = APIRouter()
async def config():
config = get_learnhouse_config()
return config.dict()
@router.get("/mock/initial")
async def initial_data(request: Request):
await create_initial_data(request)
return {"Message": "Initial data created 🤖"}

View file

@ -1,70 +1,71 @@
from fastapi import APIRouter, Request
from fastapi import APIRouter, Depends, Request
from src.core.events.database import get_db_session
from src.db.organizations import OrganizationCreate
from src.db.users import UserCreate
from src.services.install.install import (
create_install_instance,
create_sample_data,
get_latest_install_instance,
install_create_organization,
install_create_organization_user,
install_default_elements,
update_install_instance,
)
from src.services.orgs.schemas.orgs import Organization
from src.services.users.schemas.users import UserWithPassword
router = APIRouter()
@router.post("/start")
async def api_create_install_instance(request: Request, data: dict):
async def api_create_install_instance(
request: Request, data: dict, db_session=Depends(get_db_session),
):
# create install
install = await create_install_instance(request, data)
install = await create_install_instance(request, data, db_session)
return install
@router.get("/latest")
async def api_get_latest_install_instance(request: Request):
async def api_get_latest_install_instance(request: Request, db_session=Depends(get_db_session),):
# get latest created install
install = await get_latest_install_instance(request)
install = await get_latest_install_instance(request, db_session=db_session)
return install
@router.post("/default_elements")
async def api_install_def_elements(request: Request):
elements = await install_default_elements(request, {})
async def api_install_def_elements(request: Request, db_session=Depends(get_db_session),):
elements = await install_default_elements(request, {}, db_session)
return elements
@router.post("/org")
async def api_install_org(request: Request, org: Organization):
organization = await install_create_organization(request, org)
async def api_install_org(
request: Request, org: OrganizationCreate, db_session=Depends(get_db_session),
):
organization = await install_create_organization(request, org, db_session)
return organization
@router.post("/user")
async def api_install_user(request: Request, data: UserWithPassword, org_slug: str):
user = await install_create_organization_user(request, data, org_slug)
async def api_install_user(
request: Request, data: UserCreate, org_slug: str, db_session=Depends(get_db_session),
):
user = await install_create_organization_user(request, data, org_slug, db_session)
return user
@router.post("/sample")
async def api_install_user_sample(request: Request, username: str, org_slug: str):
sample = await create_sample_data(org_slug, username, request)
return sample
@router.post("/update")
async def api_update_install_instance(request: Request, data: dict, step: int):
async def api_update_install_instance(
request: Request, data: dict, step: int, db_session=Depends(get_db_session),
):
request.app.db["installs"]
# get latest created install
install = await update_install_instance(request, data, step)
install = await update_install_instance(request, data, step, db_session)
return install

View file

@ -3,7 +3,6 @@ from sqlmodel import Session
from src.core.events.database import get_db_session
from src.db.roles import RoleCreate, RoleUpdate
from src.security.auth import get_current_user
from src.services.roles.schemas.roles import Role
from src.services.roles.roles import create_role, delete_role, read_role, update_role
from src.services.users.schemas.users import PublicUser

View file

@ -1,19 +1,9 @@
import stat
from typing import Literal
from pydantic import BaseModel
from sqlmodel import Session, select
from src.db.chapters import Chapter
from src.db.organizations import Organization
from src import db
from src.db.activities import ActivityCreate, Activity, ActivityRead, ActivityUpdate
from src.db.chapter_activities import ChapterActivity
from src.security.rbac.rbac import (
authorization_verify_based_on_roles,
authorization_verify_if_element_is_public,
authorization_verify_if_user_is_anon,
)
from src.db.users import AnonymousUser, PublicUser
from fastapi import HTTPException, status, Request
from src.db.users import PublicUser
from fastapi import HTTPException, Request
from uuid import uuid4
from datetime import datetime

View file

@ -9,7 +9,6 @@ from src.db.activities import (
from src.db.chapter_activities import ChapterActivity
from src.db.course_chapters import CourseChapter
from src.db.users import PublicUser
from src.security.rbac.rbac import authorization_verify_based_on_roles
from src.services.courses.activities.uploads.pdfs import upload_pdf
from fastapi import HTTPException, status, UploadFile, Request
from uuid import uuid4

View file

@ -7,9 +7,6 @@ from src.db.activities import Activity, ActivityRead, ActivitySubTypeEnum, Activ
from src.db.chapter_activities import ChapterActivity
from src.db.course_chapters import CourseChapter
from src.db.users import PublicUser
from src.security.rbac.rbac import (
authorization_verify_based_on_roles,
)
from src.services.courses.activities.uploads.videos import upload_video
from fastapi import HTTPException, status, UploadFile, Request
from uuid import uuid4

View file

@ -2,7 +2,6 @@ from datetime import datetime
from typing import List
from uuid import uuid4
from sqlmodel import Session, select
from src import db
from src.db.course_chapters import CourseChapter
from src.db.activities import Activity, ActivityRead
from src.db.chapter_activities import ChapterActivity
@ -14,13 +13,6 @@ from src.db.chapters import (
ChapterUpdateOrder,
DepreceatedChaptersRead,
)
from src.security.auth import non_public_endpoint
from src.security.rbac.rbac import (
authorization_verify_based_on_roles,
authorization_verify_based_on_roles_and_authorship,
authorization_verify_if_element_is_public,
authorization_verify_if_user_is_anon,
)
from src.services.courses.courses import Course
from src.services.users.users import PublicUser
from fastapi import HTTPException, status, Request

View file

@ -1,8 +1,6 @@
from datetime import datetime
from gc import collect
from typing import List, Literal
from typing import List
from uuid import uuid4
from pydantic import BaseModel
from sqlmodel import Session, select
from src.db.collections import (
Collection,
@ -12,10 +10,6 @@ from src.db.collections import (
)
from src.db.collections_courses import CollectionCourse
from src.db.courses import Course
from src.security.rbac.rbac import (
authorization_verify_based_on_roles_and_authorship,
authorization_verify_if_user_is_anon,
)
from src.services.users.users import PublicUser
from fastapi import HTTPException, status, Request
from typing import List

View file

@ -1,13 +1,11 @@
import json
from typing import List, Literal, Optional
from typing import Literal
from uuid import uuid4
from pydantic import BaseModel
from sqlmodel import Session, select
from src.db.course_authors import CourseAuthor, CourseAuthorshipEnum
from src.db.users import PublicUser, AnonymousUser
from src.db.courses import Course, CourseCreate, CourseRead, CourseUpdate
from src.security.rbac.rbac import (
authorization_verify_based_on_roles,
authorization_verify_based_on_roles_and_authorship,
authorization_verify_if_element_is_public,
authorization_verify_if_user_is_anon,

View file

@ -1,213 +0,0 @@
import os
import requests
from datetime import datetime
from uuid import uuid4
from fastapi import Request
from src.services.users.schemas.users import UserInDB
from src.security.security import security_hash_password
from src.services.courses.activities.activities import Activity, create_activity
from src.services.users.users import PublicUser
from src.services.orgs.orgs import Organization, create_org
from src.services.roles.schemas.roles import Permission, Elements, RoleInDB
from faker import Faker
async def create_initial_data(request: Request):
fake = Faker(['en_US'])
fake_multilang = Faker(
['en_US', 'de_DE', 'ja_JP', 'es_ES', 'it_IT', 'pt_BR', 'ar_PS'])
# Create users
########################################
database_users = request.app.db["users"]
await database_users.delete_many({})
users = []
admin_user = UserInDB(
user_id="user_admin",
creation_date=str(datetime.now()),
update_date=str(datetime.now()),
roles= [],
orgs=[],
username="admin",
email="admin@admin.admin",
password=str(await security_hash_password("admin")),
)
await database_users.insert_one(admin_user.dict())
# find admin user
users = request.app.db["users"]
admin_user = await users.find_one({"username": "admin"})
if admin_user:
admin_user = UserInDB(**admin_user)
current_user = PublicUser(**admin_user.dict())
else:
raise Exception("Admin user not found")
# Create roles
########################################
database_roles = request.app.db["roles"]
await database_roles.delete_many({})
roles = []
admin_role = RoleInDB(
name="Admin",
description="Admin",
elements=Elements(
courses=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
users=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
houses=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
collections=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
organizations=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
coursechapters=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
activities=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
),
org_id="org_test",
role_id="role_admin",
created_at=str(datetime.now()),
updated_at=str(datetime.now()),
)
roles.append(admin_role)
for role in roles:
database_roles.insert_one(role.dict())
# Create organizations
########################################
database_orgs = request.app.db["organizations"]
await database_orgs.delete_many({})
organizations = []
for i in range(0, 2):
company = fake.company()
# remove whitespace and special characters and make lowercase
slug = ''.join(e for e in company if e.isalnum()).lower()
# org = Organization(
# name=company,
# description=fake.unique.text(),
# email=fake.unique.email(),
# slug=slug,
# logo="",
# default=False
# )
# organizations.append(org)
# await create_org(request, org, current_user)
# Generate Courses and CourseChapters
########################################
database_courses = request.app.db["courses"]
await database_courses.delete_many({})
courses = []
orgs = request.app.db["organizations"]
if await orgs.count_documents({}) > 0:
for org in await orgs.find().to_list(length=100):
for i in range(0, 5):
# get image in BinaryIO format from unsplash and save it to disk
image = requests.get(
"https://source.unsplash.com/random/800x600")
with open("thumbnail.jpg", "wb") as f:
f.write(image.content)
course_id = f"course_{uuid4()}"
# course = CourseInDB(
# name=fake_multilang.unique.sentence(),
# description=fake_multilang.unique.text(),
# mini_description=fake_multilang.unique.text(),
# thumbnail="thumbnail",
# org_id=org['org_id'],
# learnings=[fake_multilang.unique.sentence()
# for i in range(0, 5)],
# public=True,
# chapters=[],
# course_id=course_id,
# creationDate=str(datetime.now()),
# updateDate=str(datetime.now()),
# authors=[current_user.user_id],
# chapters_content=[],
# )
courses = request.app.db["courses"]
name_in_disk = f"test_mock{course_id}.jpeg"
image = requests.get(
"https://source.unsplash.com/random/800x600/?img=1")
# check if folder exists and create it if not
if not os.path.exists("content/uploads/img"):
os.makedirs("content/uploads/img")
with open(f"content/uploads/img/{name_in_disk}", "wb") as f:
f.write(image.content)
# course.thumbnail = name_in_disk
# course = CourseInDB(**course.dict())
# await courses.insert_one(course.dict())
# create chapters
# for i in range(0, 5):
# coursechapter = CourseChapter(
# name=fake_multilang.unique.sentence(),
# description=fake_multilang.unique.text(),
# activities=[],
# )
# coursechapter = await create_coursechapter(request,coursechapter, course_id, current_user)
# if coursechapter:
# # create activities
# for i in range(0, 5):
# activity = Activity(
# name=fake_multilang.unique.sentence(),
# type="dynamic",
# content={},
# )
# activity = await create_activity(request,activity, "org_test", coursechapter['coursechapter_id'], current_user)

View file

@ -1,33 +1,15 @@
from datetime import datetime
from uuid import uuid4
from fastapi import HTTPException, Request, status
from pydantic import BaseModel
import requests
from fastapi import HTTPException, Request
from sqlalchemy import desc
from sqlmodel import Session, select
from src.db.install import Install
from src.db.organizations import Organization, OrganizationCreate
from src.db.roles import Permission, Rights, Role, RoleTypeEnum
from src.db.user_organizations import UserOrganization
from src.db.users import User, UserCreate, UserRead
from config.config import get_learnhouse_config
from src.security.security import security_hash_password
from src.services.courses.activities.activities import Activity, create_activity
from src.services.orgs.schemas.orgs import Organization, OrganizationInDB
from faker import Faker
from src.services.roles.schemas.roles import Elements, Permission, RoleInDB
from src.services.users.schemas.users import (
PublicUser,
User,
UserInDB,
UserOrganization,
UserRolesInOrganization,
UserWithPassword,
)
class InstallInstance(BaseModel):
install_id: str
created_date: str
updated_date: str
step: int
data: dict
async def isInstallModeEnabled():
@ -42,37 +24,29 @@ async def isInstallModeEnabled():
)
async def create_install_instance(request: Request, data: dict):
installs = request.app.db["installs"]
async def create_install_instance(request: Request, data: dict, db_session: Session):
install = Install.from_orm(data)
# get install_id
install_id = str(f"install_{uuid4()}")
created_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
updated_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
step = 1
# complete install instance
install.install_uuid = str(f"install_{uuid4()}")
install.update_date = str(datetime.now())
install.creation_date = str(datetime.now())
# create install
install = InstallInstance(
install_id=install_id,
created_date=created_date,
updated_date=updated_date,
step=step,
data=data,
)
# insert install instance
db_session.add(install)
# insert install
installs.insert_one(install.dict())
# commit changes
db_session.commit()
# refresh install instance
db_session.refresh(install)
return install
async def get_latest_install_instance(request: Request):
installs = request.app.db["installs"]
# get latest created install instance using find_one
install = await installs.find_one(
sort=[("created_date", -1)], limit=1, projection={"_id": 0}
)
async def get_latest_install_instance(request: Request, db_session: Session):
statement = select(Install).order_by(desc(Install.creation_date)).limit(1)
install = db_session.exec(statement).first()
if install is None:
raise HTTPException(
@ -80,35 +54,29 @@ async def get_latest_install_instance(request: Request):
detail="No install instance found",
)
else:
install = InstallInstance(**install)
return install
async def update_install_instance(request: Request, data: dict, step: int):
installs = request.app.db["installs"]
# get latest created install
install = await installs.find_one(
sort=[("created_date", -1)], limit=1, projection={"_id": 0}
)
async def update_install_instance(
request: Request, data: dict, step: int, db_session: Session
):
statement = select(Install).order_by(desc(Install.creation_date)).limit(1)
install = db_session.exec(statement).first()
if install is None:
return None
else:
# update install
install["data"] = data
install["step"] = step
install["updated_date"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# update install
await installs.update_one(
{"install_id": install["install_id"]}, {"$set": install}
raise HTTPException(
status_code=404,
detail="No install instance found",
)
install = InstallInstance(**install)
install.step = step
install.data = data
# commit changes
db_session.commit()
# refresh install instance
db_session.refresh(install)
return install
@ -119,24 +87,34 @@ async def update_install_instance(request: Request, data: dict, step: int):
# Install Default roles
async def install_default_elements(request: Request, data: dict):
roles = request.app.db["roles"]
async def install_default_elements(request: Request, data: dict, db_session: Session):
# remove all default roles
statement = select(Role).where(Role.role_type == RoleTypeEnum.TYPE_GLOBAL)
roles = db_session.exec(statement).all()
# check if default roles ADMIN_ROLE and USER_ROLE already exist
admin_role = await roles.find_one({"role_id": "role_admin"})
user_role = await roles.find_one({"role_id": "role_member"})
for role in roles:
db_session.delete(role)
if admin_role is not None or user_role is not None:
db_session.commit()
# Check if default roles already exist
statement = select(Role).where(Role.role_type == RoleTypeEnum.TYPE_GLOBAL)
roles = db_session.exec(statement).all()
if roles and len(roles) == 3:
raise HTTPException(
status_code=400,
status_code=409,
detail="Default roles already exist",
)
# get default roles
ADMIN_ROLE = RoleInDB(
name="Admin Role",
description="This role grants all permissions to the user",
elements=Elements(
# Create default roles
role_global_admin = Role(
name="Admin",
description="Standard Admin Role",
id=1,
role_type=RoleTypeEnum.TYPE_GLOBAL,
role_uuid="role_global_admin",
rights=Rights(
courses=Permission(
action_create=True,
action_read=True,
@ -149,12 +127,6 @@ async def install_default_elements(request: Request, data: dict):
action_update=True,
action_delete=True,
),
houses=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
collections=Permission(
action_create=True,
action_read=True,
@ -180,16 +152,65 @@ async def install_default_elements(request: Request, data: dict):
action_delete=True,
),
),
org_id="*",
role_id="role_admin",
created_at=str(datetime.now()),
updated_at=str(datetime.now()),
creation_date=str(datetime.now()),
update_date=str(datetime.now()),
)
USER_ROLE = RoleInDB(
name="Member Role",
description="This role grants read-only permissions to the user",
elements=Elements(
role_global_maintainer = Role(
name="Maintainer",
description="Standard Maintainer Role",
id=2,
role_type=RoleTypeEnum.TYPE_GLOBAL,
role_uuid="role_global_maintainer",
rights=Rights(
courses=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
users=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
collections=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
organizations=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
coursechapters=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
activities=Permission(
action_create=True,
action_read=True,
action_update=True,
action_delete=True,
),
),
creation_date=str(datetime.now()),
update_date=str(datetime.now()),
)
role_global_user = Role(
name="User",
description="Standard User Role",
role_type=RoleTypeEnum.TYPE_GLOBAL,
role_uuid="role_global_user",
id=3,
rights=Rights(
courses=Permission(
action_create=False,
action_read=True,
@ -197,13 +218,7 @@ async def install_default_elements(request: Request, data: dict):
action_delete=False,
),
users=Permission(
action_create=False,
action_read=True,
action_update=False,
action_delete=False,
),
houses=Permission(
action_create=False,
action_create=True,
action_read=True,
action_update=False,
action_delete=False,
@ -233,185 +248,122 @@ async def install_default_elements(request: Request, data: dict):
action_delete=False,
),
),
org_id="*",
role_id="role_member",
created_at=str(datetime.now()),
updated_at=str(datetime.now()),
creation_date=str(datetime.now()),
update_date=str(datetime.now()),
)
try:
# insert default roles
await roles.insert_many([USER_ROLE.dict(), ADMIN_ROLE.dict()])
# Serialize rights to JSON
role_global_admin.rights = role_global_admin.rights.dict() # type: ignore
role_global_maintainer.rights = role_global_maintainer.rights.dict() # type: ignore
role_global_user.rights = role_global_user.rights.dict() # type: ignore
# Insert roles in DB
db_session.add(role_global_admin)
db_session.add(role_global_maintainer)
db_session.add(role_global_user)
# commit changes
db_session.commit()
# refresh roles
db_session.refresh(role_global_admin)
return True
except Exception:
raise HTTPException(
status_code=400,
detail="Error while inserting default roles",
)
# Organization creation
async def install_create_organization(
request: Request,
org_object: Organization,
request: Request, org_object: OrganizationCreate, db_session: Session
):
orgs = request.app.db["organizations"]
request.app.db["users"]
org = Organization.from_orm(org_object)
# find if org already exists using name
# Complete the org object
org.org_uuid = f"org_{uuid4()}"
org.creation_date = str(datetime.now())
org.update_date = str(datetime.now())
isOrgAvailable = await orgs.find_one({"slug": org_object.slug.lower()})
db_session.add(org)
db_session.commit()
db_session.refresh(org)
if isOrgAvailable:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="Organization slug already exists",
)
# generate org_id with uuid4
org_id = str(f"org_{uuid4()}")
org = OrganizationInDB(org_id=org_id, **org_object.dict())
org_in_db = await orgs.insert_one(org.dict())
if not org_in_db:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Unavailable database",
)
return org.dict()
return org
async def install_create_organization_user(
request: Request, user_object: UserWithPassword, org_slug: str
request: Request, user_object: UserCreate, org_slug: str, db_session: Session
):
users = request.app.db["users"]
user = User.from_orm(user_object)
isUsernameAvailable = await users.find_one({"username": user_object.username})
isEmailAvailable = await users.find_one({"email": user_object.email})
# 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())
if isUsernameAvailable:
# Verifications
# Check if Organization exists
statement = select(Organization).where(Organization.slug == org_slug)
org = db_session.exec(statement)
if not org.first():
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Username already exists"
status_code=400,
detail="Organization does not exist",
)
if isEmailAvailable:
# Username
statement = select(User).where(User.username == user.username)
result = db_session.exec(statement)
if result.first():
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Email already exists"
status_code=400,
detail="Username already exists",
)
# Generate user_id with uuid4
user_id = str(f"user_{uuid4()}")
# Email
statement = select(User).where(User.email == user.email)
result = db_session.exec(statement)
# Set the username & hash the password
user_object.username = user_object.username.lower()
user_object.password = await security_hash_password(user_object.password)
# Get org_id from org_slug
orgs = request.app.db["organizations"]
# Check if the org exists
isOrgExists = await orgs.find_one({"slug": org_slug})
# If the org does not exist, raise an error
if not isOrgExists:
if result.first():
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="You are trying to create a user in an organization that does not exist",
status_code=400,
detail="Email already exists",
)
org_id = isOrgExists["org_id"]
# Exclude unset values
user_data = user.dict(exclude_unset=True)
for key, value in user_data.items():
setattr(user, key, value)
# Create initial orgs list with the org_id passed in
orgs = [UserOrganization(org_id=org_id, org_role="owner")]
# Add user to database
db_session.add(user)
db_session.commit()
db_session.refresh(user)
# Give role
roles = [UserRolesInOrganization(role_id="role_admin", org_id=org_id)]
# Create the user
user = UserInDB(
user_id=user_id,
# get org id
statement = select(Organization).where(Organization.slug == org_slug)
org = db_session.exec(statement)
org = org.first()
org_id = org.id if org else 0
# Link user and organization
user_organization = UserOrganization(
user_id=user.id if user.id else 0,
org_id=org_id or 0,
role_id=1,
creation_date=str(datetime.now()),
update_date=str(datetime.now()),
orgs=orgs,
roles=roles,
**user_object.dict(),
)
# Insert the user into the database
await users.insert_one(user.dict())
db_session.add(user_organization)
db_session.commit()
db_session.refresh(user_organization)
return User(**user.dict())
user = UserRead.from_orm(user)
async def create_sample_data(org_slug: str, username: str, request: Request):
Faker(["en_US"])
fake_multilang = Faker(
["en_US", "de_DE", "ja_JP", "es_ES", "it_IT", "pt_BR", "ar_PS"]
)
users = request.app.db["users"]
orgs = request.app.db["organizations"]
user = await users.find_one({"username": username})
org = await orgs.find_one({"slug": org_slug.lower()})
user_id = user["user_id"]
org_id = org["org_id"]
current_user = PublicUser(**user)
for i in range(0, 5):
# get image in BinaryIO format from unsplash and save it to disk
image = requests.get("https://source.unsplash.com/random/800x600")
with open("thumbnail.jpg", "wb") as f:
f.write(image.content)
# course_id = f"course_{uuid4()}"
# course = CourseInDB(
# name=fake_multilang.unique.sentence(),
# description=fake_multilang.unique.text(),
# mini_description=fake_multilang.unique.text(),
# thumbnail="thumbnail",
# org_id=org_id,
# learnings=[fake_multilang.unique.sentence() for i in range(0, 5)],
# public=True,
# chapters=[],
# course_id=course_id,
# creationDate=str(datetime.now()),
# updateDate=str(datetime.now()),
# authors=[user_id],
# chapters_content=[],
# )
# courses = request.app.db["courses"]
# course = CourseInDB(**course.dict())
# await courses.insert_one(course.dict())
# # create chapters
# for i in range(0, 5):
# coursechapter = CourseChapter(
# name=fake_multilang.unique.sentence(),
# description=fake_multilang.unique.text(),
# activities=[],
# )
# coursechapter = await create_coursechapter(
# request, coursechapter, course_id, current_user
# )
# if coursechapter:
# # create activities
# for i in range(0, 5):
# activity = Activity(
# name=fake_multilang.unique.sentence(),
# type="dynamic",
# content={},
# )
# activity = await create_activity(
# request,
# activity,
# org_id,
# coursechapter["coursechapter_id"],
# current_user,
# )
return user

View file

@ -1,10 +1,7 @@
from datetime import datetime
import json
from operator import or_
from typing import Literal
from uuid import uuid4
from sqlmodel import Session, select
from src.db.users import UserRead, PublicUser
from src.db.users import PublicUser
from src.db.user_organizations import UserOrganization
from src.db.organizations import (
Organization,
@ -12,10 +9,6 @@ from src.db.organizations import (
OrganizationRead,
OrganizationUpdate,
)
from src.security.rbac.rbac import (
authorization_verify_based_on_roles,
authorization_verify_if_user_is_anon,
)
from src.services.orgs.logos import upload_org_logo
from fastapi import HTTPException, UploadFile, status, Request

View file

@ -1,9 +1,8 @@
from uuid import uuid4
from sqlmodel import Session, select
from src.db.roles import Role, RoleCreate, RoleUpdate
from src.security.rbac.rbac import authorization_verify_if_user_is_anon
from src.services.users.schemas.users import PublicUser
from fastapi import HTTPException, status, Request
from fastapi import HTTPException, Request
from datetime import datetime

View file

@ -1,12 +1,9 @@
from datetime import datetime
import stat
from typing import List, Literal, Optional
from uuid import uuid4
from fastapi import HTTPException, Request, status
from pydantic import BaseModel
from sqlmodel import Session, select
from src.db.courses import Course
from src.db.trail_runs import TrailRun, TrailRunCreate, TrailRunRead
from src.db.trail_runs import TrailRun, TrailRunRead
from src.db.trail_steps import TrailStep
from src.db.trails import Trail, TrailCreate, TrailRead
from src.db.users import PublicUser

View file

@ -77,7 +77,7 @@ async def create_user(
user_organization = UserOrganization(
user_id=user.id if user.id else 0,
org_id=int(org_id),
role_id=1,
role_id=3,
creation_date=str(datetime.now()),
update_date=str(datetime.now()),
)