summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJannik Schönartz2020-06-02 18:33:13 +0200
committerJannik Schönartz2020-06-02 18:33:13 +0200
commit79f09bacdc4bd515e135060226888b02e285d146 (patch)
tree0e6dd40e90834c7aa2ae8e1e2141559486c01588
parent[webapp] add no permission snackbar to 403 responses (diff)
downloadbas-79f09bacdc4bd515e135060226888b02e285d146.tar.gz
bas-79f09bacdc4bd515e135060226888b02e285d146.tar.xz
bas-79f09bacdc4bd515e135060226888b02e285d146.zip
[users/ipxe/backends] PM integration
-rw-r--r--server/api/backends.js33
-rw-r--r--server/api/ipxe.js40
-rw-r--r--server/api/users.js40
-rw-r--r--server/lib/httpresponse.js13
-rw-r--r--server/lib/permissions/modules/backends.json12
-rw-r--r--server/lib/permissions/modules/ipxe.json12
-rw-r--r--server/lib/permissions/modules/users.json12
-rw-r--r--webapp/src/components/AccountModule.vue6
-rw-r--r--webapp/src/components/BackendModuleEdit.vue2
-rw-r--r--webapp/src/components/LogModule.vue1
10 files changed, 144 insertions, 27 deletions
diff --git a/server/api/backends.js b/server/api/backends.js
index b75634f..872e0f6 100644
--- a/server/api/backends.js
+++ b/server/api/backends.js
@@ -9,18 +9,45 @@ var noAuthRouter = decorateApp(express.Router())
const HttpResponse = require(path.join(__appdir, 'lib', 'httpresponse'))
const log = require(path.join(__appdir, 'lib', 'log'))
-// GET requests.
-
// TODO DELETE
noAuthRouter.getAsync('/:id/test', async (req, res) => {
const id = req.params.id
const backend = await db.backend.findOne({ where: { id: id } })
const externalBackends = new ExternalBackends()
const instance = externalBackends.getInstance(backend.type)
- const result = await instance.test(backend.credentials)
+ // const result = await instance.test(backend.credentials)
+ const result = await instance.checkIp(backend.credentials, '10.21.9.220')
res.send(result)
})
+// Permission check middleware
+router.all(['', '/:id', '/:id/:function'], async (req, res, next) => {
+ console.log(req.params)
+ switch (req.method) {
+ case 'GET':
+ switch (req.params.function) {
+ case 'import':
+ if (!await req.user.hasPermission('backends.edit')) return res.status(403).send({ error: 'Missing permission', permission: 'backends.edit' })
+ break
+
+ default:
+ if (!await req.user.hasPermission('backends.view')) return res.status(403).send({ error: 'Missing permission', permission: 'backends.view' })
+ break
+ }
+ break
+
+ case 'POST': case 'PUT':
+ if (!await req.user.hasPermission('backends.edit')) return res.status(403).send({ error: 'Missing permission', permission: 'backends.edit' })
+ break
+
+ default:
+ return res.status(400).send()
+ }
+
+ next()
+})
+
+// GET requests.
/*
* @return: Returns a list of all backends saved in the db.
*/
diff --git a/server/api/ipxe.js b/server/api/ipxe.js
index b7e1970..b807c00 100644
--- a/server/api/ipxe.js
+++ b/server/api/ipxe.js
@@ -3,10 +3,40 @@ var path = require('path')
const fs = require('fs')
var shell = require(path.join(__appdir, 'lib', 'shell'))
var express = require('express')
-var router = express.Router()
+const { decorateApp } = require('@awaitjs/express')
+var router = decorateApp(express.Router())
var noAuthRouter = express.Router()
const log = require(path.join(__appdir, 'lib', 'log'))
+// Permission check middleware
+router.all('/:x', async (req, res, next) => {
+ switch (req.method) {
+ case 'GET':
+ switch (req.params.x) {
+ case 'script': case 'certificate': case 'general': case 'console': case 'log': case 'config': case 'status':
+ if (!await req.user.hasPermission('ipxe.view')) return res.status(403).send({ error: 'Missing permission', permission: 'ipxe.view' })
+ break
+
+ case 'build': case 'cancel': case 'clean':
+ if (!await req.user.hasPermission('ipxe.edit')) return res.status(403).send({ error: 'Missing permission', permission: 'ipxe.edit' })
+ break
+
+ default:
+ return res.status(400).send()
+ }
+ break
+
+ case 'PUT': case 'POST':
+ if (!await req.user.hasPermission('ipxe.edit')) return res.status(403).send({ error: 'Missing permission', permission: 'ipxe.edit' })
+ break
+
+ default:
+ return res.status(400).send()
+ }
+
+ next()
+})
+
// GET requests.
router.get('/script', (req, res) => {
res.setHeader('content-type', 'text/plain')
@@ -28,7 +58,7 @@ router.get('/console', (req, res) => {
res.sendFile(path.join(__appdir, 'ipxe', 'console.h'))
})
-router.get('/log', async (req, res) => {
+router.get('/log', (req, res) => {
const max = req.query.max ? req.query.max : -1
res.setHeader('content-type', 'text/plain')
const filepath = path.join(__appdir, 'ipxe', 'ipxelog.txt')
@@ -118,7 +148,7 @@ router.put('/:filename', (req, res) => {
/*
* @return: Rebuild the ipxe.
*/
-router.get('/build', async (req, res) => {
+router.getAsync('/build', async (req, res) => {
log({
category: 'IPXEBUILDER_BUILD',
description: 'User initiated the ipxe building process.',
@@ -131,7 +161,7 @@ router.get('/build', async (req, res) => {
res.send(build)
})
-router.get('/cancel', async (req, res) => {
+router.getAsync('/cancel', async (req, res) => {
log({
category: 'IPXEBUILDER_CANCEL',
description: 'User canceled the ipxe building process.',
@@ -141,7 +171,7 @@ router.get('/cancel', async (req, res) => {
res.send(result)
})
-router.get('/clean', async (req, res) => {
+router.getAsync('/clean', async (req, res) => {
log({
category: 'IPXEBUILDER_CLEAN',
description: 'User initiated ipxe cleaning process.',
diff --git a/server/api/users.js b/server/api/users.js
index d69c776..a4940e0 100644
--- a/server/api/users.js
+++ b/server/api/users.js
@@ -7,6 +7,28 @@ var router = decorateApp(express.Router())
var authentication = require(path.join(__appdir, 'lib', 'authentication'))
const log = require(path.join(__appdir, 'lib', 'log'))
+// Permission check middleware
+router.all(['', '/:id'], async (req, res, next) => {
+ // User is allowed to edit his own information even without any permissions.
+ let currentInfo = false
+ if (req.params.id && req.params.id === 'current') currentInfo = true
+
+ switch (req.method) {
+ case 'GET':
+ if (!await req.user.hasPermission('users.view') && !currentInfo) return res.status(403).send({ error: 'Missing permission', permission: 'users.view' })
+ break
+
+ case 'POST': case 'DELETE':
+ if (!await req.user.hasPermission('users.edit') && !currentInfo) return res.status(403).send({ error: 'Missing permission', permission: 'users.edit' })
+ break
+
+ default:
+ return res.status(400).send()
+ }
+
+ next()
+})
+
// ############################################################################
// ########################### GET requests #################################
@@ -36,8 +58,6 @@ router.getAsync('/:id', async (req, res) => {
// Post request for adding roles to users.
router.postAsync('/roles', async (req, res) => {
- // if (!await req.user.hasPermission('permissions.grantrevoke')) return res.status(403).end()
-
const userIds = req.body.users
const roleIds = req.body.roles
const users = await db.user.findAll({ where: { id: userIds }, include: ['roles'] })
@@ -52,7 +72,7 @@ router.postAsync('/roles', async (req, res) => {
if (count > 1) roleString += 's'
log({
category: 'USER_REVOKE_ROLE',
- description: '[' + user.id + '] ' + user.name + ': Successfully removed ' + count + ' ' + roleString + '.\n' +
+ description: '[' + user.id + '] ' + 'Successfully removed ' + count + ' ' + roleString + ' from' + user.name + '.\n' +
'ID: ' + user.id + '\n' +
'Name: ' + user.name + '\n' +
'Removed Roles: ' + roleIds.filter(y => { return roles.map(x => x.id).includes(y) }),
@@ -85,13 +105,9 @@ router.postAsync('/roles', async (req, res) => {
}
})
-// Post request for creating new user accounts.
+// Post request for creating / editing new user accounts.
router.postAsync(['/', '/:id'], async (req, res) => {
const body = req.body
- if (req.params.id !== 'current') {
- // TODO: Check for permission to delete / create / update user
- }
-
// Delete request
if (req.query.delete !== undefined && req.query.delete !== 'false') {
const user = await db.user.findOne({ where: { id: req.user.id } })
@@ -152,6 +168,7 @@ router.postAsync(['/', '/:id'], async (req, res) => {
return res.send({ deletionCounter })
}
+ // Create new user
if (req.params.id === undefined) {
const result = await authentication.signup(body)
const code = result.code
@@ -183,6 +200,7 @@ router.postAsync(['/', '/:id'], async (req, res) => {
delete result.code
return res.status(code).send(result)
} else {
+ // Edit user
const id = req.params.id === 'current' ? req.user.id : req.params.id
let user = await db.user.findOne({ where: { id: id } })
@@ -289,7 +307,7 @@ router.postAsync(['/', '/:id'], async (req, res) => {
// Post request for changing the password.
router.postAsync('/:id/password', async (req, res) => {
- const id = req.params.id
+ const id = req.params.id === 'current' ? req.user.id : req.params.id
const body = req.body
// Check if passwords are set.
if (body.passwordCurrent && body.password) {
@@ -317,10 +335,6 @@ router.postAsync('/:id/password', async (req, res) => {
// Function for deleting a single user
router.deleteAsync('/:id/', async (req, res) => {
- if (req.params.id !== 'current') {
- // Check if the user has the permission for changing those userdata. Else return.
- // return res.status(500).end()
- }
const id = req.params.id === 'current' ? req.user.id : req.params.id
const user = await db.user.findOne({ where: { id: id } })
// Every user can delete his own account.
diff --git a/server/lib/httpresponse.js b/server/lib/httpresponse.js
index cb4b216..c402e39 100644
--- a/server/lib/httpresponse.js
+++ b/server/lib/httpresponse.js
@@ -27,12 +27,25 @@ HttpResponse.successBatch = (action, type, count) => {
}
// ############################################################################
+// ############################## WARNING #####################################
+
+HttpResponse.warningBatch = (action, type, successfull, count) => {
+ const failed = count - successfull
+ let tmpType = type
+ if (failed > 1) tmpType += 's'
+ if (Array.isArray(type)) type = type[successfull === 1 ? 0 : 1]
+ else if (successfull !== 1) type += 's'
+ return new HttpResponse(200, action.toUpperCase() + '_MULTIPLE', `Warning: ${action} ${successfull}/${count} ${type}. ${failed} ${tmpType} failed.`, { successfull, count })
+}
+
+// ############################################################################
// ############################### ERROR ######################################
// General
HttpResponse.notFound = (id) => new HttpResponse(404, 'NOT_FOUND', 'ID ' + id + ' does not exist.')
HttpResponse.invalidId = (zeroAllowed) => new HttpResponse(400, 'INVALID_ID', 'ID has to be an integer' + (zeroAllowed ? '' : ' greater than 0') + '.')
HttpResponse.invalidBodyValue = (key, rule) => new HttpResponse(400, 'BAD_REQUEST', 'JSON body value for key "' + key + '" has to be ' + rule + '.')
+HttpResponse.noPermission = (id, permission) => new HttpResponse(403, 'NO_PERMISSION', 'Missing permission ' + permission + ' for object ' + id + '.')
// Authentication
HttpResponse.invalidToken = () => new HttpResponse(401, 'INVALID_TOKEN', 'The provided token is invalid.')
diff --git a/server/lib/permissions/modules/backends.json b/server/lib/permissions/modules/backends.json
new file mode 100644
index 0000000..5143ec3
--- /dev/null
+++ b/server/lib/permissions/modules/backends.json
@@ -0,0 +1,12 @@
+[
+ {
+ "name": "view",
+ "description": "View all backends including their informations.",
+ "groupdependent": false
+ },
+ {
+ "name": "edit",
+ "description": "Edit and delete backends.",
+ "groupdependent": false
+ }
+] \ No newline at end of file
diff --git a/server/lib/permissions/modules/ipxe.json b/server/lib/permissions/modules/ipxe.json
new file mode 100644
index 0000000..2375cbf
--- /dev/null
+++ b/server/lib/permissions/modules/ipxe.json
@@ -0,0 +1,12 @@
+[
+ {
+ "name": "view",
+ "description": "View all information for building ipxe.",
+ "groupdependent": false
+ },
+ {
+ "name": "edit",
+ "description": "Edit informations, configs, scripts for building ipxe.",
+ "groupdependent": false
+ }
+] \ No newline at end of file
diff --git a/server/lib/permissions/modules/users.json b/server/lib/permissions/modules/users.json
new file mode 100644
index 0000000..1818e7f
--- /dev/null
+++ b/server/lib/permissions/modules/users.json
@@ -0,0 +1,12 @@
+[
+ {
+ "name": "view",
+ "description": "View all users including their informations.",
+ "groupdependent": false
+ },
+ {
+ "name": "edit",
+ "description": "Edit and delete users.",
+ "groupdependent": false
+ }
+] \ No newline at end of file
diff --git a/webapp/src/components/AccountModule.vue b/webapp/src/components/AccountModule.vue
index 73f85fb..27ec276 100644
--- a/webapp/src/components/AccountModule.vue
+++ b/webapp/src/components/AccountModule.vue
@@ -319,7 +319,7 @@ export default {
},
submitPassword () {
if (this.$refs.passwordForm.validate()) {
- this.$http.post('/api/users/' + this.user.id + '/password', { passwordCurrent: this.passwordCurrent, password: this.passwordNew }).then(response => {
+ this.$http.post('/api/users/current/password', { passwordCurrent: this.passwordCurrent, password: this.passwordNew }).then(response => {
this.cancelEditPassword()
this.$snackbar({ color: 'success', text: this.$t('passwordChanged') })
}).catch(error => {
@@ -348,10 +348,6 @@ export default {
this.passwordCurrent = ''
this.passwordNew = ''
this.passwordConfirm = ''
- },
- newAlert () {
- this.$alert({ type: 'success', text: 'aaaaaaaaaaaaaaaaaaaaaaaaaas das dsad asdpioipoidijoijoawiojdiojijowaijo d o wiadijo oiawio jdi aaaaaaaaaaaaaaaaaaaaaa uo iashdoiuas dhuas hduioash diuash diuash diuash diuh test ' + this.testId })
- this.testId++
}
}
}
diff --git a/webapp/src/components/BackendModuleEdit.vue b/webapp/src/components/BackendModuleEdit.vue
index b6fcfd5..30dd880 100644
--- a/webapp/src/components/BackendModuleEdit.vue
+++ b/webapp/src/components/BackendModuleEdit.vue
@@ -121,7 +121,7 @@ export default {
this.$store.dispatch('backends/loadData')
this.$store.commit('backends/setEdit', false)
}).catch(error => {
- this.$snackbar({ color: 'success', text: error.response })
+ if (error.response.status !== 403) this.$snackbar({ color: 'error', text: error.response })
})
}
},
diff --git a/webapp/src/components/LogModule.vue b/webapp/src/components/LogModule.vue
index 4d08464..a759c55 100644
--- a/webapp/src/components/LogModule.vue
+++ b/webapp/src/components/LogModule.vue
@@ -264,6 +264,7 @@ export default {
'GROUP_REMOVE_CLIENT',
'GROUP_BATCH_ADD_CLIENT',
'GROUP_ADD_CLIENT',
+ 'ERROR_GROUP_EDIT',
'ERROR_GROUP_DELETE',
'ERROR_GROUP_REMOVE_SUBGROUP',
'ERROR_GROUP_ADD_SUBGROUP',