init orgs

This commit is contained in:
swve 2022-06-28 23:56:13 +02:00
parent 91f4291d9b
commit 13c6193bea
5 changed files with 221 additions and 22 deletions

View file

@ -1,18 +1,13 @@
from .routers import users
from fastapi import APIRouter from fastapi import APIRouter
from .routers import users, auth, houses from src.routers import users, auth, houses, orgs
from starlette.responses import FileResponse from starlette.responses import FileResponse
global_router = APIRouter(prefix="/api") global_router = APIRouter(prefix="/api")
## API Routes # API Routes
global_router.include_router(users.router, prefix="/users", tags=["users"]) global_router.include_router(users.router, prefix="/users", tags=["users"])
global_router.include_router(auth.router, prefix="/auth", tags=["auth"]) global_router.include_router(auth.router, prefix="/auth", tags=["auth"])
global_router.include_router(houses.router, prefix="/houses", tags=["houses"]) global_router.include_router(houses.router, prefix="/houses", tags=["houses"])
global_router.include_router(orgs.router, prefix="/orgs", tags=["orgs"])

View file

@ -24,7 +24,7 @@ async def api_get_house(house_id: str):
return await get_house(house_id) return await get_house(house_id)
@router.get("/page/{house_id}/limit/{limit}") @router.get("/page/{page}/limit/{limit}")
async def api_get_house_by(page: int, limit: int): async def api_get_house_by(page: int, limit: int):
""" """
Get houses by page and limit Get houses by page and limit

48
src/routers/orgs.py Normal file
View file

@ -0,0 +1,48 @@
from fastapi import APIRouter, Depends
from src.services.auth import get_current_user
from src.services.orgs import Organization, create_org, delete_org, get_organization, get_orgs, update_org
from src.services.users import User
router = APIRouter()
@router.post("/")
async def api_create_org(org_object: Organization, current_user: User = Depends(get_current_user)):
"""
Create new organization
"""
return await create_org(org_object, current_user)
@router.get("/{org_id}")
async def api_get_org(org_id: str):
"""
Get single Org by ID
"""
return await get_organization(org_id)
@router.get("/page/{page}/limit/{limit}")
async def api_get_org_by(page: int, limit: int):
"""
Get orgs by page and limit
"""
return await get_orgs(page, limit)
@router.put("/{org_id}")
async def api_update_org(org_object: Organization, org_id: str, current_user: User = Depends(get_current_user)):
"""
Update Org by ID
"""
return await update_org(org_object, org_id, current_user)
@router.delete("/{org_id}")
async def api_delete_org(org_id: str, current_user: User = Depends(get_current_user)):
"""
Delete Org by ID
"""
return await delete_org(org_id, current_user)

View file

@ -22,6 +22,7 @@ class House(BaseModel):
class HouseInDB(House): class HouseInDB(House):
house_id: str house_id: str
owners: List[str] owners: List[str]
admins: List[str]
#### Classes #################################################### #### Classes ####################################################
@ -55,6 +56,7 @@ async def create_house(house_object: House, current_user: User):
house_id = str(f"house_{uuid4()}") house_id = str(f"house_{uuid4()}")
house = HouseInDB(house_id=house_id, owners=[ house = HouseInDB(house_id=house_id, owners=[
current_user.username], admins=[
current_user.username], **house_object.dict()) current_user.username], **house_object.dict())
house_in_db = houses.insert_one(house.dict()) house_in_db = houses.insert_one(house.dict())
@ -68,22 +70,24 @@ async def create_house(house_object: House, current_user: User):
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: User):
await check_database() await check_database()
# verify house rights # verify house rights
await verify_house_ownership(house_id, current_user) await verify_house_rights(house_id, current_user)
houses = learnhouseDB["houses"] houses = learnhouseDB["houses"]
house = houses.find_one({"house_id": house_id}) house = houses.find_one({"house_id": house_id})
## get owner value from house object database # get owner value from house object database
owners = house["owners"] owners = house["owners"]
admins = house["admins"]
if not house: if not house:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="House does not exist") status_code=status.HTTP_409_CONFLICT, detail="House does not exist")
updated_house = HouseInDB(house_id=house_id, owners=owners, **house_object.dict()) updated_house = HouseInDB(
house_id=house_id, owners=owners, admins=admins, **house_object.dict())
houses.update_one({"house_id": house_id}, {"$set": updated_house.dict()}) houses.update_one({"house_id": house_id}, {"$set": updated_house.dict()})
@ -92,10 +96,10 @@ async def update_house(house_object: House, house_id: str, current_user: User):
async def delete_house(house_id: str, current_user: User): async def delete_house(house_id: str, current_user: User):
await check_database() await check_database()
# verify house rights # verify house rights
await verify_house_ownership(house_id, current_user) await verify_house_rights(house_id, current_user)
houses = learnhouseDB["houses"] houses = learnhouseDB["houses"]
house = houses.find_one({"house_id": house_id}) house = houses.find_one({"house_id": house_id})
@ -125,7 +129,7 @@ async def get_houses(page: int = 1, limit: int = 10):
#### Security #################################################### #### Security ####################################################
async def verify_house_ownership(house_id: str, current_user: User): async def verify_house_rights(house_id: str, current_user: User):
await check_database() await check_database()
houses = learnhouseDB["houses"] houses = learnhouseDB["houses"]
@ -135,9 +139,12 @@ async def verify_house_ownership(house_id: str, current_user: User):
raise HTTPException( raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="House does not exist") status_code=status.HTTP_409_CONFLICT, detail="House does not exist")
if current_user.username not in house["owners"]: isAdmin = current_user.username in house["admins"]
isOwner = current_user.username in house["owners"]
if not isAdmin and not isOwner:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="User does not own this house") status_code=status.HTTP_403_FORBIDDEN, detail="You do not have rights to this house")
return True return True

149
src/services/orgs.py Normal file
View file

@ -0,0 +1,149 @@
import json
from typing import List
from uuid import uuid4
from pydantic import BaseModel
from src.services.users import User
from ..services.database import create_config_collection, check_database, create_database, learnhouseDB, learnhouseDB
from ..services.security import *
from fastapi import FastAPI, HTTPException, status, Request, Response, BackgroundTasks
from datetime import datetime
#### Classes ####################################################
class Organization(BaseModel):
name: str
description: str
email: str
class OrganizationInDB(Organization):
org_id: str
owners: List[str]
admins: List[str]
#### Classes ####################################################
async def get_organization(org_id: str):
await check_database()
orgs = learnhouseDB["organizations"]
org = orgs.find_one({"org_id": org_id})
if not org:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist")
org = Organization(**org)
return org
async def create_org(org_object: Organization, current_user: User):
await check_database()
orgs = learnhouseDB["organizations"]
# find if org already exists using name
isOrgAvailable = orgs.find_one({"name": org_object.name})
if isOrgAvailable:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Organization name already exists")
# generate org_id with uuid4
org_id = str(f"org_{uuid4()}")
org = OrganizationInDB(org_id=org_id, owners=[
current_user.username], admins=[
current_user.username], **org_object.dict())
org_in_db = 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 update_org(org_object: Organization, org_id: str, current_user: User):
await check_database()
# verify org rights
await verify_org_rights(org_id, current_user)
orgs = learnhouseDB["organizations"]
org = orgs.find_one({"org_id": org_id})
# get owner & adminds value from org object database
owners = org["owners"]
admins = org["admins"]
if not org:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist")
updated_org = OrganizationInDB(
org_id=org_id, owners=owners, admins=admins, **org_object.dict())
orgs.update_one({"org_id": org_id}, {"$set": updated_org.dict()})
return Organization(**updated_org.dict())
async def delete_org(org_id: str, current_user: User):
await check_database()
await verify_org_rights(org_id, current_user)
orgs = learnhouseDB["organizations"]
org = orgs.find_one({"org_id": org_id})
if not org:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist")
isDeleted = orgs.delete_one({"org_id": org_id})
if isDeleted:
return {"detail": "Org deleted"}
else:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database")
async def get_orgs(page: int = 1, limit: int = 10):
await check_database()
orgs = learnhouseDB["orgs"]
# get all orgs from database
all_orgs = orgs.find().sort("name", 1).skip(10 * (page - 1)).limit(limit)
return [json.loads(json.dumps(house, default=str)) for house in all_orgs]
#### Security ####################################################
async def verify_org_rights(org_id: str, current_user: User):
await check_database()
orgs = learnhouseDB["organizations"]
org = orgs.find_one({"org_id": org_id})
if not org:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist")
isAdmin = current_user.username in org["admins"]
isOwner = current_user.username in org["owners"]
if not isAdmin and not isOwner:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="You do not have rights to this organization")
return True
#### Security ####################################################