Skip to content

Architecture

RacoonByte01 edited this page Oct 7, 2026 · 1 revision

Architecture

ChatyChat is a single Spring Boot application. Every request is handled by a REST controller that loads the whole state from JSON files, mutates it in memory, and writes it back.

Components

flowchart LR
    client[Client / curl]

    subgraph app["ChatyChat (Spring Boot)"]
        uc[UserController]
        gc[GroupController]
        um[UserModel]
        gm[GroupModel]
        rm[RoleModel]
        mm[MessageModel]
        f4m[Files4Models<br/>Jackson ObjectMapper]
        hash[Hash<br/>SHA-512]
    end

    subgraph disk["data/"]
        users[users.json]
        groups[groups.json]
        msgs["groups/&lt;id&gt;.json"]
    end

    client -->|Authorization: token| uc
    client -->|Authorization: token| gc
    uc --> um
    um --> hash
    uc --> f4m
    gc --> gm
    gc --> rm
    gc --> mm
    gc --> f4m
    f4m --> users
    f4m --> groups
    f4m --> msgs
Loading
Layer Files
Controllers controllers/UserController.java, controllers/GroupController.java
Models models/UserModel.java, GroupModel.java, RoleModel.java, MessageModel.java
Utils utils/Files4Models.java (JSON persistence), utils/Hash.java (SHA-512), utils/Views.java (JSON views)
Storage data/users.json, data/groups.json, data/groups/<id>.json

Storage layout

data/
|- users.json          # all users: name, password (SHA-512), pgp, tokens
|- groups.json         # all groups: id, name, { username: roleByte }
|- groups/
    |- 0.json          # messages of group 0
    |- <id>.json       # messages of group <id>
  • Group ids start at 0; new ids are max(existing ids) + 1.
  • Every read loads the file, every write rewrites the whole file.
  • On a missing/empty file the loaders return an empty list (fresh install).

Authentication flow

Tokens are opaque random strings passed raw in the Authorization header (no Bearer prefix).

sequenceDiagram
    participant C as Client
    participant U as UserController
    participant D as data/users.json

    C->>U: POST /login<br/>form: name, password
    U->>D: load users
    U->>U: SHA-512(password) == stored hash?
    U->>U: generate 32 random bytes → Base64url token
    U->>D: append token to user
    U-->>C: token

    Note over C,U: every later request

    C->>U: GET /groups<br/>Authorization: <token>
    U->>D: load users
    U->>U: find user whose token list contains header value
    U-->>C: response (or null/empty if token unknown)
Loading
  • A token belongs to one user; a user can have several tokens (several sessions).
  • DELETE /logout removes the token used in the header; DELETE /token with a token form field removes an arbitrary one.
  • Passwords are hashed with SHA-512 (no salt) at write time.

Request authorization

Two independent checks gate every group/message endpoint:

flowchart TD
    A[Request + Authorization header] --> B{User found?}
    B -- no --> X[null / empty response]
    B -- yes --> C{User is member<br/>of the group?}
    C -- no --> X
    C -- yes --> D{Required bit ON<br/>in the user's role byte?}
    D -- no --> X
    D -- yes --> E[Endpoint executes]
Loading

The role byte is per-group and per-user — see Roles.

Clone this wiki locally