forked from verdnatura/salix-front
Reviewed-on: verdnatura/salix-front#345 Reviewed-by: Juan Ferrer <juan@verdnatura.es>
This commit is contained in:
commit
31081bd471
|
@ -0,0 +1,33 @@
|
||||||
|
import axios from 'axios';
|
||||||
|
import { useState } from './useState';
|
||||||
|
|
||||||
|
export function useAcl() {
|
||||||
|
const state = useState();
|
||||||
|
|
||||||
|
async function fetch() {
|
||||||
|
const { data } = await axios.get('VnUsers/acls');
|
||||||
|
const acls = {};
|
||||||
|
data.forEach((acl) => {
|
||||||
|
acls[acl.model] = acls[acl.model] || {};
|
||||||
|
acls[acl.model][acl.property] = acls[acl.model][acl.property] || {};
|
||||||
|
acls[acl.model][acl.property][acl.accessType] = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
state.setAcls(acls);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasAny(model, prop, accessType) {
|
||||||
|
const acls = state.getAcls().value[model];
|
||||||
|
if (acls)
|
||||||
|
return ['*', prop].some((key) => {
|
||||||
|
const acl = acls[key];
|
||||||
|
return acl && (acl['*'] || acl[accessType]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
fetch,
|
||||||
|
hasAny,
|
||||||
|
state,
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import { useState } from './useState';
|
import { useState } from './useState';
|
||||||
import { useRole } from './useRole';
|
import { useRole } from './useRole';
|
||||||
|
import { useAcl } from './useAcl';
|
||||||
import { useUserConfig } from './useUserConfig';
|
import { useUserConfig } from './useUserConfig';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import useNotify from './useNotify';
|
import useNotify from './useNotify';
|
||||||
|
@ -88,6 +89,7 @@ export function useSession() {
|
||||||
setSession(data);
|
setSession(data);
|
||||||
|
|
||||||
await useRole().fetch();
|
await useRole().fetch();
|
||||||
|
await useAcl().fetch();
|
||||||
await useUserConfig().fetch();
|
await useUserConfig().fetch();
|
||||||
await useTokenConfig().fetch();
|
await useTokenConfig().fetch();
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ if (sessionStorage.getItem('user'))
|
||||||
user.value = JSON.parse(sessionStorage.getItem('user'));
|
user.value = JSON.parse(sessionStorage.getItem('user'));
|
||||||
|
|
||||||
const roles = ref([]);
|
const roles = ref([]);
|
||||||
|
const acls = ref([]);
|
||||||
const tokenConfig = ref({});
|
const tokenConfig = ref({});
|
||||||
const drawer = ref(true);
|
const drawer = ref(true);
|
||||||
const headerMounted = ref(false);
|
const headerMounted = ref(false);
|
||||||
|
@ -42,6 +43,14 @@ export function useState() {
|
||||||
function setRoles(data) {
|
function setRoles(data) {
|
||||||
roles.value = data;
|
roles.value = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAcls() {
|
||||||
|
return computed(() => acls.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAcls(data) {
|
||||||
|
acls.value = data;
|
||||||
|
}
|
||||||
function getTokenConfig() {
|
function getTokenConfig() {
|
||||||
return computed(() => {
|
return computed(() => {
|
||||||
return tokenConfig.value;
|
return tokenConfig.value;
|
||||||
|
@ -69,6 +78,8 @@ export function useState() {
|
||||||
setUser,
|
setUser,
|
||||||
getRoles,
|
getRoles,
|
||||||
setRoles,
|
setRoles,
|
||||||
|
getAcls,
|
||||||
|
setAcls,
|
||||||
getTokenConfig,
|
getTokenConfig,
|
||||||
setTokenConfig,
|
setTokenConfig,
|
||||||
set,
|
set,
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { useRole } from 'src/composables/useRole';
|
||||||
import { useUserConfig } from 'src/composables/useUserConfig';
|
import { useUserConfig } from 'src/composables/useUserConfig';
|
||||||
import { toLowerCamel } from 'src/filters';
|
import { toLowerCamel } from 'src/filters';
|
||||||
import { useTokenConfig } from 'src/composables/useTokenConfig';
|
import { useTokenConfig } from 'src/composables/useTokenConfig';
|
||||||
|
import { useAcl } from 'src/composables/useAcl';
|
||||||
|
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
|
@ -55,6 +56,7 @@ export default route(function (/* { store, ssrContext } */) {
|
||||||
const stateRoles = state.getRoles().value;
|
const stateRoles = state.getRoles().value;
|
||||||
if (stateRoles.length === 0) {
|
if (stateRoles.length === 0) {
|
||||||
await useRole().fetch();
|
await useRole().fetch();
|
||||||
|
await useAcl().fetch();
|
||||||
await useUserConfig().fetch();
|
await useUserConfig().fetch();
|
||||||
await useTokenConfig().fetch();
|
await useTokenConfig().fetch();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest';
|
||||||
|
import { axios, flushPromises } from 'app/test/vitest/helper';
|
||||||
|
import { useAcl } from 'src/composables/useAcl';
|
||||||
|
|
||||||
|
describe('useAcl', () => {
|
||||||
|
const acl = useAcl();
|
||||||
|
const mockAcls = [
|
||||||
|
{
|
||||||
|
model: 'Address',
|
||||||
|
property: '*',
|
||||||
|
accessType: '*',
|
||||||
|
permission: 'ALLOW',
|
||||||
|
principalType: 'ROLE',
|
||||||
|
principalId: 'employee',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: 'Worker',
|
||||||
|
property: 'holidays',
|
||||||
|
accessType: 'READ',
|
||||||
|
permission: 'ALLOW',
|
||||||
|
principalType: 'ROLE',
|
||||||
|
principalId: 'employee',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: 'Url',
|
||||||
|
property: 'getByUser',
|
||||||
|
accessType: 'READ',
|
||||||
|
permission: 'ALLOW',
|
||||||
|
principalType: 'ROLE',
|
||||||
|
principalId: '$everyone',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: 'TpvTransaction',
|
||||||
|
property: 'start',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
permission: 'ALLOW',
|
||||||
|
principalType: 'ROLE',
|
||||||
|
principalId: '$authenticated',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
vi.spyOn(axios, 'get').mockResolvedValue({ data: mockAcls });
|
||||||
|
await acl.fetch();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => await flushPromises());
|
||||||
|
|
||||||
|
describe('hasAny', () => {
|
||||||
|
it('should return false if no roles matched', async () => {
|
||||||
|
expect(acl.hasAny('Worker', 'updateAttributes', 'WRITE')).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if no roles matched', async () => {
|
||||||
|
expect(acl.hasAny('Worker', 'holidays', 'READ')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('*', () => {
|
||||||
|
it('should return true if an acl matched', async () => {
|
||||||
|
expect(acl.hasAny('Address', '*', 'WRITE')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if no acls matched', async () => {
|
||||||
|
expect(acl.hasAny('Worker', '*', 'READ')).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('$authenticated', () => {
|
||||||
|
it('should return false if no acls matched', async () => {
|
||||||
|
expect(acl.hasAny('Url', 'getByUser', '*')).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true if an acl matched', async () => {
|
||||||
|
expect(acl.hasAny('Url', 'getByUser', 'READ')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('$everyone', () => {
|
||||||
|
it('should return false if no acls matched', async () => {
|
||||||
|
expect(acl.hasAny('TpvTransaction', 'start', 'READ')).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if an acl matched', async () => {
|
||||||
|
expect(acl.hasAny('TpvTransaction', 'start', 'WRITE')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,5 +1,5 @@
|
||||||
import { vi, describe, expect, it, beforeAll, beforeEach } from 'vitest';
|
import { vi, describe, expect, it, beforeAll, beforeEach } from 'vitest';
|
||||||
import { axios, flushPromises } from 'app/test/vitest/helper';
|
import { axios } from 'app/test/vitest/helper';
|
||||||
import { useSession } from 'composables/useSession';
|
import { useSession } from 'composables/useSession';
|
||||||
import { useState } from 'composables/useState';
|
import { useState } from 'composables/useState';
|
||||||
|
|
||||||
|
@ -87,13 +87,17 @@ describe('session', () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.spyOn(axios, 'get').mockImplementation((url) => {
|
||||||
|
if (url === 'VnUsers/acls') return Promise.resolve({ data: [] });
|
||||||
|
return Promise.resolve({
|
||||||
|
data: { roles: rolesData, user: expectedUser },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should fetch the user roles and then set token in the sessionStorage', async () => {
|
it('should fetch the user roles and then set token in the sessionStorage', async () => {
|
||||||
const expectedRoles = ['salesPerson', 'admin'];
|
const expectedRoles = ['salesPerson', 'admin'];
|
||||||
vi.spyOn(axios, 'get').mockResolvedValue({
|
|
||||||
data: { roles: rolesData, user: expectedUser },
|
|
||||||
});
|
|
||||||
|
|
||||||
const expectedToken = 'mySessionToken';
|
const expectedToken = 'mySessionToken';
|
||||||
const expectedTokenMultimedia = 'mySessionTokenMultimedia';
|
const expectedTokenMultimedia = 'mySessionTokenMultimedia';
|
||||||
const keepLogin = false;
|
const keepLogin = false;
|
||||||
|
@ -117,10 +121,6 @@ describe('session', () => {
|
||||||
|
|
||||||
it('should fetch the user roles and then set token in the localStorage', async () => {
|
it('should fetch the user roles and then set token in the localStorage', async () => {
|
||||||
const expectedRoles = ['salesPerson', 'admin'];
|
const expectedRoles = ['salesPerson', 'admin'];
|
||||||
vi.spyOn(axios, 'get').mockResolvedValue({
|
|
||||||
data: { roles: rolesData, user: expectedUser },
|
|
||||||
});
|
|
||||||
|
|
||||||
const expectedToken = 'myLocalToken';
|
const expectedToken = 'myLocalToken';
|
||||||
const expectedTokenMultimedia = 'myLocalTokenMultimedia';
|
const expectedTokenMultimedia = 'myLocalTokenMultimedia';
|
||||||
const keepLogin = true;
|
const keepLogin = true;
|
||||||
|
|
|
@ -23,8 +23,9 @@ describe('Login', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
vi.spyOn(axios, 'post').mockResolvedValueOnce({ data: { token: 'token' } });
|
vi.spyOn(axios, 'post').mockResolvedValueOnce({ data: { token: 'token' } });
|
||||||
vi.spyOn(axios, 'get').mockResolvedValue({
|
vi.spyOn(axios, 'get').mockImplementation((url) => {
|
||||||
data: { roles: [], user: expectedUser , multimediaToken: {id:'multimediaToken' }},
|
if (url === 'VnUsers/acls') return Promise.resolve({ data: [] });
|
||||||
|
return Promise.resolve({data: { roles: [], user: expectedUser , multimediaToken: {id:'multimediaToken' }}});
|
||||||
});
|
});
|
||||||
vi.spyOn(vm.quasar, 'notify');
|
vi.spyOn(vm.quasar, 'notify');
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue