summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Hofmaier2018-08-10 02:28:51 +0200
committerChristian Hofmaier2018-08-10 02:28:51 +0200
commit79966027428a7d9e1425c63777647e53c9167066 (patch)
treebe23858c24b4ffedd19a6ec188fc5eb87a9c6090
parent[server/config] Add server configs. (diff)
downloadbas-79966027428a7d9e1425c63777647e53c9167066.tar.gz
bas-79966027428a7d9e1425c63777647e53c9167066.tar.xz
bas-79966027428a7d9e1425c63777647e53c9167066.zip
[permissions] Add recursive group selection + tables changed to search tables
Role Table has now a new column recursiveGroups to display if recursive selection is wanted Roles and Permissions can now have longer descriptions Data-Tables are now Udos Search-Tables
-rw-r--r--server/api/permissions.js9
-rw-r--r--server/app.js2
-rw-r--r--server/migrations/20180726033100-create-role.js5
-rw-r--r--server/migrations/20180726171200-create-permission.js2
-rw-r--r--server/migrations/20180809013230-create-role_x_group.js (renamed from server/migrations/20180804234000-create-role_x_group.js)0
-rw-r--r--server/models/permission.js2
-rw-r--r--server/models/role.js3
-rw-r--r--webapp/src/components/PermissionModuleEdit.vue122
-rw-r--r--webapp/src/components/PermissionModuleGrantRevoke.vue49
-rw-r--r--webapp/src/components/PermissionModuleRoleList.vue29
-rw-r--r--webapp/src/components/PermissionModuleUserList.vue28
11 files changed, 135 insertions, 116 deletions
diff --git a/server/api/permissions.js b/server/api/permissions.js
index 5ed09e0..7894719 100644
--- a/server/api/permissions.js
+++ b/server/api/permissions.js
@@ -59,16 +59,17 @@ module.exports.post = {
* name: <ROLE_NAME>
* descr: <ROLE_DESCRIPTION>
* permissions: <PERMISSION_IDS>
- * groups: <GROUP_IDS>
+ * groups: <GROUP_IDS>,
+ * recursiveMode: < RECURSIVE_MODE>
*
- * Creates or updates a role.
+ * Creates or updates a role. If recursiveMode is set to true, the <GROUP_IDS> are saved with childs.
*/
saveRole: function (req, res) {
const role = req.body
if (role.id === 0) {
// Insert new role in the db.
- db.role.create({ name: role.name, descr: role.descr }).then(roleDb => {
+ db.role.create({ name: role.name, descr: role.descr, recursiveGroups: role.recursiveMode }).then(roleDb => {
var promises = []
promises.push(roleDb.addPermissions(role.permissions))
promises.push(roleDb.addGroups(role.groups))
@@ -78,7 +79,7 @@ module.exports.post = {
// Update an existing role in the db.
db.role.findOne({ where: { id: role.id } }).then(roleDb => {
var promises = []
- promises.push(roleDb.update({ name: role.name, descr: role.descr }))
+ promises.push(roleDb.update({ name: role.name, descr: role.descr, recursiveGroups: role.recursiveMode }))
promises.push(roleDb.setPermissions(role.permissions))
promises.push(roleDb.setGroups(role.groups))
Promise.all(promises).then(() => { res.send({ id: role.id }) })
diff --git a/server/app.js b/server/app.js
index c9a270c..f9b0845 100644
--- a/server/app.js
+++ b/server/app.js
@@ -12,7 +12,7 @@ global.__appdir = __dirname
require('./lib/tftp')
// Read permissions from JSON and update the database
-require('./lib/permissions')
+require('./lib/permissions/index.js')
// ############################################################################
// ########################### setup middleware ###############################
diff --git a/server/migrations/20180726033100-create-role.js b/server/migrations/20180726033100-create-role.js
index c930148..20736a2 100644
--- a/server/migrations/20180726033100-create-role.js
+++ b/server/migrations/20180726033100-create-role.js
@@ -12,7 +12,10 @@ module.exports = {
type: Sequelize.STRING
},
descr: {
- type: Sequelize.STRING
+ type: Sequelize.STRING(2048)
+ },
+ recursiveGroups: {
+ type: Sequelize.BOOLEAN
}
})
},
diff --git a/server/migrations/20180726171200-create-permission.js b/server/migrations/20180726171200-create-permission.js
index 822e47c..a20ca79 100644
--- a/server/migrations/20180726171200-create-permission.js
+++ b/server/migrations/20180726171200-create-permission.js
@@ -12,7 +12,7 @@ module.exports = {
type: Sequelize.STRING
},
descr: {
- type: Sequelize.STRING
+ type: Sequelize.STRING(2048)
},
groupdependent: {
type: Sequelize.BOOLEAN
diff --git a/server/migrations/20180804234000-create-role_x_group.js b/server/migrations/20180809013230-create-role_x_group.js
index a6dd792..a6dd792 100644
--- a/server/migrations/20180804234000-create-role_x_group.js
+++ b/server/migrations/20180809013230-create-role_x_group.js
diff --git a/server/models/permission.js b/server/models/permission.js
index a1bd5d3..af007a0 100644
--- a/server/models/permission.js
+++ b/server/models/permission.js
@@ -8,7 +8,7 @@ module.exports = (sequelize, DataTypes) => {
type: DataTypes.INTEGER
},
name: DataTypes.STRING,
- descr: DataTypes.STRING,
+ descr: DataTypes.STRING(2048),
groupdependent: DataTypes.BOOLEAN
}, {
timestamps: false
diff --git a/server/models/role.js b/server/models/role.js
index f33b042..f88c132 100644
--- a/server/models/role.js
+++ b/server/models/role.js
@@ -8,7 +8,8 @@ module.exports = (sequelize, DataTypes) => {
type: DataTypes.INTEGER
},
name: DataTypes.STRING,
- descr: DataTypes.STRING
+ descr: DataTypes.STRING(2048),
+ recursiveGroups: DataTypes.BOOLEAN
}, {
timestamps: false
})
diff --git a/webapp/src/components/PermissionModuleEdit.vue b/webapp/src/components/PermissionModuleEdit.vue
index e1cf45f..8a981ca 100644
--- a/webapp/src/components/PermissionModuleEdit.vue
+++ b/webapp/src/components/PermissionModuleEdit.vue
@@ -11,7 +11,8 @@
"groups": "Groups",
"summary": "Summary",
"roleName": "Role Name",
- "roleNameEmptyError": "Role Name can't be empty."
+ "roleNameEmptyError": "Role Name can't be empty.",
+ "recursiveMode": "Select Groups recursive"
},
"de": {
"id": "ID",
@@ -24,7 +25,8 @@
"groups": "Gruppen",
"summary": "Zusammenfassung",
"roleName": "Rollenname",
- "roleNameEmptyError": "Rollenname kann nicht leer sein."
+ "roleNameEmptyError": "Rollenname kann nicht leer sein.",
+ "recursiveMode": "Gruppen rekursiv auswählen"
}
}
</i18n>
@@ -33,8 +35,9 @@
<v-dialog
:value="$store.state.permissions.edit"
@input="$store.commit('permissions/setEdit', $event)"
- max-width="700px"
+ max-width="800px"
scrollable
+ persistent
>
<v-card>
<v-card-title class="dialog-title">
@@ -78,7 +81,7 @@
</v-stepper-header>
</v-stepper>
</v-card-title>
- <v-card-text style="height: 500px;">
+ <v-card-text class="table-container">
<v-form v-model="valid" ref="form" @submit.prevent="submit" lazy-validation>
<v-stepper v-model="step" horizontal style="width: 100%; background: transparent" class="elevation-0">
<v-stepper-items>
@@ -103,64 +106,48 @@
rows="1"
auto-grow
></v-textarea>
-
</v-stepper-content>
- <v-stepper-content step="2">
- <v-data-table
- :headers="permissionHeaders"
- :items="permissions"
- item-key="id"
- hide-actions
- select-all
- :value="permissionsSelected"
- @input="setPermissionsSelected($event)"
- >
+ <v-stepper-content step="2" class="stepper-padding-0">
+ <component-search-table v-model="permissionsSelected" :headers="permissionHeaders" :items="permissions" select-all>
<template slot="items" slot-scope="props">
- <tr @click="props.selected = !props.selected">
+ <tr :style="props.color" @click="props.data.selected = !props.data.selected">
<td>
<v-checkbox
color="primary"
- v-model="props.selected"
+ v-model="props.data.selected"
hide-details
- @click.native.stop
></v-checkbox>
</td>
- <td hidden>{{ props.item.id }}</td>
- <td>{{ props.item.name }}</td>
- <td>{{ props.item.descr }}</td>
- <td>{{ props.item.groupdependent }}</td>
+ <td>{{ props.data.item.name }}</td>
+ <td>{{ props.data.item.descr }}</td>
+ <td>{{ props.data.item.groupdependent }}</td>
</tr>
</template>
- </v-data-table>
+ </component-search-table>
</v-stepper-content>
- <v-stepper-content step="3">
- <v-data-table
- :headers="groupHeaders"
- :items="groups"
- item-key="id"
- hide-actions
- select-all
- :value="groupsSelected"
- @input="setGroupsSelected($event)"
- >
+ <v-stepper-content step="3" class="stepper-padding-0">
+ <v-switch
+ :label="$t('recursiveMode')"
+ :input-value="recursiveSwitch"
+ ></v-switch>
+ <component-search-table v-model="groupsSelected" :headers="groupHeaders" :items="groups" select-all>
<template slot="items" slot-scope="props">
- <tr @click="props.selected = !props.selected">
+ <tr :style="props.color" @click="props.data.selected = !props.data.selected">
<td>
<v-checkbox
color="primary"
- v-model="props.selected"
+ v-model="props.data.selected"
hide-details
- @click.native.stop
></v-checkbox>
</td>
- <td>{{ props.item.id }}</td>
- <td>{{ props.item.name }}</td>
- <td>{{ props.item.description }}</td>
+ <td>{{ props.data.item.id }}</td>
+ <td>{{ props.data.item.name }}</td>
+ <td>{{ props.data.item.description }}</td>
</tr>
</template>
- </v-data-table>
+ </component-search-table>
</v-stepper-content>
<v-stepper-content step="4">
@@ -207,7 +194,7 @@
<v-subheader inset>{{ $t('groups') }}</v-subheader>
<v-divider class="list-header-margin"></v-divider>
<v-list-tile
- v-for="group in groupsSelected"
+ v-for="group in groupsSummary"
:key="group.id"
>
<v-list-tile-content>
@@ -239,10 +226,15 @@
</template>
<script>
+import _arrayIncludes from 'lodash/_arrayIncludes'
+import ComponentSearchTable from '@/components/ComponentSearchTable'
export default {
name: 'PermissionModuleEdit',
props: ['roleId'],
+ components: {
+ ComponentSearchTable
+ },
data () {
return {
valid: true,
@@ -252,6 +244,8 @@ export default {
groups: [],
permissionsSelected: [],
groupsSelected: [],
+ groupsSummary: [],
+ recursiveSwitch: true,
permissionHeaders: [
{ text: this.$t('name'), value: 'name' },
{ text: this.$t('description'), value: 'descr' },
@@ -276,11 +270,12 @@ export default {
name: this.roleName,
descr: this.roleDescr,
permissions: filteredPermissions,
- groups: filteredGroups
+ groups: filteredGroups,
+ recursiveMode: this.recursiveSwitch
}).then(response => {
// TODO: Add backend saved successfull msg.
console.log('TODO: Implement snackbar and print role saved successfully msg.')
- this.$store.dispatch('permissions/loadData')
+ this.$store.dispatch('permissions/loadRoleData')
this.$store.commit('permissions/setEdit', false)
}).catch(error => {
console.log(error)
@@ -293,6 +288,7 @@ export default {
this.roleDescr = response.data.descr
this.permissionsSelected = response.data.permissions
this.groupsSelected = response.data.groups
+ this.recursiveSwitch = response.data.recursiveGroups
})
},
completeStepOne () {
@@ -308,15 +304,32 @@ export default {
this.stepCompleted = Math.max(2, this.stepCompleted)
},
completeStepThree () {
+ if (this.recursiveSwitch === true) {
+ var promises = []
+ var childGroups = []
+ var self = this
+ // _arrayIncludes.js
+ this.groupsSelected.forEach(function (group) {
+ promises.push(self.$http('/api/groups/getGroup?all=true&id=' + group.id).then(response => {
+ response.data.subgroups.forEach(function (subgroup) {
+ if (!(_arrayIncludes(self.groupsSelected, subgroup) || _arrayIncludes(childGroups, subgroup))) {
+ childGroups.push(subgroup)
+ }
+ })
+ }))
+ })
+
+ Promise.all(promises).then(() => {
+ console.log(JSON.stringify(this.groupsSelected))
+ console.log(JSON.stringify(childGroups))
+ this.groupsSummary = this.groupsSelected.concat(childGroups)
+ })
+ } else {
+ this.groupsSummary = this.groupsSelected
+ }
this.step = 4
this.stepCompleted = Math.max(3, this.stepCompleted)
},
- setPermissionsSelected (value) {
- this.permissionsSelected = value
- },
- setGroupsSelected (value) {
- this.groupsSelected = value
- },
loadGroups () {
this.$http('/api/groups/getList').then(response => {
this.groups = response.data
@@ -341,12 +354,14 @@ export default {
this.permissionsSelected = []
this.groupsSelected = []
this.step = 1
- this.stepCompleted = 0
if (this.roleId !== 0) {
this.loadRole(this.roleId)
+ this.stepCompleted = 4
} else {
+ this.recursiveSwitch = true
this.roleName = ''
this.roleDescr = ''
+ this.stepCompleted = 0
}
}
}
@@ -359,6 +374,13 @@ export default {
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
+.table-container {
+ padding: 0;
+ height: 700px;
+}
+.stepper-padding-0 {
+ padding: 0;
+}
.info-input {
margin: 20px;
}
diff --git a/webapp/src/components/PermissionModuleGrantRevoke.vue b/webapp/src/components/PermissionModuleGrantRevoke.vue
index 06868d5..24a9ab4 100644
--- a/webapp/src/components/PermissionModuleGrantRevoke.vue
+++ b/webapp/src/components/PermissionModuleGrantRevoke.vue
@@ -29,11 +29,11 @@
<v-dialog
:value="$store.state.permissions.grantRevoke"
@input="$store.commit('permissions/setGrantRevoke', $event)"
- max-width="700px"
+ max-width="800px"
scrollable
>
<v-card>
- <v-card-title style="padding: 0px">
+ <v-card-title class="dialog-title">
<v-stepper v-model="step" horizontal style="width: 100%; background: transparent;" class="elevation-3">
<v-stepper-header>
<v-stepper-step
@@ -56,36 +56,27 @@
</v-stepper-header>
</v-stepper>
</v-card-title>
- <v-card-text style="height: 500px;">
+ <v-card-text class="table-container">
<v-form v-model="valid" ref="form" @submit.prevent="submit" lazy-validation>
<v-stepper v-model="step" horizontal style="width: 100%; background: transparent" class="elevation-0">
<v-stepper-items>
- <v-stepper-content step="1">
- <v-data-table
- :headers="roleHeaders"
- :items="roles"
- item-key="id"
- hide-actions
- select-all
- :value="rolesSelected"
- @input="setRolesSelected($event)"
- >
+ <v-stepper-content step="1" class="stepper-padding-0">
+ <component-search-table v-model="rolesSelected" :headers="roleHeaders" :items="roles" select-all>
<template slot="items" slot-scope="props">
- <tr @click="props.selected = !props.selected">
+ <tr :style="props.color" @click="props.data.selected = !props.data.selected">
<td>
<v-checkbox
color="primary"
- v-model="props.selected"
+ v-model="props.data.selected"
hide-details
- @click.native.stop
></v-checkbox>
</td>
- <td>{{ props.item.id }}</td>
- <td>{{ props.item.name }}</td>
- <td>{{ props.item.descr }}</td>
+ <td>{{ props.data.item.id }}</td>
+ <td>{{ props.data.item.name }}</td>
+ <td>{{ props.data.item.descr }}</td>
</tr>
</template>
- </v-data-table>
+ </component-search-table>
</v-stepper-content>
<v-stepper-content step="2">
<v-layout row wrap>
@@ -140,10 +131,14 @@
<script>
import { mapState } from 'vuex'
+import ComponentSearchTable from '@/components/ComponentSearchTable'
export default {
name: 'PermissionModuleGrantRevoke',
props: ['grant'],
+ components: {
+ ComponentSearchTable
+ },
data () {
return {
valid: true,
@@ -190,9 +185,6 @@ export default {
completeStepOne () {
this.step = 2
this.stepCompleted = Math.max(1, this.stepCompleted)
- },
- setRolesSelected (value) {
- this.rolesSelected = value
}
},
computed: {
@@ -215,7 +207,18 @@ export default {
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
+.table-container {
+ padding: 0;
+ height: 700px;
+}
+.stepper-padding-0 {
+ padding: 0;
+}
.list-header-margin {
margin-bottom: 10px;
}
+.dialog-title {
+ padding: 0px;
+ z-index: 1;
+}
</style>
diff --git a/webapp/src/components/PermissionModuleRoleList.vue b/webapp/src/components/PermissionModuleRoleList.vue
index 067f161..3eade73 100644
--- a/webapp/src/components/PermissionModuleRoleList.vue
+++ b/webapp/src/components/PermissionModuleRoleList.vue
@@ -20,38 +20,29 @@
<template>
<div>
<v-card>
- <v-data-table
- :headers="headers"
- :items="roles"
- item-key="id"
- hide-actions
- select-all
- :value="selectedRoles"
- @input="$store.commit('permissions/setSelectedRoles', $event)"
- >
+ <component-search-table :value="selectedRoles" @input="$store.commit('permissions/setSelectedRoles', $event)" :headers="headers" :items="roles" select-all>
<template slot="items" slot-scope="props">
- <tr @click="props.selected = !props.selected">
+ <tr :style="props.color" @click="props.data.selected = !props.data.selected">
<td>
<v-checkbox
color="primary"
- v-model="props.selected"
+ v-model="props.data.selected"
hide-details
- @click.native.stop
></v-checkbox>
</td>
- <td>{{ props.item.id }}</td>
- <td>{{ props.item.name }}</td>
- <td>{{ props.item.descr }}</td>
+ <td>{{ props.data.item.id }}</td>
+ <td>{{ props.data.item.name }}</td>
+ <td>{{ props.data.item.descr }}</td>
<td>
<v-layout>
- <v-btn flat icon color="primary" @click.stop="$store.commit('permissions/editRole', props.item.id)">
+ <v-btn flat icon color="primary" @click.stop="$store.commit('permissions/editRole', props.data.item.id)">
<v-icon>edit</v-icon>
</v-btn>
</v-layout>
</td>
</tr>
</template>
- </v-data-table>
+ </component-search-table>
</v-card>
<div class="text-xs-right">
<v-btn color="error" flat @click="$store.commit('permissions/setDialog', true )" :disabled="selectedRoles.length === 0">
@@ -66,9 +57,13 @@
<script>
import { mapState } from 'vuex'
+import ComponentSearchTable from '@/components/ComponentSearchTable'
export default {
name: 'PermissionModuleRoleList',
+ components: {
+ ComponentSearchTable
+ },
data () {
return {
headers: [
diff --git a/webapp/src/components/PermissionModuleUserList.vue b/webapp/src/components/PermissionModuleUserList.vue
index 1a28304..4222ba1 100644
--- a/webapp/src/components/PermissionModuleUserList.vue
+++ b/webapp/src/components/PermissionModuleUserList.vue
@@ -20,30 +20,20 @@
<template>
<div>
<v-card>
- <v-data-table
- :headers="headers"
- :items="users"
- item-key="id"
- hide-actions
- select-all
- :value="selectedUsers"
- @input="$store.commit('permissions/setSelectedUsers', $event)"
- >
+ <component-search-table :value="selectedUsers" @input="$store.commit('permissions/setSelectedUsers', $event)" :headers="headers" :items="users" select-all>
<template slot="items" slot-scope="props">
- <tr @click="props.selected = !props.selected">
+ <tr :style="props.color" @click="props.data.selected = !props.data.selected">
<td>
<v-checkbox
color="primary"
- v-model="props.selected"
+ v-model="props.data.selected"
hide-details
- @click.native.stop
></v-checkbox>
</td>
- <td hidden>{{ props.item.id }}</td>
- <td>{{ props.item.username }}</td>
- <td>{{ props.item.name }}</td>
+ <td>{{ props.data.item.username }}</td>
+ <td>{{ props.data.item.name }}</td>
<td>
- <template v-for="role in props.item.roles">
+ <template v-for="role in props.data.item.roles">
<v-tooltip bottom :key="role.id">
<v-chip small slot="activator">{{ role.name }}</v-chip>
<span>{{ role.descr }}</span>
@@ -52,7 +42,7 @@
</td>
</tr>
</template>
- </v-data-table>
+ </component-search-table>
</v-card>
<div class="text-xs-right">
<v-btn color="error" flat @click="$store.commit('permissions/grantRevoke', { show: true, grant: false } )" :disabled="selectedUsers.length === 0">
@@ -67,9 +57,13 @@
<script>
import { mapState } from 'vuex'
+import ComponentSearchTable from '@/components/ComponentSearchTable'
export default {
name: 'PermissionModuleUserList',
+ components: {
+ ComponentSearchTable
+ },
data () {
return {
headers: [