abilitiesUtils.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import {accessProfile} from "@/services/profile/accessProfile"
  2. import {organizationProfile} from "@/services/profile/organizationProfile"
  3. import {$roleUtils} from "~/services/rights/roleUtils";
  4. import {AbilitiesType, AccessStore, AnyJson, AnyStore} from "~/types/types";
  5. import {Ability} from "@casl/ability";
  6. import YamlParser from "~/services/utils/yamlParser";
  7. import * as _ from "lodash";
  8. /**
  9. * @category Services/droits
  10. * @class AbilitiesUtils
  11. * Classe permettant de mener des opérations sur les abilités
  12. */
  13. class AbilitiesUtils {
  14. private $store: AnyStore = {} as AnyStore
  15. private $ability: Ability = {} as Ability
  16. private factory: AnyJson = {}
  17. /**
  18. * @constructor
  19. */
  20. constructor(store: AnyStore, ability: Ability) {
  21. this.$store = store
  22. this.$ability = ability
  23. }
  24. /**
  25. * Initialise les services factories
  26. */
  27. initFactory() {
  28. this.factory = {
  29. access: accessProfile(this.$store, this.$ability),
  30. organization: organizationProfile(this.$store)
  31. }
  32. }
  33. /**
  34. * Récupération de l'ensemble des abilities quelles soient par Roles ou par Config.
  35. * @returns {Array<AbilitiesType>}
  36. */
  37. getAbilities():Array<AbilitiesType> {
  38. const abilitiesByRoles = this.getAbilitiesByRoles(this.$store.state.profile.access.roles)
  39. this.$ability.update(abilitiesByRoles);
  40. this.initFactory();
  41. return abilitiesByRoles.concat(this.getAbilitiesByConfig('./config/abilities/config.yaml'))
  42. }
  43. /**
  44. * Adaptation et transformations des roles en abilities
  45. * @param {Array<string>} roles
  46. * @returns {Array<AbilitiesType>}
  47. */
  48. getAbilitiesByRoles(roles: Array<string>): Array<AbilitiesType> {
  49. roles = $roleUtils.transformUnderscoreToHyphenBeforeCompleteMigration(roles);
  50. return $roleUtils.transformRoleToAbilities(roles);
  51. }
  52. /**
  53. * - Parcours la config d'abilities en Yaml
  54. * - filtres la config pour ne garder que les abilities autorisées
  55. * - transform la config restante en Object Abilities
  56. * @param {string} configPath
  57. * @returns {Array<AbilitiesType>}
  58. */
  59. getAbilitiesByConfig(configPath:string): Array<AbilitiesType> {
  60. let abilitiesByConfig: Array<AbilitiesType> = []
  61. try {
  62. const doc = YamlParser.parse(configPath);
  63. const abilitiesAvailable = doc['abilities']
  64. const abilitiesFiltered = this.abilitiesAvailableFilter(abilitiesAvailable)
  65. abilitiesByConfig = this.transformAbilitiesConfigToAbility(abilitiesFiltered)
  66. } catch (e) {
  67. console.debug(e)
  68. }
  69. return abilitiesByConfig;
  70. }
  71. /**
  72. * Filtre toutes les abilities possible suivant si l'utilisateur est autorisé ou non à les posséder
  73. * @param {AnyJson} abilitiesAvailable
  74. * @returns {AnyJson}
  75. */
  76. abilitiesAvailableFilter(abilitiesAvailable:AnyJson):AnyJson{
  77. return _.pickBy(abilitiesAvailable, (ability:any) =>{
  78. const services = ability['services']
  79. return this.canHaveTheAbility(services)
  80. })
  81. }
  82. /**
  83. * Transform une config d'abilities en un tableau d'Abilities
  84. * @param {AnyJson} abilitiesAvailable
  85. * @returns {Array<AbilitiesType>}
  86. */
  87. transformAbilitiesConfigToAbility(abilitiesAvailable:AnyJson):Array<AbilitiesType>{
  88. let abilitiesByConfig: Array<AbilitiesType> = []
  89. _.each(abilitiesAvailable, (ability, subject) => {
  90. let myAbility: AbilitiesType = {
  91. action: ability['action'],
  92. subject: subject
  93. }
  94. abilitiesByConfig.push(myAbility)
  95. })
  96. return abilitiesByConfig;
  97. }
  98. /**
  99. * Parcours les fonctions par services et établit si oui ou non l'abilité est autorisée
  100. * @param {AnyJson} functionByservices
  101. * @returns {boolean}
  102. */
  103. canHaveTheAbility(functionByservices: AnyJson) {
  104. let hasAbility = true;
  105. _.each(functionByservices, (functions, service) => {
  106. if (hasAbility) {
  107. const nbFunctions = functions.length
  108. let cmpt = 0
  109. while (hasAbility && nbFunctions > cmpt) {
  110. const f = functions[cmpt]['function'];
  111. const parameters = functions[cmpt]['parameters'] ?? null;
  112. const result = functions[cmpt]['result'] ?? null;
  113. hasAbility = result !== null ? this.factory[service].handler()[f](parameters) == result : this.factory[service].handler()[f](parameters)
  114. cmpt++
  115. }
  116. }
  117. })
  118. return hasAbility;
  119. }
  120. }
  121. export const $abilitiesUtils = (store: AnyStore, ability:Ability) => new AbilitiesUtils(store, ability);