Repository navigation
Architecture
RacoonByte01 edited this page Oct 7, 2026
·
1 revision
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.
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/<id>.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
| 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
|
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 aremax(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).
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)
- A token belongs to one user; a user can have several tokens (several sessions).
-
DELETE /logoutremoves the token used in the header;DELETE /tokenwith atokenform field removes an arbitrary one. - Passwords are hashed with SHA-512 (no salt) at write time.
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]
The role byte is per-group and per-user — see Roles.