feat: init activities

This commit is contained in:
swve 2023-11-14 22:30:39 +01:00
parent ee07f49139
commit 727f17ba7c
9 changed files with 358 additions and 370 deletions

View file

@ -1,35 +1,21 @@
import stat
from typing import Literal
from pydantic import BaseModel
from sqlmodel import Session, select
from src.db.organizations import Organization
from src import db
from src.db.activities import ActivityCreate, Activity, ActivityRead, ActivityUpdate
from src.db.chapter_activities import ChapterActivity
from src.security.rbac.rbac import (
authorization_verify_based_on_roles,
authorization_verify_if_element_is_public,
authorization_verify_if_user_is_anon,
)
from src.services.users.schemas.users import AnonymousUser, PublicUser
from src.db.users import AnonymousUser, PublicUser
from fastapi import HTTPException, status, Request
from uuid import uuid4
from datetime import datetime
#### Classes ####################################################
class Activity(BaseModel):
name: str
type: str
content: object
class ActivityInDB(Activity):
activity_id: str
course_id: str
coursechapter_id: str
org_id: str
creationDate: str
updateDate: str
#### Classes ####################################################
####################################################
# CRUD
@ -38,148 +24,130 @@ class ActivityInDB(Activity):
async def create_activity(
request: Request,
activity_object: Activity,
org_id: str,
coursechapter_id: str,
activity_object: ActivityCreate,
current_user: PublicUser,
db_session: Session,
):
activities = request.app.db["activities"]
courses = request.app.db["courses"]
users = request.app.db["users"]
activity = Activity.from_orm(activity_object)
# get user
user = await users.find_one({"user_id": current_user.user_id})
# CHeck if org exists
statement = select(Organization).where(Organization.id == activity_object.org_id)
org = db_session.exec(statement).first()
# generate activity_id
activity_id = str(f"activity_{uuid4()}")
if not org:
raise HTTPException(
status_code=404,
detail="Organization not found",
)
# verify activity rights
await authorization_verify_based_on_roles(
request,
current_user.user_id,
"create",
user["roles"],
activity_id,
activity.activity_uuid = str(f"activity_{uuid4()}")
activity.creation_date = str(datetime.now())
activity.update_date = str(datetime.now())
# Insert Activity in DB
db_session.add(activity)
db_session.commit()
db_session.refresh(activity)
# Add activity to chapter
activity_chapter = ChapterActivity(
chapter_id=activity_object.chapter_id,
activity_id=activity.id is not None,
course_id=activity_object.course_id,
org_id=activity_object.org_id,
creation_date=str(datetime.now()),
update_date=str(datetime.now()),
order=activity_object.order,
)
# get course_id from activity
course = await courses.find_one({"chapters": coursechapter_id})
# Insert ChapterActivity link in DB
db_session.add(activity_chapter)
db_session.commit()
db_session.refresh(activity_chapter)
# create activity
activity = ActivityInDB(
**activity_object.dict(),
creationDate=str(datetime.now()),
coursechapter_id=coursechapter_id,
updateDate=str(datetime.now()),
activity_id=activity_id,
org_id=org_id,
course_id=course["course_id"],
)
await activities.insert_one(activity.dict())
# update chapter
await courses.update_one(
{"chapters_content.coursechapter_id": coursechapter_id},
{"$addToSet": {"chapters_content.$.activities": activity_id}},
)
return activity
return ActivityRead.from_orm(activity)
async def get_activity(request: Request, activity_id: str, current_user: PublicUser):
activities = request.app.db["activities"]
courses = request.app.db["courses"]
activity = await activities.find_one({"activity_id": activity_id})
# get course_id from activity
coursechapter_id = activity["coursechapter_id"]
await courses.find_one({"chapters": coursechapter_id})
# verify course rights
await verify_rights(request, activity["course_id"], current_user, "read")
async def get_activity(
request: Request,
activity_id: str,
current_user: PublicUser,
db_session: Session,
):
statement = select(Activity).where(Activity.id == activity_id)
activity = db_session.exec(statement).first()
if not activity:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist"
status_code=404,
detail="Activity not found",
)
activity = ActivityInDB(**activity)
return activity
async def update_activity(
request: Request,
activity_object: Activity,
activity_id: str,
activity_object: ActivityUpdate,
current_user: PublicUser,
db_session: Session,
):
activities = request.app.db["activities"]
activity = await activities.find_one({"activity_id": activity_id})
# verify course rights
await verify_rights(request, activity_id, current_user, "update")
if activity:
creationDate = activity["creationDate"]
# get today's date
datetime_object = datetime.now()
updated_course = ActivityInDB(
activity_id=activity_id,
coursechapter_id=activity["coursechapter_id"],
creationDate=creationDate,
updateDate=str(datetime_object),
course_id=activity["course_id"],
org_id=activity["org_id"],
**activity_object.dict(),
)
await activities.update_one(
{"activity_id": activity_id}, {"$set": updated_course.dict()}
)
return ActivityInDB(**updated_course.dict())
else:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="activity does not exist"
)
async def delete_activity(request: Request, activity_id: str, current_user: PublicUser):
activities = request.app.db["activities"]
activity = await activities.find_one({"activity_id": activity_id})
# verify course rights
await verify_rights(request, activity_id, current_user, "delete")
statement = select(Activity).where(Activity.id == activity_object.activity_id)
activity = db_session.exec(statement).first()
if not activity:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="activity does not exist"
status_code=404,
detail="Activity not found",
)
# Remove Activity
isDeleted = await activities.delete_one({"activity_id": activity_id})
del activity_object.activity_id
# Remove Activity from chapter
courses = request.app.db["courses"]
isDeletedFromChapter = await courses.update_one(
{"chapters_content.activities": activity_id},
{"$pull": {"chapters_content.$.activities": activity_id}},
)
# Update only the fields that were passed in
for var, value in vars(activity_object).items():
if value is not None:
setattr(activity, var, value)
if isDeleted and isDeletedFromChapter:
return {"detail": "Activity deleted"}
else:
db_session.add(activity)
db_session.commit()
db_session.refresh(activity)
return activity
async def delete_activity(
request: Request,
activity_id: str,
current_user: PublicUser,
db_session: Session,
):
statement = select(Activity).where(Activity.id == activity_id)
activity = db_session.exec(statement).first()
if not activity:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Unavailable database",
status_code=404,
detail="Activity not found",
)
# Delete activity from chapter
statement = select(ChapterActivity).where(
ChapterActivity.activity_id == activity_id
)
activity_chapter = db_session.exec(statement).first()
if not activity_chapter:
raise HTTPException(
status_code=404,
detail="Activity not found in chapter",
)
db_session.delete(activity_chapter)
db_session.delete(activity)
db_session.commit()
return {"detail": "Activity deleted"}
####################################################
# Misc
@ -187,64 +155,20 @@ async def delete_activity(request: Request, activity_id: str, current_user: Publ
async def get_activities(
request: Request, coursechapter_id: str, current_user: PublicUser
request: Request,
coursechapter_id: str,
current_user: PublicUser,
db_session: Session,
):
activities = request.app.db["activities"]
activities = activities.find({"coursechapter_id": coursechapter_id})
statement = select(ChapterActivity).where(
ChapterActivity.chapter_id == coursechapter_id
)
activities = db_session.exec(statement).all()
if not activities:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist"
status_code=404,
detail="No activities found",
)
activities = [
ActivityInDB(**activity) for activity in await activities.to_list(length=100)
]
return activities
#### Security ####################################################
async def verify_rights(
request: Request,
activity_id: str, # course_id in case of read
current_user: PublicUser | AnonymousUser,
action: Literal["create", "read", "update", "delete"],
):
if action == "read":
if current_user.user_id == "anonymous":
await authorization_verify_if_element_is_public(
request, activity_id, current_user.user_id, action
)
else:
users = request.app.db["users"]
user = await users.find_one({"user_id": current_user.user_id})
await authorization_verify_if_user_is_anon(current_user.user_id)
await authorization_verify_based_on_roles(
request,
current_user.user_id,
action,
user["roles"],
activity_id,
)
else:
users = request.app.db["users"]
user = await users.find_one({"user_id": current_user.user_id})
await authorization_verify_if_user_is_anon(current_user.user_id)
await authorization_verify_based_on_roles(
request,
current_user.user_id,
action,
user["roles"],
activity_id,
)
#### Security ####################################################