UNPKG

@backstage/plugin-permission-node

Version:

Common permission and authorization utilities for backend plugins

89 lines (85 loc) 3.22 kB
'use strict'; var pluginPermissionCommon = require('@backstage/plugin-permission-common'); class ServerPermissionClient { #auth; #permissionClient; #permissionEnabled; static fromConfig(config, options) { const { auth, discovery } = options; const permissionClient = new pluginPermissionCommon.PermissionClient({ discovery, config }); const permissionEnabled = config.getOptionalBoolean("permission.enabled") ?? false; return new ServerPermissionClient({ auth, permissionClient, permissionEnabled }); } constructor(options) { this.#auth = options.auth; this.#permissionClient = options.permissionClient; this.#permissionEnabled = options.permissionEnabled; } async authorizeConditional(queries, options) { const credentials = await this.#getIncomingCredentials(options); if (credentials && this.#auth.isPrincipal(credentials, "service")) { return this.#servicePrincipalDecision(queries, credentials); } else if (!this.#permissionEnabled) { return queries.map((_) => ({ result: pluginPermissionCommon.AuthorizeResult.ALLOW })); } return this.#permissionClient.authorizeConditional( queries, await this.#getRequestOptions(options) ); } async authorize(requests, options) { const credentials = await this.#getIncomingCredentials(options); if (credentials && this.#auth.isPrincipal(credentials, "service")) { return this.#servicePrincipalDecision(requests, credentials); } else if (!this.#permissionEnabled) { return requests.map((_) => ({ result: pluginPermissionCommon.AuthorizeResult.ALLOW })); } return this.#permissionClient.authorize( requests, await this.#getRequestOptions(options) ); } async #getRequestOptions(options) { if (options && "credentials" in options) { if (this.#auth.isPrincipal(options.credentials, "none")) { return {}; } return this.#auth.getPluginRequestToken({ onBehalfOf: options.credentials, targetPluginId: "permission" }); } return options; } async #getIncomingCredentials(options) { if (options && "credentials" in options) { return options.credentials; } return void 0; } /** * For service principals, we can always make an immediate definitive decision * based on their associated access restrictions (if any). */ #servicePrincipalDecision(input, credentials) { const { permissionNames, permissionAttributes } = credentials.principal.accessRestrictions ?? {}; return input.map((item) => { if (permissionNames && !permissionNames.includes(item.permission.name)) { return { result: pluginPermissionCommon.AuthorizeResult.DENY }; } if (permissionAttributes?.action) { const action = item.permission.attributes?.action; if (!action || !permissionAttributes.action.includes(action)) { return { result: pluginPermissionCommon.AuthorizeResult.DENY }; } } return { result: pluginPermissionCommon.AuthorizeResult.ALLOW }; }); } } exports.ServerPermissionClient = ServerPermissionClient; //# sourceMappingURL=ServerPermissionClient.cjs.js.map