From c978cca8c5c760f03c67d3cf1693a4f998d3d492 Mon Sep 17 00:00:00 2001
From: jorgep <jorgep@verdnatura.es>
Date: Mon, 9 Sep 2024 11:35:49 +0200
Subject: [PATCH] refactor: refs #4074 useAcl in navigationStore & router

---
 src/components/common/VnSelectDialog.vue |  8 ++------
 src/composables/useAcl.js                | 21 +++++++++++++--------
 src/router/index.js                      | 11 ++++-------
 src/router/modules/account.js            |  6 +++---
 src/stores/useNavigationStore.js         |  6 +++---
 5 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/src/components/common/VnSelectDialog.vue b/src/components/common/VnSelectDialog.vue
index 0ade82bda..7338e752d 100644
--- a/src/components/common/VnSelectDialog.vue
+++ b/src/components/common/VnSelectDialog.vue
@@ -31,12 +31,8 @@ const acl = useAcl();
 const showForm = ref(false);
 
 const isAllowedToCreate = computed(() => {
-    const hasMissingAcl = $props.acls.some(
-        (x) => !acl.hasAny(x.model, x.props, x.accessType)
-    );
-    const hasRequiredRole = role.hasAny($props.rolesAllowedToCreate);
-    if ($props.acls.length) return !hasMissingAcl;
-    return hasRequiredRole;
+    if ($props.acls.length) return acl.hasAny($props.acls);
+    return role.hasAny($props.rolesAllowedToCreate);
 });
 </script>
 
diff --git a/src/composables/useAcl.js b/src/composables/useAcl.js
index bebeda039..539e89622 100644
--- a/src/composables/useAcl.js
+++ b/src/composables/useAcl.js
@@ -16,14 +16,19 @@ export function useAcl() {
         state.setAcls(acls);
     }
 
-    function hasAny(model, props, accessType) {
-        const acls = state.getAcls().value[model];
-        Array.isArray(props) || (props = [props]);
-        if (acls) 
-            return ['*', ...props].some((key) => {
-                const acl = acls[key];
-                return acl && (acl['*'] || acl[accessType]);
-            });
+    function hasAny(acls) {
+        if (!Array.isArray(acls)) acls = [acls];
+        for (const acl of acls) {
+            let { model, props, accessType } = acl;
+            const modelAcls = state.getAcls().value[model];
+            Array.isArray(props) || (props = [props]);
+            if (modelAcls)
+                return ['*', ...props].some((key) => {
+                    const acl = modelAcls[key];
+                    return acl && (acl['*'] || acl[accessType]);
+                });
+        }
+        return false;
     }
 
     return {
diff --git a/src/router/index.js b/src/router/index.js
index 686da2dde..18541c0b2 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -60,15 +60,12 @@ export default route(function (/* { store, ssrContext } */) {
                 await useTokenConfig().fetch();
             }
             const matches = to.matched;
-            const hasRequiredRoles = matches.every((route) => {
+            const hasRequiredAcls = matches.every((route) => {
                 const meta = route.meta;
-                if (meta && meta.roles) return useRole().hasAny(meta.roles);
-                return true;
+                if (!meta?.acls) return true;
+                return useAcl().hasAny(meta.acls);
             });
-
-            if (!hasRequiredRoles) {
-                return next({ path: '/' });
-            }
+            if (!hasRequiredAcls) return next({ path: '/' });
         }
 
         next();
diff --git a/src/router/modules/account.js b/src/router/modules/account.js
index cfec2b95d..bb1c38c8e 100644
--- a/src/router/modules/account.js
+++ b/src/router/modules/account.js
@@ -79,7 +79,7 @@ export default {
                     meta: {
                         title: 'accounts',
                         icon: 'accessibility',
-                        roles: ['itManagement'],
+                        acls: [{ model: 'Account', props: '*', accessType: '*' }],
                     },
                     component: () => import('src/pages/Account/AccountAccounts.vue'),
                 },
@@ -89,7 +89,7 @@ export default {
                     meta: {
                         title: 'ldap',
                         icon: 'account_tree',
-                        roles: ['itManagement'],
+                        acls: [{ model: 'LdapConfig', props: '*', accessType: '*' }],
                     },
                     component: () => import('src/pages/Account/AccountLdap.vue'),
                 },
@@ -99,7 +99,7 @@ export default {
                     meta: {
                         title: 'samba',
                         icon: 'preview',
-                        roles: ['itManagement'],
+                        acls: [{ model: 'SambaConfig', props: '*', accessType: '*' }],
                     },
                     component: () => import('src/pages/Account/AccountSamba.vue'),
                 },
diff --git a/src/stores/useNavigationStore.js b/src/stores/useNavigationStore.js
index 961e80377..784e5063a 100644
--- a/src/stores/useNavigationStore.js
+++ b/src/stores/useNavigationStore.js
@@ -2,7 +2,7 @@ import axios from 'axios';
 import { ref } from 'vue';
 import { defineStore } from 'pinia';
 import { toLowerCamel } from 'src/filters';
-import { useRole } from 'src/composables/useRole';
+import { useAcl } from 'src/composables/useAcl';
 import routes from 'src/router/modules';
 
 export const useNavigationStore = defineStore('navigationStore', () => {
@@ -26,7 +26,7 @@ export const useNavigationStore = defineStore('navigationStore', () => {
         'zone',
     ];
     const pinnedModules = ref([]);
-    const role = useRole();
+    const acl = useAcl();
 
     function getModules() {
         const modulesRoutes = ref([]);
@@ -63,7 +63,7 @@ export const useNavigationStore = defineStore('navigationStore', () => {
                 title: `globals.pageTitles.${title}`,
             }));
 
-        if (meta && meta.roles && role.hasAny(meta.roles) === false) return;
+        if (meta && meta.acls && acl.hasAny(meta.acls) === false) return;
 
         const item = {
             name: route.name,