Skip to content

Conversation

landongrindheim
Copy link
Member

Until now, we've allowed a Rubygem to be owned by users (via Ownerships) and an Organization. This has some downsides. For example, we've had to explicitly check both ownerships and organization membership in our gem-related policies.

I've opted to push this logic into Rubygem and enforce the ownership check to be organization-specific if the gem belongs to an organization OR ownership-specific (i.e. user-specific) if it is not.

Until now, we've allowed a `Rubygem` to be owned by users (via
`Ownership`s) and an `Organization`. This has some downsides. For
example, we've had to explicitly check both ownerships and organization
membership in our gem-related policies.

I've opted to push this logic into `Rubygem` and enforce the ownership
check to be organization-specific if the gem belongs to an organization
OR ownership-specific (i.e. user-specific) if it is not.
Copy link

codecov bot commented Jul 25, 2025

Codecov Report

❌ Patch coverage is 98.33333% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 97.19%. Comparing base (2cb8609) to head (9e868f7).
⚠️ Report is 49 commits behind head on master.

Files with missing lines Patch % Lines
app/models/gem_permissions.rb 96.42% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #5849   +/-   ##
=======================================
  Coverage   97.19%   97.19%           
=======================================
  Files         471      472    +1     
  Lines        9703     9745   +42     
=======================================
+ Hits         9431     9472   +41     
- Misses        272      273    +1     

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

ownerships.user_with_minimum_role(user, minimum_required_role).exists?

if owned_by_organization?
organization.memberships.where(user: user).with_minimum_role(minimum_required_role).exists?
Copy link
Member

Choose a reason for hiding this comment

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

This will leave out the current implementation of Outside Contributors, which uses the ownerships table.

@landongrindheim landongrindheim changed the title Make ownership an organization OR user concern 🛂 Update Handling of Gem Permissions Jul 30, 2025
This variant feels cleaner to me. Hopefully others will agree.
@landongrindheim landongrindheim force-pushed the landon/push-ownership-logic-to-rubygem-model branch from 618894b to 964234a Compare July 30, 2025 12:33
Ownership is proving to be trickier to keep consistent than I had hoped
it would be. I've been migrating to a permissions-based approach, which
has similar concerns beneath the covers, but is more explicit in its
implementation.
Ownership has proven to be more complicated than expected, and these
methods were primarily used by our policy code. The logic has been
extracted into GemPermissions, where we've been able to get a bit more
exact.
@landongrindheim landongrindheim force-pushed the landon/push-ownership-logic-to-rubygem-model branch from bf3166e to f155580 Compare July 31, 2025 17:02
Comment on lines +39 to +54
def org_member_in_role?(minimum_role)
case minimum_role
when :maintainer
rubygem.organization.user_is_member?(user)
when :admin
rubygem.organization.administered_by?(user)
when :owner
rubygem.organization.owned_by?(user)
else
false
end
end

def user_in_role?(minimum_role)
rubygem.ownerships.user_with_minimum_role(user, minimum_role).exists?
end
Copy link
Member Author

Choose a reason for hiding this comment

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

I think it makes sense to leave these here for now, but I foresee a future where org- (and team-) based permissions are checked in a separate class.

@landongrindheim landongrindheim marked this pull request as ready for review August 7, 2025 17:11
@colby-swandale
Copy link
Member

I feel that this Pull Request needs a bit more time to bake before I'm ready to accept it. This is a good step, but I also feel it's not complete either. With Organisation teams coming down the pipeline I feel it would be a good opportunity to spend a bit more time on this?

@landongrindheim
Copy link
Member Author

I feel that this Pull Request needs a bit more time to bake before I'm ready to accept it. This is a good step, but I also feel it's not complete either. With Organisation teams coming down the pipeline I feel it would be a good opportunity to spend a bit more time on this?

@colby-swandale I think you're right to be cautious with core permission logic. The organization teams work will add complexity here.

Would it be helpful if I walked through how this is designed to extend? I can show how the permission methods would handle the additional cases we'll need, or we can schedule a quick call to discuss the technical approach.

Happy to adjust the design based on our conversations, or hold off if you'd prefer to finalize the broader requirements first 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

2 participants