Skip to content

Admin: Create admin table - #101

Open
RandyJDean wants to merge 1 commit into
mainfrom
08-31-admin_create_admin_table
Open

Admin: Create admin table#101
RandyJDean wants to merge 1 commit into
mainfrom
08-31-admin_create_admin_table

Conversation

@RandyJDean

@RandyJDean RandyJDean commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Admin allowlist

Adds an admins table so ROLE_ADMIN can be granted.

SecurityConfig already gated POST /api/email/** and GET /api/members behind
hasRole("ADMIN").

  • admins is keyed by email, with no API or UI write path — rows are inserted by
    hand in psql, so the app can't grant itself admin (yet).
  • The allowlist is read once at magic-link sign-in; the result rides in the session's
    granted authorities. isAdmin in /api/session is derived from those same authorities,
    so the SPA's view and the backend's enforcement can't disagree.
  • A normalize_email() function (shared by the table's write trigger and AdminRepo's
    lookup) means casing/whitespace in a hand-typed insert doesn't matter, and the primary
    key prevents casing variants coexisting as separate rows.

Adding an admin

INSERT INTO admins (email, note) VALUES ('someone@patinanetwork.org', 'Ops lead');

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@RandyJDean
RandyJDean force-pushed the 08-31-admin_create_admin_table branch from 34d163a to fdeaee2 Compare September 7, 2026 17:30
@sonarqubecloud

sonarqubecloud Bot commented Sep 7, 2026

Copy link
Copy Markdown

@RandyJDean
RandyJDean marked this pull request as ready for review September 7, 2026 17:55
@RandyJDean
RandyJDean requested a review from a team September 7, 2026 17:55
@graphite-app

graphite-app Bot commented Sep 7, 2026

Copy link
Copy Markdown

Graphite Automations

"Request reviewers once CI passes" took an action on this PR • (09/07/26)

2 reviewers were added to this PR based on Henry Chen's automation.

LANGUAGE sql IMMUTABLE STRICT AS
$$ SELECT LOWER(BTRIM(addr, E' \t\n\r\f\v')) $$;

CREATE TABLE IF NOT EXISTS "admins" (

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we'll need a follow up item to add everyone to this table or else we won't be able to test out the admin endpoints. do you have access to the DB?

can you also add documentation on how to write to the DB (i.e. steps for authentication, the query, etc?) so people in the future know how to add themselves?

*/
@Repository
@RequiredArgsConstructor
public class AdminRepo {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we're going to use the pattern of Repo/SqlRepo for members/matches/etc, we should also do it here. for consistency purposes.


/** A {@link JdbcClient} whose single query resolves to {@code result}; the same statement mock is reused. */
private static JdbcClient stubbedClient(final Boolean result) {
final JdbcClient jdbc = mock(JdbcClient.class);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the issue with these kinds of tests is that because the repo is just a wrapepr, they're not really testing anything. we're saying "here's this mock SQL repo that should return true/false for any type of query, check that the wrapper for it returns true/false".

#102 - look at what arsh is doing here with his tests. these should be testing the actual sql query functionality.

we want to test things like you already have, but also:

  • fails on duplicate admin
  • deleting from admin table should have the admin check be false
  • inserting someone with a non-normalized email should query later as a normalized email

and so on.

.session(session)
.with(csrf()))
.andExpect(result -> assertNotEquals(
HttpServletResponse.SC_FORBIDDEN,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we just assert that it's a 2xx code? why would we only check for non forbidden?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants