Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store ephemeral user group associations #1491

Merged
merged 5 commits into from
Feb 12, 2025
Merged

Conversation

slifty
Copy link
Member

@slifty slifty commented Feb 10, 2025

This PR expands our auth middleware to store a user's group associations as part of the process of establishing the authentication context.

It does not actually use those associations when populating a user's roles (This will be in a future PR).

Resolves #1483

@slifty slifty force-pushed the 1483-user-group-associations branch from 3e491f6 to 939d9e9 Compare February 10, 2025 16:32
Copy link

codecov bot commented Feb 10, 2025

Codecov Report

Attention: Patch coverage is 92.15686% with 4 lines in your changes missing coverage. Please review.

Project coverage is 86.90%. Comparing base (b96f134) to head (fe75765).
Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
src/middleware/addUserContext.ts 80.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1491      +/-   ##
==========================================
+ Coverage   86.89%   86.90%   +0.01%     
==========================================
  Files         235      238       +3     
  Lines        2931     2964      +33     
  Branches      402      407       +5     
==========================================
+ Hits         2547     2576      +29     
+ Misses        384      355      -29     
- Partials        0       33      +33     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@slifty
Copy link
Member Author

slifty commented Feb 10, 2025

I'm adding a test to ensure that the rows are properly inserted by the middlware

@hminsky2002
Copy link
Contributor

hminsky2002 commented Feb 10, 2025

I'm adding a test to ensure that the rows are properly inserted by the middlware

One of my comments was going to be adding some amount of tests so I will wait for your updates to give final review!

Copy link
Contributor

@bickelj bickelj left a comment

Choose a reason for hiding this comment

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

Overall, as awkward as it is, I still strongly support leaving users and groups up to PDC Keycloak while managing PDC service object permissions within the PDC service.

The ephemeral table approach is a good starting point. I wonder, though, if we are going from JSON to SQL rows back to JSON again unnecessarily, and if we can do something more JSONy with postgres in the future. For example, if we ephemerally store (or not store but use) the whole validated JWT (maybe sans header, sans signature), then we have a single thing to pass to postgres queries instead of multiple things. This idea only occurred to me while reviewing here and I haven't tried writing anything that would make use of such a JWT in postgres. So it may not slay the complexity dragon but merely move it into the queries that make use of the JWT. Again, for now I think the approach here is what we should use. If it is slow to run a query or two on every request, I think we could increase the resources of the app and its database before we try calling the auth server instead (which in turn probably queries its own database and has the overhead of an HTTP request).

In any case, there are some plain old errors or typos that need to be fixed before this can be merged. See inline.

@bickelj
Copy link
Contributor

bickelj commented Feb 10, 2025

I am kind of surprised that so many tests pass since not a single authenticated endpoint works on the Swagger UI. I guess that means we don't integrate our mandatory middleware into those tests. That cannot be true because we have to use auth headers to do anything in the software. Maybe we are missing a couple of tests that capture that, though I don't know how difficult that would be with supertest and jest.

@slifty
Copy link
Member Author

slifty commented Feb 10, 2025

I am kind of surprised that so many tests pass since not a single authenticated endpoint works on the Swagger UI. I guess that means we don't integrate our mandatory middleware into those tests. That cannot be true because we have to use auth headers to do anything in the software. Maybe we are missing a couple of tests that capture that, though I don't know how difficult that would be with supertest and jest.

I'm betting it's because I didn't update our tests to actually include an ephemeral organization association (and as you pointed out most of the code is broken) WHOOPS!

@slifty slifty force-pushed the 1483-user-group-associations branch 3 times, most recently from 918bb05 to 1be5b07 Compare February 11, 2025 18:15
@slifty slifty requested a review from bickelj February 11, 2025 20:53
Copy link
Contributor

@bickelj bickelj left a comment

Choose a reason for hiding this comment

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

It looks like all my concerns were addressed. Note I did not try this locally but reviewed some of the changes and noticed the very good tests added. LGTM if you are comfortable with it.

@slifty slifty force-pushed the 1483-user-group-associations branch from 9b73c3f to 80bcff2 Compare February 12, 2025 18:38
We set up our sql linter to use tabs, which aligns with the rest of the
project.  This tweaks the editorconfig to reflect that decision.
Our user entity has a natural key and so our insert operation can be an
"insert or update" operation instead.  This allows us to leverage the
operation directly in the user context middleware, in addition to better
aligning with other entity patterns.
Users are associated with user groups via the "organizations" attribute
of their authentication JWT.  We're going to want our queries and
authentication checks to account for those group associations, but we
don't want to have to constantly pass an unpredictably long list of
associations every time we make a query.

This entity, and the middleware that populates it, allows a given API
call to have those associations accounted for in a given HTTP request
context.  The table is labeled "ephemeral" to try to convey the fact
that the data it contains should not be considered accurate outside of
that context.

The implementation of the middleware right now is intentionally simple
and does not attempt to be efficient.  For example, it does not attempt
to re-use any past data in the table (e.g. associations that may have
existed from a past transaction and wouldn't necessarily have to be
re-created).

We may find that having O(n) insert queries for every authenticated API
call is too slow; if that ends up becoming a problem we may determine
that our model for using KeyCloak as the group management and JWTs as
the communication mechanism isn't correct.

These associations are not actually used when making auth decisions yet.
This commit is, however, a prerequisite for that feature.

Issue #Create user-group associations "cache" middleware
Now that we have user group permissions and the ability to associate
a user with a given group we can incorporate those permissions in
a user's roles.

Issue #1483 Create user-group associations "cache" middleware
@slifty slifty force-pushed the 1483-user-group-associations branch from 80bcff2 to fe75765 Compare February 12, 2025 18:44
@slifty slifty merged commit 47d529b into main Feb 12, 2025
11 checks passed
@slifty slifty deleted the 1483-user-group-associations branch February 12, 2025 18:50
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.

Create user-group associations "cache" middleware
3 participants