mattermost-mobile-upstream/app/utils/render_permissions.ts
Mattermost Build 287db3bd17
MM-70693: Hide burn-on-read quick action when ABAC policy denies it (#10239) (#10260)
* Remove BoR quick action on ABAC permission denial

* Update Render Permission to support handling for ABAC servers that do not yet support a particular permision action - they will be treated as "unenforced"

* detox - allow skipping of tests on permission policy actions that are not supported by the test server yet

(cherry picked from commit 16c5849eb6)

Co-authored-by: Nate Schlossberg <nate.schlossberg@mattermost.com>
2026-10-20 09:01:17 +03:00

52 lines
2.0 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import type {RenderPermissionActionName} from '@constants/access_control';
import type {RenderPermissionsEntry} from '@store/render_permissions_store';
/**
* Whether the decisions for a channel have to be (re)fetched: only while ABAC is enforced, and when
* none are stored, they expired, or an ABAC invalidation happened after they were requested.
*/
export function shouldFetchRenderPermissions(enforced: boolean, requiredEpoch: number, entry?: RenderPermissionsEntry): boolean {
if (!enforced) {
return false;
}
return !entry || Boolean(entry.expired) || entry.epoch < requiredEpoch;
}
/**
* The decision to render for an action. The last known decision is kept while it is revalidated, so a
* control does not flip to its default and back on every refresh; the server enforces every action on
* its own, so the client only decides how the control looks.
* @param allowWhenUnenforced - What to render while ABAC is not enforced, or when the server answered
* without the action because it predates it
* @param allowWhenNotEvaluated - What to render while ABAC is enforced but the server has not answered
* yet, or could not evaluate the action; defaults to allowWhenUnenforced
*/
export function resolveRenderPermission(
enforced: boolean,
entry: RenderPermissionsEntry | undefined,
action: RenderPermissionActionName,
allowWhenUnenforced: boolean,
allowWhenNotEvaluated = allowWhenUnenforced,
): boolean {
if (!enforced) {
return allowWhenUnenforced;
}
if (!entry) {
return allowWhenNotEvaluated;
}
// The server returns every action it registers, so one missing from an answer is not governed there.
const decision = entry.decisions[action];
if (!decision) {
return allowWhenUnenforced;
}
if (!decision.evaluated) {
return allowWhenNotEvaluated;
}
return decision.allowed;
}