update many files

This commit is contained in:
ben
2026-08-03 16:21:10 +02:00
parent 9e69edc08b
commit cff9aa0dd1
5 changed files with 220 additions and 110 deletions
+8 -22
View File
@@ -5,7 +5,10 @@ from datetime import datetime, timedelta
from fastapi import Header, HTTPException
from dotenv import load_dotenv
import os
from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
security = HTTPBearer()
load_dotenv()
SECRET_KEY = os.getenv("SECRET_KEY")
@@ -64,19 +67,10 @@ def verify_user(username, password):
return None
def get_current_user(authorization: str = Header(None)):
if authorization is None:
raise HTTPException(
status_code=401,
detail="Missing token"
)
try:
scheme, token = authorization.split(" ")
if scheme.lower() != "bearer":
raise Exception()
def get_current_user(
credentials: HTTPAuthorizationCredentials = Depends(security)
):
token = credentials.credentials
payload = jwt.decode(
token,
@@ -84,12 +78,4 @@ def get_current_user(authorization: str = Header(None)):
algorithms=[ALGORITHM]
)
user_id = payload["user_id"]
return user_id
except JWTError:
raise HTTPException(
status_code=401,
detail="Invalid token"
)
return payload["user_id"]
+115 -54
View File
@@ -1,22 +1,24 @@
from fastapi import FastAPI
from fastapi import FastAPI, Depends
from pydantic import BaseModel
from database import fetch_all
from database import fetch_all, fetch_one
from events import create_event
from auth import create_user, verify_user, create_token
from auth import create_user, verify_user, create_token, get_current_user
from rooms import create_room, search_room, accept_room
class Login(BaseModel):
username: str
password: str
class UserCreate(BaseModel):
username: str
password: str
class EventCreate(BaseModel):
room_id: int
creator_id: int
type: str
title: str
description: str
@@ -26,19 +28,20 @@ class EventCreate(BaseModel):
status: str
min_people: int
class RoomCreate(BaseModel):
room_name: str
creator_id: int
invite_code: str
class RoomSearch(BaseModel):
user_id: int
invite_code: str
class RoomJoin(BaseModel):
user_id: int
invite_code: str
app = FastAPI(
title="Calendar API",
description="Room based agenda system",
@@ -50,8 +53,7 @@ app = FastAPI(
def home():
return {
"status": "online",
"service": "Calendar API",
"cheese": "tasty"
"service": "Calendar API"
}
@@ -66,42 +68,15 @@ def database_status():
}
@app.post("/events")
def api_create_event(event: EventCreate):
# users
event_id = create_event(
room_id=event.room_id,
creator_id=event.creator_id,
type=event.type,
title=event.title,
description=event.description,
start_time=event.start_time,
end_time=event.end_time,
visibility=event.visibility,
status=event.status,
min_people=event.min_people
)
return {
"status": "created",
"event_id": event_id
}
@app.get("/events")
def get_events():
events = fetch_all("SELECT * FROM events;")
return {
"events": [dict(event) for event in events]
}
@app.post("/create-user")
def api_create_user(user: UserCreate):
user_id = create_user(
username=user.username,
password=user.password,
user.username,
user.password
)
return {
@@ -109,6 +84,7 @@ def api_create_user(user: UserCreate):
"user_id": user_id
}
@app.post("/login")
def api_login(login: Login):
@@ -131,46 +107,65 @@ def api_login(login: Login):
}
@app.post("/create_room")
def api_create_room(room: RoomCreate):
@app.get("/me")
def get_me(
user_id: int = Depends(get_current_user)
):
return {
"user_id": user_id
}
# rooms
@app.post("/create-room")
def api_create_room(
room: RoomCreate,
user_id: int = Depends(get_current_user)
):
room_id = create_room(
room.room_name,
room.creator_id,
user_id,
room.invite_code
)
if room_id is None:
return {
"status": "failed"
}
return {
"status": "success",
"status": "created",
"room_id": room_id
}
@app.post("/search-room")
def api_search_room(search_for_room: RoomSearch):
def api_search_room(
room: RoomSearch
):
room_name = search_room(
search_for_room.invite_code
room.invite_code
)
if room_name is None:
return {
"status": "failed"
"status": "failed",
"reason": "room_not_found"
}
return {
"status": "success",
"status": "found",
"room_name": room_name
}
@app.post("/join-room")
def api_join_room(room: RoomJoin):
def api_join_room(
room: RoomJoin,
user_id: int = Depends(get_current_user)
):
result = accept_room(
room.user_id,
user_id,
room.invite_code
)
@@ -184,3 +179,69 @@ def api_join_room(room: RoomJoin):
"status": "joined",
**result
}
# events
@app.post("/events")
def api_create_event(
event: EventCreate,
user_id: int = Depends(get_current_user)
):
# check of gebruiker lid is
member = fetch_one(
"""
SELECT *
FROM room_members
WHERE room_id = ?
AND user_id = ?
""",
(
event.room_id,
user_id
)
)
if member is None:
return {
"status": "failed",
"reason": "not_room_member"
}
event_id = create_event(
room_id=event.room_id,
creator_id=user_id,
type=event.type,
title=event.title,
description=event.description,
start_time=event.start_time,
end_time=event.end_time,
visibility=event.visibility,
status=event.status,
min_people=event.min_people
)
return {
"status": "created",
"event_id": event_id
}
@app.get("/events")
def get_events(
user_id: int = Depends(get_current_user)
):
events = fetch_all(
"""
SELECT *
FROM events
WHERE creator_id = ?
""",
(user_id,)
)
return {
"events": [dict(event) for event in events]
}
+29 -14
View File
@@ -81,39 +81,54 @@ def search_room(
return room["name"]
def accept_room(
user_id,
invite_code
):
def accept_room(user_id, invite_code):
query = """
SELECT id
FROM rooms
WHERE invite_code = ?
"""
room = fetch_one(
query,
(
invite_code,
)
(invite_code,)
)
if room is None:
return None
room_id = room["id"]
role = DEFAULT_ROLE
query2 = """
INSERT INTO "main"."room_members"
("room_id", "user_id", "role")
VALUES (?, ?, ?);
# check dubbele join
existing = fetch_one(
"""
SELECT id
FROM room_members
WHERE room_id = ?
AND user_id = ?
""",
(
room_id,
user_id
)
)
if existing:
return None
query = """
INSERT INTO room_members
(room_id, user_id, role)
VALUES (?, ?, ?)
"""
member_id = execute(
query2,
query,
(
room_id,
user_id,
role
"member"
)
)
Binary file not shown.
+59 -11
View File
@@ -3,8 +3,13 @@ import sqlite3
DB_NAME = "calendar.db"
conn = sqlite3.connect(DB_NAME)
# SQLite foreign keys activeren
conn.execute("PRAGMA foreign_keys = ON;")
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -13,73 +18,116 @@ CREATE TABLE IF NOT EXISTS users (
);
""")
cur.execute("""
CREATE TABLE IF NOT EXISTS rooms (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
owner_id INTEGER NOT NULL,
invite_code TEXT UNIQUE,
invite_code TEXT NOT NULL UNIQUE,
FOREIGN KEY (owner_id) REFERENCES users(id)
);
""")
cur.execute("""
CREATE TABLE IF NOT EXISTS room_members (
room_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
role TEXT NOT NULL DEFAULT 'member',
role TEXT NOT NULL DEFAULT 'member'
CHECK(role IN ('owner', 'admin', 'member')),
PRIMARY KEY (room_id, user_id),
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
FOREIGN KEY (room_id)
REFERENCES rooms(id)
ON DELETE CASCADE,
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE
);
""")
cur.execute("""
CREATE TABLE IF NOT EXISTS events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
room_id INTEGER NOT NULL,
creator_id INTEGER NOT NULL,
type TEXT NOT NULL CHECK(type IN ('private', 'busy', 'proposal')),
type TEXT NOT NULL
CHECK(type IN ('private', 'busy', 'proposal')),
title TEXT NOT NULL,
description TEXT,
start_time TEXT NOT NULL,
end_time TEXT NOT NULL,
visibility TEXT NOT NULL CHECK(visibility IN ('private', 'busy_only', 'room')),
visibility TEXT NOT NULL
CHECK(visibility IN ('private', 'busy_only', 'room')),
status TEXT NOT NULL DEFAULT 'draft'
CHECK(status IN ('draft', 'proposed', 'confirmed', 'cancelled')),
min_people INTEGER DEFAULT 0,
FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE,
FOREIGN KEY (creator_id) REFERENCES users(id)
FOREIGN KEY (room_id)
REFERENCES rooms(id)
ON DELETE CASCADE,
FOREIGN KEY (creator_id)
REFERENCES users(id)
);
""")
cur.execute("""
CREATE TABLE IF NOT EXISTS event_signups (
event_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
status TEXT NOT NULL DEFAULT 'going'
CHECK(status IN ('going', 'maybe', 'declined')),
PRIMARY KEY(event_id, user_id),
FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
FOREIGN KEY(event_id)
REFERENCES events(id)
ON DELETE CASCADE,
FOREIGN KEY(user_id)
REFERENCES users(id)
ON DELETE CASCADE
);
""")
# Snellere zoekopdrachten
cur.execute("""
CREATE INDEX IF NOT EXISTS idx_room_members_user
ON room_members(user_id);
""")
cur.execute("""
CREATE INDEX IF NOT EXISTS idx_events_room
ON events(room_id);
""")
conn.commit()
print("Database aangemaakt.")
print("Tabellen:")
for row in cur.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;"):
for row in cur.execute(
"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;"
):
print(" -", row[0])
conn.close()