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

Builds out roles + role-specific landing UX + tighten up auth guards #455

Merged
merged 27 commits into from
Nov 1, 2024

Conversation

thomhickey
Copy link
Contributor

  • migration changes users.role to four roles: admin, case_manager, para, user
  • user.role added to session context (this is done via db lookup on each request - can be optimized to instead store user.role in session at login that's a @todo)
  • new UserType enum for role string constants, and applied everywhere instead of using string literals
  • trpc.ts exports four procedures for trpc use and implements cascading access control user -> para -> case_manager -> admin. so para can do everything user can do, case_manager can do everything para and user can do, etc.
  • all endpoints tightened up to use the appropriate trpc procedure according to role base access control
  • oauth redirect route is now / instead of /students, with each role being forwarded to appropriate landing page including a new 'sorry' page that says you cannot access compass
  • tests updated

to test:

  • change your role in db
  • log out/log in
    --> user goes to /sorry
    --> para goes to /benchmarks and has limited nav menus
    --> case_manager goes to /students and has appropriate nav menus
    --> admin goes to /students but has all nav

@thomhickey thomhickey linked an issue Oct 18, 2024 that may be closed by this pull request
};

// Function to compare roles
function hasMinimumRole(auth: Auth, requiredRole: UserType): boolean {
Copy link
Contributor

Choose a reason for hiding this comment

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

this function assumes that each role is a superset of the prior one; does this mean a case manager should be able to do what a para does?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. Uncommon work flows could be removed from the UI, but I'm thinking in the future there could be an administrator panel that could change database records through trpc calls

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, @nickvisut for now cascading roles on the backend seems like a good fit for POC/MVP. And as mentioned by Vince, the front-end doesn't do much in the way of auth guards, it just hides ui, but entering a route by hand will render the page, even if the api won't fill the page with data. We can add stories for those use cases as well.

};
}

export enum UserType {
Copy link
Contributor

Choose a reason for hiding this comment

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

nice!

Copy link
Contributor

Choose a reason for hiding this comment

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

Honestly I'm wondering if it would be possible to just use the default TypeScript enum where UserType.User = 0, UserType.Para = 1, and then use it as our ROLE_LEVEL, and instead have some fixed function called getUserTypeString(userType: UserType) that returns "user", "para", "case_manager", "admin", and is used only for writing to the database, which stores these strings rather than the enum.

@nickvisut nickvisut requested a review from a team October 23, 2024 00:24
@nickvisut
Copy link
Contributor

added Compass Engineering Reviewers as test of the new team

await trpc.case_manager.addStudent.mutate({
first_name: "Foo",
last_name: "Bar",
email: "invalid-email",
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: this shouldn't be an invalid email because that's not what we're testing. I'm going to fix this


export interface GetTestServerOptions {
authenticateAs?: "case_manager" | "para" | "admin";
authenticateAs?: UserType.CaseManager | UserType.Para | UserType.Admin;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to just set the type to UserType, and make it default to UserType.User if it's not specified?

Copy link
Contributor

Choose a reason for hiding this comment

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

^^ Just tried this, there's not much benefit because the seed file doesn't have a "UserType.User" key so it becomes more trouble than it's worth

import $box from "@/styles/Box.module.css";
import $typo from "@/styles/Typography.module.css";

const SorryPage: React.FC = () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

If we aren't going to use this element in this PR, let's remove it and add it to a new branch split from this one.

});

test("getMyTasks - regular users don't have access", async (t) => {
const { trpc } = await getTestServer(t, {});
Copy link
Contributor

@canjalal canjalal Oct 27, 2024

Choose a reason for hiding this comment

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

See my comment on making authenticateAs default to UserType.User if not specified, and have authenticateAs just have type UserType

@thomhickey thomhickey merged commit 3c95751 into main Nov 1, 2024
3 checks passed
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.

Working roles/UI
4 participants