feat: refs #7822 implement ACL directive and enhance ACL handling in useAcl
gitea/salix-front/pipeline/pr-dev There was a failure building this commit
Details
gitea/salix-front/pipeline/pr-dev There was a failure building this commit
Details
This commit is contained in:
parent
8b61d1a4c7
commit
94f995f2b3
|
@ -0,0 +1,14 @@
|
||||||
|
import { useAcl } from 'src/composables/useAcl';
|
||||||
|
export default {
|
||||||
|
mounted(el, binding) {
|
||||||
|
if (!binding.value) return;
|
||||||
|
|
||||||
|
const allowed = useAcl().hasAcl(
|
||||||
|
binding.value.model,
|
||||||
|
binding.value.prop,
|
||||||
|
binding.value.accessType || 'READ',
|
||||||
|
);
|
||||||
|
|
||||||
|
el.disabled = !allowed;
|
||||||
|
},
|
||||||
|
};
|
|
@ -2,6 +2,7 @@ import axios from 'axios';
|
||||||
import { boot } from 'quasar/wrappers';
|
import { boot } from 'quasar/wrappers';
|
||||||
import qFormMixin from './qformMixin';
|
import qFormMixin from './qformMixin';
|
||||||
import keyShortcut from './keyShortcut';
|
import keyShortcut from './keyShortcut';
|
||||||
|
import checkAcl from './checkAcl';
|
||||||
import { QForm } from 'quasar';
|
import { QForm } from 'quasar';
|
||||||
import { QLayout } from 'quasar';
|
import { QLayout } from 'quasar';
|
||||||
import mainShortcutMixin from './mainShortcutMixin';
|
import mainShortcutMixin from './mainShortcutMixin';
|
||||||
|
@ -12,6 +13,7 @@ export default boot(({ app }) => {
|
||||||
QLayout.mixins = [mainShortcutMixin];
|
QLayout.mixins = [mainShortcutMixin];
|
||||||
|
|
||||||
app.directive('shortcut', keyShortcut);
|
app.directive('shortcut', keyShortcut);
|
||||||
|
app.directive('acl', checkAcl);
|
||||||
app.config.errorHandler = async (error) => {
|
app.config.errorHandler = async (error) => {
|
||||||
let message;
|
let message;
|
||||||
const response = error.response;
|
const response = error.response;
|
||||||
|
|
|
@ -150,6 +150,10 @@ const $props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: 'vnTable',
|
default: 'vnTable',
|
||||||
},
|
},
|
||||||
|
checkCreateAcl: {
|
||||||
|
type: Object,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -1084,6 +1088,7 @@ const handleHeaderSelection = (evt, data) => {
|
||||||
fab
|
fab
|
||||||
icon="add"
|
icon="add"
|
||||||
v-shortcut="'+'"
|
v-shortcut="'+'"
|
||||||
|
v-acl="checkCreateAcl"
|
||||||
data-cy="vnTableCreateBtn"
|
data-cy="vnTableCreateBtn"
|
||||||
/>
|
/>
|
||||||
<QTooltip self="top right">
|
<QTooltip self="top right">
|
||||||
|
|
|
@ -8,32 +8,37 @@ export function useAcl() {
|
||||||
const { data } = await axios.get('VnUsers/acls');
|
const { data } = await axios.get('VnUsers/acls');
|
||||||
const acls = {};
|
const acls = {};
|
||||||
data.forEach((acl) => {
|
data.forEach((acl) => {
|
||||||
acls[acl.model] = acls[acl.model] || {};
|
const model = acl.model?.toLowerCase();
|
||||||
acls[acl.model][acl.property] = acls[acl.model][acl.property] || {};
|
const property = acl.property?.toLowerCase();
|
||||||
acls[acl.model][acl.property][acl.accessType] = true;
|
acls[model] = acls[model] || {};
|
||||||
|
acls[model][property] = acls[model][property] || {};
|
||||||
|
acls[model][property][acl.accessType?.toLowerCase()] = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
state.setAcls(acls);
|
state.setAcls(acls);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasAny(acls) {
|
function hasAny(acls) {
|
||||||
|
let result = false;
|
||||||
for (const acl of acls) {
|
for (const acl of acls) {
|
||||||
let { model, props, accessType } = acl;
|
let { model, props, accessType } = acl;
|
||||||
const modelAcls = state.getAcls().value[model];
|
const modelAcls = state.getAcls().value[model.toLowerCase()];
|
||||||
Array.isArray(props) || (props = [props]);
|
Array.isArray(props) || (props = [props]);
|
||||||
if (modelAcls)
|
if (modelAcls) {
|
||||||
return ['*', ...props].some((key) => {
|
result = ['*', ...props].some((key) => {
|
||||||
const acl = modelAcls[key];
|
const acl = modelAcls[key.toLowerCase()];
|
||||||
return acl && (acl['*'] || acl[accessType]);
|
return acl && (acl['*'] || acl[accessType]);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
if (result) return result;
|
||||||
}
|
}
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasAcl(model, prop, accessType) {
|
function hasAcl(model, prop, accessType) {
|
||||||
const modelAcl = state.getAcls().value[model];
|
const modelAcl = state.getAcls().value[model?.toLowerCase()];
|
||||||
const propAcl = modelAcl?.[prop] || modelAcl?.['*'];
|
const propAcl = modelAcl?.[prop?.toLowerCase()] || modelAcl?.['*'];
|
||||||
return !!(propAcl?.[accessType] || propAcl?.['*']);
|
return !!(propAcl?.[accessType?.toLowerCase()] || propAcl?.['*']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in New Issue