Skip to content

Commit

Permalink
Merge pull request #88 from velrest/new_admin_permissions
Browse files Browse the repository at this point in the history
New admin permissions
  • Loading branch information
velrest authored Jul 6, 2018
2 parents 1d952e9 + e65d4b7 commit 1b47934
Show file tree
Hide file tree
Showing 61 changed files with 344 additions and 220 deletions.
3 changes: 2 additions & 1 deletion backend/config-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
},
login: {
adminRole: 'adsy-user',
employeeRole: 'adsy-user',

ldap: {
searchBase: 'cn=users,dc=adsy-ext,dc=becs,dc=adfinis-sygroup,dc=ch',
Expand Down Expand Up @@ -86,7 +87,7 @@ module.exports = {
timed: {
type: 'timed',
host: 'http://timedbackend',
user: 'sysupport_api',
user: 'timed_api',
password: 'hallo123',
prefix: '/api/v1',
authPath: '/auth/login',
Expand Down
3 changes: 3 additions & 0 deletions backend/config.example.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ module.exports = {
cert: '/path/to/root_ca_cert.crt'
},
login: {
adminRole: 'some-role',
employeeRole: 'some-other-role',

ldap: {
// Further information how to configure LDAP under:
// https://github.com/vesse/passport-ldapauth
Expand Down
2 changes: 1 addition & 1 deletion backend/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import passwordreset from './password-reset'
import services from './services'
import userRoute from './user/route'
import vaultTokenRenewer from './vault/vault-token'
import { timedTokenRenew } from './sysupport/token'
import { timedTokenRenew } from './timed/token'
import config from './config'

const app = express()
Expand Down
10 changes: 5 additions & 5 deletions backend/src/login/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import passport from 'passport'
import LdapStrategy from 'passport-ldapauth'
import User from '../user/model'
import config from '../config'
import { timedLogin } from '../sysupport/token'
import { getCustomer as getTimedCustomer } from '../sysupport/custom'
import { timedLogin } from '../timed/token'
import { getCustomer as getTimedCustomer } from '../timed/custom'

passport.use(
'ldapauth-user',
Expand Down Expand Up @@ -115,8 +115,8 @@ function loginSuccessful(req, res, next, ldapUser) {
)
}

// If user is in the sysupport group, get timed token
if (isMember('sysupport')) {
// If user is in the timed group, get timed token
if (isMember('timed')) {
req.session = await addTimedTokenToSession(
req.session,
users.get(ldapUser)
Expand Down Expand Up @@ -146,7 +146,7 @@ async function addTimedTokenToSession(session, user) {
try {
session.timedToken = await timedLogin()
session.timedTokenTTL = new Date().getTime()
if (!user.isAdmin()) {
if (!user.isEmployee()) {
session.timedCustomer = await getTimedCustomer(session.timedToken, user)
}
} catch (e) {
Expand Down
4 changes: 2 additions & 2 deletions backend/src/services.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import express from 'express'
import VaultProxy from './vault/vault-proxy'
import vaultCustom from './vault/vault-custom'
import SysupportProxy from './sysupport/proxy'
import TimedProxy from './timed/proxy'
import gitlabProxy from './gitlab/proxy'
import config from './config'

Expand All @@ -12,7 +12,7 @@ const { vault, timed, gitlab } = config.services
router.use('/vault', vaultCustom(vault))
router.use('/proxy/vault', VaultProxy.createProxy(vault))

router.use('/proxy/sysupport', SysupportProxy.createProxy(timed))
router.use('/proxy/timed', TimedProxy.createProxy(timed))

router.use('/proxy/gitlab', gitlabProxy(gitlab))

Expand Down
File renamed without changes.
20 changes: 15 additions & 5 deletions backend/src/sysupport/proxy.js → backend/src/timed/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const routes = {
path: /^\/subscription-projects(\/[1-9][0-9]*|)$/,
access: {
admin: ['GET'],
user: ['GET'],
customer: ['GET']
}
},
Expand All @@ -19,13 +20,15 @@ const routes = {
path: /^\/subscription-orders$/,
access: {
admin: ['GET', 'DELETE', 'POST'],
user: ['GET', 'DELETE'],
customer: ['GET', 'POST']
}
},
subscriptionOrder: {
path: /^\/subscription-orders\/[1-9][0-9]*$/,
access: {
admin: ['DELETE']
admin: ['DELETE'],
user: ['DELETE']
}
},
subscriptionOrderConfirm: {
Expand All @@ -38,13 +41,15 @@ const routes = {
path: /^\/reports$/,
access: {
admin: ['GET'],
user: ['GET'],
customer: ['GET']
}
},
customer: {
path: /^\/customers(\/[1-9][0-9]*|)$/,
access: {
admin: ['GET']
admin: ['GET'],
user: ['GET']
}
}
}
Expand All @@ -54,10 +59,15 @@ const routes = {
* @return boolean - returns true if has access
**/
function checkAccess(req) {
if (!req.user.isAdmin() && typeof req.session.timedCustomer === 'undefined') {
if (
!req.user.isEmployee() &&
typeof req.session.timedCustomer === 'undefined'
) {
return false
}
let access = req.user.isAdmin() ? 'admin' : 'customer'
let access = req.user.isAdmin()
? 'admin'
: req.user.isAdsyUser() ? 'user' : 'customer'
for (let route in routes) {
if (req.path.match(routes[route].path)) {
if (routes[route].access.hasOwnProperty(access)) {
Expand Down Expand Up @@ -88,7 +98,7 @@ function createProxy(config) {
.map(key => `${key}=${queryParams[key]}`)
.join('&')

if (!req.user.isAdmin()) {
if (!req.user.isEmployee()) {
newPath += `customer=${req.session.timedCustomer.id}`
}
if (req.path.match(routes.reports.path)) {
Expand Down
File renamed without changes.
25 changes: 23 additions & 2 deletions backend/src/user/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ const { isArray } = Array
const bookshelf = new Bookshelf(knex(config.database))

/**
* User model
*
* User model *
* @class User
* @public
*/
Expand Down Expand Up @@ -71,6 +70,28 @@ export default bookshelf.Model.extend(
return this.getGroupNames().includes(config.login.adminRole)
},

/**
* Check if user is employee
*
* @returns {boolean}
* @public
* @author Jonas Cosandey ([email protected])
*/
isAdsyUser() {
return this.getGroupNames().includes(config.login.employeeRole)
},

/**
* Is user a adsy user
*
* @returns {boolean}
* @public
* @author Jonas Cosandey ([email protected])
*/
isEmployee() {
return this.isAdmin() || this.isAdsyUser()
},

/**
* Does this user have redmine access?
*
Expand Down
2 changes: 1 addition & 1 deletion frontend/app/adapters/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import DS from 'ember-data'
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin'

export default DS.JSONAPIAdapter.extend(DataAdapterMixin, {
namespace: '/api/proxy/sysupport',
namespace: '/api/proxy/timed',
authorize(xhr) {
if (this.get('session.data.authenticated.data.token')) {
xhr.setRequestHeader(
Expand Down
5 changes: 4 additions & 1 deletion frontend/app/gitlab/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { computed } from '@ember/object'

export default Route.extend(RouteAccessMixin, {
//specify which groups have access to this route.
groups: computed(() => ['adsy-customer', 'gitlab']),
groups: computed(() => ({
requireAll: ['gitlab'],
requireOne: ['adsy-customer']
})),

i18n: service(),
session: service(),
Expand Down
4 changes: 2 additions & 2 deletions frontend/app/helpers/format-duration.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export default Helper.extend({
hoursCount: 0,
minutesCount: 0,

hoursTranslation: t('sysupport.durations.hour', { count: 'hoursCount' }),
minutesTranslation: t('sysupport.durations.minute', {
hoursTranslation: t('timed.durations.hour', { count: 'hoursCount' }),
minutesTranslation: t('timed.durations.minute', {
count: 'minutesCount'
}),

Expand Down
10 changes: 5 additions & 5 deletions frontend/app/locales/de/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ export default {
symonitoring: 'SyMonitoring',
'symonitoring.description': 'Überwachung von Server und Diensten',

sysupport: 'SySupport',
'sysupport.description': 'Support Abonnemente',
timed: 'Credits / Reports',
'timed.description': 'Support Abonnemente',

ppa: 'PPA',
'ppa.description': 'Verwaltung ihrer Webhostings',
Expand All @@ -74,7 +74,7 @@ export default {
nav: {
dashboard: 'Übersicht',
vault: 'Vault',
sysupport: 'SySupport',
timed: 'Credits / Reports',
gitlab: 'Projekte',
settings: 'Einstellungen',
logout: 'Logout'
Expand All @@ -92,7 +92,7 @@ export default {
'Das Passwort konnte nicht in die Zwischenablage kopiert werden.'
},

sysupport: {
timed: {
breadcrumbs: {
reload: 'Aufladen',
overview: 'Übersicht'
Expand Down Expand Up @@ -120,7 +120,7 @@ export default {
},

index: {
title: 'Sysupport Abonnements',
title: 'Abonnements',
charge: 'Aufladen',
details: 'Details'
},
Expand Down
10 changes: 5 additions & 5 deletions frontend/app/locales/en/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ export default {
symonitoring: 'SyMonitoring',
'symonitoring.description': 'Monitoring of servers and services',

sysupport: 'SySupport',
'sysupport.description': 'Support subscriptions',
timed: 'Credits / Reports',
'timed.description': 'Support subscriptions',

ppa: 'PPA',
'ppa.description': 'Manage your web-hostings',
Expand All @@ -74,7 +74,7 @@ export default {
nav: {
dashboard: 'Dashboard',
vault: 'Vault',
sysupport: 'SySupport',
timed: 'Credits / Reports',
gitlab: 'Projects',
settings: 'Settings',
logout: 'Sign out'
Expand All @@ -91,7 +91,7 @@ export default {
'clipboard-error': 'The secret could not be saved to your clipboard.'
},

sysupport: {
timed: {
breadcrumbs: {
reload: 'Reload',
overview: 'Overview'
Expand All @@ -118,7 +118,7 @@ export default {
}
},
index: {
title: 'Sysupport Subscriptions',
title: 'Credits / Reports',
charge: 'Reload',
details: 'Details'
},
Expand Down
13 changes: 11 additions & 2 deletions frontend/app/mixins/route-access-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,17 @@ export default Mixin.create({
},

_hasPermissions(user) {
return this.groups.every(
role => user.get(role) || user.get('groups').includes(role)
return (
(this.groups.requireAll
? this.groups.requireAll.every(
role => user.get(role) || user.get('groups').includes(role)
)
: true) &&
(this.groups.requireOne
? this.groups.requireOne.some(
role => user.get(role) || user.get('groups').includes(role)
)
: true)
)
}
})
8 changes: 6 additions & 2 deletions frontend/app/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export default Model.extend({
return this._checkGroup('vault')
}),

sysupport: computed('groups.[]', function() {
return this._checkGroup('sysupport')
timed: computed('groups.[]', function() {
return this._checkGroup('timed')
}),

gitlab: computed('groups.[]', function() {
Expand Down Expand Up @@ -64,6 +64,10 @@ export default Model.extend({
return this._checkGroup(ENV.APP.adminGroup)
}),

adsyUser: computed('groups.[]', function() {
return this._checkGroup(ENV.APP.adsyUserGroup)
}),

_checkGroup(name) {
return this.groups.find(g => g.endsWith(name))
}
Expand Down
24 changes: 13 additions & 11 deletions frontend/app/protected/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,20 @@
{{#list.item 'gitlab'}}{{t 'nav.gitlab'}}{{/list.item}}
{{/if}}

{{#if (and (service-enabled 'sysupport') model.sysupport)}}
{{#if model.admin}}
{{#list.item 'sysupport-admin' }}{{t 'nav.sysupport'}}{{/list.item}}
<ul class="uk-nav-sub">
<li>
{{#link-to "sysupport-admin.confirm-subscriptions"}}
{{t 'sysupport.admin.confirm-subscription'}}
{{/link-to}}
</li>
</ul>
{{#if (and (service-enabled 'timed') model.timed)}}
{{#if (or model.adsyUser model.admin)}}
{{#list.item 'timed-admin' }}{{t 'nav.timed'}}{{/list.item}}
{{#if model.admin}}
<ul class="uk-nav-sub">
<li>
{{#link-to "timed-admin.confirm-subscriptions"}}
{{t 'timed.admin.confirm-subscription'}}
{{/link-to}}
</li>
</ul>
{{/if}}
{{else}}
{{#list.item 'sysupport-subscriptions' }}{{t 'nav.sysupport'}}{{/list.item}}
{{#list.item 'timed-subscriptions' }}{{t 'nav.timed'}}{{/list.item}}
{{/if}}
{{/if}}
{{/nav.list}}
Expand Down
4 changes: 2 additions & 2 deletions frontend/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ Router.map(function() {
this.route('vault', { resetNamespace: true }, function() {
this.route('edit', { path: '/*path' })
})
this.route('sysupport-subscriptions', { resetNamespace: true }, function() {
this.route('timed-subscriptions', { resetNamespace: true }, function() {
this.route('detail', { path: ':project_id' }, function() {
this.route('reload')
})
})
this.route('sysupport-admin', { resetNamespace: true }, function() {
this.route('timed-admin', { resetNamespace: true }, function() {
this.route('detail', { path: ':project' })
this.route('confirm-subscriptions')
})
Expand Down
Loading

0 comments on commit 1b47934

Please sign in to comment.