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

feat: add limits and tier to jwt claim #1382

Merged
merged 16 commits into from
Nov 16, 2023

Conversation

oddgrd
Copy link
Contributor

@oddgrd oddgrd commented Nov 13, 2023

Description of change

Add a Limits struct that will hold all the account limits to the JWT Claim, and also add the AccountTier (moved to shuttle-common) to the Claim, so we can use it in instrumentation. I left adding it to instrumentation out of this PR, that will be done in a follow-up.

I used an extension trait for the methods to extract the limits from the Claim. This allows us to have the methods for extracting limits from the claim only available where they are needed. An alternative would be to implement the methods on Claim directly, or make the fields of Claim public, but that would make us more exposed to breaking changes. I'm not sure that breaking changes will be an issue here, though, since we create the limits from the tier. Thoughts on this subject are very welcome!

How has this been tested? (if applicable)

Updated the auth test to verify that the limits and tier are correctly set for an admin and for a basic user, and verified that the gateway tests that test project limit still pass.

Additionally, I tested deploying a hello-world and postgres project to staging on an old deployer, as well as a new deployer (after deploying this branch to staging).

@oddgrd oddgrd changed the title Feature/eng 1777 implement jwt refactor feat: add limits and tier to jwt claim Nov 13, 2023
auth/src/api/handlers.rs Outdated Show resolved Hide resolved
common/src/claims.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@chesedo chesedo left a comment

Choose a reason for hiding this comment

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

Looking good, thanks O!

}

pub trait ClaimExt {
fn project_limit(&self) -> u32;
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be better to have this method as can_create_project() to prevent the logic from spilling into the handlers (controllers).

Copy link
Contributor

Choose a reason for hiding this comment

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

It would also be good to put this trait in a separate file.

Copy link
Member

Choose a reason for hiding this comment

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

It would also be good to put this trait in a separate file.

Why?

can_create_project

Are you saying that the business logic should live in that function? Then it has to take in current_project_count or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I implemented these changes last night: f900d1a

It feels more organized, but it meant needing to make some changes to the test code in gateway.

Copy link
Contributor

Choose a reason for hiding this comment

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

@jonaro00 to have the business logic in one file. Thereby being easier to update 😄

common/src/claims.rs Outdated Show resolved Hide resolved
common/src/claims.rs Outdated Show resolved Hide resolved
Copy link
Member

@jonaro00 jonaro00 left a comment

Choose a reason for hiding this comment

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

You could mark some of the now-outdated scopes as "deprecated but keep for compatibility"

}

pub trait ClaimExt {
fn project_limit(&self) -> u32;
Copy link
Member

Choose a reason for hiding this comment

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

It would also be good to put this trait in a separate file.

Why?

can_create_project

Are you saying that the business logic should live in that function? Then it has to take in current_project_count or something.

Copy link
Contributor

@chesedo chesedo left a comment

Choose a reason for hiding this comment

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

Just one comment about the function in the test

Comment on lines 437 to 442
project_name: ProjectName,
account_name: AccountName,
is_admin: bool,
limit: Option<u32>,
can_create_project: bool,
idle_minutes: u64,
) -> Result<FindProjectPayload, Error> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Technically this function should not take in an argument to check if a project can be created. I think it is fine for now since I don't see an easy way to move the logic to the caller.

Comment on lines 966 to 982
/// Verify that the account's current project count is lower than its limit.
async fn can_create_project(
service: Arc<GatewayService>,
account_name: &AccountName,
is_admin: bool,
) -> bool {
if is_admin {
return true;
};

let project_count = service
.get_project_count(account_name)
.await
.expect("to get the account's project count");

project_count < MAX_PROJECTS_DEFAULT
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally tests should not have logic that replicates the code being tested. Can we not just pass true and false into the test arguments?

Copy link
Contributor

Choose a reason for hiding this comment

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

Replicating the logic means your test won't identify any errors in the replicated code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't want to remove our only test of project limits, but I guess replicating the logic here does not resolve that. I think this should rather be tested at a higher level (handler tests), since it's now checked there. Thanks! I will remove this change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a new test for project limits. These tests could use some more work I think, but they're not run in CI, and we may be rewriting them for the new orchestrator anyway.

Copy link
Contributor

@chesedo chesedo left a comment

Choose a reason for hiding this comment

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

LGTM

@oddgrd oddgrd merged commit 6a55b14 into main Nov 16, 2023
31 of 33 checks passed
@oddgrd oddgrd deleted the feature/eng-1777-implement-jwt-refactor branch November 16, 2023 10:52
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.

3 participants