fix: safecheck code

This commit is contained in:
swve 2022-10-12 22:06:19 +02:00
parent 4b623ae1b8
commit 977008f0ae
21 changed files with 234 additions and 151 deletions

3
.gitignore vendored
View file

@ -6,6 +6,9 @@ __pycache__/
# C extensions # C extensions
*.so *.so
# Visual Studio Code
.vscode/
# Distribution / packaging # Distribution / packaging
.Python .Python
build/ build/

8
app.py
View file

@ -11,7 +11,7 @@ from fastapi_jwt_auth.exceptions import AuthJWTException
# (c) LearnHouse 2022 # (c) LearnHouse 2022
######################## ########################
#
# Global Config # Global Config
app = FastAPI( app = FastAPI(
title="LearnHouse", title="LearnHouse",
@ -28,13 +28,13 @@ app.add_middleware(
allow_headers=["*"] allow_headers=["*"]
) )
#
# Exception Handler # Exception Handler
@app.exception_handler(AuthJWTException) @app.exception_handler(AuthJWTException)
def authjwt_exception_handler(request: Request, exc: AuthJWTException): def authjwt_exception_handler(request: Request, exc: AuthJWTException):
return JSONResponse( return JSONResponse(
status_code=exc.status_code, status_code=exc.status_code, # type: ignore
content={"detail": exc.message} content={"detail": exc.message} # type: ignore
) )
app.include_router(global_router) app.include_router(global_router)

View file

@ -7,7 +7,6 @@ import styled from "styled-components";
export const Header = () => { export const Header = () => {
return ( return (
<div> <div>
<Menu></Menu>
</div> </div>
); );
}; };

View file

@ -3,8 +3,16 @@ import Head from "next/head";
import { Header } from "./header"; import { Header } from "./header";
import styled from "styled-components"; import styled from "styled-components";
import AuthProvider from "../security/AuthProvider"; import AuthProvider from "../security/AuthProvider";
import { motion } from "framer-motion";
import { Menu } from "./elements/menu";
const Layout = (props: any) => { const Layout = (props: any) => {
const variants = {
hidden: { opacity: 0, x: 0, y: 0 },
enter: { opacity: 1, x: 0, y: 0 },
exit: { opacity: 0, x: 0, y: 0 },
};
return ( return (
<div> <div>
<AuthProvider> <AuthProvider>
@ -14,8 +22,17 @@ const Layout = (props: any) => {
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
</Head> </Head>
<PreAlphaLabel>🚧 Pre-Alpha</PreAlphaLabel> <PreAlphaLabel>🚧 Pre-Alpha</PreAlphaLabel>
<Menu></Menu>
<motion.main
variants={variants} // Pass the variant object into Framer Motion
initial="hidden" // Set the initial state to variants.hidden
animate="enter" // Animated state to variants.enter
exit="exit" // Exit state (used later) to variants.exit
transition={{ type: "linear" }} // Set the transition to linear
className=""
>
<Main className="min-h-screen">{props.children}</Main> <Main className="min-h-screen">{props.children}</Main>
</motion.main>
<Footer> <Footer>
<a href="" target="_blank" rel="noopener noreferrer"> <a href="" target="_blank" rel="noopener noreferrer">
<img src="/learnhouse_icon.png" alt="Learnhouse Logo" /> <img src="/learnhouse_icon.png" alt="Learnhouse Logo" />

View file

@ -0,0 +1,32 @@
import { useRouter } from "next/router";
import React from "react";
import Layout from "../../../../components/ui/layout";
import { getCourse } from "../../../../services/courses";
import { getOrganizationContextInfo } from "../../../../services/orgs";
const CourseIdPage = () => {
const router = useRouter();
const { courseid } = router.query;
const { orgslug } = router.query;
const [isLoading, setIsLoading] = React.useState(true);
const [courseInfo, setCourseInfo] = React.useState("") as any;
async function fetchCourseInfo() {
const orgid = await getOrganizationContextInfo(orgslug);
const response = await getCourse(courseid, orgid);
const data = await response.json();
setCourseInfo(data);
setIsLoading(false);
}
React.useEffect(() => {
if (router.isReady) {
fetchCourseInfo();
}
}, [isLoading, router.isReady]);
return <Layout>{isLoading ? <div>Loading...</div> : <div>{courseInfo.name}</div>}</Layout>;
};
export default CourseIdPage;

View file

@ -14,3 +14,19 @@ export async function getOrgCourses(org_id: number) {
.then((result) => result.json()) .then((result) => result.json())
.catch((error) => console.log("error", error)); .catch((error) => console.log("error", error));
} }
export async function getCourse(org_id: any, course_id: any) {
const HeadersConfig = new Headers({ "Content-Type": "application/json" });
const requestOptions: any = {
method: "GET",
headers: HeadersConfig,
redirect: "follow",
credentials: "include",
};
// todo : add course id to url
return fetch(`${getAPIUrl()}courses/${course_id}`, requestOptions)
.then((result) => result.json())
.catch((error) => console.log("error", error));
}

View file

@ -28,7 +28,7 @@ async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(
) )
response = JSONResponse(content={"access_token" : access_token ,"token_type": "bearer"}) response = JSONResponse(content={"access_token" : access_token ,"token_type": "bearer"})
response.set_cookie(key="user_token", value=access_token, httponly=True, expires="3600",secure=True) response.set_cookie(key="user_token", value=access_token, httponly=True, expires=3600,secure=True)
return response return response
@ -43,7 +43,7 @@ def refresh(Authorize: AuthJWT = Depends()):
Authorize.jwt_refresh_token_required() Authorize.jwt_refresh_token_required()
current_user = Authorize.get_jwt_subject() current_user = Authorize.get_jwt_subject()
new_access_token = Authorize.create_access_token(subject=current_user) new_access_token = Authorize.create_access_token(subject=current_user) # type: ignore
return {"access_token": new_access_token} return {"access_token": new_access_token}
@router.post('/login') @router.post('/login')

View file

@ -1,6 +1,6 @@
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from src.services.auth import get_current_user from src.services.auth import get_current_user
from src.services.users import User from src.services.users import PublicUser, User
from src.services.collections import Collection, create_collection, get_collection, get_collections, update_collection, delete_collection from src.services.collections import Collection, create_collection, get_collection, get_collections, update_collection, delete_collection
@ -8,7 +8,7 @@ router = APIRouter()
@router.post("/") @router.post("/")
async def api_create_collection(collection_object: Collection, current_user: User = Depends(get_current_user)): async def api_create_collection(collection_object: Collection, current_user: PublicUser = Depends(get_current_user)):
""" """
Create new Collection Create new Collection
""" """
@ -16,7 +16,7 @@ async def api_create_collection(collection_object: Collection, current_user: Use
@router.get("/{collection_id}") @router.get("/{collection_id}")
async def api_get_collection(collection_id: str, current_user: User = Depends(get_current_user)): async def api_get_collection(collection_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Get single collection by ID Get single collection by ID
""" """
@ -24,15 +24,15 @@ async def api_get_collection(collection_id: str, current_user: User = Depends(ge
@router.get("/page/{page}/limit/{limit}") @router.get("/page/{page}/limit/{limit}")
async def api_get_collection_by(page: int, limit: int, current_user: User = Depends(get_current_user)): async def api_get_collection_by(page: int, limit: int, current_user: PublicUser = Depends(get_current_user)):
""" """
Get collections by page and limit Get collections by page and limit
""" """
return await get_collections(page, limit, current_user) return await get_collections(page, limit)
@router.put("/{collection_id}") @router.put("/{collection_id}")
async def api_update_collection(collection_object: Collection, collection_id: str, current_user: User = Depends(get_current_user)): async def api_update_collection(collection_object: Collection, collection_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Update collection by ID Update collection by ID
""" """
@ -40,7 +40,7 @@ async def api_update_collection(collection_object: Collection, collection_id: st
@router.delete("/{collection_id}") @router.delete("/{collection_id}")
async def api_delete_collection(collection_id: str, current_user: User = Depends(get_current_user)): async def api_delete_collection(collection_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Delete collection by ID Delete collection by ID
""" """

View file

@ -1,15 +1,15 @@
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends, File, UploadFile
from src.services.auth import get_current_user from src.services.auth import get_current_user
from src.services.courses import Course, CourseChapter, create_course, create_coursechapter, delete_coursechapter, get_course, get_coursechapter, get_coursechapters, get_courses, update_course, delete_course, update_coursechapter from src.services.courses import Course, CourseChapter, create_course, create_coursechapter, delete_coursechapter, get_course, get_coursechapter, get_coursechapters, get_courses, update_course, delete_course, update_coursechapter
from src.services.users import User from src.services.users import PublicUser, User
router = APIRouter() router = APIRouter()
@router.post("/") @router.post("/")
async def api_create_course(course_object: Course, org_id :str , current_user: User = Depends(get_current_user)): async def api_create_course(course_object: Course, org_id :str , current_user: PublicUser = Depends(get_current_user)):
""" """
Create new Course Create new Course
""" """
@ -17,7 +17,7 @@ async def api_create_course(course_object: Course, org_id :str , current_user:
@router.get("/{course_id}") @router.get("/{course_id}")
async def api_get_course(course_id: str, org_id : str, current_user: User = Depends(get_current_user)): async def api_get_course(course_id: str, org_id : str, current_user: PublicUser = Depends(get_current_user)):
""" """
Get single Course by course_id Get single Course by course_id
""" """
@ -33,7 +33,7 @@ async def api_get_course_by(page: int, limit: int, org_id: str):
@router.put("/{course_id}") @router.put("/{course_id}")
async def api_update_course(course_object: Course, course_id: str, current_user: User = Depends(get_current_user)): async def api_update_course(course_object: Course, course_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Update Course by course_id Update Course by course_id
""" """
@ -41,7 +41,7 @@ async def api_update_course(course_object: Course, course_id: str, current_user:
@router.delete("/{course_id}") @router.delete("/{course_id}")
async def api_delete_course(course_id: str, current_user: User = Depends(get_current_user)): async def api_delete_course(course_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Delete Course by ID Delete Course by ID
""" """
@ -52,7 +52,7 @@ async def api_delete_course(course_id: str, current_user: User = Depends(get_cur
@router.post("/chapters/") @router.post("/chapters/")
async def api_create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: User = Depends(get_current_user)): async def api_create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Create new CourseChapter Create new CourseChapter
""" """
@ -60,7 +60,7 @@ async def api_create_coursechapter(coursechapter_object: CourseChapter, course_i
@router.get("/chapters/{coursechapter_id}") @router.get("/chapters/{coursechapter_id}")
async def api_get_coursechapter(coursechapter_id: str, current_user: User = Depends(get_current_user)): async def api_get_coursechapter(coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Get single CourseChapter by coursechapter_id Get single CourseChapter by coursechapter_id
""" """
@ -76,7 +76,7 @@ async def api_get_coursechapter_by(course_id: str, page: int, limit: int):
@router.put("/chapters/{coursechapter_id}") @router.put("/chapters/{coursechapter_id}")
async def api_update_coursechapter(coursechapter_object: CourseChapter, coursechapter_id: str, current_user: User = Depends(get_current_user)): async def api_update_coursechapter(coursechapter_object: CourseChapter, coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Update CourseChapters by course_id Update CourseChapters by course_id
""" """
@ -84,7 +84,7 @@ async def api_update_coursechapter(coursechapter_object: CourseChapter, coursech
@router.delete("/chapters/{coursechapter_id}") @router.delete("/chapters/{coursechapter_id}")
async def api_delete_coursechapter(coursechapter_id: str, current_user: User = Depends(get_current_user)): async def api_delete_coursechapter(coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Delete CourseChapters by ID Delete CourseChapters by ID
""" """

View file

@ -2,14 +2,14 @@ from fastapi import APIRouter, Depends
from src.services.auth import get_current_user from src.services.auth import get_current_user
from src.services.houses import House, HouseInDB, create_house, get_house, get_houses, update_house, delete_house from src.services.houses import House, HouseInDB, create_house, get_house, get_houses, update_house, delete_house
from src.services.users import User from src.services.users import PublicUser, User
router = APIRouter() router = APIRouter()
@router.post("/") @router.post("/")
async def api_create_house(house_object: House, current_user: User = Depends(get_current_user)): async def api_create_house(house_object: House, current_user: PublicUser = Depends(get_current_user)):
""" """
Create new house Create new house
""" """
@ -17,7 +17,7 @@ async def api_create_house(house_object: House, current_user: User = Depends(get
@router.get("/{house_id}") @router.get("/{house_id}")
async def api_get_house(house_id: str, current_user: User = Depends(get_current_user)): async def api_get_house(house_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Get single House by house_id Get single House by house_id
""" """
@ -33,7 +33,7 @@ async def api_get_house_by(page: int, limit: int):
@router.put("/{house_id}") @router.put("/{house_id}")
async def api_update_house(house_object: House, house_id: str, current_user: User = Depends(get_current_user)): async def api_update_house(house_object: House, house_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Update House by house_id Update House by house_id
""" """
@ -41,7 +41,7 @@ async def api_update_house(house_object: House, house_id: str, current_user: Use
@router.delete("/{house_id}") @router.delete("/{house_id}")
async def api_delete_house(house_id: str, current_user: User = Depends(get_current_user)): async def api_delete_house(house_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Delete House by ID Delete House by ID
""" """

View file

@ -1,14 +1,14 @@
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from src.services.auth import get_current_user from src.services.auth import get_current_user
from src.services.orgs import Organization, create_org, delete_org, get_organization, get_organization_by_slug, get_orgs, get_orgs_by_user, update_org from src.services.orgs import Organization, create_org, delete_org, get_organization, get_organization_by_slug, get_orgs, get_orgs_by_user, update_org
from src.services.users import User from src.services.users import PublicUser, User
router = APIRouter() router = APIRouter()
@router.post("/") @router.post("/")
async def api_create_org(org_object: Organization, current_user: User = Depends(get_current_user)): async def api_create_org(org_object: Organization, current_user: PublicUser = Depends(get_current_user)):
""" """
Create new organization Create new organization
""" """
@ -16,14 +16,14 @@ async def api_create_org(org_object: Organization, current_user: User = Depends(
@router.get("/{org_id}") @router.get("/{org_id}")
async def api_get_org(org_id: str, current_user: User = Depends(get_current_user)): async def api_get_org(org_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Get single Org by ID Get single Org by ID
""" """
return await get_organization(org_id, current_user) return await get_organization(org_id)
@router.get("/slug/{org_slug}") @router.get("/slug/{org_slug}")
async def api_get_org(org_slug: str, current_user: User = Depends(get_current_user)): async def api_get_org_by_slug(org_slug: str, current_user: User = Depends(get_current_user)):
""" """
Get single Org by Slug Get single Org by Slug
""" """
@ -38,7 +38,7 @@ async def api_get_org_by(page: int, limit: int):
return await get_orgs(page, limit) return await get_orgs(page, limit)
@router.get("/user/page/{page}/limit/{limit}") @router.get("/user/page/{page}/limit/{limit}")
async def api_user_orgs(page: int, limit: int, current_user: User = Depends(get_current_user)): async def api_user_orgs(page: int, limit: int, current_user: PublicUser = Depends(get_current_user)):
""" """
Get orgs by page and limit by user Get orgs by page and limit by user
""" """
@ -46,7 +46,7 @@ async def api_user_orgs(page: int, limit: int, current_user: User = Depends(get_
@router.put("/{org_id}") @router.put("/{org_id}")
async def api_update_org(org_object: Organization, org_id: str, current_user: User = Depends(get_current_user)): async def api_update_org(org_object: Organization, org_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Update Org by ID Update Org by ID
""" """
@ -54,7 +54,7 @@ async def api_update_org(org_object: Organization, org_id: str, current_user: Us
@router.delete("/{org_id}") @router.delete("/{org_id}")
async def api_delete_org(org_id: str, current_user: User = Depends(get_current_user)): async def api_delete_org(org_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Delete Org by ID Delete Org by ID
""" """

View file

@ -2,14 +2,14 @@ from fastapi import APIRouter, Depends
from src.services.auth import get_current_user from src.services.auth import get_current_user
from src.services.roles import Role, create_role, delete_role, get_role, get_roles, update_role from src.services.roles import Role, create_role, delete_role, get_role, get_roles, update_role
from src.services.users import User from src.services.users import PublicUser, User
router = APIRouter() router = APIRouter()
@router.post("/") @router.post("/")
async def api_create_role(role_object: Role, current_user: User = Depends(get_current_user)): async def api_create_role(role_object: Role, current_user: PublicUser = Depends(get_current_user)):
""" """
Create new role Create new role
""" """
@ -33,7 +33,7 @@ async def api_get_role_by(page: int, limit: int):
@router.put("/{role_id}") @router.put("/{role_id}")
async def api_update_role(role_object: Role, role_id: str, current_user: User = Depends(get_current_user)): async def api_update_role(role_object: Role, role_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Update role by role_id Update role by role_id
""" """
@ -41,7 +41,7 @@ async def api_update_role(role_object: Role, role_id: str, current_user: User =
@router.delete("/{role_id}") @router.delete("/{role_id}")
async def api_delete_role(role_id: str, current_user: User = Depends(get_current_user)): async def api_delete_role(role_id: str, current_user: PublicUser = Depends(get_current_user)):
""" """
Delete role by ID Delete role by ID
""" """

View file

@ -11,7 +11,7 @@ router = APIRouter()
# DEPRECATED # DEPRECATED
@router.get("/me") @router.get("/me")
async def api_get_current_user(current_user: User = Depends(get_current_user)): async def api_get_current_user_old(current_user: User = Depends(get_current_user)):
""" """
Get current user Get current user
""" """

View file

@ -20,7 +20,7 @@ class Settings(BaseModel):
authjwt_access_token_expires = False # (pre-alpha only) # TODO: set to 1 hour authjwt_access_token_expires = False # (pre-alpha only) # TODO: set to 1 hour
@AuthJWT.load_config @AuthJWT.load_config # type: ignore
def get_config(): def get_config():
return Settings() return Settings()
@ -72,13 +72,13 @@ async def get_current_user_old(token: str = Depends(oauth2_scheme)):
) )
try: try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub") username: str = payload.get("sub") # type: ignore
if username is None: if username is None:
raise credentials_exception raise credentials_exception
token_data = TokenData(username=username) token_data = TokenData(username=username)
except JWTError: except JWTError:
raise credentials_exception raise credentials_exception
user = await security_get_user(email=token_data.username) user = await security_get_user(email=token_data.username) # type: ignore
if user is None: if user is None:
raise credentials_exception raise credentials_exception
return PublicUser(**user.dict()) return PublicUser(**user.dict())
@ -94,10 +94,10 @@ async def get_current_user(Authorize: AuthJWT = Depends()):
try: try:
Authorize.jwt_required() Authorize.jwt_required()
username = Authorize.get_jwt_subject() username = Authorize.get_jwt_subject()
token_data = TokenData(username=username) token_data = TokenData(username=username) # type: ignore
except JWTError: except JWTError:
raise credentials_exception raise credentials_exception
user = await security_get_user(email=token_data.username) # treated as an email user = await security_get_user(email=token_data.username) # type: ignore # treated as an email
if user is None: if user is None:
raise credentials_exception raise credentials_exception
return PublicUser(**user.dict()) return PublicUser(**user.dict())

View file

@ -2,7 +2,7 @@ import json
from typing import List from typing import List
from uuid import uuid4 from uuid import uuid4
from pydantic import BaseModel from pydantic import BaseModel
from src.services.users import User from src.services.users import PublicUser, User
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
from src.services.security import * from src.services.security import *
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks
@ -24,7 +24,7 @@ class CollectionInDB(Collection):
#### Classes #################################################### #### Classes ####################################################
async def get_collection(collection_id: str, current_user: User): async def get_collection(collection_id: str, current_user: PublicUser):
await check_database() await check_database()
collections = learnhouseDB["collections"] collections = learnhouseDB["collections"]
@ -41,7 +41,7 @@ async def get_collection(collection_id: str, current_user: User):
return collection return collection
async def create_collection(collection_object: Collection, current_user: User): async def create_collection(collection_object: Collection, current_user: PublicUser):
await check_database() await check_database()
collections = learnhouseDB["collections"] collections = learnhouseDB["collections"]
@ -68,7 +68,7 @@ async def create_collection(collection_object: Collection, current_user: User):
return collection.dict() return collection.dict()
async def update_collection(collection_object: Collection, collection_id: str, current_user: User): async def update_collection(collection_object: Collection, collection_id: str, current_user: PublicUser):
await check_database() await check_database()
# verify collection rights # verify collection rights
@ -91,7 +91,7 @@ async def update_collection(collection_object: Collection, collection_id: str, c
return Collection(**updated_collection.dict()) return Collection(**updated_collection.dict())
async def delete_collection(collection_id: str, current_user: User): async def delete_collection(collection_id: str, current_user: PublicUser):
await check_database() await check_database()
await verify_collection_rights(collection_id, current_user,"delete") await verify_collection_rights(collection_id, current_user,"delete")
@ -127,7 +127,7 @@ async def get_collections(page: int = 1, limit: int = 10):
#### Security #################################################### #### Security ####################################################
async def verify_collection_rights(collection_id: str, current_user: User, action: str): async def verify_collection_rights(collection_id: str, current_user: PublicUser, action: str):
await check_database() await check_database()
collections = learnhouseDB["collections"] collections = learnhouseDB["collections"]

View file

@ -1,11 +1,12 @@
import json import json
import os
from typing import List from typing import List
from uuid import uuid4 from uuid import uuid4
from pydantic import BaseModel from pydantic import BaseModel
from src.services.users import User from src.services.users import PublicUser, User
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
from src.services.security import * from src.services.security import *
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks, UploadFile, File
from datetime import datetime from datetime import datetime
#### Classes #################################################### #### Classes ####################################################
@ -61,7 +62,7 @@ class CourseChapterInDB(CourseChapter):
# Courses # Courses
async def get_course(course_id: str, org_id :str , current_user: User): async def get_course(course_id: str, org_id :str , current_user: PublicUser):
await check_database() await check_database()
courses = learnhouseDB["courses"] courses = learnhouseDB["courses"]
@ -78,7 +79,7 @@ async def get_course(course_id: str, org_id :str , current_user: User):
return course return course
async def create_course(course_object: Course, org_id : str , current_user: User): async def create_course(course_object: Course, org_id : str , current_user: PublicUser):
await check_database() await check_database()
courses = learnhouseDB["courses"] courses = learnhouseDB["courses"]
@ -105,7 +106,7 @@ async def create_course(course_object: Course, org_id : str , current_user: User
return course.dict() return course.dict()
async def update_course(course_object: Course, course_id: str, current_user: User): async def update_course(course_object: Course, course_id: str, current_user: PublicUser):
await check_database() await check_database()
# verify course rights # verify course rights
@ -115,16 +116,13 @@ async def update_course(course_object: Course, course_id: str, current_user: Use
course = courses.find_one({"course_id": course_id}) course = courses.find_one({"course_id": course_id})
if course:
creationDate = course["creationDate"] creationDate = course["creationDate"]
authors = course["authors"] authors = course["authors"]
# get today's date # get today's date
datetime_object = datetime.now() datetime_object = datetime.now()
if not course:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
updated_course = CourseInDB( updated_course = CourseInDB(
course_id=course_id, creationDate=creationDate, authors=authors, updateDate=str(datetime_object), **course_object.dict()) course_id=course_id, creationDate=creationDate, authors=authors, updateDate=str(datetime_object), **course_object.dict())
@ -133,8 +131,14 @@ async def update_course(course_object: Course, course_id: str, current_user: Use
return CourseInDB(**updated_course.dict()) return CourseInDB(**updated_course.dict())
else:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
async def delete_course(course_id: str, current_user: User):
async def delete_course(course_id: str, current_user: PublicUser):
await check_database() await check_database()
# verify course rights # verify course rights
@ -157,7 +161,7 @@ async def delete_course(course_id: str, current_user: User):
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database") status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
async def get_courses(page: int = 1, limit: int = 10 , org_id : str = None): async def get_courses(page: int = 1, limit: int = 10 , org_id : str | None = None):
await check_database() await check_database()
courses = learnhouseDB["courses"] courses = learnhouseDB["courses"]
# TODO : Get only courses that user is admin/has roles of # TODO : Get only courses that user is admin/has roles of
@ -168,7 +172,7 @@ async def get_courses(page: int = 1, limit: int = 10 , org_id : str = None):
# CoursesChapters # CoursesChapters
async def create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: User): async def create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: PublicUser):
await check_database() await check_database()
coursechapters = learnhouseDB["coursechapters"] coursechapters = learnhouseDB["coursechapters"]
@ -193,30 +197,34 @@ async def create_coursechapter(coursechapter_object: CourseChapter, course_id: s
return coursechapter.dict() return coursechapter.dict()
async def get_coursechapter(coursechapter_id: str, current_user: User): async def get_coursechapter(coursechapter_id: str, current_user: PublicUser):
await check_database() await check_database()
coursechapters = learnhouseDB["coursechapters"] coursechapters = learnhouseDB["coursechapters"]
coursechapter = coursechapters.find_one( coursechapter = coursechapters.find_one(
{"coursechapter_id": coursechapter_id}) {"coursechapter_id": coursechapter_id})
if coursechapter:
# verify course rights # verify course rights
await verify_rights(coursechapter["course_id"], current_user, "read") await verify_rights(coursechapter["course_id"], current_user, "read")
coursechapter = CourseChapter(**coursechapter)
if not coursechapter: return coursechapter
else:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="CourseChapter does not exist") status_code=status.HTTP_409_CONFLICT, detail="CourseChapter does not exist")
coursechapter = CourseChapter(**coursechapter)
return coursechapter
async def update_coursechapter(coursechapter_object: CourseChapter, coursechapter_id: str, current_user: User):
async def update_coursechapter(coursechapter_object: CourseChapter, coursechapter_id: str, current_user: PublicUser):
await check_database() await check_database()
coursechapters = learnhouseDB["coursechapters"] coursechapters = learnhouseDB["coursechapters"]
coursechapter = coursechapters.find_one( coursechapter = coursechapters.find_one(
{"coursechapter_id": coursechapter_id}) {"coursechapter_id": coursechapter_id})
if coursechapter:
# verify course rights # verify course rights
await verify_rights(coursechapter["course_id"], current_user, "update") await verify_rights(coursechapter["course_id"], current_user, "update")
creationDate = coursechapter["creationDate"] creationDate = coursechapter["creationDate"]
@ -224,10 +232,6 @@ async def update_coursechapter(coursechapter_object: CourseChapter, coursechapt
# get today's date # get today's date
datetime_object = datetime.now() datetime_object = datetime.now()
if not coursechapter:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Coursechapter does not exist")
updated_coursechapter = CourseChapterInDB( updated_coursechapter = CourseChapterInDB(
coursechapter_id=coursechapter_id, creationDate=creationDate, course_id=coursechapter["course_id"], updateDate=str(datetime_object), **coursechapter_object.dict()) coursechapter_id=coursechapter_id, creationDate=creationDate, course_id=coursechapter["course_id"], updateDate=str(datetime_object), **coursechapter_object.dict())
@ -236,8 +240,14 @@ async def update_coursechapter(coursechapter_object: CourseChapter, coursechapt
return CourseChapterInDB(**updated_coursechapter.dict()) return CourseChapterInDB(**updated_coursechapter.dict())
else:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Coursechapter does not exist")
async def delete_coursechapter(coursechapter_id: str, current_user: User):
async def delete_coursechapter(coursechapter_id: str, current_user: PublicUser):
await check_database() await check_database()
coursechapters = learnhouseDB["coursechapters"] coursechapters = learnhouseDB["coursechapters"]
@ -245,13 +255,10 @@ async def delete_coursechapter(coursechapter_id: str, current_user: User):
coursechapter = coursechapters.find_one( coursechapter = coursechapters.find_one(
{"coursechapter_id": coursechapter_id}) {"coursechapter_id": coursechapter_id})
if coursechapter:
# verify course rights # verify course rights
await verify_rights(coursechapter["course_id"], current_user, "delete") await verify_rights(coursechapter["course_id"], current_user, "delete")
if not coursechapter:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
isDeleted = coursechapters.delete_one( isDeleted = coursechapters.delete_one(
{"coursechapter_id": coursechapter_id}) {"coursechapter_id": coursechapter_id})
@ -261,6 +268,12 @@ async def delete_coursechapter(coursechapter_id: str, current_user: User):
raise HTTPException( raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database") status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
else:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
async def get_coursechapters(course_id: str, page: int = 1, limit: int = 10): async def get_coursechapters(course_id: str, page: int = 1, limit: int = 10):
await check_database() await check_database()
@ -275,7 +288,7 @@ async def get_coursechapters(course_id: str, page: int = 1, limit: int = 10):
#### Security #################################################### #### Security ####################################################
async def verify_rights(course_id: str, current_user: User, action: str): async def verify_rights(course_id: str, current_user: PublicUser, action: str):
await check_database() await check_database()
courses = learnhouseDB["courses"] courses = learnhouseDB["courses"]

View file

@ -1,7 +1,7 @@
import pymongo import pymongo
# MongoDB # MongoDB
client = pymongo.MongoClient("mongodb://learnhouse:learnhouse@mongo:27017/") client = pymongo.MongoClient("mongodb://learnhouse:learnhouse@mongo:27017/") # type: ignore
learnhouseDB = client["learnhouse"] learnhouseDB = client["learnhouse"]
@ -15,7 +15,7 @@ async def check_database():
if "learnhouse" in client.list_database_names(): if "learnhouse" in client.list_database_names():
return True return True
else: else:
create_database() await create_database()
async def create_config_collection(): async def create_config_collection():

View file

@ -2,7 +2,7 @@ import json
from typing import List from typing import List
from uuid import uuid4 from uuid import uuid4
from pydantic import BaseModel from pydantic import BaseModel
from src.services.users import User from src.services.users import PublicUser, User
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
from src.services.security import * from src.services.security import *
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks
@ -28,7 +28,7 @@ class HouseInDB(House):
# TODO : Add house photo upload and delete # TODO : Add house photo upload and delete
async def get_house(house_id: str, current_user: User): async def get_house(house_id: str, current_user: PublicUser):
await check_database() await check_database()
houses = learnhouseDB["houses"] houses = learnhouseDB["houses"]
@ -45,7 +45,7 @@ async def get_house(house_id: str, current_user: User):
return house return house
async def create_house(house_object: House, current_user: User): async def create_house(house_object: House, current_user: PublicUser):
await check_database() await check_database()
houses = learnhouseDB["houses"] houses = learnhouseDB["houses"]
@ -78,7 +78,7 @@ async def create_house(house_object: House, current_user: User):
return house.dict() return house.dict()
async def update_house(house_object: House, house_id: str, current_user: User): async def update_house(house_object: House, house_id: str, current_user: PublicUser):
await check_database() await check_database()
# verify house rights # verify house rights
@ -88,14 +88,11 @@ async def update_house(house_object: House, house_id: str, current_user: User):
house = houses.find_one({"house_id": house_id}) house = houses.find_one({"house_id": house_id})
if house:
# get owner value from house object database # get owner value from house object database
owners = house["owners"] owners = house["owners"]
admins = house["admins"] admins = house["admins"]
if not house:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="House does not exist")
updated_house = HouseInDB( updated_house = HouseInDB(
house_id=house_id, owners=owners, admins=admins, **house_object.dict()) house_id=house_id, owners=owners, admins=admins, **house_object.dict())
@ -103,8 +100,14 @@ async def update_house(house_object: House, house_id: str, current_user: User):
return HouseInDB(**updated_house.dict()) return HouseInDB(**updated_house.dict())
else:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="House does not exist")
async def delete_house(house_id: str, current_user: User):
async def delete_house(house_id: str, current_user: PublicUser):
await check_database() await check_database()
# verify house rights # verify house rights
@ -139,7 +142,7 @@ async def get_houses(page: int = 1, limit: int = 10):
#### Security #################################################### #### Security ####################################################
async def verify_house_rights(house_id: str, current_user: User, action: str): async def verify_house_rights(house_id: str, current_user: PublicUser, action: str):
await check_database() await check_database()
houses = learnhouseDB["houses"] houses = learnhouseDB["houses"]

View file

@ -2,7 +2,7 @@ import json
from typing import List from typing import List
from uuid import uuid4 from uuid import uuid4
from pydantic import BaseModel from pydantic import BaseModel
from src.services.users import User from src.services.users import PublicUser, User
from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB from src.services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
from src.services.security import * from src.services.security import *
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks
@ -61,7 +61,7 @@ async def get_organization_by_slug(org_slug: str):
return org return org
async def create_org(org_object: Organization, current_user: User): async def create_org(org_object: Organization, current_user: PublicUser):
await check_database() await check_database()
orgs = learnhouseDB["organizations"] orgs = learnhouseDB["organizations"]
@ -88,21 +88,21 @@ async def create_org(org_object: Organization, current_user: User):
return org.dict() return org.dict()
async def update_org(org_object: Organization, org_id: str, current_user: User): async def update_org(org_object: Organization, org_id: str, current_user: PublicUser):
await check_database() await check_database()
# verify org rights # verify org rights
await verify_org_rights(org_id, current_user) await verify_org_rights(org_id, current_user,"update")
orgs = learnhouseDB["organizations"] orgs = learnhouseDB["organizations"]
org = orgs.find_one({"org_id": org_id}) org = orgs.find_one({"org_id": org_id})
# get owner & adminds value from org object database if org:
owners = org["owners"] owners = org["owners"]
admins = org["admins"] admins = org["admins"]
if not org: else:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist") status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist")
@ -114,7 +114,7 @@ async def update_org(org_object: Organization, org_id: str, current_user: User):
return Organization(**updated_org.dict()) return Organization(**updated_org.dict())
async def delete_org(org_id: str, current_user: User): async def delete_org(org_id: str, current_user: PublicUser):
await check_database() await check_database()
await verify_org_rights(org_id, current_user,"delete") await verify_org_rights(org_id, current_user,"delete")
@ -160,7 +160,7 @@ async def get_orgs_by_user(user_id: str, page: int = 1, limit: int = 10):
#### Security #################################################### #### Security ####################################################
async def verify_org_rights(org_id: str, current_user: User, action: str,): async def verify_org_rights(org_id: str, current_user: PublicUser, action: str,):
await check_database() await check_database()
orgs = learnhouseDB["organizations"] orgs = learnhouseDB["organizations"]

View file

@ -58,7 +58,7 @@ async def get_role(role_id: str):
return role return role
async def create_role(role_object: Role, current_user: User): async def create_role(role_object: Role, current_user: PublicUser):
await check_database() await check_database()
roles = learnhouseDB["roles"] roles = learnhouseDB["roles"]
@ -86,7 +86,7 @@ async def create_role(role_object: Role, current_user: User):
return role.dict() return role.dict()
async def update_role(role_object: House, role_id: str, current_user: User): async def update_role(role_object: Role, role_id: str, current_user: PublicUser):
await check_database() await check_database()
# verify house rights # verify house rights
@ -98,7 +98,7 @@ async def update_role(role_object: House, role_id: str, current_user: User):
if not role: if not role:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="House does not exist") status_code=status.HTTP_409_CONFLICT, detail="Role does not exist")
updated_role = RoleInDB( updated_role = RoleInDB(
role_id=role_id, updateDate=str(datetime.now()), creationDate=role["creationDate"], **role_object.dict()) role_id=role_id, updateDate=str(datetime.now()), creationDate=role["creationDate"], **role_object.dict())
@ -108,7 +108,7 @@ async def update_role(role_object: House, role_id: str, current_user: User):
return RoleInDB(**updated_role.dict()) return RoleInDB(**updated_role.dict())
async def delete_role(role_id: str, current_user: User): async def delete_role(role_id: str, current_user: PublicUser):
await check_database() await check_database()
# verify house rights # verify house rights

View file

@ -42,7 +42,7 @@ class UserInDB(UserWithPassword):
async def get_user(username: str): async def get_user(username: str):
check_database() await check_database()
users = learnhouseDB["users"] users = learnhouseDB["users"]
user = users.find_one({"username": username}) user = users.find_one({"username": username})
@ -56,7 +56,7 @@ async def get_user(username: str):
async def get_user_by_userid(user_id: str): async def get_user_by_userid(user_id: str):
check_database() await check_database()
users = learnhouseDB["users"] users = learnhouseDB["users"]
user = users.find_one({"user_id": user_id}) user = users.find_one({"user_id": user_id})
@ -70,7 +70,7 @@ async def get_user_by_userid(user_id: str):
async def security_get_user(email: str): async def security_get_user(email: str):
check_database() await check_database()
users = learnhouseDB["users"] users = learnhouseDB["users"]
user = users.find_one({"email": email}) user = users.find_one({"email": email})
@ -83,7 +83,7 @@ async def security_get_user(email: str):
async def get_userid_by_username(username: str): async def get_userid_by_username(username: str):
check_database() await check_database()
users = learnhouseDB["users"] users = learnhouseDB["users"]
user = users.find_one({"username": username}) user = users.find_one({"username": username})
@ -96,7 +96,7 @@ async def get_userid_by_username(username: str):
async def update_user(user_id: str, user_object: UserWithPassword): async def update_user(user_id: str, user_object: UserWithPassword):
check_database() await check_database()
users = learnhouseDB["users"] users = learnhouseDB["users"]
isUserExists = users.find_one({"user_id": user_id}) isUserExists = users.find_one({"user_id": user_id})
@ -119,7 +119,7 @@ async def update_user(user_id: str, user_object: UserWithPassword):
async def delete_user(user_id: str): async def delete_user(user_id: str):
check_database() await check_database()
users = learnhouseDB["users"] users = learnhouseDB["users"]
isUserAvailable = users.find_one({"user_id": user_id}) isUserAvailable = users.find_one({"user_id": user_id})
@ -134,7 +134,7 @@ async def delete_user(user_id: str):
async def create_user(user_object: UserWithPassword): async def create_user(user_object: UserWithPassword):
check_database() await check_database()
users = learnhouseDB["users"] users = learnhouseDB["users"]
isUserAvailable = users.find_one({"username": user_object.username}) isUserAvailable = users.find_one({"username": user_object.username})