UNPKG

passbolt-styleguide

Version:

Passbolt styleguide contains common styling assets used by the different sites, plugin, etc.

309 lines (288 loc) 9.13 kB
/** * Passbolt ~ Open source password manager for teams * Copyright (c) Passbolt SA (https://www.passbolt.com) * * Licensed under GNU Affero General Public License version 3 of the or any later version. * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * * @copyright Copyright (c) Passbolt SA (https://www.passbolt.com) * @license https://opensource.org/licenses/AGPL-3.0 AGPL License * @link https://www.passbolt.com Passbolt(tm) * @since 2.0.0 */ const READ = 1; // const UPDATE = 7; const ADMIN = 15; export default class ShareChanges { /** * Constructor * @param {array} resources * @param {array} folders */ constructor(resources, folders) { this._folders = folders || []; this._resources = resources || []; this._permissions = []; this._aroPermissions = []; this._aros = {}; this._acos = []; /* * Remap the resources and folder into an ACO array * Extend object with "_type" to keep distinction */ this._resources.forEach((resource) => { resource._type = "Resource"; this._acos.push(resource); }); this._folders.forEach((folder) => { folder._type = "Folder"; this._acos.push(folder); }); // Build the permission list this._acos.forEach((aco) => { aco.permissions.forEach((permission) => { const aro = permission.user || permission.group; if (!this._aros[aro.id]) { this._aros[aro.id] = aro; } this._permissions.push(permission); }); }); this._changes = []; } // new getChanges() { return this._changes; } getResourcesChanges() { return this._changes.filter((element) => element.aco === "Resource"); } getFoldersChanges() { return this._changes.filter((element) => element.aco === "Folder"); } getAcos() { return this._acos; } /** * Check that a user is the original owner of the resources * @return {boolean} */ isOriginalResourcesOwner() { return this._acos.reduce((carry, aco) => carry && aco.permission.type === ADMIN, true); } /** * Aggregate the permissions by user. * @return {object} The mapped permissions list * * { * ARO_ID: { * id: {string}, // The aro id * aro: {object}, * type: int, * permissions: array<object> * } * } */ aggregatePermissionsByAro() { // Aggregate the data as expected. const arosPermissions = this._permissions.reduce((carry, permission) => { let aroPermission = carry.find((_data) => _data.id === permission.aro_foreign_key); if (!aroPermission) { const aro = permission.user || permission.group; aroPermission = { id: aro.id, aro: aro, type: permission.type, permissions: [], }; carry.push(aroPermission); } aroPermission.type = aroPermission.type === permission.type ? aroPermission.type : -1; aroPermission.permissions.push(permission); return carry; }, []); // Calculate varies details arosPermissions.forEach((aroPermissions) => { // permission type varies also in the case there is less permissions than resources shared. if (aroPermissions.permissions.length !== this._acos.length) { aroPermissions.type = -1; } if (aroPermissions.type === -1) { // For each permission, aggregate the resources aro has access. aroPermissions.variesDetails = this._acos.reduce( (carry, aco) => { const result = aroPermissions.permissions.filter((permission) => permission.aco_foreign_key === aco.id); const carryType = result[0]?.type || 0; const acoName = aco.metadata.name; carry[carryType].push(acoName); return carry; }, { 0: [], 1: [], 7: [], 15: [] }, ); } }); // Order the array by aros (user firstname / group name). arosPermissions.sort((a, b) => { const aValue = a.aro.profile ? a.aro.profile.first_name : a.aro.name; const bValue = b.aro.profile ? b.aro.profile.first_name : b.aro.name; if (aValue < bValue) { return -1; } else if (aValue > bValue) { return 1; } return 0; }); this._aroPermissions = arosPermissions; return this._aroPermissions; } /** * Check if an aro has some changes * @param {string} aroId The aro identifier * @return {boolean} */ hasChanges(aroId) { const change = this._changes.find((change) => change.aro_foreign_key === aroId); return change !== undefined; } /** * Add new permission for a given aro * @return {object} The mapped permission * * { * ARO_ID: { * id: {string}, // The aro id * aro: {object}, * type: int, * permissions: array<object> * } * } */ addAroPermissions(aro) { const type = READ; this._aros[aro.id] = aro; this.updateAroPermissions(aro.id, READ); return { id: aro.id, aro: aro, type: type, permissions: [], }; } /** * Update aro's permissions. * @param {string} aroId The aro to update the permissions for * @param {int} type */ updateAroPermissions(aroId, type) { this._removeAroChanges(aroId); this._acos.forEach((aco) => { const permissionOriginal = this.getAcoAroPermission(aco, aroId); if (permissionOriginal) { if (permissionOriginal.type !== type) { const permissionChange = JSON.parse(JSON.stringify(permissionOriginal)); permissionChange.type = type; this._changes.push(permissionChange); } } else { const aro = this._aros[aroId]; const permissionChange = this._buildChange(aco, aro, type); this._changes.push(permissionChange); } }); } /** * Delete aro's permissions. * @param {string} aroId The aro to delete the permissions for */ deleteAroPermissions(aroId) { this._removeAroChanges(aroId); this._acos.forEach((aco) => { const permissionOriginal = this.getAcoAroPermission(aco, aroId); if (permissionOriginal) { const permissionChange = JSON.parse(JSON.stringify(permissionOriginal)); permissionChange.delete = true; this._changes.push(permissionChange); } }); delete this._aros[aroId]; } /** * Get the permission for a given resource and a given aro * @param {object} aco The resource or Folder to get the aro permission for * @param {string} aroId The User or Group to get the resource or folder permission for * @returns {object} */ getAcoAroPermission(aco, aroId) { return this._permissions.find( (permission) => permission.aro_foreign_key === aroId && permission.aco_foreign_key === aco.id, ); } /** * Get the resources with no owners after applying the changes. * @returns {Resource.List} */ getResourcesWithNoOwner() { return this._acos.filter((aco) => { const changes = this._changes.filter((change) => change.aco_foreign_key === aco.id); // Check if a new owner is promoted. const grantedOwner = changes.find((change) => change.type === ADMIN && !change.delete); if (grantedOwner) { return false; } // Check if there is at least one of the original owners after applying the change. const originalOwnersPermissionsIds = this._permissions.reduce((carry, permission) => { if (permission.aco_foreign_key === aco.id && permission.type === ADMIN) { carry = [...carry, permission.id]; } return carry; }, []); // Check if owner was removed const revokedOwners = changes.filter( (change) => (change.delete || change.type !== ADMIN) && originalOwnersPermissionsIds.indexOf(change.id) !== -1, ); return revokedOwners.length === originalOwnersPermissionsIds.length; }); } /** * Remove all the permissions changes related to a given aro. * @param {string} aroId The aro to delete the changes for * @private */ _removeAroChanges(aroId) { this._acos.forEach((aco) => { this._changes = this._changes.filter( (change) => !(change.aco_foreign_key === aco.id && change.aro_foreign_key === aroId), ); }); } /** * Build a permission change * @param {object} aco The resource or folder to build a change for * @param {object} aro The aro to build a change for * @param {int} type The type of permission * @returns {object} * { * { * is_new: boolean, * aro: string, * aro_foreign_key: string * aco: string, * aco_foreign_key: string, * type: int * } * } * * @private */ _buildChange(aco, aro, type) { return { is_new: true, aro: aro.profile ? "User" : "Group", aro_foreign_key: aro.id, aco: aco._type, aco_foreign_key: aco.id, type: type, }; } }