141 lines
3.6 KiB
TypeScript
141 lines
3.6 KiB
TypeScript
/**
|
|
* Zentrale Definition aller Berechtigungen.
|
|
*
|
|
* Aus plan.md Abschnitt 20: Eine zentrale Berechtigungsschicht, damit
|
|
* Berechtigungslogik nicht ueber den ganzen Code verteilt wird.
|
|
* Alle API-Routen und Server-Komponenten MUSSSEN diese Funktionen
|
|
* verwenden statt eigene Ad-hoc-Pruefungen zu schreiben.
|
|
*/
|
|
import type { Role } from '@prisma/client';
|
|
|
|
/** Minimal notwendige Informationen ueber den angemeldeten Benutzer. */
|
|
export interface AuthenticatedUser {
|
|
id: string;
|
|
email: string;
|
|
/** Frei waehlbarer Anzeigename; null, wenn nicht gesetzt. */
|
|
username: string | null;
|
|
role: Role;
|
|
}
|
|
|
|
/** Minimal notwendige Informationen ueber einen Kalender. */
|
|
export interface CalendarRef {
|
|
id: string;
|
|
ownerId: string;
|
|
isActive: boolean;
|
|
}
|
|
|
|
/** Minimal notwendige Informationen ueber eine Reservierung. */
|
|
export interface ReservationRef {
|
|
id: string;
|
|
calendarId: string;
|
|
userId: string;
|
|
}
|
|
|
|
/** Minimal notwendige Informationen ueber eine Mitgliedschaft. */
|
|
export interface MembershipRef {
|
|
calendarId: string;
|
|
userId: string;
|
|
}
|
|
|
|
/**
|
|
* Darf der User den Kalender sehen?
|
|
* Admin: alle Kalender (Verwaltungsrolle). User: nur Kalender, in
|
|
* denen er Mitglied ist. Deaktivierte Kalender bleiben fuer Member
|
|
* sichtbar (mit Hinweis), damit sie ihre Reservierungen noch einsehen
|
|
* koennen.
|
|
*/
|
|
export function canViewCalendar(
|
|
user: AuthenticatedUser,
|
|
calendar: CalendarRef,
|
|
isMember: boolean,
|
|
): boolean {
|
|
if (user.role === 'ADMIN') {
|
|
return true;
|
|
}
|
|
return isMember;
|
|
}
|
|
|
|
/**
|
|
* Darf der User den Kalender verwalten (bearbeiten, Invites erstellen,
|
|
* loeschen)? Admins duerfen alle Kalender verwalten (auch die anderer
|
|
* Benutzer), normale User keinen.
|
|
*/
|
|
export function canManageCalendar(
|
|
user: AuthenticatedUser,
|
|
calendar: CalendarRef,
|
|
): boolean {
|
|
return user.role === 'ADMIN';
|
|
}
|
|
|
|
/**
|
|
* Darf der User eine Reservierung in diesem Kalender erstellen?
|
|
* Admins in allen aktiven Kalendern, User nur in ihrem einen Kalender
|
|
* (Mitgliedschaft). Deaktivierte Kalender erlauben keine neuen
|
|
* Reservierungen.
|
|
*/
|
|
export function canCreateReservation(
|
|
user: AuthenticatedUser,
|
|
calendar: CalendarRef,
|
|
isMember: boolean,
|
|
): boolean {
|
|
if (!calendar.isActive) {
|
|
return false;
|
|
}
|
|
if (user.role === 'ADMIN') {
|
|
return true;
|
|
}
|
|
return isMember;
|
|
}
|
|
|
|
/**
|
|
* Darf der User eine Reservierung LOESCHEN?
|
|
* Ausschliesslich Admins (in allen Kalendern). Normale User koennen
|
|
* Reservierungen nur anlegen und sehen - nicht loeschen.
|
|
*/
|
|
export function canDeleteReservation(
|
|
user: AuthenticatedUser,
|
|
_reservation: ReservationRef,
|
|
calendar: CalendarRef,
|
|
): boolean {
|
|
return user.role === 'ADMIN' && canViewCalendar(user, calendar, false);
|
|
}
|
|
|
|
/**
|
|
* Darf der User die Reservierung sehen?
|
|
* Admin: in allen Kalendern alle. User: nur eigene Reservierungen
|
|
* im eigenen Kalender.
|
|
*/
|
|
export function canViewReservation(
|
|
user: AuthenticatedUser,
|
|
reservation: ReservationRef,
|
|
calendar: CalendarRef,
|
|
isMember: boolean,
|
|
): boolean {
|
|
if (!canViewCalendar(user, calendar, isMember)) {
|
|
return false;
|
|
}
|
|
if (user.role === 'ADMIN') {
|
|
return true;
|
|
}
|
|
return reservation.userId === user.id;
|
|
}
|
|
|
|
/**
|
|
* Darf der User die Reservierung aendern oder loeschen?
|
|
* Admin: alle Reservierungen in allen Kalendern.
|
|
* User: ausschliesslich eigene Reservierungen.
|
|
*/
|
|
export function canModifyReservation(
|
|
user: AuthenticatedUser,
|
|
reservation: ReservationRef,
|
|
calendar: CalendarRef,
|
|
isMember: boolean,
|
|
): boolean {
|
|
if (!canViewCalendar(user, calendar, isMember)) {
|
|
return false;
|
|
}
|
|
if (user.role === 'ADMIN') {
|
|
return true;
|
|
}
|
|
return reservation.userId === user.id;
|
|
} |