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

Plugins access control #3486

Merged
merged 58 commits into from
Mar 17, 2021
Merged

Plugins access control #3486

merged 58 commits into from
Mar 17, 2021

Conversation

Twixes
Copy link
Collaborator

@Twixes Twixes commented Feb 25, 2021

Changes

Basically, resolves #3328. Context in the issue.

Checklist

  • All querysets/queries filter by Organization, by Team, and by User
  • Django backend tests

@timgl timgl temporarily deployed to posthog-plugins-access--myqlh7 February 25, 2021 16:12 Inactive
@Twixes Twixes temporarily deployed to posthog-plugins-access--myqlh7 February 25, 2021 23:57 Inactive
@Twixes Twixes temporarily deployed to posthog-plugins-access--myqlh7 February 26, 2021 13:58 Inactive
@Twixes Twixes temporarily deployed to posthog-plugins-access--myqlh7 February 26, 2021 14:07 Inactive
This was referenced Feb 26, 2021
@Twixes Twixes temporarily deployed to posthog-plugins-access--myqlh7 March 2, 2021 12:29 Inactive
@Twixes Twixes mentioned this pull request Mar 2, 2021
4 tasks
@Twixes Twixes temporarily deployed to posthog-plugins-access--myqlh7 March 3, 2021 15:03 Inactive
@Twixes Twixes temporarily deployed to posthog-plugins-access--vpaftb March 3, 2021 15:24 Inactive
@Twixes Twixes temporarily deployed to posthog-plugins-access--rhvzlk March 4, 2021 20:54 Inactive
@Twixes Twixes temporarily deployed to posthog-plugins-access--ggxdau March 12, 2021 14:00 Inactive
Copy link
Collaborator

@mariusandra mariusandra left a comment

Choose a reason for hiding this comment

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

Two extra frontend comments for now...

frontend/src/scenes/plugins/plugin/PluginCard.tsx Outdated Show resolved Hide resolved
frontend/src/scenes/plugins/edit/PluginDrawer.tsx Outdated Show resolved Hide resolved
@Twixes Twixes temporarily deployed to posthog-plugins-access--ggxdau March 12, 2021 14:32 Inactive
@mariusandra
Copy link
Collaborator

@macobo I'm unfortunately going to have to put this on your lap as well. I have reviewed the frontend and all seems good there! Yet I did not manage to go through any .py file yet. I'm not that at home with permissions in django, and hence have to be really meticulous when reviewing this and test everything... but don't have the time anymore. :/

@mariusandra mariusandra requested a review from macobo March 12, 2021 15:55
Copy link
Contributor

@macobo macobo left a comment

Choose a reason for hiding this comment

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

Did my first code-level pass. The logic looks great, but I think the FE code can be cleaned up a lot. For the backend, seeing an absence of tests?

@@ -747,3 +747,14 @@ export function sortedKeys(object: Record<string, any>): Record<string, any> {
}
return newObject
}

export function endWithPeriod(text?: string | null): string {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: endWithPunctation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Why not

<TabPane tab="Repository" key={PluginTab.Repository}>
<RepositoryTab />
</TabPane>
{user.organization?.plugins_access_level === PluginsAccessLevel.Root && (
Copy link
Contributor

Choose a reason for hiding this comment

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

This code is not self-evident, it's not clear to a reader what plugin_access_level stands for or what the right levels are.

Suggestion:

Extract module frontend/src/scenes/plugins/accessControl.ts containing function(s) like hasAccessToPlugins(user), canInstallPlugins(user) etc. This keeps the business logic centralized and the component files readable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

@@ -170,6 +173,35 @@ export function PluginDrawer(): JSX.Element {
</div>
) : null}

{user?.organization?.plugins_access_level === PluginsAccessLevel.Root &&
user?.is_multi_tenancy && (
Copy link
Contributor

Choose a reason for hiding this comment

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

Q: Will this mean that this is a cloud user or...?

Also: Extract function canEnableGlobalPlugins.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Didn't extract the is_multi_tenancy since it'd require passing in user too and it's not globally relevant to permissioning. Just a presentation thing for now. Did extract the Root (etc.) check though.

<GlobalOutlined /> Managed by {organization_name}
</Tag>
)}
{user?.organization?.id === organization_id &&
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: canManage(user, plugin)

posthog/settings.py Show resolved Hide resolved
posthog/plugins/access.py Outdated Show resolved Hide resolved
posthog/api/plugin.py Show resolved Hide resolved
posthog/api/plugin.py Outdated Show resolved Hide resolved
posthog/api/plugin.py Show resolved Hide resolved
@Twixes Twixes temporarily deployed to posthog-plugins-access--ggxdau March 16, 2021 13:10 Inactive
@Twixes Twixes temporarily deployed to posthog-plugins-access--ggxdau March 16, 2021 13:38 Inactive
@Twixes Twixes requested a review from macobo March 16, 2021 13:38
@Twixes Twixes temporarily deployed to posthog-plugins-access--ggxdau March 16, 2021 13:38 Inactive
Copy link
Contributor

@macobo macobo left a comment

Choose a reason for hiding this comment

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

Good work. :shipit:

@@ -112,11 +114,9 @@ export const pluginsLogic = kea<
return { ...plugins, [id]: response }
},
updatePlugin: async ({ id }) => {
const { plugins } = values
const response = await api.update(`api/organizations/@current/plugins/${id}`, {})
const response = await api.create(`api/organizations/@current/plugins/${id}/upgrade`)
Copy link
Contributor

Choose a reason for hiding this comment

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

Note: I find the update/upgrade vs patch semantics a bit weird, but not sure how to improve this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

(blame Marius) Well initially PATCH was responsible for triggering this, but considering PATCH is represented as update in our API helper and in DRF, it is confusing. Had to change the endpoint to a separate /upgrade, but in the UI the feature is still "update".

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed. This is non-blocking imo.

@Twixes Twixes temporarily deployed to posthog-plugins-access--ggxdau March 17, 2021 13:36 Inactive
@Twixes Twixes temporarily deployed to posthog-plugins-access--ggxdau March 17, 2021 13:41 Inactive
@Twixes Twixes temporarily deployed to posthog-plugins-access--ggxdau March 17, 2021 13:42 Inactive
@Twixes Twixes merged commit 3c0737f into master Mar 17, 2021
@Twixes Twixes deleted the plugins-access-control branch March 17, 2021 14:01
Twixes added a commit that referenced this pull request Mar 18, 2021
* Add Organization.PluginsAccess

* Rename PluginsAccess to PluginsAccessLevel

* Use Organization.plugins_access_level in can_…_plugins_via_api

* Add migration for Organization.plugins_access_level

* Remove unused PLUGINS_CLOUD_WHITELISTED_ORG_IDS

* Update access.py

* Add OrganizationPluginsAccessLevel TS enum

* Fix merge

* Disable LocalPlugin UI on Cloud

* Move away from PluginAccess interface

* Extend PluginsAccessLevel range

* Refactor PluginsAccessLevel for brevity

* Remove PluginAccess interface completely

* Add plugins managed globally

* Update migration

* Show managing org name in "Managed" plugin tag

* Smoothen some rough edges

* Smoothen more edges

* Restore correct MULTI_TENANCY default

* All the edges

* Fix most existing tests

* Remove PLUGINS_*_VIA_API env var support

* Update pluginsNeedingUpdates

* Remove can_*_plugins_via_api from instance status page

* Add tests and polish permissioning

* Update migration

* Fix typing

* Make plugin drawer UI less intrusive

* Update migration

* Fix Uninstall button condition

* Use unified _preflight status endpoint instead of the custom plugins one

* Fix plugin update label condition

* Fix "Check for updates" button condition

* Explain PluginsAccessLevel choices with comments

* Hide global plugin installation option on self-hosted

* Don't actions.loadRepository() as install org

* Improve permissioning with tests

* Satisfy mypy

* Add plugins access level to admin and fix org admin

* Check plugins access level more

* Rename endWithPeriod

* Refactor FE access control checks to accessControl.ts

* Deduplicate permissioning

* Add exception message

* Align backend and frontend plugins access level helpers

* Add plugins access level helper tests

* Fix ChartFilter
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.

Access control for plugins on cloud
4 participants