| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- 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
- /**
- * @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)
- // const abilities: Array<AbilitiesType> = this.buildAbilities();
- // this.accessProfile.abilities = abilities
- // this.ability.update(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: Array<AbilitiesType> = 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> {
- const abilitiesByRoles: Array<AbilitiesType> = this.buildAbilitiesFromRoles(this.accessProfile.roles)
- const abilitiesByConfig = this.buildAbilitiesFromConfig('./config/abilities/config.yaml')
- return abilitiesByRoles.concat(abilitiesByConfig)
- }
- /**
- * Adaptation et transformations des roles symfony en abilities Casl
- *
- * @param {Array<string>} roles
- * @return {Array<AbilitiesType>}
- */
- buildAbilitiesFromRoles(roles: Array<string>): Array<AbilitiesType> {
- return RoleUtils.rolesToAbilities(roles)
- }
- /**
- * Charge les habilités depuis les fichiers de configuration
- *
- * @param {string} configPath
- * @return {Array<AbilitiesType>}
- */
- buildAbilitiesFromConfig(configPath: string): Array<AbilitiesType> {
- const doc = YamlDenormalizer.denormalize({path: configPath})
- const fromConfig = doc.abilities
- const abilities: Array<AbilitiesType> = []
- useEach(fromConfig, (ability: { action: ABILITIES, services: object }, subject: string) => {
- const { action, services } = ability
- if (this.hasConfigAbility(services)) {
- abilities.push({ action, subject })
- }
- })
- return abilities
- }
- /**
- * Parcourt les services définis dans la configuration, et établit si oui ou non l'habilité est autorisée
- *
- * @return {boolean}
- * @param services
- */
- hasConfigAbility(services: AnyJson) {
- const handlerMap: any = {
- hasRole: (parameters: any) => this.hasRoles(parameters),
- hasAbility: (parameters: any) => this.hasAbilities(parameters),
- hasProfile: (parameters: any) => this.hasProfileAmong(parameters),
- isAdminAccount: (parameters: any) => this.accessProfile.isAdminAccount,
- hasModule: (parameters: any) => this.hasModule(parameters),
- 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,
- }
- let hasAbility = true
- useEach(services, (handlers: Array<{ function: string, parameters?: Array<any>, result?: any }>, service: string) => {
- useEach(handlers, (handler: { function: string, parameters?: Array<any>, result?: any }) => {
- const expectedResult: boolean = handler.result ?? true;
- const parametersArray = handler.parameters ?? []
- useEach(parametersArray, (parameters: any) => {
- const actualResult = handlerMap[handler.function](parameters ?? null)
- if (actualResult !== expectedResult) {
- hasAbility = false
- return false
- }
- })
- if (!hasAbility) { return false }
- })
- if (!hasAbility) { return false }
- })
- return hasAbility
- }
- /**
- * Est-ce que l'utilisateur possède la ou les habilités
- *
- * @param {Array<AbilitiesType>} abilities Habilités à tester
- * @return {boolean}
- */
- hasAbilities(abilities: Array<AbilitiesType>|null): boolean{
- useEach(abilities ?? [], (ability) => {
- if (!this.ability.can(ability.action, ability.subject)) {
- return false
- }
- })
- return true
- }
- /**
- * Teste le profil d'un utilisateur
- *
- * @param {string} profile : profile à tester
- * @return {boolean}
- */
- private testProfile(profile: string): boolean {
- const factory: {[key: string]: boolean|null} = {
- '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,
- }
- return factory[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}
- */
- hasProfileAmong (profiles: Array<string>|null): boolean {
- if (null === profiles)
- return true;
- useEach(profiles, (profile) => {
- if (this.testProfile(profile)) {
- return true
- }
- })
- return false
- }
- /**
- * Est-ce que l'utilisateur possède le rôle donné ?
- *
- * @return {boolean}
- * @param role
- */
- hasRole(role: string|null): boolean {
- return role === null || this.accessProfile.roles.includes(role)
- }
- /**
- * Est-ce que l'utilisateur possède tous les rôles donnés ?
- *
- * @return {boolean}
- * @param roles
- */
- hasRoles(roles: Array<string>): boolean {
- useEach(roles, (r: string) => {
- if (!this.accessProfile.roles.includes(r)) {
- return false
- }
- })
- return true
- }
- /**
- * Est-ce que l'organisation possède le module donné
- *
- * @return {boolean}
- * @param module
- */
- hasModule(module: string): boolean {
- return this.organizationProfile.modules.includes(module)
- }
- }
- export default AbilityUtils
|