summaryrefslogtreecommitdiffstats
path: root/server/lib/permissions/permissionutil.js
blob: 709cd29131b94ad9ac1c4f5ce12bed9324bddd7f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* global __appdir */
const path = require('path')
var db = require(path.join(__appdir, 'lib', 'sequelize'))
var groupUtil = require(path.join(__appdir, 'lib', 'grouputil'))

module.exports = { exportFunctions }

function exportFunctions (req, res, next) {
  req.user.hasPermission = permissionName => hasPermission(req.user.id, permissionName)
  req.user.getAllowedGroups = permissionName => getAllowedGroups(req.user.id, permissionName)
  req.user.hasPermissionForGroup = (permissionName, groupId) => hasPermissionForGroup(req.user.id, permissionName, groupId)
  req.user.getAllowedClients = permissionName => getAllowedClients(req.user.id, permissionName)
  req.user.hasPermissionForClient = (permissionName, clientId) => hasPermissionForClient(req.user.id, permissionName, clientId)
  next()
}

async function hasPermission (userid, permissionName) {
  var user = await db.user.findOne({
    where: { id: userid, '$roles.permissions.name$': permissionName },
    include: [{ as: 'roles', model: db.role, include: ['permissions'] }]
  })
  return user !== null
}

async function getAllowedGroups (userid, permissionName) {
  var user = await db.user.findOne({
    where: { id: userid, '$roles.permissions.name$': permissionName },
    include: [{ as: 'roles', model: db.role, include: ['permissions', 'groups'] }]
  })
  // User doesn't have the permission
  if (user === null) return []
  // User has permission, permission is not groupdependent
  else if (!user.roles[0].permissions[0].groupdependent) return [0]
  // User has permission, permission is groupdependent
  else {
    var permGrps = []
    for (let i = 0; i < user.roles.length; i++) {
      // Add groups of the roles to the result
      permGrps = permGrps.concat(user.roles[i].groups.map(g => g.id))
      if (user.roles[i].recursiveGroups) {
        // The role is flagged recursive, so add child ids to result
        var subChilds = await groupUtil.getAllChildren(user.roles[i].groups)
        permGrps = permGrps.concat(subChilds.subgroups.map(s => s.id))
      }
    }
    // Filter result for unique entries
    return permGrps.filter(function (elem, pos, arr) { return arr.indexOf(elem) === pos })
  }
}

async function hasPermissionForGroup (userid, permissionName, groupId) {
  var user = await db.user.findOne({
    where: { id: userid, '$roles.permissions.name$': permissionName },
    include: [{ as: 'roles', model: db.role, include: ['permissions', 'groups'] }]
  })
  // User doesn't have permission
  if (user === null) return false
  // User has permission, permission is not groupdependent
  else if (!user.roles[0].permissions[0].groupdependent) return true
  // User has permission, permission is groupdependent, check for group
  else {
    if (user.roles.map(r => r.groups.map(g => g.id)).includes(groupId)) return true
    var permGrps = []
    for (let i = 0; i < user.roles.length; i++) {
      if (user.roles[i].recursiveGroups) permGrps = permGrps.concat(user.roles[i].groups.map(g => g.id))
    }
    permGrps = permGrps.filter(function (elem, pos, arr) { return arr.indexOf(elem) === pos })
    // get all parents of groupId and check if any parentid is in the list of groups of RECURSIVE flagged roles.
    var result = await checkParentsForIds(groupId, permGrps)
    return result
  }
}

async function getAllowedClients (userid, permissionName) {
  var user = await db.user.findOne({
    where: { id: userid, '$roles.permissions.name$': permissionName },
    include: [{ as: 'roles', model: db.role, include: ['permissions', { as: 'groups', model: db.group, include: ['clients'] }] }]
  })
  // User doesn't have the permission
  if (user === null) return []
  // User has permission, permission is not groupdependent
  else if (!user.roles[0].permissions[0].groupdependent) return [0]
  // User has permission, permission is groupdependent
  else {
    var permClients = []
    for (let i = 0; i < user.roles.length; i++) {
      if (user.roles[i].recursiveGroups) {
        // The role is flagged recursive, so add clients of childs to result
        var subChilds = await groupUtil.getAllChildren(user.roles[i].groups)
        permClients = permClients.concat(subChilds.clients.map(c => c.id))
      } else {
        for (let j = 0; j < user.roles[i].groups.length; j++) {
          permClients = permClients.concat(user.roles[i].groups[j].clients.map(c => c.id))
        }
      }
    }
    // Filter result for unique entries
    return permClients.filter(function (elem, pos, arr) { return arr.indexOf(elem) === pos })
  }
}

async function hasPermissionForClient (userid, permissionName, clientId) {
  var user = await db.user.findOne({
    where: { id: userid, '$roles.permissions.name$': permissionName },
    include: [{ as: 'roles', model: db.role, include: ['permissions', { as: 'groups', model: db.group, include: ['clients'] }] }]
  })
  if (user === null) return false
  else if (!user.roles[0].permissions[0].groupdependent) return true
  else {
    var permGrps = []
    for (let i = 0; i < user.roles.length; i++) {
      for (let j = 0; j < user.roles[i].groups.length; j++) {
        var groupClients = user.roles[i].groups[j].clients.map(c => c.id)
        if (groupClients.includes(clientId)) return true
      }
      if (user.roles[i].recursiveGroups) permGrps = permGrps.concat(user.roles[i].groups.map(g => g.id))
    }
    permGrps = permGrps.filter(function (elem, pos, arr) { return arr.indexOf(elem) === pos })
    var client = await db.client.findOne({
      where: { id: clientId },
      include: [{ as: 'groups', model: db.group }]
    })
    var groupIds = client.groups.map(g => g.id)
    var result = await checkParentsForIds(groupIds, permGrps)
    return result
  }
}

async function checkParentsForIds (groupIds, listOfIds) {
  if (listOfIds.length === 0) return false
  if (groupIds.length === 0) return false

  var parentIds = []
  return db.group.findAll({ where: { id: groupIds }, include: ['parents'] }).then(groups => {
    for (let i = 0; i < groups.length; i++) {
      for (let j = 0; j < groups[i].parents.length; j++) {
        var id = groups[i].parents[j].id
        if (listOfIds.includes(id)) return true
        if (!parentIds.includes(id)) parentIds.push(id)
      }
    }
    if (parentIds.length === 0) return false
    return checkParentsForIds(parentIds, listOfIds).then(response => {
      return response
    })
  })
}