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(core): Refactor how permissions get serialized for sessions into using a new strategy #3222

Draft
wants to merge 35 commits into
base: master
Choose a base branch
from

Conversation

DanielBiegler
Copy link
Contributor

@DanielBiegler DanielBiegler commented Nov 20, 2024

Preamble

This is a proof of concept for #3095

Description

Since people are asking for more details on how this works I'll copy the docs here as quick reminder:

/**
 * @description
 * This plugin extends the Admin-API and provides a {@link ChannelRolePermissionResolverStrategy} which
 * fundamentally changes how Vendure resolves {@link Permission}s for {@link User}s.
 *
 * By default with the included {@link DefaultRolePermissionResolverStrategy}
 * Vendure stores and resolves permissions by assigning {@link User}s
 * `N` {@link Role}s of which each role can relate to `M` {@link Channel}s.
 *
 * This works well, but it also means you cannot share roles between channels while restricting
 * your users exclusively to their own channel, because channels are tied to the role.
 *
 * Imagine a scenario where you have two users called `UserA`, `UserB`, two channels called
 * `ChannelA`, `ChannelB` and a `CatalogManager`-Role which has permissions for creating,
 * updating and deleting products. You want `UserA` to only be able to work on products that
 * belong to `ChannelA` and `UserB` should only be allowed to work on `ChannelB`.
 *
 * Sharing of a general `CatalogManager`-Role between these channels is not possible under the
 * default strategy because once you relate both channels to the role, both users will have
 * permissions to access each others channels, looking like so:
 *
 * ```
 * UserA ═══➤ CatalogManager ═╦═➤ ChannelA
 *                            ╚═➤ ChannelB
 * UserB ═══➤ CatalogManager ═╦═➤ ChannelA
 *                            ╚═➤ ChannelB
 * ```
 *
 * This means in order to isolate them from each other you must duplicate and maintain two separate
 * `CatalogManager`-Role like so:
 *
 * ```
 * UserA ═══➤ CatalogManagerA ═══➤ ChannelA
 * UserB ═══➤ CatalogManagerB ═══➤ ChannelB
 * ```
 *
 * This scales badly and makes it hard to maintain for marketplaces with lots of administrators.
 *
 * This plugin replaces the default strategy with {@link ChannelRolePermissionResolverStrategy}
 * which allows you to share roles between channels, while still being able to restrict users
 * to their dedicated channels. Using the previously mentioned example, adding the plugin lets you
 * share the permissions from a role granularly for any channel, like so:
 *
 * ```
 * UserA ═══➤ CatalogManager ═══➤ ChannelA
 * UserB ═══➤ CatalogManager ═══➤ ChannelB
 * UserC ═══➤ CatalogManager ═══➤ ChannelA
 * UserC ═══➤ CatalogManager ═══➤ ChannelB
 * UserD ═══➤ CatalogManager ═══➤ ChannelD
 * ... etc. ...
 * ```
 *
 * This is especially useful for multi vendor marketplaces where each vendor has their own channel with `N` roles respectively.
 *
 * @docsCategory auth
 * @docsPage ChannelRolePlugin
 * @docsWeight 0
 * @since 3.2.0
 */

Breaking changes

Nothing should change with the default strategy but once you use the new strategy there is a migration needed because the plugin introduces a new Entity (ChannelRole) and existing roles will stop working. This makes this feature purely opt-in for people that are interested in multi-vendor setups.

Screenshots

You can add screenshots here if applicable.

ToDo

  • New UI dropdown depending on the strategy, on admin creation and update page
  • Fix/answer remaining TODO comments
  • Migration
  • Docs
  • Unit tests for new strategy
  • E2E tests for new strategy

Checklist

📌 Always:

  • I have set a clear title
  • My PR is small and contains a single feature
  • I have checked my own PR

👍 Most of the time:

  • I have added or updated test cases
  • I have updated the README if needed

Copy link

vercel bot commented Nov 20, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
docs ✅ Ready (Inspect) Visit Preview Mar 12, 2025 0:27am

…ResolverStrategy`

We need UI for the selection of channels but for the POC it will simply assign the default channel.
Also moved emitting of events to the end of admin-update function so
that a failure from updating custom field relations doesnt lead to wrong behavior of event handlers.
Copy link

sonarqubecloud bot commented Dec 1, 2024

Quality Gate Failed Quality Gate failed

Failed conditions
9.8% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@@ -14,6 +14,7 @@ export interface UserChannelPermissions {

/**
* Returns an array of Channels and permissions on those Channels for the given User.
* @deprecated See `RolePermissionResolverStrategy`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we really need to deprecate this first? This helper isn't exported, so I would say it's ok to just mention in the changelog that you should use configService.authOptions.rolePermissionResolverStrategy.resolvePermissions from now on.

@martijnvdbrug
Copy link
Collaborator

I like it already. One question, to mess everything up: Is there any functional benefit of useing DefaultRolePermissionResolverStrategy over the new ChannelRolePermissionResolverStrategy, or would the latter always be better and more flexible?

I know it makes this PR less complex and less breaking, but if there is no functional benefit over the DefaultRolePermissionResolverStrategy, is it worth maintaining for ever? Or would it be better to do a more painful migration now, and be done with it forever?

@DanielBiegler
Copy link
Contributor Author

FYI: Questions have been answered in private but I'll resurface them here to be visible for future interested parties (cc @mohdbk )

I'm not sure but I do think replacing this with the default role permission resolver strategy would be better

and

Or would it be better to do a more painful migration now, and be done with it forever?

Talked about it with Michael and our consensus is that breaking existing Vendure instances is a non starter, especially since technically nothing is "wrong" with the existing handling of Roles/Permissions, it just doesnt fit marketplaces specifically. Marketplaces are a niche and not the norm, so it feels more correct to have this as purely opt in.

There might come a point in the future where this new channel role strategy becomes the default, like for example the next major Vendure version, but for now keeping it a strict opt-in is a lot nicer to the existing user base. :-)

This is needed in order to construct the `ChannelRoleInput`s
Copy link

vercel bot commented Apr 2, 2025

Deployment failed with the following error:

The provided GitHub repository does not contain the requested branch or commit reference. Please ensure the repository is not empty.

Copy link

vercel bot commented Apr 3, 2025

@DanielBiegler is attempting to deploy a commit to the Vendure Team on Vercel.

A member of the Team first needs to authorize it.

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.

5 participants