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

A license should have multiple users #534

Closed
ezekg opened this issue Dec 20, 2021 · 10 comments · Fixed by #774 or #802
Closed

A license should have multiple users #534

ezekg opened this issue Dec 20, 2021 · 10 comments · Fixed by #774 or #802

Comments

@ezekg
Copy link
Member

ezekg commented Dec 20, 2021

Related to #533. For project-based licenses, where a main licensee can invite other licensees to utilize the same license. Or for company-wide licenses for particular named-users.

@ezekg ezekg changed the title License should have many users or "members" License should have many users or "licensees" Dec 30, 2021
@ezekg
Copy link
Member Author

ezekg commented Apr 20, 2022

  1. Create license<>licensees relationship, where licensees is a join table for license<>users.
  2. Deprecate license<>user relationship.

@ezekg ezekg changed the title License should have many users or "licensees" A license should have multiple users Aug 2, 2023
@ezekg
Copy link
Member Author

ezekg commented Nov 4, 2023

Current plan is to add a LicenseUser model, with a new has_many :license_users for both users and licenses, with a corresponding has_many through: for each as well. One change that would be introduced is that on user deletion, the user's licenses would no longer be cascade deleted. Rather, the join table will be deleted, but the license left, potentially orphaned. This is because the license could theoretically belong to another user now, or in the future.

To retain backwards compatibility with current API behavior, we should leave the existing user_id column on the licenses table, along with the deprecated belongs_to :user association. This will allow us to differentiate between single- vs multi-user associations for a license. This will ensure behavior does not change.

One difficultly with this decision is creating a licenses association on the user model that reads from both the new join table as well the deprecated user_id column on the licenses table. Need to think on how to best achieve this. I know we've done something similar in the past with user and license entitlements, joining across multiple tables.

@ezekg
Copy link
Member Author

ezekg commented Nov 9, 2023

After writing a couple POC implementations, I decided that rather than dealing with unioning a new has-many association with the old user_id has-one association, the easier route forward would be to migrate existing data to a new HABTM licenses<>users association. This will make upgrading Keygen CE/EE a bit more challenging, but with good documentation, this direction will pay off in the long run and allow us to not have to worry about denormalized assocations.

@ezekg
Copy link
Member Author

ezekg commented Dec 15, 2023

How should permissions be handled for a license? We'll be moving from a license intersecting its user's permissions, to…? Should we have a "primary" user for a license, for the license's permissions to intersect with? Should we drop the concept of a license's permissions intersecting their users' permissions? How could we do this in a backwards compatible way? Should see if we can swing intersecting a license's permissions with all of its users? Lots of questions here that I hadn't thought about…

Intersecting a license's permissions with a primary user, or with all of its users' permissions seem like the only 2 solutions here that are backwards compatible. Need to think on what would be the most performant way to accomplish that.

What's funny is that the license.user_id column would be perfect for the primary user concept. 😂

@ezekg
Copy link
Member Author

ezekg commented Dec 15, 2023

With the permissions problem in mind, what if we went in a new direction with #768

  1. The current user relationship is renamed to owner (or just keep it as user?). This user would be allowed to manage the license, e.g. update it, renew it, etc. (in accordance with the user's permissions and the policy's protected status, ofc.)
  2. A new users relationship is introduced, essentially acting as sub-users for the license. These sub-users cannot manage the license, but they can validate it, activate machines for it, etc. (essentially allowed the same permission set as a license.)

This could let us recycle the licenses.user_id column, and actually limit any real breaking changes to the API. This would have the benefit of making the upgrade process for Keygen CE/EE simpler vs our previous approach.

Moving to an owner model also allows for use-cases where a manager can assign/unassign users to a license, which is pretty common and one of the use-cases #604 was meant to accomplish (on a larger scale).

@ezekg
Copy link
Member Author

ezekg commented Dec 15, 2023

One of the challenges here would be that User#licenses would need to once again union between the licenses.user_id and license_users.user_id sources. I previously hit issues with the various has_many :users, through: :licenses associations, because we can't union a through association across multiple sources.

But that may actually be worth exploring a solution for:

has_many :users, union_of: %i[owner licensees]

Let's write up a POC and see what it looks like.

(Such a solution could also eventually be used for entitlements as well.)

@ezekg
Copy link
Member Author

ezekg commented Dec 15, 2023

What if we kept the API changes to a minimum — keep the License#user association and introduce License#licensees?

Would still need the union_of: union, but this gets rid of any baggage from renaming the user assocation.

@ezekg
Copy link
Member Author

ezekg commented Dec 15, 2023

We'd also need to union User#licenses across licenses.user_id and license_users.user_id. What would be really beneficial here is if we could define an association object that simply implements the entire association API, providing it like so:

has_many :licenses, UserHasManyLicensesAssociation.new

I may explore this idea in particular.

@ezekg
Copy link
Member Author

ezekg commented Dec 17, 2023

Should we also rename license_users to licensees?

@ezekg ezekg mentioned this issue Jan 12, 2024
25 tasks
@ezekg
Copy link
Member Author

ezekg commented Mar 1, 2024

Reopening because #774 had to be reverted.

@ezekg ezekg reopened this Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant