feat: add Role (owner|admin) to the user domain, persistence model and mapper
This commit is contained in:
1 parent
162fea4afb
commit
461e93e3b5
30 files changed
+791
-48
No files matched your search
@@ -14,11 +14,13 @@ plus a `fixedClock` only if the use case takes one. Reuse `mockUserRepo` and `st
|
||||
3. Handler: `user.NewHandler(updateProfile, createInvite, listUsersAndInvites)` mounted on a fresh
|
||||
`chi.NewRouter()` mirroring `NewUserRouter`: `jwtauth.Verifier` + `jwtauth.Authenticator` with
|
||||
`jwtauth.New("HS256", []byte("test-secret"), nil)`, `RequireCurrentToken(getUser)`,
|
||||
`RequireVerifiedUser(getUser)`, then `POST /invite` and `GET /`. For the rate-limit case
|
||||
wrap only `POST /invite` in `TrustedProxyRealIP(nil)` + `NewRateLimiter(2, time.Minute)`.
|
||||
`RequireVerifiedUser(getUser)`, then `POST /invite` and `GET /`. `POST /invite` is also wrapped
|
||||
in `RequireOwner(getUser)`, placed before the limiter. For the rate-limit case
|
||||
wrap only `POST /invite` in `RequireOwner(getUser)` + `TrustedProxyRealIP(nil)` +
|
||||
`NewRateLimiter(2, time.Minute)`.
|
||||
Requests via `httptest`; jwt cookie built with the `user_id` and `token_version` claims as in
|
||||
`test/verified_account_required_http_test.go`. No live server, no real SQLite, no real SMTP.
|
||||
4. Seed users: verified id 7 "marta"; unverified id 8 for the 403 cases. Time is real: build
|
||||
4. Seed users: verified id 7 "marta" with `Role: owner`; unverified id 8 for the 403 cases. Time is real: build
|
||||
invites with `ExpiresAt`/`CreatedAt` relative to `time.Now()` and compare with a 5 s tolerance.
|
||||
|
||||
## POST /v1/user/invite
|
||||
@@ -47,7 +49,8 @@ plus a `fixedClock` only if the use case takes one. Reuse `mockUserRepo` and `st
|
||||
`inviteRepo` empty. Repeat the same request without re-arming -> `201`. With a seeded expired invite and a
|
||||
failing send -> `500` and no invite for that address remains.
|
||||
13. Auth table (`POST`): no cookie -> `401`; cookie of unverified user 8 -> `403`; cookie with stale
|
||||
`token_version` -> `401`. Each asserts no invite and no mail.
|
||||
`token_version` -> `401`; cookie of a verified admin (seeded with `Role: admin`) -> `403`, plain
|
||||
text body exactly `apperr.OwnerRequiredErrorMessage`. Each asserts no invite and no mail.
|
||||
14. Rate limit: limiter of 2 per minute, `RemoteAddr` `203.0.113.20:1234`, three valid POSTs -> `201`,
|
||||
`201`, `429`; third body is exactly `apperr.TooManyRequestsErrorMessage`, has `Retry-After`, and adds no
|
||||
invite or mail. `GET /` from the same address afterwards is not `429`.
|
||||
@@ -55,9 +58,10 @@ plus a `fixedClock` only if the use case takes one. Reuse `mockUserRepo` and `st
|
||||
## GET /v1/user/
|
||||
15. Seed per the feature scenario (three users, an expired, a pending and an accepted invite, with the
|
||||
stated `CreatedAt` values). `200`; decode as `[]map[string]json.RawMessage`. Assert length 5, order
|
||||
(pending sam, expired p.huber, ines, jonas, marta), key sets exactly as specified for user and invite
|
||||
items, accepted invite absent, and none of the forbidden keys anywhere. Also assert the raw body string
|
||||
contains no user email address.
|
||||
(pending sam, expired p.huber, ines, jonas, marta), key sets exactly as specified: `id`, `kind`,
|
||||
`username`, `display_name`, `email`, `role`, `status`, `created_at` for user items and `id`, `kind`,
|
||||
`email`, `status`, `created_at` for invite items, accepted invite absent, and none of the forbidden
|
||||
keys anywhere. Also assert the raw body string contains each accepted user's own email address.
|
||||
16. Only user 7 -> array with exactly one `kind:"user"` item, status `accepted`.
|
||||
17. Invite created 3 days + 1 minute ago -> `status:"expired"`; created 2 days ago -> `pending`;
|
||||
with `AcceptedAt` set -> not listed.
|
||||
|
||||
Reference in new issue
Block a user