Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions frontend/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import Utils from './utils/utils'

import Project from './project'
import { integrationCategories } from 'components/pages/IntegrationsPage'
import {
EnvironmentPermissionDescription,
OrganisationPermissionDescription,
ProjectPermissionDescription,
} from './types/permissions.types'
const keywords = {
FEATURE_FUNCTION: 'myCoolFeature',
FEATURE_NAME: 'my_cool_feature',
Expand Down Expand Up @@ -252,7 +257,7 @@ const Constants = {
value: '',
} as SegmentCondition,
defaultTagColor: '#3d4db6',
environmentPermissions: (perm: string) =>
environmentPermissions: (perm: EnvironmentPermissionDescription) =>
`To manage this feature you need the <i>${perm}</i> permission for this environment.<br/>Please contact a member of this environment who has administrator privileges.`,
events: {
'ACCEPT_INVITE': (org: any) => ({
Expand Down Expand Up @@ -623,7 +628,7 @@ const Constants = {
modals: {
'PAYMENT': 'Payment Modal',
},
organisationPermissions: (perm: string) =>
organisationPermissions: (perm: OrganisationPermissionDescription) =>
`To manage this feature you need the <i>${perm}</i> permission for this organisastion.<br/>Please contact a member of this organisation who has administrator privileges.`,
pages: {
'ACCOUNT': 'Account Page',
Expand Down Expand Up @@ -656,7 +661,7 @@ const Constants = {
'#FFBE71',
'#F57C78',
],
projectPermissions: (perm: string) =>
projectPermissions: (perm: ProjectPermissionDescription) =>
`To use this feature you need the <i>${perm}</i> permission for this project.<br/>Please contact a member of this project who has administrator privileges.`,
resourceTypes: {
GITHUB_ISSUE: {
Expand Down
30 changes: 26 additions & 4 deletions frontend/common/providers/Permission.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import intersection from 'lodash/intersection'
import { cloneDeep } from 'lodash'
import Utils from 'common/utils/utils'
import Constants from 'common/constants'
import {
Permission as PermissionEnum,
PermissionDescriptions,
ProjectPermission,
} from 'common/types/permissions.types'

/**
* Props for the Permission component
Expand All @@ -21,7 +26,7 @@ import Constants from 'common/constants'
*/
type PermissionType = {
id: number | string
permission: string
permission: PermissionEnum
tags?: number[]
level: PermissionLevel
children:
Expand Down Expand Up @@ -153,7 +158,18 @@ const Permission: FC<PermissionType> = ({
})

const finalPermission = hasPermission || AccountStore.isAdmin()

let permissionDescriptionFunc: (perm: any) => any =
Constants.organisationPermissions
switch (level) {
case 'environment':
permissionDescriptionFunc = Constants.environmentPermissions
break
case 'project':
permissionDescriptionFunc = Constants.projectPermissions
break
default:
break
}
if (typeof children === 'function') {
const renderedChildren = children({
isLoading,
Expand All @@ -166,7 +182,10 @@ const Permission: FC<PermissionType> = ({

return Utils.renderWithPermission(
finalPermission,
permissionName || Constants.projectPermissions(permission),
permissionName ||
permissionDescriptionFunc(
PermissionDescriptions[permission as ProjectPermission],
),
renderedChildren,
)
}
Expand All @@ -178,7 +197,10 @@ const Permission: FC<PermissionType> = ({
if (showTooltip) {
return Utils.renderWithPermission(
finalPermission,
permissionName || Constants.projectPermissions(permission),
permissionName ||
permissionDescriptionFunc(
PermissionDescriptions[permission as ProjectPermission],
),
children,
)
}
Expand Down
89 changes: 89 additions & 0 deletions frontend/common/types/permissions.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Organization Permissions
export enum OrganisationPermission {
CREATE_PROJECT = 'CREATE_PROJECT',
MANAGE_USERS = 'MANAGE_USERS',
MANAGE_USER_GROUPS = 'MANAGE_USER_GROUPS',
}
export const OrganisationPermissionDescriptions = {
[OrganisationPermission.CREATE_PROJECT]: 'Create project',
[OrganisationPermission.MANAGE_USERS]: 'Manage users',
[OrganisationPermission.MANAGE_USER_GROUPS]: 'Manage user groups',
} as const

export type OrganisationPermissionDescription =
| (typeof OrganisationPermissionDescriptions)[keyof typeof OrganisationPermissionDescriptions]
| typeof ADMIN_PERMISSION_DESCRIPTION

export const ADMIN_PERMISSION = 'ADMIN' as const
export const ADMIN_PERMISSION_DESCRIPTION = 'Administrator' as const

// Project Permissions
export enum ProjectPermission {
VIEW_PROJECT = 'VIEW_PROJECT',
CREATE_ENVIRONMENT = 'CREATE_ENVIRONMENT',
DELETE_FEATURE = 'DELETE_FEATURE',
CREATE_FEATURE = 'CREATE_FEATURE',
MANAGE_SEGMENTS = 'MANAGE_SEGMENTS',
VIEW_AUDIT_LOG = 'VIEW_AUDIT_LOG',
MANAGE_TAGS = 'MANAGE_TAGS',
MANAGE_PROJECT_LEVEL_CHANGE_REQUESTS = 'MANAGE_PROJECT_LEVEL_CHANGE_REQUESTS',
APPROVE_PROJECT_LEVEL_CHANGE_REQUESTS = 'APPROVE_PROJECT_LEVEL_CHANGE_REQUESTS',
CREATE_PROJECT_LEVEL_CHANGE_REQUESTS = 'CREATE_PROJECT_LEVEL_CHANGE_REQUESTS',
}
export const ProjectPermissionDescriptions = {
[ProjectPermission.VIEW_PROJECT]: 'View project',
[ProjectPermission.CREATE_ENVIRONMENT]: 'Create environment',
[ProjectPermission.DELETE_FEATURE]: 'Delete feature',
[ProjectPermission.CREATE_FEATURE]: 'Create feature',
[ProjectPermission.MANAGE_SEGMENTS]: 'Manage segments',
[ProjectPermission.VIEW_AUDIT_LOG]: 'View audit log',
[ProjectPermission.MANAGE_TAGS]: 'Manage tags',
[ProjectPermission.MANAGE_PROJECT_LEVEL_CHANGE_REQUESTS]:
'Manage project level change requests',
[ProjectPermission.APPROVE_PROJECT_LEVEL_CHANGE_REQUESTS]:
'Approve project level change requests',
[ProjectPermission.CREATE_PROJECT_LEVEL_CHANGE_REQUESTS]:
'Create project level change requests',
} as const

export type ProjectPermissionDescription =
| (typeof ProjectPermissionDescriptions)[keyof typeof ProjectPermissionDescriptions]
| typeof ADMIN_PERMISSION_DESCRIPTION

// Environment Permissions
export enum EnvironmentPermission {
VIEW_ENVIRONMENT = 'VIEW_ENVIRONMENT',
UPDATE_FEATURE_STATE = 'UPDATE_FEATURE_STATE',
MANAGE_IDENTITIES = 'MANAGE_IDENTITIES',
CREATE_CHANGE_REQUEST = 'CREATE_CHANGE_REQUEST',
APPROVE_CHANGE_REQUEST = 'APPROVE_CHANGE_REQUEST',
VIEW_IDENTITIES = 'VIEW_IDENTITIES',
MANAGE_SEGMENT_OVERRIDES = 'MANAGE_SEGMENT_OVERRIDES',
}
export const EnvironmentPermissionDescriptions = {
[EnvironmentPermission.VIEW_ENVIRONMENT]: 'View environment',
[EnvironmentPermission.UPDATE_FEATURE_STATE]: 'Update feature state',
[EnvironmentPermission.MANAGE_IDENTITIES]: 'Manage identities',
[EnvironmentPermission.CREATE_CHANGE_REQUEST]: 'Create change request',
[EnvironmentPermission.APPROVE_CHANGE_REQUEST]: 'Approve change request',
[EnvironmentPermission.VIEW_IDENTITIES]: 'View identities',
[EnvironmentPermission.MANAGE_SEGMENT_OVERRIDES]: 'Manage segment overrides',
} as const

export type EnvironmentPermissionDescription =
| (typeof EnvironmentPermissionDescriptions)[keyof typeof EnvironmentPermissionDescriptions]
| typeof ADMIN_PERMISSION_DESCRIPTION

export type Permission =
| OrganisationPermission
| ProjectPermission
| EnvironmentPermission
| typeof ADMIN_PERMISSION

// Combined permission descriptions record
export const PermissionDescriptions = {
...OrganisationPermissionDescriptions,
...ProjectPermissionDescriptions,
...EnvironmentPermissionDescriptions,
[ADMIN_PERMISSION]: ADMIN_PERMISSION_DESCRIPTION,
} as const
49 changes: 27 additions & 22 deletions frontend/common/utils/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import {
MultivariateFeatureStateValue,
MultivariateOption,
Organisation,
PConfidence,
Project as ProjectType,
ProjectFlag,
SegmentCondition,
Tag,
PConfidence,
UserPermissions,
} from 'common/types/responses'
import flagsmith from 'flagsmith'
Expand All @@ -28,6 +28,15 @@ import { selectBuildVersion } from 'common/services/useBuildVersion'
import { getStore } from 'common/store'
import { TRACKED_UTMS, UtmsType } from 'common/types/utms'
import { TimeUnit } from 'components/release-pipelines/constants'
import {
ADMIN_PERMISSION,
ADMIN_PERMISSION_DESCRIPTION,
EnvironmentPermission,
EnvironmentPermissionDescription,
EnvironmentPermissionDescriptions,
OrganisationPermission,
OrganisationPermissionDescriptions,
} from 'common/types/permissions.types'

const semver = require('semver')

Expand Down Expand Up @@ -218,15 +227,15 @@ const Utils = Object.assign({}, require('./base/_utils'), {
},
getCreateProjectPermission(organisation: Organisation) {
if (organisation?.restrict_project_create_to_admin) {
return 'ADMIN'
return ADMIN_PERMISSION
}
return 'CREATE_PROJECT'
return OrganisationPermission.CREATE_PROJECT
},
getCreateProjectPermissionDescription(organisation: Organisation) {
if (organisation?.restrict_project_create_to_admin) {
return 'Administrator'
return ADMIN_PERMISSION_DESCRIPTION
}
return 'Create Project'
return OrganisationPermissionDescriptions.CREATE_PROJECT
},
getExistingWaitForTime: (
waitFor: string | undefined,
Expand Down Expand Up @@ -376,22 +385,15 @@ const Utils = Object.assign({}, require('./base/_utils'), {
},
getManageFeaturePermission(isChangeRequest: boolean) {
if (isChangeRequest) {
return 'CREATE_CHANGE_REQUEST'
return EnvironmentPermission.CREATE_CHANGE_REQUEST
}
return 'UPDATE_FEATURE_STATE'
return EnvironmentPermission.UPDATE_FEATURE_STATE
},
getManageFeaturePermissionDescription(isChangeRequest: boolean) {
if (isChangeRequest) {
return 'Create Change Request'
return EnvironmentPermissionDescriptions.CREATE_CHANGE_REQUEST
}
return 'Update Feature State'
},

getManageUserPermission() {
return 'MANAGE_IDENTITIES'
},
getManageUserPermissionDescription() {
return 'Manage Identities'
return EnvironmentPermissionDescriptions.UPDATE_FEATURE_STATE
},

getNextPlan: (skipFree?: boolean) => {
Expand Down Expand Up @@ -423,7 +425,12 @@ const Utils = Object.assign({}, require('./base/_utils'), {
const organisationId = match?.params?.organisationId
return organisationId ? parseInt(organisationId) : null
},
getOverridePermission: (level: 'identity' | 'segment') => {
getOverridePermission: (
level: 'identity' | 'segment',
): {
permission: EnvironmentPermission
permissionDescription: EnvironmentPermissionDescription
} => {
switch (level) {
case 'identity':
return {
Expand All @@ -433,8 +440,9 @@ const Utils = Object.assign({}, require('./base/_utils'), {
}
default:
return {
permission: 'MANAGE_SEGMENT_OVERRIDES',
permissionDescription: 'Manage Segment Overrides',
permission: EnvironmentPermission.MANAGE_SEGMENT_OVERRIDES,
permissionDescription:
EnvironmentPermissionDescriptions.MANAGE_SEGMENT_OVERRIDES,
}
}
},
Expand Down Expand Up @@ -622,9 +630,6 @@ const Utils = Object.assign({}, require('./base/_utils'), {
return utms
}, {} as UtmsType)
},
getViewIdentitiesPermission() {
return 'VIEW_IDENTITIES'
},

hasEntityPermission(key: string, entityPermissions: UserPermissions) {
if (entityPermissions?.admin) return true
Expand Down
10 changes: 8 additions & 2 deletions frontend/web/components/CompareIdentities.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import IdentityOverridesIcon from './IdentityOverridesIcon'
import Tooltip from './Tooltip'
import PageTitle from './PageTitle'
import { getDarkMode } from 'project/darkMode'
import {
EnvironmentPermission,
EnvironmentPermissionDescriptions,
} from 'common/types/permissions.types'

type CompareIdentitiesType = {
projectId: string
Expand Down Expand Up @@ -69,7 +73,7 @@ const CompareIdentities: FC<CompareIdentitiesType> = ({
const { isLoading: permissionLoading, permission } = useHasPermission({
id: environmentId,
level: 'environment',
permission: Utils.getViewIdentitiesPermission(),
permission: EnvironmentPermission.VIEW_IDENTITIES,
})

const { data: leftUser } = useGetIdentityFeatureStatesAllQuery(
Expand Down Expand Up @@ -189,7 +193,9 @@ const CompareIdentities: FC<CompareIdentitiesType> = ({
{!permission && !permissionLoading ? (
<div
dangerouslySetInnerHTML={{
__html: Constants.environmentPermissions('View Identities'),
__html: Constants.environmentPermissions(
EnvironmentPermissionDescriptions.VIEW_IDENTITIES,
),
}}
/>
) : (
Expand Down
12 changes: 8 additions & 4 deletions frontend/web/components/IdentityTraits.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import {
useGetIdentityTraitsQuery,
} from 'common/services/useIdentityTrait'
import { IdentityTrait } from 'common/types/responses'
import {
EnvironmentPermission,
EnvironmentPermissionDescriptions,
} from 'common/types/permissions.types'

type IdentityTraitsType = {
projectId: string | number
Expand All @@ -33,7 +37,7 @@ const IdentityTraits: FC<IdentityTraitsType> = ({
const { permission: manageUserPermission } = useHasPermission({
id: environmentId,
level: 'environment',
permission: Utils.getManageUserPermission(),
permission: EnvironmentPermission.MANAGE_IDENTITIES,
})

const { data: traits } = useGetIdentityTraitsQuery({
Expand Down Expand Up @@ -126,7 +130,7 @@ const IdentityTraits: FC<IdentityTraitsType> = ({
{Utils.renderWithPermission(
manageUserPermission,
Constants.environmentPermissions(
Utils.getManageUserPermissionDescription(),
EnvironmentPermissionDescriptions.MANAGE_IDENTITIES,
),
<Button
disabled={!manageUserPermission}
Expand Down Expand Up @@ -183,7 +187,7 @@ const IdentityTraits: FC<IdentityTraitsType> = ({
{Utils.renderWithPermission(
manageUserPermission,
Constants.environmentPermissions(
Utils.getManageUserPermissionDescription(),
EnvironmentPermissionDescriptions.MANAGE_IDENTITIES,
),
<Button
id='remove-feature'
Expand All @@ -208,7 +212,7 @@ const IdentityTraits: FC<IdentityTraitsType> = ({
{Utils.renderWithPermission(
manageUserPermission,
Constants.environmentPermissions(
Utils.getManageUserPermissionDescription(),
EnvironmentPermissionDescriptions.MANAGE_IDENTITIES,
),
<Button
disabled={!manageUserPermission}
Expand Down
Loading