mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 03:45:06 +03:00
change getRolesManagementPermissions to hook
This commit is contained in:
1 parent
8836a1b023
commit
a59e45191d
5 files changed
+105
-70
No files matched your search
@@ -2,19 +2,18 @@ import * as Tooltip from '@radix-ui/react-tooltip'
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FC } from 'react'
|
||||
import { Button, Dropdown, IconMoreHorizontal, IconTrash } from 'ui'
|
||||
|
||||
import { confirmAlert } from 'components/to-be-cleaned/ModalsDeprecated/ConfirmModal'
|
||||
import { checkPermissions, useSelectedOrganization, useStore } from 'hooks'
|
||||
import { useParams } from 'common/hooks'
|
||||
import { Member, Role } from 'types'
|
||||
|
||||
import { confirmAlert } from 'components/to-be-cleaned/ModalsDeprecated/ConfirmModal'
|
||||
import { useOrganizationMemberDeleteMutation } from 'data/organizations/organization-member-delete-mutation'
|
||||
import { useOrganizationMemberInviteCreateMutation } from 'data/organizations/organization-member-invite-create-mutation'
|
||||
import { useOrganizationMemberInviteDeleteMutation } from 'data/organizations/organization-member-invite-delete-mutation'
|
||||
import { isInviteExpired } from '../Organization.utils'
|
||||
import { getRolesManagementPermissions } from './TeamSettings.utils'
|
||||
import { usePermissionsQuery } from 'data/permissions/permissions-query'
|
||||
import { checkPermissions, useSelectedOrganization, useStore } from 'hooks'
|
||||
import { Member, Role } from 'types'
|
||||
import { Button, Dropdown, IconMoreHorizontal, IconTrash } from 'ui'
|
||||
import { isInviteExpired } from '../Organization.utils'
|
||||
import { useGetRolesManagementPermissions } from './TeamSettings.utils'
|
||||
|
||||
interface Props {
|
||||
member: Member
|
||||
@@ -26,10 +25,11 @@ const MemberActions: FC<Props> = ({ member, roles }) => {
|
||||
const { slug } = useParams()
|
||||
const selectedOrganization = useSelectedOrganization()
|
||||
const { data: permissions } = usePermissionsQuery()
|
||||
const { rolesRemovable } =
|
||||
selectedOrganization !== undefined
|
||||
? getRolesManagementPermissions(selectedOrganization.id, roles, permissions ?? [])
|
||||
: { rolesRemovable: [] as number[] }
|
||||
const { rolesRemovable } = useGetRolesManagementPermissions(
|
||||
selectedOrganization?.id,
|
||||
roles,
|
||||
permissions ?? []
|
||||
)
|
||||
|
||||
const isExpired = isInviteExpired(member?.invited_at ?? '')
|
||||
const isPendingInviteAcceptance = member.invited_id
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
import Image from 'next/image'
|
||||
import * as Tooltip from '@radix-ui/react-tooltip'
|
||||
import { useState, Fragment } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Badge, Button, Loading, Listbox, IconUser, Modal, IconAlertCircle, IconLoader } from 'ui'
|
||||
import Image from 'next/image'
|
||||
import { Fragment, useState } from 'react'
|
||||
|
||||
import { Member } from 'types'
|
||||
import { useSelectedOrganization, useStore } from 'hooks'
|
||||
import { useParams } from 'common/hooks'
|
||||
|
||||
import ShimmeringLoader from 'components/ui/ShimmeringLoader'
|
||||
import Table from 'components/to-be-cleaned/Table'
|
||||
import MemberActions from './MemberActions'
|
||||
import RolesHelperModal from './RolesHelperModal/RolesHelperModal'
|
||||
import { getRolesManagementPermissions } from './TeamSettings.utils'
|
||||
import { isInviteExpired, getUserDisplayName } from '../Organization.utils'
|
||||
import { useOrganizationRolesQuery } from 'data/organizations/organization-roles-query'
|
||||
import ShimmeringLoader from 'components/ui/ShimmeringLoader'
|
||||
import { useOrganizationDetailQuery } from 'data/organizations/organization-detail-query'
|
||||
import { useOrganizationMemberUpdateMutation } from 'data/organizations/organization-member-update-mutation'
|
||||
import { useProfileQuery } from 'data/profile/profile-query'
|
||||
import { useOrganizationRolesQuery } from 'data/organizations/organization-roles-query'
|
||||
import { usePermissionsQuery } from 'data/permissions/permissions-query'
|
||||
import { useProfileQuery } from 'data/profile/profile-query'
|
||||
import { useSelectedOrganization, useStore } from 'hooks'
|
||||
import { Member } from 'types'
|
||||
import { Badge, Button, IconAlertCircle, IconLoader, IconUser, Listbox, Loading, Modal } from 'ui'
|
||||
import { getUserDisplayName, isInviteExpired } from '../Organization.utils'
|
||||
import MemberActions from './MemberActions'
|
||||
import RolesHelperModal from './RolesHelperModal/RolesHelperModal'
|
||||
import { useGetRolesManagementPermissions } from './TeamSettings.utils'
|
||||
|
||||
interface SelectedMember extends Member {
|
||||
oldRoleId: number
|
||||
@@ -55,10 +54,11 @@ const MembersView = ({ searchString }: MembersViewProps) => {
|
||||
|
||||
const roles = rolesData?.roles ?? []
|
||||
const members = detailData?.members ?? []
|
||||
const { rolesAddable, rolesRemovable } =
|
||||
selectedOrganization !== undefined
|
||||
? getRolesManagementPermissions(selectedOrganization.id, roles, permissions ?? [])
|
||||
: { rolesAddable: [] as number[], rolesRemovable: [] as number[] }
|
||||
const { rolesAddable, rolesRemovable } = useGetRolesManagementPermissions(
|
||||
selectedOrganization?.id,
|
||||
roles,
|
||||
permissions ?? []
|
||||
)
|
||||
|
||||
const [selectedMember, setSelectedMember] = useState<SelectedMember>()
|
||||
const [userRoleChangeModalVisible, setUserRoleChangeModalVisible] = useState(false)
|
||||
|
||||
@@ -13,7 +13,7 @@ import { delete_ } from 'lib/common/fetch'
|
||||
import { API_URL } from 'lib/constants'
|
||||
import InviteMemberButton from './InviteMemberButton'
|
||||
import MembersView from './MembersView'
|
||||
import { getRolesManagementPermissions, hasMultipleOwners } from './TeamSettings.utils'
|
||||
import { hasMultipleOwners, useGetRolesManagementPermissions } from './TeamSettings.utils'
|
||||
|
||||
const TeamSettings = () => {
|
||||
const { ui } = useStore()
|
||||
@@ -30,10 +30,11 @@ const TeamSettings = () => {
|
||||
const members = detailData?.members ?? []
|
||||
const roles = rolesData?.roles ?? []
|
||||
|
||||
const { rolesAddable } =
|
||||
selectedOrganization !== undefined
|
||||
? getRolesManagementPermissions(selectedOrganization?.id, roles, permissions ?? [])
|
||||
: { rolesAddable: [] as number[] }
|
||||
const { rolesAddable } = useGetRolesManagementPermissions(
|
||||
selectedOrganization?.id,
|
||||
roles,
|
||||
permissions ?? []
|
||||
)
|
||||
|
||||
const [isLeaving, setIsLeaving] = useState(false)
|
||||
const [searchString, setSearchString] = useState('')
|
||||
|
||||
@@ -1,36 +1,42 @@
|
||||
import { Member, Permission, Role } from 'types'
|
||||
import { useCheckPermissions } from 'hooks'
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { doPermissionsCheck, useGetPermissions } from 'hooks'
|
||||
import { Member, Permission, Role } from 'types'
|
||||
|
||||
export const getRolesManagementPermissions = (
|
||||
orgId: number,
|
||||
roles: Role[],
|
||||
permissions: Permission[]
|
||||
export const useGetRolesManagementPermissions = (
|
||||
orgId?: number,
|
||||
roles?: Role[],
|
||||
permissions?: Permission[]
|
||||
): { rolesAddable: Number[]; rolesRemovable: Number[] } => {
|
||||
const { permissions: allPermissions, organizationId } = useGetPermissions(
|
||||
permissions,
|
||||
orgId,
|
||||
permissions !== undefined && orgId !== undefined
|
||||
)
|
||||
|
||||
const rolesAddable: Number[] = []
|
||||
const rolesRemovable: Number[] = []
|
||||
if (!roles) return { rolesAddable, rolesRemovable }
|
||||
if (!roles || !orgId) return { rolesAddable, rolesRemovable }
|
||||
|
||||
roles.forEach((role: Role) => {
|
||||
const canAdd = useCheckPermissions(
|
||||
const canAdd = doPermissionsCheck(
|
||||
allPermissions,
|
||||
PermissionAction.CREATE,
|
||||
'auth.subject_roles',
|
||||
{
|
||||
resource: { role_id: role.id },
|
||||
},
|
||||
orgId,
|
||||
permissions
|
||||
organizationId
|
||||
)
|
||||
if (canAdd) rolesAddable.push(role.id)
|
||||
|
||||
const canRemove = useCheckPermissions(
|
||||
const canRemove = doPermissionsCheck(
|
||||
allPermissions,
|
||||
PermissionAction.DELETE,
|
||||
'auth.subject_roles',
|
||||
{
|
||||
resource: { role_id: role.id },
|
||||
},
|
||||
orgId,
|
||||
permissions
|
||||
organizationId
|
||||
)
|
||||
if (canRemove) rolesRemovable.push(role.id)
|
||||
})
|
||||
|
||||
@@ -2,12 +2,58 @@ import jsonLogic from 'json-logic-js'
|
||||
|
||||
import { usePermissionsQuery } from 'data/permissions/permissions-query'
|
||||
import { IS_PLATFORM } from 'lib/constants'
|
||||
import { useSelectedOrganization } from './useSelectedOrganization'
|
||||
import { Permission } from 'types'
|
||||
import { useSelectedOrganization } from './useSelectedOrganization'
|
||||
|
||||
const toRegexpString = (actionOrResource: string) =>
|
||||
`^${actionOrResource.replace('.', '\\.').replace('%', '.*')}$`
|
||||
|
||||
export function doPermissionsCheck(
|
||||
permissions: Permission[] | undefined,
|
||||
action: string,
|
||||
resource: string,
|
||||
data?: object,
|
||||
organizationId?: number
|
||||
) {
|
||||
return (permissions ?? [])
|
||||
.filter(
|
||||
(permission) =>
|
||||
permission.organization_id === organizationId &&
|
||||
permission.actions.some((act) => (action ? action.match(toRegexpString(act)) : null)) &&
|
||||
permission.resources.some((res) => resource.match(toRegexpString(res)))
|
||||
)
|
||||
.some(
|
||||
({ condition }: { condition: jsonLogic.RulesLogic }) =>
|
||||
condition === null || jsonLogic.apply(condition, { resource_name: resource, ...data })
|
||||
)
|
||||
}
|
||||
|
||||
export function useGetPermissions(
|
||||
permissionsOverride?: Permission[],
|
||||
organizationIdOverride?: number,
|
||||
enabled = true
|
||||
) {
|
||||
const permissionsResult = usePermissionsQuery({
|
||||
enabled: permissionsOverride === undefined && enabled,
|
||||
})
|
||||
|
||||
const permissions =
|
||||
permissionsOverride === undefined ? permissionsResult.data : permissionsOverride
|
||||
|
||||
const organizationResult = useSelectedOrganization({
|
||||
enabled: organizationIdOverride === undefined && enabled,
|
||||
})
|
||||
|
||||
const organization =
|
||||
organizationIdOverride === undefined ? organizationResult : { id: organizationIdOverride }
|
||||
const organizationId = organization?.id
|
||||
|
||||
return {
|
||||
permissions,
|
||||
organizationId,
|
||||
}
|
||||
}
|
||||
|
||||
export function useCheckPermissions(
|
||||
action: string,
|
||||
resource: string,
|
||||
@@ -17,32 +63,14 @@ export function useCheckPermissions(
|
||||
organizationId?: number,
|
||||
permissions?: Permission[]
|
||||
) {
|
||||
const permissionsResult = usePermissionsQuery({
|
||||
enabled: permissions === undefined,
|
||||
})
|
||||
|
||||
const allPermissions = permissions === undefined ? permissionsResult.data : permissions
|
||||
|
||||
const organizationResult = useSelectedOrganization({
|
||||
enabled: organizationId === undefined,
|
||||
})
|
||||
|
||||
const organization = organizationId === undefined ? organizationResult : { id: organizationId }
|
||||
const orgId = organization?.id
|
||||
const { permissions: allPermissions, organizationId: orgId } = useGetPermissions(
|
||||
permissions,
|
||||
organizationId
|
||||
)
|
||||
|
||||
if (!IS_PLATFORM) return true
|
||||
|
||||
return (allPermissions ?? [])
|
||||
.filter(
|
||||
(permission) =>
|
||||
permission.organization_id === orgId &&
|
||||
permission.actions.some((act) => (action ? action.match(toRegexpString(act)) : null)) &&
|
||||
permission.resources.some((res) => resource.match(toRegexpString(res)))
|
||||
)
|
||||
.some(
|
||||
({ condition }: { condition: jsonLogic.RulesLogic }) =>
|
||||
condition === null || jsonLogic.apply(condition, { resource_name: resource, ...data })
|
||||
)
|
||||
return doPermissionsCheck(allPermissions, action, resource, data, orgId)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user