mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: init install + cleanup code
This commit is contained in:
parent
2485285a06
commit
38288e8a57
28 changed files with 310 additions and 583 deletions
|
|
@ -1,23 +1,8 @@
|
||||||
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 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(
|
engine = create_engine(
|
||||||
"postgresql://learnhouse:learnhouse@db:5432/learnhouse", echo=True
|
"postgresql://learnhouse:learnhouse@db:5432/learnhouse", echo=True
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
from typing import Literal, Optional
|
from typing import Optional
|
||||||
from click import Option
|
|
||||||
from sqlalchemy import JSON, Column
|
from sqlalchemy import JSON, Column
|
||||||
from sqlmodel import Field, Session, SQLModel, create_engine, select
|
from sqlmodel import Field, SQLModel
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from sqlmodel import Field, SQLModel
|
from sqlmodel import Field, SQLModel
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class ChapterActivity(SQLModel, table=True):
|
class ChapterActivity(SQLModel, table=True):
|
||||||
id: Optional[int] = Field(default=None, primary_key=True)
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from sqlmodel import Field, SQLModel
|
from sqlmodel import Field, SQLModel
|
||||||
from src.db.activities import Activity, ActivityRead, ActivityUpdate
|
from src.db.activities import ActivityRead
|
||||||
|
|
||||||
|
|
||||||
class ChapterBase(SQLModel):
|
class ChapterBase(SQLModel):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from sqlmodel import Field, SQLModel
|
from sqlmodel import Field, SQLModel
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class CourseChapter(SQLModel, table=True):
|
class CourseChapter(SQLModel, table=True):
|
||||||
id: Optional[int] = Field(default=None, primary_key=True)
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||||||
|
|
|
||||||
31
apps/api/src/db/install.py
Normal file
31
apps/api/src/db/install.py
Normal 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
|
||||||
|
|
@ -1,19 +1,46 @@
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Optional
|
from typing import Optional, Union
|
||||||
|
from pydantic import BaseModel
|
||||||
from sqlalchemy import JSON, Column
|
from sqlalchemy import JSON, Column
|
||||||
from sqlmodel import Field, SQLModel
|
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):
|
class RoleTypeEnum(str, Enum):
|
||||||
TYPE_ORGANIZATION = "TYPE_ORGANIZATION"
|
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"
|
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"
|
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):
|
class RoleBase(SQLModel):
|
||||||
name: str
|
name: str
|
||||||
description: Optional[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):
|
class Role(RoleBase, table=True):
|
||||||
|
|
@ -26,11 +53,12 @@ class Role(RoleBase, table=True):
|
||||||
|
|
||||||
|
|
||||||
class RoleCreate(RoleBase):
|
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):
|
class RoleUpdate(SQLModel):
|
||||||
role_id: int = Field(default=None, foreign_key="role.id")
|
role_id: int = Field(default=None, foreign_key="role.id")
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
description: 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))
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from sqlmodel import Field, SQLModel
|
from sqlmodel import Field, SQLModel
|
||||||
from enum import Enum
|
from src.db.trail_runs import TrailRunRead
|
||||||
from src.db.trail_runs import TrailRun, TrailRunRead
|
|
||||||
|
|
||||||
from src.db.trail_steps import TrailStep
|
|
||||||
|
|
||||||
|
|
||||||
class TrailBase(SQLModel):
|
class TrailBase(SQLModel):
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ from src.db.users import UserRead
|
||||||
from src.core.events.database import get_db_session
|
from src.core.events.database import get_db_session
|
||||||
from config.config import get_learnhouse_config
|
from config.config import get_learnhouse_config
|
||||||
from src.security.auth import AuthJWT, authenticate_user
|
from src.security.auth import AuthJWT, authenticate_user
|
||||||
from src.services.users.users import PublicUser
|
|
||||||
|
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ from src.db.activities import ActivityCreate, ActivityUpdate
|
||||||
from src.db.users import PublicUser
|
from src.db.users import PublicUser
|
||||||
from src.core.events.database import get_db_session
|
from src.core.events.database import get_db_session
|
||||||
from src.services.courses.activities.activities import (
|
from src.services.courses.activities.activities import (
|
||||||
Activity,
|
|
||||||
create_activity,
|
create_activity,
|
||||||
get_activity,
|
get_activity,
|
||||||
get_activities,
|
get_activities,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ from src.db.collections import CollectionCreate, CollectionUpdate
|
||||||
from src.security.auth import get_current_user
|
from src.security.auth import get_current_user
|
||||||
from src.services.users.users import PublicUser
|
from src.services.users.users import PublicUser
|
||||||
from src.services.courses.collections import (
|
from src.services.courses.collections import (
|
||||||
Collection,
|
|
||||||
create_collection,
|
create_collection,
|
||||||
get_collection,
|
get_collection,
|
||||||
get_collections,
|
get_collections,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ from fastapi import APIRouter, Depends, UploadFile, Form, Request
|
||||||
from sqlmodel import Session
|
from sqlmodel import Session
|
||||||
from src.core.events.database import get_db_session
|
from src.core.events.database import get_db_session
|
||||||
from src.db.users import PublicUser
|
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.security.auth import get_current_user
|
||||||
|
|
||||||
from src.services.courses.courses import (
|
from src.services.courses.courses import (
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
from fastapi import APIRouter, Request
|
from fastapi import APIRouter
|
||||||
from config.config import get_learnhouse_config
|
from config.config import get_learnhouse_config
|
||||||
from src.services.dev.mocks.initial import create_initial_data
|
|
||||||
|
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
@ -10,9 +9,3 @@ router = APIRouter()
|
||||||
async def config():
|
async def config():
|
||||||
config = get_learnhouse_config()
|
config = get_learnhouse_config()
|
||||||
return config.dict()
|
return config.dict()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/mock/initial")
|
|
||||||
async def initial_data(request: Request):
|
|
||||||
await create_initial_data(request)
|
|
||||||
return {"Message": "Initial data created 🤖"}
|
|
||||||
|
|
|
||||||
|
|
@ -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 (
|
from src.services.install.install import (
|
||||||
create_install_instance,
|
create_install_instance,
|
||||||
create_sample_data,
|
|
||||||
get_latest_install_instance,
|
get_latest_install_instance,
|
||||||
install_create_organization,
|
install_create_organization,
|
||||||
install_create_organization_user,
|
install_create_organization_user,
|
||||||
install_default_elements,
|
install_default_elements,
|
||||||
update_install_instance,
|
update_install_instance,
|
||||||
)
|
)
|
||||||
from src.services.orgs.schemas.orgs import Organization
|
|
||||||
from src.services.users.schemas.users import UserWithPassword
|
|
||||||
|
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/start")
|
@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
|
# create install
|
||||||
install = await create_install_instance(request, data)
|
install = await create_install_instance(request, data, db_session)
|
||||||
|
|
||||||
return install
|
return install
|
||||||
|
|
||||||
|
|
||||||
@router.get("/latest")
|
@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
|
# get latest created install
|
||||||
install = await get_latest_install_instance(request)
|
install = await get_latest_install_instance(request, db_session=db_session)
|
||||||
|
|
||||||
return install
|
return install
|
||||||
|
|
||||||
|
|
||||||
@router.post("/default_elements")
|
@router.post("/default_elements")
|
||||||
async def api_install_def_elements(request: Request):
|
async def api_install_def_elements(request: Request, db_session=Depends(get_db_session),):
|
||||||
elements = await install_default_elements(request, {})
|
elements = await install_default_elements(request, {}, db_session)
|
||||||
|
|
||||||
return elements
|
return elements
|
||||||
|
|
||||||
|
|
||||||
@router.post("/org")
|
@router.post("/org")
|
||||||
async def api_install_org(request: Request, org: Organization):
|
async def api_install_org(
|
||||||
organization = await install_create_organization(request, org)
|
request: Request, org: OrganizationCreate, db_session=Depends(get_db_session),
|
||||||
|
):
|
||||||
|
organization = await install_create_organization(request, org, db_session)
|
||||||
|
|
||||||
return organization
|
return organization
|
||||||
|
|
||||||
|
|
||||||
@router.post("/user")
|
@router.post("/user")
|
||||||
async def api_install_user(request: Request, data: UserWithPassword, org_slug: str):
|
async def api_install_user(
|
||||||
user = await install_create_organization_user(request, data, org_slug)
|
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
|
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")
|
@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"]
|
request.app.db["installs"]
|
||||||
|
|
||||||
# get latest created install
|
# get latest created install
|
||||||
install = await update_install_instance(request, data, step)
|
install = await update_install_instance(request, data, step, db_session)
|
||||||
|
|
||||||
return install
|
return install
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ from sqlmodel import Session
|
||||||
from src.core.events.database import get_db_session
|
from src.core.events.database import get_db_session
|
||||||
from src.db.roles import RoleCreate, RoleUpdate
|
from src.db.roles import RoleCreate, RoleUpdate
|
||||||
from src.security.auth import get_current_user
|
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.roles.roles import create_role, delete_role, read_role, update_role
|
||||||
from src.services.users.schemas.users import PublicUser
|
from src.services.users.schemas.users import PublicUser
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,9 @@
|
||||||
import stat
|
|
||||||
from typing import Literal
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from sqlmodel import Session, select
|
from sqlmodel import Session, select
|
||||||
from src.db.chapters import Chapter
|
|
||||||
from src.db.organizations import Organization
|
from src.db.organizations import Organization
|
||||||
from src import db
|
|
||||||
from src.db.activities import ActivityCreate, Activity, ActivityRead, ActivityUpdate
|
from src.db.activities import ActivityCreate, Activity, ActivityRead, ActivityUpdate
|
||||||
from src.db.chapter_activities import ChapterActivity
|
from src.db.chapter_activities import ChapterActivity
|
||||||
from src.security.rbac.rbac import (
|
from src.db.users import PublicUser
|
||||||
authorization_verify_based_on_roles,
|
from fastapi import HTTPException, Request
|
||||||
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 uuid import uuid4
|
from uuid import uuid4
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ from src.db.activities import (
|
||||||
from src.db.chapter_activities import ChapterActivity
|
from src.db.chapter_activities import ChapterActivity
|
||||||
from src.db.course_chapters import CourseChapter
|
from src.db.course_chapters import CourseChapter
|
||||||
from src.db.users import PublicUser
|
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 src.services.courses.activities.uploads.pdfs import upload_pdf
|
||||||
from fastapi import HTTPException, status, UploadFile, Request
|
from fastapi import HTTPException, status, UploadFile, Request
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,6 @@ from src.db.activities import Activity, ActivityRead, ActivitySubTypeEnum, Activ
|
||||||
from src.db.chapter_activities import ChapterActivity
|
from src.db.chapter_activities import ChapterActivity
|
||||||
from src.db.course_chapters import CourseChapter
|
from src.db.course_chapters import CourseChapter
|
||||||
from src.db.users import PublicUser
|
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 src.services.courses.activities.uploads.videos import upload_video
|
||||||
from fastapi import HTTPException, status, UploadFile, Request
|
from fastapi import HTTPException, status, UploadFile, Request
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ from datetime import datetime
|
||||||
from typing import List
|
from typing import List
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from sqlmodel import Session, select
|
from sqlmodel import Session, select
|
||||||
from src import db
|
|
||||||
from src.db.course_chapters import CourseChapter
|
from src.db.course_chapters import CourseChapter
|
||||||
from src.db.activities import Activity, ActivityRead
|
from src.db.activities import Activity, ActivityRead
|
||||||
from src.db.chapter_activities import ChapterActivity
|
from src.db.chapter_activities import ChapterActivity
|
||||||
|
|
@ -14,13 +13,6 @@ from src.db.chapters import (
|
||||||
ChapterUpdateOrder,
|
ChapterUpdateOrder,
|
||||||
DepreceatedChaptersRead,
|
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.courses.courses import Course
|
||||||
from src.services.users.users import PublicUser
|
from src.services.users.users import PublicUser
|
||||||
from fastapi import HTTPException, status, Request
|
from fastapi import HTTPException, status, Request
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from gc import collect
|
from typing import List
|
||||||
from typing import List, Literal
|
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from pydantic import BaseModel
|
|
||||||
from sqlmodel import Session, select
|
from sqlmodel import Session, select
|
||||||
from src.db.collections import (
|
from src.db.collections import (
|
||||||
Collection,
|
Collection,
|
||||||
|
|
@ -12,10 +10,6 @@ from src.db.collections import (
|
||||||
)
|
)
|
||||||
from src.db.collections_courses import CollectionCourse
|
from src.db.collections_courses import CollectionCourse
|
||||||
from src.db.courses import Course
|
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 src.services.users.users import PublicUser
|
||||||
from fastapi import HTTPException, status, Request
|
from fastapi import HTTPException, status, Request
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
import json
|
import json
|
||||||
from typing import List, Literal, Optional
|
from typing import Literal
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from pydantic import BaseModel
|
|
||||||
from sqlmodel import Session, select
|
from sqlmodel import Session, select
|
||||||
from src.db.course_authors import CourseAuthor, CourseAuthorshipEnum
|
from src.db.course_authors import CourseAuthor, CourseAuthorshipEnum
|
||||||
from src.db.users import PublicUser, AnonymousUser
|
from src.db.users import PublicUser, AnonymousUser
|
||||||
from src.db.courses import Course, CourseCreate, CourseRead, CourseUpdate
|
from src.db.courses import Course, CourseCreate, CourseRead, CourseUpdate
|
||||||
from src.security.rbac.rbac import (
|
from src.security.rbac.rbac import (
|
||||||
authorization_verify_based_on_roles,
|
|
||||||
authorization_verify_based_on_roles_and_authorship,
|
authorization_verify_based_on_roles_and_authorship,
|
||||||
authorization_verify_if_element_is_public,
|
authorization_verify_if_element_is_public,
|
||||||
authorization_verify_if_user_is_anon,
|
authorization_verify_if_user_is_anon,
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
@ -1,33 +1,15 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from fastapi import HTTPException, Request, status
|
from fastapi import HTTPException, Request
|
||||||
from pydantic import BaseModel
|
from sqlalchemy import desc
|
||||||
import requests
|
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 config.config import get_learnhouse_config
|
||||||
from src.security.security import security_hash_password
|
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():
|
async def isInstallModeEnabled():
|
||||||
|
|
@ -42,37 +24,29 @@ async def isInstallModeEnabled():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def create_install_instance(request: Request, data: dict):
|
async def create_install_instance(request: Request, data: dict, db_session: Session):
|
||||||
installs = request.app.db["installs"]
|
install = Install.from_orm(data)
|
||||||
|
|
||||||
# get install_id
|
# complete install instance
|
||||||
install_id = str(f"install_{uuid4()}")
|
install.install_uuid = str(f"install_{uuid4()}")
|
||||||
created_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
install.update_date = str(datetime.now())
|
||||||
updated_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
install.creation_date = str(datetime.now())
|
||||||
step = 1
|
|
||||||
|
|
||||||
# create install
|
# insert install instance
|
||||||
install = InstallInstance(
|
db_session.add(install)
|
||||||
install_id=install_id,
|
|
||||||
created_date=created_date,
|
|
||||||
updated_date=updated_date,
|
|
||||||
step=step,
|
|
||||||
data=data,
|
|
||||||
)
|
|
||||||
|
|
||||||
# insert install
|
# commit changes
|
||||||
installs.insert_one(install.dict())
|
db_session.commit()
|
||||||
|
|
||||||
|
# refresh install instance
|
||||||
|
db_session.refresh(install)
|
||||||
|
|
||||||
return install
|
return install
|
||||||
|
|
||||||
|
|
||||||
async def get_latest_install_instance(request: Request):
|
async def get_latest_install_instance(request: Request, db_session: Session):
|
||||||
installs = request.app.db["installs"]
|
statement = select(Install).order_by(desc(Install.creation_date)).limit(1)
|
||||||
|
install = db_session.exec(statement).first()
|
||||||
# get latest created install instance using find_one
|
|
||||||
install = await installs.find_one(
|
|
||||||
sort=[("created_date", -1)], limit=1, projection={"_id": 0}
|
|
||||||
)
|
|
||||||
|
|
||||||
if install is None:
|
if install is None:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
@ -80,37 +54,31 @@ async def get_latest_install_instance(request: Request):
|
||||||
detail="No install instance found",
|
detail="No install instance found",
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
return install
|
||||||
install = InstallInstance(**install)
|
|
||||||
|
|
||||||
return install
|
|
||||||
|
|
||||||
|
|
||||||
async def update_install_instance(request: Request, data: dict, step: int):
|
async def update_install_instance(
|
||||||
installs = request.app.db["installs"]
|
request: Request, data: dict, step: int, db_session: Session
|
||||||
|
):
|
||||||
# get latest created install
|
statement = select(Install).order_by(desc(Install.creation_date)).limit(1)
|
||||||
install = await installs.find_one(
|
install = db_session.exec(statement).first()
|
||||||
sort=[("created_date", -1)], limit=1, projection={"_id": 0}
|
|
||||||
)
|
|
||||||
|
|
||||||
if install is None:
|
if install is None:
|
||||||
return None
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
else:
|
detail="No install instance found",
|
||||||
# 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}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
install = InstallInstance(**install)
|
install.step = step
|
||||||
|
install.data = data
|
||||||
|
|
||||||
return install
|
# 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
|
# Install Default roles
|
||||||
async def install_default_elements(request: Request, data: dict):
|
async def install_default_elements(request: Request, data: dict, db_session: Session):
|
||||||
roles = request.app.db["roles"]
|
# 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
|
for role in roles:
|
||||||
admin_role = await roles.find_one({"role_id": "role_admin"})
|
db_session.delete(role)
|
||||||
user_role = await roles.find_one({"role_id": "role_member"})
|
|
||||||
|
|
||||||
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(
|
raise HTTPException(
|
||||||
status_code=400,
|
status_code=409,
|
||||||
detail="Default roles already exist",
|
detail="Default roles already exist",
|
||||||
)
|
)
|
||||||
|
|
||||||
# get default roles
|
# Create default roles
|
||||||
ADMIN_ROLE = RoleInDB(
|
role_global_admin = Role(
|
||||||
name="Admin Role",
|
name="Admin",
|
||||||
description="This role grants all permissions to the user",
|
description="Standard Admin Role",
|
||||||
elements=Elements(
|
id=1,
|
||||||
|
role_type=RoleTypeEnum.TYPE_GLOBAL,
|
||||||
|
role_uuid="role_global_admin",
|
||||||
|
rights=Rights(
|
||||||
courses=Permission(
|
courses=Permission(
|
||||||
action_create=True,
|
action_create=True,
|
||||||
action_read=True,
|
action_read=True,
|
||||||
|
|
@ -149,12 +127,6 @@ async def install_default_elements(request: Request, data: dict):
|
||||||
action_update=True,
|
action_update=True,
|
||||||
action_delete=True,
|
action_delete=True,
|
||||||
),
|
),
|
||||||
houses=Permission(
|
|
||||||
action_create=True,
|
|
||||||
action_read=True,
|
|
||||||
action_update=True,
|
|
||||||
action_delete=True,
|
|
||||||
),
|
|
||||||
collections=Permission(
|
collections=Permission(
|
||||||
action_create=True,
|
action_create=True,
|
||||||
action_read=True,
|
action_read=True,
|
||||||
|
|
@ -180,16 +152,65 @@ async def install_default_elements(request: Request, data: dict):
|
||||||
action_delete=True,
|
action_delete=True,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
org_id="*",
|
creation_date=str(datetime.now()),
|
||||||
role_id="role_admin",
|
update_date=str(datetime.now()),
|
||||||
created_at=str(datetime.now()),
|
|
||||||
updated_at=str(datetime.now()),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
USER_ROLE = RoleInDB(
|
role_global_maintainer = Role(
|
||||||
name="Member Role",
|
name="Maintainer",
|
||||||
description="This role grants read-only permissions to the user",
|
description="Standard Maintainer Role",
|
||||||
elements=Elements(
|
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(
|
courses=Permission(
|
||||||
action_create=False,
|
action_create=False,
|
||||||
action_read=True,
|
action_read=True,
|
||||||
|
|
@ -197,13 +218,7 @@ async def install_default_elements(request: Request, data: dict):
|
||||||
action_delete=False,
|
action_delete=False,
|
||||||
),
|
),
|
||||||
users=Permission(
|
users=Permission(
|
||||||
action_create=False,
|
action_create=True,
|
||||||
action_read=True,
|
|
||||||
action_update=False,
|
|
||||||
action_delete=False,
|
|
||||||
),
|
|
||||||
houses=Permission(
|
|
||||||
action_create=False,
|
|
||||||
action_read=True,
|
action_read=True,
|
||||||
action_update=False,
|
action_update=False,
|
||||||
action_delete=False,
|
action_delete=False,
|
||||||
|
|
@ -233,185 +248,122 @@ async def install_default_elements(request: Request, data: dict):
|
||||||
action_delete=False,
|
action_delete=False,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
org_id="*",
|
creation_date=str(datetime.now()),
|
||||||
role_id="role_member",
|
update_date=str(datetime.now()),
|
||||||
created_at=str(datetime.now()),
|
|
||||||
updated_at=str(datetime.now()),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
# Serialize rights to JSON
|
||||||
# insert default roles
|
role_global_admin.rights = role_global_admin.rights.dict() # type: ignore
|
||||||
await roles.insert_many([USER_ROLE.dict(), ADMIN_ROLE.dict()])
|
role_global_maintainer.rights = role_global_maintainer.rights.dict() # type: ignore
|
||||||
return True
|
role_global_user.rights = role_global_user.rights.dict() # type: ignore
|
||||||
|
|
||||||
except Exception:
|
# Insert roles in DB
|
||||||
raise HTTPException(
|
db_session.add(role_global_admin)
|
||||||
status_code=400,
|
db_session.add(role_global_maintainer)
|
||||||
detail="Error while inserting default roles",
|
db_session.add(role_global_user)
|
||||||
)
|
|
||||||
|
# commit changes
|
||||||
|
db_session.commit()
|
||||||
|
|
||||||
|
# refresh roles
|
||||||
|
db_session.refresh(role_global_admin)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
# Organization creation
|
# Organization creation
|
||||||
async def install_create_organization(
|
async def install_create_organization(
|
||||||
request: Request,
|
request: Request, org_object: OrganizationCreate, db_session: Session
|
||||||
org_object: Organization,
|
|
||||||
):
|
):
|
||||||
orgs = request.app.db["organizations"]
|
org = Organization.from_orm(org_object)
|
||||||
request.app.db["users"]
|
|
||||||
|
|
||||||
# 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:
|
return org
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
||||||
async def install_create_organization_user(
|
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})
|
# Complete the user object
|
||||||
isEmailAvailable = await users.find_one({"email": user_object.email})
|
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(
|
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(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Email already exists"
|
status_code=400,
|
||||||
|
detail="Username already exists",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Generate user_id with uuid4
|
# Email
|
||||||
user_id = str(f"user_{uuid4()}")
|
statement = select(User).where(User.email == user.email)
|
||||||
|
result = db_session.exec(statement)
|
||||||
|
|
||||||
# Set the username & hash the password
|
if result.first():
|
||||||
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:
|
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT,
|
status_code=400,
|
||||||
detail="You are trying to create a user in an organization that does not exist",
|
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
|
# Add user to database
|
||||||
orgs = [UserOrganization(org_id=org_id, org_role="owner")]
|
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
|
# get org id
|
||||||
user = UserInDB(
|
statement = select(Organization).where(Organization.slug == org_slug)
|
||||||
user_id=user_id,
|
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()),
|
creation_date=str(datetime.now()),
|
||||||
update_date=str(datetime.now()),
|
update_date=str(datetime.now()),
|
||||||
orgs=orgs,
|
|
||||||
roles=roles,
|
|
||||||
**user_object.dict(),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Insert the user into the database
|
db_session.add(user_organization)
|
||||||
await users.insert_one(user.dict())
|
db_session.commit()
|
||||||
|
db_session.refresh(user_organization)
|
||||||
|
|
||||||
return User(**user.dict())
|
user = UserRead.from_orm(user)
|
||||||
|
|
||||||
|
return 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,
|
|
||||||
# )
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import json
|
|
||||||
from operator import or_
|
|
||||||
from typing import Literal
|
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from sqlmodel import Session, select
|
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.user_organizations import UserOrganization
|
||||||
from src.db.organizations import (
|
from src.db.organizations import (
|
||||||
Organization,
|
Organization,
|
||||||
|
|
@ -12,10 +9,6 @@ from src.db.organizations import (
|
||||||
OrganizationRead,
|
OrganizationRead,
|
||||||
OrganizationUpdate,
|
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 src.services.orgs.logos import upload_org_logo
|
||||||
from fastapi import HTTPException, UploadFile, status, Request
|
from fastapi import HTTPException, UploadFile, status, Request
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from sqlmodel import Session, select
|
from sqlmodel import Session, select
|
||||||
from src.db.roles import Role, RoleCreate, RoleUpdate
|
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 src.services.users.schemas.users import PublicUser
|
||||||
from fastapi import HTTPException, status, Request
|
from fastapi import HTTPException, Request
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import stat
|
|
||||||
from typing import List, Literal, Optional
|
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from fastapi import HTTPException, Request, status
|
from fastapi import HTTPException, Request, status
|
||||||
from pydantic import BaseModel
|
|
||||||
from sqlmodel import Session, select
|
from sqlmodel import Session, select
|
||||||
from src.db.courses import Course
|
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.trail_steps import TrailStep
|
||||||
from src.db.trails import Trail, TrailCreate, TrailRead
|
from src.db.trails import Trail, TrailCreate, TrailRead
|
||||||
from src.db.users import PublicUser
|
from src.db.users import PublicUser
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ async def create_user(
|
||||||
user_organization = UserOrganization(
|
user_organization = UserOrganization(
|
||||||
user_id=user.id if user.id else 0,
|
user_id=user.id if user.id else 0,
|
||||||
org_id=int(org_id),
|
org_id=int(org_id),
|
||||||
role_id=1,
|
role_id=3,
|
||||||
creation_date=str(datetime.now()),
|
creation_date=str(datetime.now()),
|
||||||
update_date=str(datetime.now()),
|
update_date=str(datetime.now()),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue