-
Notifications
You must be signed in to change notification settings - Fork 617
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(cms): bring back old permissions checking-related utils (#3904)
- Loading branch information
Showing
5 changed files
with
217 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
packages/api-headless-cms/src/utils/permissions/EntriesPermissions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { CmsEntryPermission } from "~/types"; | ||
import { AppPermissions } from "@webiny/api-security"; | ||
|
||
export class EntriesPermissions extends AppPermissions<CmsEntryPermission> {} |
52 changes: 52 additions & 0 deletions
52
packages/api-headless-cms/src/utils/permissions/ModelGroupsPermissions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { AppPermissions, NotAuthorizedError } from "@webiny/api-security"; | ||
import { CmsGroup, CmsGroupPermission } from "~/types"; | ||
|
||
export interface CanAccessGroupParams { | ||
group: Pick<CmsGroup, "id" | "locale">; | ||
} | ||
|
||
export class ModelGroupsPermissions extends AppPermissions<CmsGroupPermission> { | ||
async canAccessGroup({ group }: CanAccessGroupParams) { | ||
if (await this.hasFullAccess()) { | ||
return true; | ||
} | ||
|
||
const permissions = await this.getPermissions(); | ||
|
||
const locale = group.locale; | ||
|
||
for (const permission of permissions) { | ||
const { groups } = permission; | ||
|
||
// When no groups defined on permission it means user has access to everything. | ||
if (!groups) { | ||
return true; | ||
} | ||
|
||
// when there is no locale in groups, it means that no access was given | ||
// this happens when access control was set but no models or groups were added | ||
if ( | ||
Array.isArray(groups[locale]) === false || | ||
groups[locale].includes(group.id) === false | ||
) { | ||
continue; | ||
} | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
async ensureCanAccessGroup(params: CanAccessGroupParams) { | ||
const canAccessModel = await this.canAccessGroup(params); | ||
if (canAccessModel) { | ||
return; | ||
} | ||
|
||
throw new NotAuthorizedError({ | ||
data: { | ||
reason: `Not allowed to access group "${params.group.id}".` | ||
} | ||
}); | ||
} | ||
} |
113 changes: 113 additions & 0 deletions
113
packages/api-headless-cms/src/utils/permissions/ModelsPermissions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import { AppPermissions, AppPermissionsParams, NotAuthorizedError } from "@webiny/api-security"; | ||
import { | ||
CmsGroupPermission, | ||
CmsModel as BaseCmsModel, | ||
CmsModelGroup as BaseCmsModelGroup, | ||
CmsModelPermission | ||
} from "~/types"; | ||
import { ModelGroupsPermissions } from "~/utils/permissions/ModelGroupsPermissions"; | ||
|
||
export interface ModelsPermissionsParams extends AppPermissionsParams<CmsGroupPermission> { | ||
modelGroupsPermissions: ModelGroupsPermissions; | ||
} | ||
|
||
interface PickedCmsModel extends Pick<BaseCmsModel, "modelId" | "locale"> { | ||
group: Pick<BaseCmsModelGroup, "id">; | ||
} | ||
|
||
export interface CanAccessModelParams { | ||
model: PickedCmsModel; | ||
} | ||
|
||
export interface EnsureModelAccessParams { | ||
model: PickedCmsModel; | ||
} | ||
|
||
export class ModelsPermissions extends AppPermissions<CmsModelPermission> { | ||
private readonly modelGroupsPermissions: ModelGroupsPermissions; | ||
|
||
public constructor(params: ModelsPermissionsParams) { | ||
super(params); | ||
this.modelGroupsPermissions = params.modelGroupsPermissions; | ||
} | ||
|
||
public async canAccessModel({ model }: CanAccessModelParams) { | ||
if (await this.hasFullAccess()) { | ||
return true; | ||
} | ||
|
||
const modelGroupsPermissions = this.modelGroupsPermissions; | ||
|
||
// eslint-disable-next-line | ||
const modelsPermissions = this; | ||
|
||
const canReadGroups = await modelGroupsPermissions.ensure({ rwd: "r" }, { throw: false }); | ||
if (!canReadGroups) { | ||
return false; | ||
} | ||
|
||
const canReadModels = await modelsPermissions.ensure({ rwd: "r" }, { throw: false }); | ||
if (!canReadModels) { | ||
return false; | ||
} | ||
|
||
const modelGroupsPermissionsList = await modelGroupsPermissions.getPermissions(); | ||
const modelsPermissionsList = await this.getPermissions(); | ||
|
||
const locale = model.locale; | ||
|
||
for (let i = 0; i < modelGroupsPermissionsList.length; i++) { | ||
const modelGroupPermission = modelGroupsPermissionsList[i]; | ||
|
||
const { groups } = modelGroupPermission; | ||
|
||
for (let j = 0; j < modelsPermissionsList.length; j++) { | ||
const modelPermission = modelsPermissionsList[j]; | ||
|
||
const { models } = modelPermission; | ||
// when no models or groups defined on permission | ||
// it means user has access to everything | ||
if (!models && !groups) { | ||
return true; | ||
} | ||
|
||
// Does the model belong to a group for which user has permission? | ||
if (groups) { | ||
if ( | ||
Array.isArray(groups[locale]) === false || | ||
groups[locale].includes(model.group.id) === false | ||
) { | ||
continue; | ||
} | ||
} | ||
|
||
// Does the user have access to the specific model? | ||
if (models) { | ||
if ( | ||
Array.isArray(models[locale]) === false || | ||
models[locale].includes(model.modelId) === false | ||
) { | ||
continue; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
public async ensureCanAccessModel(params: EnsureModelAccessParams) { | ||
const canAccessModel = await this.canAccessModel(params); | ||
if (canAccessModel) { | ||
return; | ||
} | ||
|
||
throw new NotAuthorizedError({ | ||
data: { | ||
reason: `Not allowed to access model "${params.model.modelId}".` | ||
} | ||
}); | ||
} | ||
} |