Add ACL settings for app configure

This commit is contained in:
Johannes Zellner
2025-03-02 16:23:14 +01:00
parent e13db20c85
commit ab0d5c8967
6 changed files with 83 additions and 21 deletions
+5 -10
View File
@@ -4,12 +4,7 @@ import { ref, onMounted } from 'vue';
import { FormGroup, Radiobutton, MultiSelect } from 'pankow';
import UsersModel from '../models/UsersModel.js';
import GroupsModel from '../models/GroupsModel.js';
const OPTIONS = Object.freeze({
ANY: 'any',
RESTRICTED: 'restricted',
NOSSO: 'nosso',
});
import { ACL_OPTIONS } from '../constants.js';
const usersModel = UsersModel.create();
const groupsModel = GroupsModel.create();
@@ -53,12 +48,12 @@ onMounted(async () => {
<p v-show="cloudronAuth && !manifest.addons.email">{{ $t('app.accessControl.userManagement.description') }}</p>
<label v-show="!cloudronAuth || manifest.addons.email">{{ $t('app.accessControl.userManagement.dashboardVisibility') }} <sup><a href="https://docs.cloudron.io/apps/#dashboard-visibility" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
<p v-show="!cloudronAuth || manifest.addons.email">{{ $t('appstore.installDialog.userManagementNone') }}</p>
<Radiobutton v-model="accessRestrictionOption" :value="OPTIONS.NOSSO" v-if="optionalSso" :label="$t('appstore.installDialog.userManagementLeaveToApp')"/>
<Radiobutton v-model="accessRestrictionOption" :value="OPTIONS.ANY" :label="cloudronAuth ? $t('appstore.installDialog.userManagementAllUsers') : $t('app.accessControl.userManagement.visibleForAllUsers')"/>
<Radiobutton v-model="accessRestrictionOption" :value="OPTIONS.RESTRICTED" :label="cloudronAuth ? $t('appstore.installDialog.userManagementSelectUsers') : $t('app.accessControl.userManagement.visibleForSelected')"/>
<Radiobutton v-model="accessRestrictionOption" :value="ACL_OPTIONS.NOSSO" v-if="optionalSso" :label="$t('appstore.installDialog.userManagementLeaveToApp')"/>
<Radiobutton v-model="accessRestrictionOption" :value="ACL_OPTIONS.ANY" :label="cloudronAuth ? $t('appstore.installDialog.userManagementAllUsers') : $t('app.accessControl.userManagement.visibleForAllUsers')"/>
<Radiobutton v-model="accessRestrictionOption" :value="ACL_OPTIONS.RESTRICTED" :label="cloudronAuth ? $t('appstore.installDialog.userManagementSelectUsers') : $t('app.accessControl.userManagement.visibleForSelected')"/>
</FormGroup>
<div v-if="accessRestrictionOption === OPTIONS.RESTRICTED">
<div v-if="accessRestrictionOption === ACL_OPTIONS.RESTRICTED">
<div style="margin-left: 20px; display: flex;">
<div>
{{ $t('appstore.installDialog.users') }}: <MultiSelect v-model="accessRestriction.users" :options="users" option-key="id" option-label="username" />
@@ -9,7 +9,7 @@ import PortBindings from './PortBindings.vue';
import DomainsModel from '../models/DomainsModel.js';
import AppsModel from '../models/AppsModel.js';
import DashboardModel from '../models/DashboardModel.js';
import { PROXY_APP_ID } from '../constants.js';
import { PROXY_APP_ID, ACL_OPTIONS } from '../constants.js';
const STEP = Object.freeze({
DETAILS: Symbol('details'),
@@ -51,11 +51,8 @@ function setStep(newStep) {
// form data
const location = ref('');
// accessRestriction:
// object = SSO with user groups
// true = SSO all
// false = NOSSO
const accessRestriction = ref(true);
const accessRestrictionOption = ref(ACL_OPTIONS.ANY);
const accessRestrictionAcl = ref({ users: [], groups: [] });
const domain = ref({});
const tcpPorts = ref({});
const udpPorts = ref({});
@@ -66,10 +63,10 @@ async function submit() {
const config = {
subdomain: location.value,
domain: domain.value.domain,
accessRestriction: typeof accessRestriction.value === 'object' ? accessRestriction.value : null,
accessRestriction: accessRestrictionOption.value === ACL_OPTIONS.ANY ? null : (accessRestrictionOption.value === ACL_OPTIONS.NOSSO ? false : accessRestrictionAcl.value)
};
if (manifest.value.optionalSso) config.sso = accessRestriction.value;
if (manifest.value.optionalSso) config.sso = accessRestrictionOption.value !== ACL_OPTIONS.NOSSO;
const finalPorts = {};
for (const p in tcpPorts.value) {
@@ -204,7 +201,7 @@ defineExpose({
</FormGroup>
<PortBindings v-model:tcp-ports="tcpPorts" v-model:udp-ports="udpPorts" :error="formError"/>
<AccessControl v-model="accessRestriction" :manifest="manifest"/>
<AccessControl v-model:option="accessRestrictionOption" v-model:acl="accessRestrictionAcl" :manifest="manifest"/>
<Button style="margin-top: 15px" @click="submit" icon="fa-solid fa-circle-down" :disabled="!formValid" :loading="busy">Install {{ manifest.title }}</Button>
</fieldset>
+1 -1
View File
@@ -61,7 +61,7 @@ export default {
} else if (this.iconUrl) { // current icon
return API_ORIGIN + this.iconUrl;
} else {
return API_ORIGIN + 'img/appicon_fallback.png';
return API_ORIGIN + '/img/appicon_fallback.png';
}
}
},
+58
View File
@@ -0,0 +1,58 @@
<script setup>
import { ref, onMounted } from 'vue';
import { Button } from 'pankow';
import AccessControl from '../AccessControl.vue';
import AppsModel from '../../models/AppsModel.js';
import { ACL_OPTIONS } from '../../constants.js';
const props = defineProps([ 'app' ]);
const appsModel = AppsModel.create();
const busy = ref(false);
const errorMessage = ref('');
const accessRestrictionOption = ref(ACL_OPTIONS.ANY);
const accessRestrictionAcl = ref({ users: [], groups: [] });
async function onSubmit() {
busy.value = true;
errorMessage.value = '';
const data = {
accessRestriction: accessRestrictionOption.value === ACL_OPTIONS.ANY ? null : (accessRestrictionOption.value === ACL_OPTIONS.NOSSO ? false : accessRestrictionAcl.value)
};
const [error] = await appsModel.configure(props.app.id, 'access_restriction', data);
if (error) {
errorMessage.value = error.body ? error.body.message : 'Internal error';
busy.value = false;
return console.error(error);
}
busy.value = false;
}
onMounted(() => {
if (props.app.accessRestriction === null) {
accessRestrictionOption.value = ACL_OPTIONS.ANY;
accessRestrictionAcl.value = { users: [], groups: [] };
} else if (props.app.accessRestriction === false) {
accessRestrictionOption.value = ACL_OPTIONS.NOSSO;
accessRestrictionAcl.value = { users: [], groups: [] };
} else {
accessRestrictionOption.value = ACL_OPTIONS.RESTRICTED;
accessRestrictionAcl.value = props.app.accessRestriction;
}
});
</script>
<template>
<div>
<div class="text-danger" v-if="errorMessage">{{ errorMessage }}</div>
<AccessControl v-model:option="accessRestrictionOption" v-model:acl="accessRestrictionAcl" :manifest="app.manifest"/>
<br/>
<Button @click="onSubmit()" :loading="busy" :disabled="busy">{{ $t('main.dialog.save') }}</Button>
</div>
</template>