diff --git a/README.md b/README.md index 86a9a803..5ea31e8a 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,9 @@ journey ## Architecture ```mermaid +--- +title: Ticketing architecture +--- flowchart LR %% defining styles classDef app fill:#f7e081,stroke:#333,stroke-width:1px @@ -103,60 +106,99 @@ flowchart LR ``` -## Models +## Entities ```mermaid -classDiagram -direction RL -class User { - <> - +id : int - +email : string - -password : string -} - -class Ticket { - <> - +id : string - +title : string - +price : float - +version : int - +userId : User - +orderId ?: Order -} - -class Order { - <> - +id : string - +title : string - +status : OrderStatus - +version : int - +ticketId : Ticket - +userId : User -} - -class OrderStatus{ - <> - Created - Cancelled - Complete - AwaitingPayment -} - -class Payment { - <> - +id : string - +orderId : string - +stripeId : OrderStatus - +version : int -} - -User "1" --> "*" Ticket -User "1" --> "*" Order -Ticket "1" --> "1" Order -Order ..> OrderStatus -Payment "1" --> "1" Order +--- +title: Ticketing entities +--- +erDiagram + User ||--o{ Ticket : owns + User ||--o{ Order : owns + User ||--o{ Payment : owns + Ticket ||--o| Order : "bound to" + Order ||--o| Payment : "bound to" + + User { + int id PK + string email "unique" + } + Ticket { + string id PK + string title + float price + int version + string userId FK + string orderId FK "Optional" + } + Order { + string id PK + string status + int version + string ticketId FK + string userId FK + } + Payment { + string id PK + string orderId FK + string stripeId "Charge ID from Stripe" + int version + } +``` + +## Permissions +Permissions are granted or denied using Ory Permissions (Keto) [policies](https://www.ory.sh/docs/keto/). + +```mermaid +--- +title: Entities namespaces and relationships +--- +classDiagram + note for User "Base entity for all users" + class User { + <> + } + + note for Group "Users can be members of a group" + class Group { + <> + +related.members: User[] + } + + note for Ticket "Users (in owners) are allowed to edit. \nHowever Ticket owners cannot order a ticket. \nImplicitly, anyone can view tickets" + class Ticket { + <> + +related.owners: User[] + +permits.edit(ctx: Context): boolean + +permits.order(ctx: Context): boolean + } + + note for Order "Order is bound to a ticket. \nUsers (in owners) are allowed to view and edit. \n Order's Ticket owners are allowed to view." + class Order { + <> + +related.owners: User[] + +related.parents: Tickets[] + +permits.edit(ctx: Context): boolean + +permits.view(ctx: Context): boolean + } + + note for Payment "Payment is bound to a Ticket's Order. \nUsers (in owners) are allowed to view and edit. \n Payment can be viewed by Order's Ticket owners." + class Payment { + <> + +related.owners: User[] + +related.parents: Order[] + +permits.edit(ctx: Context): boolean + +permits.view(ctx: Context): boolean + } + + note for Moderation "Only Users from specific Group can access Moderation.\n" + class Moderation { + <> + +related.editors: Group.members[] + +permits.edit(ctx: Context): boolean + +permits.view(ctx: Context): boolean + } ``` ## Events diff --git a/docker-compose.yaml b/docker-compose.yaml index 8c10b4e9..e956f084 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -513,6 +513,7 @@ services: # endregion # region Ory Oathkeeper + # oathkeeper: # image: oryd/oathkeeper:v0.40 # depends_on: diff --git a/tools/ory/namespaces.ts b/tools/ory/namespaces.ts index 6125f973..83efce6c 100644 --- a/tools/ory/namespaces.ts +++ b/tools/ory/namespaces.ts @@ -18,8 +18,8 @@ class Moderation implements Namespace { }; permits = { - view: (ctx: Context) => this.related.editors.includes(ctx.subject), edit: (ctx: Context) => this.related.editors.includes(ctx.subject), + view: (ctx: Context) => this.permits.edit(ctx.subject), }; }