You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
2.4 KiB

  1. 'use strict'
  2. /* global db */
  3. const _ = require('lodash')
  4. /**
  5. * Rights
  6. */
  7. module.exports = {
  8. guest: {
  9. provider: 'local',
  10. email: 'guest',
  11. name: 'Guest',
  12. password: '',
  13. rights: [
  14. {
  15. role: 'read',
  16. path: '/',
  17. deny: false,
  18. exact: false
  19. }
  20. ]
  21. },
  22. /**
  23. * Initialize Rights module
  24. *
  25. * @return {void} Void
  26. */
  27. init () {
  28. let self = this
  29. db.onReady.then(() => {
  30. db.User.findOne({ provider: 'local', email: 'guest' }).then((u) => {
  31. if (u) {
  32. self.guest = u
  33. }
  34. })
  35. })
  36. },
  37. /**
  38. * Check user permissions for this request
  39. *
  40. * @param {object} req The request object
  41. * @return {object} List of permissions for this request
  42. */
  43. check (req) {
  44. let self = this
  45. let perm = {
  46. read: false,
  47. write: false,
  48. manage: false
  49. }
  50. let rt = []
  51. let p = _.chain(req.originalUrl).toLower().trim().value()
  52. // Load user rights
  53. if (_.isArray(req.user.rights)) {
  54. rt = req.user.rights
  55. }
  56. // Check rights
  57. if (self.checkRole(p, rt, 'admin')) {
  58. perm.read = true
  59. perm.write = true
  60. perm.manage = true
  61. } else if (self.checkRole(p, rt, 'write')) {
  62. perm.read = true
  63. perm.write = true
  64. } else if (self.checkRole(p, rt, 'read')) {
  65. perm.read = true
  66. }
  67. return perm
  68. },
  69. /**
  70. * Check for a specific role based on list of user rights
  71. *
  72. * @param {String} p Base path
  73. * @param {array<object>} rt The user rights
  74. * @param {string} role The minimum role required
  75. * @return {boolean} True if authorized
  76. */
  77. checkRole (p, rt, role) {
  78. if (_.find(rt, { role: 'admin' })) { return true }
  79. // Check specific role on path
  80. let filteredRights = _.filter(rt, (r) => {
  81. if (r.role === role || (r.role === 'write' && role === 'read')) {
  82. if ((!r.exact && _.startsWith(p, r.path)) || (r.exact && p === r.path)) {
  83. return true
  84. }
  85. }
  86. return false
  87. })
  88. // Check for deny scenario
  89. let isValid = false
  90. if (filteredRights.length > 1) {
  91. isValid = !_.chain(filteredRights).sortBy((r) => {
  92. return r.path.length + ((r.deny) ? 0.5 : 0)
  93. }).last().get('deny').value()
  94. } else if (filteredRights.length === 1 && filteredRights[0].deny === false) {
  95. isValid = true
  96. }
  97. // Deny by default
  98. return isValid
  99. }
  100. }