Skip to content

Feature/inf 158#17

Merged
ctucker3 merged 15 commits intodevelopfrom
feature/INF-158
May 21, 2020
Merged

Feature/inf 158#17
ctucker3 merged 15 commits intodevelopfrom
feature/INF-158

Conversation

@ctucker3
Copy link
Contributor

@ctucker3 ctucker3 commented May 14, 2020

This features adds the user system roles and the user id into JWT claims. It also adds a means for the controllers to easily access those roles and id in the claims.

This feature also includes some code contributed by Tim that will be used when program roles enforcement is implemented. The code is active, but won't be called if the @ProgramSecured annotation is not used on any controllers. Which it is not yet.

Tests were added for the rare case that a user has a valid JWT, but not a user account. This case can occur if the user is valid, gets their JWT, but then their user account gets deleted (by a dev directly in the database), but there JWT hasn't expired yet. We don't check for this in the controller, but will be caught in the database because there is a foreign key constraint on the updated_by, created_by in the database.

Dependencies

This feature modifies the login flow to bi-web. There is a matching feature card in bi-web, INF-158 that should be reviewed alongside this.

Review and Tests

  1. Do the bad authentication cases work?
    • Logging in with an orcid that doesn't exist in bi-api
    • Logging in with an orcid whose user account is deactivate
  2. If a non-admin user tries to access an ADMIN endpoint, do they get a 403
  3. Have all controllers been updated to use the new SecurityService
  4. General code review

@ctucker3 ctucker3 marked this pull request as ready for review May 14, 2020 16:08
@ctucker3
Copy link
Contributor Author

@nickpalladino
Copy link
Member

A database migration was added for this so make sure you do a flyway migration and generate the jooq sources.

@nickpalladino
Copy link
Member

bi-web uses a health endpoint that is provided by micronaut which is not currently in the api docs. Even though we didn't write it, it's still part of the api for the system so I think it should be added to the api docs.

@nickpalladino
Copy link
Member

  • Do the bad authentication cases work?

    • Logging in with an orcid that doesn't exist in bi-api (works)
    • Logging in with an orcid whose user account is deactivate (works)
  • Does it matter if the orcid is changed after the user has the JWT that they can still perform operations? Technically the orcid logged in with doesn't exist anymore but the user still does. Not sure that's really possible outside of test cases.

  • If a non-admin user tries to access an ADMIN endpoint, do they get a 403 (works)

  • Have all controllers been updated to use the new SecurityService (yes)

@@ -107,18 +102,13 @@ public HttpResponse<Response<Program>> createProgram(Principal principal, @Valid
@Produces(MediaType.APPLICATION_JSON)
@AddMetadata
@Secured(SecurityRule.IS_AUTHENTICATED)
Copy link
Member

Choose a reason for hiding this comment

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

I see that the edit endpoints are not set to ADMIN which looks consistent with the requirements flow charts (admin & breeder) but I'm wondering about the front end. Currently you can only edit a program on the admin page. Not for this card but do we need to add editing capability to the user program management page if you have a breeder program role? Or would a breeder get pieces of admin functionality on the sidebar? Just discussing here because this permission thing made me think of it. Thoughts @eawoods?

Copy link

@eawoods eawoods May 18, 2020

Choose a reason for hiding this comment

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

I believe that permission scheme is an intentional decision -> program metadata (name and species) is not editable by anyone except the admin role.

@Produces(MediaType.APPLICATION_JSON)
@Secured(SecurityRule.IS_AUTHENTICATED)
@Secured({"ADMIN"})
public HttpResponse deleteUser(@PathVariable UUID userId){
Copy link
Member

Choose a reason for hiding this comment

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

Maybe not this card but eventually we're going to have deactivating users I think so this would be using the securityService to get the acting user. I see we have the active flag in the database now so may be a good time to change this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After talking with Tim, I think the thought right now is to shorten the JWT expiration time and add a refresh token capability so that the user will get their refreshed info frequently. Not checking the user on the incoming call does leave a gap equal to the duration of the JWT expiration where a bad actor with an account can still have access though. But, I think the thought was that the case would be rare and they would have to be in the system to start anyway, so the case may not be worth making checks for it. It does avoid having to query the user on every single call. I'm down to discuss this again though if you had thoughts?

Also, for the deactivate user endpoint, there is a card made for switching that endpoint over on the UI side,

https://trello.com/c/ij6pPrRN/127-pro-56-ui-update-deactivate-modal-text-to-replace-remove-with-deactivate

We could just mix the controller in on that too. I want to save it for later since changing it over is outside of scope for this card.

Copy link
Member

Choose a reason for hiding this comment

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

I'm happy to discuss this further too

Copy link
Member

Choose a reason for hiding this comment

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

Posting this thought before I forget it. We could create a security rule that will check if the method being requested has the @Secured annotation, and if it's anything but a GET, and if so, then check in the db to make sure the user that the JWT was issued for is still active, therefore preventing a bad actor from making destructive changes the instant their account is deactivated.

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 like that idea! It seems like a good balance between cutting down the queries, but giving us some added protection as well. @nickpalladino thoughts about this?

Copy link
Member

Choose a reason for hiding this comment

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

sounds good

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@timparsons @nickpalladino A new security role has been added. A lot of the new tests were removed that checked for an active user that didn't exist in the database because the security rule will stop the flow before they get to the controller in that case. New tests were added for the security rule cases.

I put a TODO in ProgramSecuredAnnotationRule class to add tests when the time comes.

@ctucker3
Copy link
Contributor Author

  • Does it matter if the orcid is changed after the user has the JWT that they can still perform operations? Technically the orcid logged in with doesn't exist anymore but the user still does. Not sure that's really possible outside of test cases.

Yeah that is a good point. My thought would be that it doesn't matter to us if their orcid account was removed. Since the orcid is used so we can know they are who they are, once we know who they are we can decide whether they should continue to have access to our system on our side and just check to see if they are who they are when they need a new JWT.

@ctucker3
Copy link
Contributor Author

bi-web uses a health endpoint that is provided by micronaut which is not currently in the api docs. Even though we didn't write it, it's still part of the api for the system so I think it should be added to the api docs.

changed and pushed

Copy link

@eawoods eawoods left a comment

Choose a reason for hiding this comment

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

Looks good to me, and I got all the possible error states to trigger at the correct times.
I defer to @nickpalladino and @timparsons on technical endpoints/permissions/token/timeout questions.

Copy link
Member

@timparsons timparsons left a comment

Choose a reason for hiding this comment

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

Looks good. One comment on one test

Copy link
Member

@timparsons timparsons left a comment

Choose a reason for hiding this comment

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

A few small comments/quick discussion points

@ctucker3 ctucker3 merged commit 3ce61c9 into develop May 21, 2020
@ctucker3 ctucker3 deleted the feature/INF-158 branch May 21, 2020 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants