| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- import RoleUtils from '~/services/rights/roleUtils'
- import {AbilitiesType} from '~/types/interfaces'
- import YamlDenormalizer from "~/services/data/serializer/denormalizer/yamlDenormalizer";
- import {MongoAbility} from "@casl/ability/dist/types/Ability";
- import {AnyJson} from "~/types/data";
- import {useEach} from "#imports";
- import {ABILITIES} from "~/types/enum/enums";
- /**
- * Classe permettant de mener des opérations sur les habilités
- */
- class AbilityUtils {
- private readonly ability: MongoAbility = {} as MongoAbility
- private readonly accessProfile: any
- private readonly organizationProfile: any
- private readonly configDir = './config/abilities/config.yaml'
- private abilitiesByRoles: Array<AbilitiesType> = []
- private abilitiesByConfig: Array<AbilitiesType> = []
- /**
- * @constructor
- */
- constructor(
- ability: MongoAbility,
- accessProfile: any,
- organizationProfile: any,
- ) {
- this.ability = ability
- this.accessProfile = accessProfile
- this.organizationProfile = organizationProfile
- }
- /**
- * Définit les abilities de l'utilisateur selon son profil
- */
- setupAbilities() {
- // Nécessaire pour que l'update des habilités soit correcte après la phase SSR
- this.ability.update(this.accessProfile.abilities)
- // Au moment où l'on effectue une action organizationProfileStore.setProfile, il faut aller récupérer
- // les différentes habilités que l'utilisateur peut effectuer. (Tout cela se passe en SSR)
- const unsubscribe = this.organizationProfile.$onAction(({
- name, // name of the action
- store, // store instance, same as `someStore`
- args, // array of parameters passed to the action
- after, // hook after the action returns or resolves
- onError, // hook if the action throws or rejects
- }: any) => {
- after((result: any)=>{
- if (name === 'setProfile'){
- //On récupère les habilités
- const abilities = this.buildAbilities();
- //On les store puis on update le service ability pour le mettre à jour.
- this.accessProfile.abilities = abilities
- this.ability.update(abilities)
- // Unsubscribe pour éviter les memory leaks
- unsubscribe()
- }
- })
- })
- }
- /**
- * Récupération de l'ensemble des habilités de l'utilisateur, qu'elles soient par Roles ou par Config
- *
- * @return {Array<AbilitiesType>}
- */
- buildAbilities(): Array<AbilitiesType> {
- this.buildAbilitiesFromRoles()
- this.buildAbilitiesFromConfig()
- return this.abilities()
- }
- abilities(): Array<AbilitiesType> {
- return ([] as Array<AbilitiesType>).concat(this.abilitiesByRoles).concat(this.abilitiesByConfig)
- }
- /**
- * Adaptation et transformations des roles symfony en abilities Casl
- */
- buildAbilitiesFromRoles() {
- this.abilitiesByRoles = RoleUtils.rolesToAbilities(this.accessProfile.roles)
- }
- /**
- * Charge les habilités depuis les fichiers de configuration
- */
- buildAbilitiesFromConfig() {
- const doc = YamlDenormalizer.denormalize({path: this.configDir})
- const fromConfig = doc.abilities
- useEach(fromConfig, (ability: { action: ABILITIES, services: object }, subject: string) => {
- const { action, services } = ability
- if (this.hasConfigAbility(services)) {
- this.abilitiesByConfig.push({ action, subject })
- }
- })
- }
- /**
- * Parcourt les services définis dans la configuration, et établit si oui ou non l'habilité est autorisée
- *
- * TODO: voir pourquoi on a besoin d'accepter un param null pour le hasProfile?
- *
- * @return {boolean}
- * @param services
- */
- hasConfigAbility(services: AnyJson) {
- for (const service in services) {
- let handlers = services[service] as Array<{ function: string, parameters?: Array<any>, result?: any }>
- if (handlers.some((handler) => !this.testConfigService(handler))) {
- return false
- }
- }
- return true
- }
- handlerMap: any = {
- hasAllRoleAbilities: (parameters: any) => this.hasAllRoleAbilities(parameters),
- hasAnyProfile: (parameters: any) => parameters === null || this.hasAnyProfile(parameters),
- hasAllModules: (parameters: any) => this.hasAllModules(parameters),
- isAdminAccount: (parameters: any) => this.accessProfile.isAdminAccount,
- isSchool: (parameters: any) => this.organizationProfile.isSchool,
- isArtist: (parameters: any) => this.organizationProfile.isArtist,
- isManagerProduct: (parameters: any) => this.organizationProfile.isManagerProduct,
- isOrganizationWithChildren: (parameters: any) => this.organizationProfile.hasChildren,
- isAssociation: (parameters: any) => this.organizationProfile.isAssociation,
- isShowAdherentList: (parameters: any) => this.organizationProfile.isShowAdherentList,
- isCmf: (parameters: any) => this.organizationProfile.isCmf,
- getWebsite: (parameters: any) => this.organizationProfile.getWebsite,
- }
- private testConfigService(handler: { function: string, parameters?: Array<any>, result?: any }) {
- const expectedResult: boolean = handler.result ?? true;
- const parameters = handler.parameters ?? []
- const actualResult = this.handlerMap[handler.function](parameters ?? null)
- return actualResult === expectedResult
- }
- /**
- * Est-ce que l'utilisateur possède l'habilité passée en paramètre
- *
- * @return {boolean}
- * @param ability
- */
- hasRoleAbility(ability: AbilitiesType) {
- return this.abilitiesByRoles.some(
- (candidate) => candidate.action === ability.action && candidate.subject === ability.subject
- )
- }
- /**
- * Est-ce que l'utilisateur possède toutes les habilités passées en paramètre
- *
- * @param {Array<AbilitiesType>} abilities Habilités à tester
- * @return {boolean}
- */
- hasAllRoleAbilities(abilities: Array<AbilitiesType>): boolean {
- return abilities.every(
- ability => this.hasRoleAbility(ability)
- )
- }
- /**
- * Teste si l'utilisateur possède le profil donné
- *
- * @param {string} profile Profil à tester
- * @return {boolean}
- */
- hasProfile(profile: string): boolean {
- return {
- 'admin': this.accessProfile.isAdmin,
- 'administratifManager': this.accessProfile.isAdministratifManager,
- 'pedagogicManager': this.accessProfile.isPedagogicManager,
- 'financialManager': this.accessProfile.isFinancialManager,
- 'caMember': this.accessProfile.isCaMember,
- 'student': this.accessProfile.isStudent,
- 'teacher': this.accessProfile.isTeacher,
- 'member': this.accessProfile.isMember,
- 'other': this.accessProfile.isOther,
- 'guardian': this.accessProfile.isGuardian,
- 'payor': this.accessProfile.isPayer,
- }[profile] ?? false
- }
- /**
- * Retourne vrai si l'utilisateur connecté possède l'un des profils passés en paramètre
- *
- * @param {Array<string>} profiles Profils à tester
- * @return {boolean}
- */
- hasAnyProfile (profiles: Array<string>): boolean {
- return profiles.some(p => this.hasProfile(p))
- }
- /**
- * Retourne vrai si l'utilisateur connecté possède tous les profils passés en paramètre
- *
- * @param {Array<string>} profiles Profils à tester
- * @return {boolean}
- */
- hasAllProfiles (profiles: Array<string>): boolean {
- return profiles.every(p => this.hasProfile(p))
- }
- /**
- * Est-ce que l'utilisateur possède le rôle donné ?
- *
- * @return {boolean}
- * @param role
- */
- hasRole(role: string): boolean {
- return this.accessProfile.hasRole(role)
- }
- /**
- * L'utilisateur possède-t-il au moins l'un des rôles donnés
- *
- * @return {boolean}
- * @param roles
- */
- hasAnyRole(roles: Array<string>): boolean {
- return roles.some(r => this.hasRole(r))
- }
- /**
- * L'utilisateur possède-t-il tous les rôles donnés
- *
- * @return {boolean}
- * @param roles
- */
- hasAllRoles(roles: Array<string>): boolean {
- return roles.every(r => this.hasRole(r))
- }
- /**
- * Est-ce que l'organisation possède le module donné
- *
- * @return {boolean}
- * @param module
- */
- hasModule(module: string): boolean {
- return this.organizationProfile.hasModule(module)
- }
- /**
- * Est-ce que l'organisation possède au moins un des modules donnés
- *
- * @param modules
- * @return {boolean}
- */
- hasAnyModule(modules: Array<string>): boolean {
- return modules.some(r => this.hasModule(r))
- }
- /**
- * Est-ce que l'organisation possède-t-il tous les modules donnés
- *
- * @param modules
- * @return {boolean}
- */
- hasAllModules(modules: Array<string>): boolean {
- return modules.every(r => this.hasModule(r))
- }
- }
- export default AbilityUtils
|