8000 Allow organization admins to view pending and rejected invitations by kathy-t · Pull Request #5243 · dockstore/dockstore · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Allow organization admins to view pending and rejected invitations #5243

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

Merged
merged 9 commits into from
Nov 30, 2022

Conversation

kathy-t
Copy link
Contributor
@kathy-t kathy-t commented Nov 17, 2022

Description
The OrganizationUser class currently has the accepted boolean, which tracks if the invite is accepted or pending, but it doesn't track if the invite was rejected. This PR adds the status field to OrganizationUser so that we can track the status of an organization invite and removes the accepted field.

There is a UI PR dockstore/dockstore-ui2#1648 that relies on this PR. There is also a compose_setup PR that adds 1.14.0 migrations dockstore/compose_setup#242.

Review Instructions
Follow the review instructions in the UI PR dockstore/dockstore-ui2#1648

Issue
#4226
DOCK-1781

Please make sure that you've checked the following before submitting your pull request. Thanks!

  • Check that you pass the basic style checks and unit tests by running mvn clean install
  • Ensure that the PR targets the correct branch. Check the milestone or fix version of the ticket.
  • Follow the existing JPA patterns for queries, using named parameters, to avoid SQL injection
  • If you are changing dependencies, check the Snyk status check or the dashboard to ensure you are not introducing new high/critical vulnerabilities
  • Assume that inputs to the API can be malicious, and sanitize and/or check for Denial of Service type values, e.g., massive sizes
  • Do not serve user-uploaded binary images through the Dockstore API
  • Ensure that endpoints that only allow privileged access enforce that with the @RolesAllowed annotation
  • Do not create cookies, although this may change in the future
  • If this PR is for a user-facing feature, create and link a documentation ticket for this feature (usually in the same milestone as the linked issue). Style points if you create a documentation PR directly and link that instead.

@kathy-t kathy-t self-assigned this Nov 17, 2022
@codecov
Copy link
codecov bot commented Nov 17, 2022

Codecov Report

Base: 73.23% // Head: 73.27% // Increases project coverage by +0.04% 🎉

Coverage data is based on head (8e211bb) compared to base (61861c1).
Patch coverage: 76.00% of modified lines in pull request are covered.

Additional details and impacted files
@@              Coverage Diff              @@
##             develop    #5243      +/-   ##
=============================================
+ Coverage      73.23%   73.27%   +0.04%     
- Complexity      4375     4394      +19     
=============================================
  Files            292      292              
  Lines          16701    16717      +16     
  Branches        1834     1839       +5     
=============================================
+ Hits           12231    12250      +19     
- Misses          3596     3599       +3     
+ Partials         874      868       -6     
Flag Coverage Δ
bitbuckettests 28.25% <0.00%> (-0.03%) ⬇️
integrationtests 57.97% <76.00%> (+0.06%) ⬆️
languageparsingtests 10.84% <0.00%> (-0.02%) ⬇️
toolintegrationtests 30.38% <8.00%> (-0.04%) ⬇️
unit-tests_and_non-confidential-tests 26.84% <0.00%> (-0.03%) ⬇️
workflowintegrationtests 40.45% <0.00%> (-0.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...io/dockstore/webservice/core/OrganizationUser.java 60.37% <60.00%> (-3.09%) ⬇️
...ore/webservice/resources/OrganizationResource.java 79.49% <74.35%> (+0.23%) ⬆️
...store/webservice/resources/CollectionResource.java 79.85% <100.00%> (+1.13%) ⬆️
...ckstore/webservice/resources/WorkflowResource.java 71.07% <0.00%> (-0.14%) ⬇️
...main/java/io/swagger/api/impl/ToolsImplCommon.java 85.77% <0.00%> (+0.40%) ⬆️
.../java/io/openapi/api/impl/ToolsApiServiceImpl.java 70.73% <0.00%> (+0.66%) ⬆️
...bservice/resources/AliasableResourceInterface.java 96.87% <0.00%> (+3.12%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@kathy-t kathy-t changed the title Feature/4226/organization invites Allow organization admins to view pending and rejected invitations Nov 17, 2022
@kathy-t kathy-t marked this pull request as ready for review November 17, 2022 18:43
Copy link
Collaborator
@coverbeck coverbeck left a comment

Choose a reason for hiding this comment

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

On the no downtime comment, that's more aspirational and Denis and your call if we want to start down that route.

UPDATE organization_user SET status='ACCEPTED' where accepted=true;
UPDATE organization_user SET status='PENDING' where accepted=false;
</sql>
<dropColumn columnName="accepted" tableName="organization_user"/>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Once the migration is done, this will break old web service code that is still running. We often do have downtime with major releases, but we could try as an experiment to not have the downtime. So either

  1. Can you please note this in the 1.14 deploy notes -- we always hypothesize if the web service will be broken by a release, we should start tracking it when we know it will.
  2. Optionally, you could do something with a trigger, that keeps the new column in sync with the old column. Then in 1.15 we drop this column. Probably overkill, but OTOH if we want to eventually get to fully automated deploys, we may need to start doing this.

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 ok with either but second that this should either be clearly noted in the deploy notes or deprecated in the second case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ended up going with number 2, maybe overkill, but it will be interesting to experiment with this

.collect(Collectors.toSet());

return acceptedUsers;
return getOrganizationByIdOptionalAuth(user, id).getUsers();
Copy link
Collaborator

Choose a reason for hiding this comment

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

I didn't try running this, so I might be wrong, but won't this allow all Dockstore users to view all invited/rejected users of an org?

If so, I don't think that should be allowed; only org admins should have access to invites and rejections.

UPDATE organization_user SET status='ACCEPTED' where accepted=true;
UPDATE organization_user SET status='PENDING' where accepted=false;
</sql>
<dropColumn columnName="accepted" tableName="organization_user"/>
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 ok with either but second that this should either be clearly noted in the deploy notes or deprecated in the second case.

- Bring back the accepted column and deprecate it
- Create a DB trigger that syncs the accepted and status columns
- Fix permissions so only accepted admins/maintainers can perform actions
- Only return all organization members if the user is an org admin
@kathy-t
8000 Copy link
Contributor Author
kathy-t commented Nov 28, 2022

Re-requesting reviews for these new changes:

  • Brought back the accepted field and created a DB trigger that keeps the old accepted and new status fields in sync. This should allow us to do a no downtime deploy. The old accepted field is deprecated. Upon approval, will create a follow-up ticket to remove this deprecated field in 1.15
  • Only organization admins can view all memberships. Unauthorized/public users can only view accepted members
  • In implementing the previous point, I noticed that we were only checking if a user was an admin/curator without checking that they accepted the invitation so a pending admin/curator can make changes to the organization. I went through all of the endpoints and made sure that we also check that they have accepted the invitation
    • This is more so important with the rejected status because we don't want rejected members to perform admin/maintainer actions

* Test that invited users who have not accepted their invitations are powerless. Tests all roles: Member, Maintainer, Admin
*/
@Test
public void testPendingAndRejectedUsersArePowerless() {
Copy link
Member

Choose a reason for hiding this comment

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

very nice for catching this and locking it down with a test

Copy link
Collaborator
@coverbeck coverbeck left a comment

Choose a reason for hiding this comment

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

This is great! Thanks for figuring out this path. We can use it as a template for future migrations.

One question, after the migration has been run, and you bring up a new instance of the old web service, will that work? I know existing old running code will work, but would the startup schema check pass or fail?

If it fails, I don't know that there's a lot we can do about it. Your code solves the problem of a no-downtime update, but the next thing to potentially plan for is a rollback (something is so wrong with the new version, that we need to temporarily deploy the old version). We've never needed to do this, and hopefully never will, so this is just a question, no need to change anything, and we already have this issue -- just trying to think ahead a little.

Also, if you agree, could you create a followup ticket with a 1.15 milestone to delete the accepted column/field? I suppose we could live with it forever and it would work, but might as well clean it up.

// and if the user is neither an admin nor curator, then throw an error
if ((orgUser == null || orgUser.getRole() != OrganizationUser.Role.ADMIN) && (!user.isCurator() && !user.getIsAdmin())) {
// If the user is not an admin or maintainer of the organization and if the user is neither an admin nor curator, then throw an error
if (!isUserAdminOrMaintainer && (!user.isCurator() && !user.getIsAdmin())) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should maintainers be able to delete their own org? I would argue that they shouldn't, if they're not allowed to update memberships.

This is pretty edge-casey, as it's unlikely that a deleted or rejected org will have any maintainers to begin with.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will change it bac 6DAF k so only the organization admin can delete the org

<addNotNullConstraint tableName="organization_user" columnName="status"/>
<sql dbms="postgresql">
<comment>Create a trigger that syncs the old accepted column with the new status column</comment>
CREATE OR REPLACE FUNCTION insert_organization_user_sync_status_func()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yowsa, that was more complex than I thought it would be. I see you have a two-way sync as well. Nice!

@denis-yuen
Copy link
Member

One question, after the migration has been run, and you bring up a new instance of the old web service, will that work? I know existing old running code will work, but would the startup schema check pass or fail?

FYI, had this same thought separately in our meeting. As long as we have https://github.com/dockstore/compose_setup/blob/develop/templates/web.yml.template#L115 existing webservices will continue running if currently running, but will kill themselves on start-up
We probably need a ticket to turn this off in, say 1.14.0, so when we delete the column in 1.14.1, the 1.14.0 service will stillbe able to start if there's an issue

@ApiModelProperty(value = "Has the user accepted their membership.", required = true)
private boolean accepted = false;
@Schema(description = "Has the user accepted their membership.", required = true, deprecated = true)
private Boolean accepted;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Belated thought after this came up in a different meeting with @denis-yuen -- do we need this at all?

I guess it depends on how the Hibernate schema validator works. Does it allow extra columns that aren't mapped? According to this unverified StackOverflow question it does. The user is complaining that it does, but that would work to our advantage.

If that's true, then I think you can just remove this from the Java code entirely. The 1.14 code will access and only know about the new column, the 1.13 code will access and only know about the old column, and the DB keeps them in sync behind the scenes. Untested theory.

Copy link
Member

Choose a reason for hiding this comment

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

Interesting. The thought above about turning off the validator is if it didn't allow unmapped columns.

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 tested this by removing the accepted field and the webservice starts with no errors, but I believe this will fail the CircleCI build here because the migrations are not consistent with the JPA class

*/
public static List<String> listMigrations(String... additionals) {
if (additionals.length > 0) {
return Stream.concat(COMMON_MIGRATIONS.stream(), Stream.of(additionals)).collect(Collectors.toList());
Copy link
Contributor

Choose a reason for hiding this comment

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

Entirely out of curiosity, and no need to change this, but could this line do all the work by itself, no if necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah you're right, the if isn't necessary

@kathy-t
Copy link
Contributor Author
kathy-t commented Nov 29, 2022

One question, after the migration has been run, and you bring up a new instance of the old web service, will that work? I know existing old running code will work, but would the startup schema check pass or fail?

If it fails, I don't know that there's a lot we can do about it. Your code solves the problem of a no-downtime update, but the next thing to potentially plan for is a rollback (something is so wrong with the new version, that we need to temporarily deploy the old version). We've never needed to do this, and hopefully never will, so this is just a question, no need to change anything, and we already have this issue -- just trying to think ahead a little.

I tried testing this locally by running the 1.14 migrations then starting the develop webservice (aka an old webservice without 1.14 migrations) and the webservice started with no schema errors. Keep in mind that if we actually do rollback in AWS, the 1.13 migrations will run before the old webservice container starts since every task has its own migrations container.

Also, if you agree, could you create a followup ticket with a 1.15 milestone to delete the accepted column/field? I suppose we could live with it forever and it would work, but might as well clean it up.

Created #5256

@kathy-t kathy-t requested a review from coverbeck November 29, 2022 18:04
Copy link
Collaborator
@coverbeck coverbeck left a comment

Choose a reason for hiding this comment

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

Was here, going to wait for further implementation per our Slack huddle.

@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 2 Code Smells

87.0% 87.0% Coverage
0.0% 0.0% Duplication

@kathy-t
Copy link
Contributor Author
kathy-t commented Nov 30, 2022

My newest change removes the accepted field from the OrganizationUser class. It does not remove the accepted column. I had to add a hack in import.sql so that the CircleCI step that checks if JPA classes are consistent with migrations passes. I added a comment in the file.

Pros:

  • 1.13 code only knows about accepted and 1.14 code only knows about status
  • After deploying 1.14, we can still rollback to 1.13 if needed because the accepted column still exists in the database
  • In 1.15, when we drop the accepted column and triggers in the database, if we need to roll back to 1.14, the webservice should be able to start without schema validation errors because the class doesn't have the accepted field
    • I tested this scenario locally by running migrations that drop the triggers and the accepted column, then starting the webservice from this PR and it started successfully.

Table summarizing the state of accepted and status through the releases:

  • field = Java field in the OrganizationUser class
  • column = database column
Release Change accepted field accepted column status field status column
1.13 n/a ✔️ ✔️
1.14 Remove accepted field, create status field and column, and create triggers ✔️ ✔️ ✔️
1.15 Remove accepted column and triggers ✔️ ✔️

Copy link
Collaborator
@coverbeck coverbeck left a comment

Choose a reason for hiding this comment

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

Nice!

@kathy-t kathy-t merged commit aa64a3a into develop Nov 30, 2022
@kathy-t kathy-t deleted the feature/4226/organization-invites branch November 30, 2022 20:38
denis-yuen added a commit to dockstore/dockstore-cli that referenced this pull request Dec 14, 2022
denis-yuen added a commit to dockstore/dockstore-cli that referenced this pull request Dec 20, 2022
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.

4 participants
0