Skip to content

Commit

Permalink
refactor: store a stringified version of ACL fields and filters
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardoboucas committed Jun 26, 2018
1 parent 58c2290 commit be5de8b
Show file tree
Hide file tree
Showing 5 changed files with 381 additions and 72 deletions.
4 changes: 3 additions & 1 deletion dadi/lib/model/acl/access.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ Access.prototype.get = function ({clientId = null, accessType = null} = {}, reso
}).then(({results}) => {
if (!resource) {
let accessByResource = results.reduce((output, result) => {
output[result.resource] = result.access
output[result.resource] = resolveOwnTypes
? this.resolveOwnTypes(result.access, clientId)
: result.access

return output
}, {})
Expand Down
12 changes: 9 additions & 3 deletions dadi/lib/model/acl/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ Client.prototype.resourceAdd = function (clientId, resource, access) {
},
rawOutput: true,
update: {
resources: resources.getAll()
resources: resources.getAll({
formatForInput: true
})
},
validate: false
})
Expand Down Expand Up @@ -290,7 +292,9 @@ Client.prototype.resourceUpdate = function (clientId, resource, access) {
},
rawOutput: true,
update: {
resources: resources.getAll()
resources: resources.getAll({
formatForInput: true
})
},
validate: false
})
Expand Down Expand Up @@ -443,7 +447,9 @@ Client.prototype.sanitise = function (client) {
if (key === 'resources') {
let resources = new ACLMatrix(value)

value = resources.format()
value = resources.getAll({
formatForOutput: true
})
}

output[key] = value
Expand Down
106 changes: 99 additions & 7 deletions dadi/lib/model/acl/matrix.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const log = require('@dadi/logger')

const ACCESS_TYPES = [
'delete',
'deleteOwn',
Expand All @@ -12,20 +14,60 @@ const Matrix = function (map) {
this.map = map || {}
}

/**
* Returns the resource map with access matrices formatted
* for insertion in the database.
*
* @param {Object} map
* @return {Object}
*/
Matrix.prototype._formatForInput = function (map) {
return Object.keys(map).reduce((output, resource) => {
output[resource] = this._formatMatrixForInput(
this.map[resource]
)

return output
}, {})
}

/**
* Returns the resource map with access matrices containing
* the value for all access types, i.e. if a particular access
* type is not defined for the resource, its value will be set
* to `false` in the output.
*
* @param {Object} map
* @return {Object}
*/
Matrix.prototype.format = function () {
return Object.keys(this.map).reduce((output, resource) => {
Matrix.prototype._formatForOutput = function (map) {
return Object.keys(map).reduce((output, resource) => {
let formattedResource = {}

ACCESS_TYPES.forEach(type => {
formattedResource[type] = this.map[resource][type] || false
let value = map[resource][type]

if (typeof value === 'object') {
value = Object.keys(value).reduce((sanitised, key) => {
if (typeof value[key] === 'string') {
try {
let parsedValue = JSON.parse(value[key])

sanitised[key] = parsedValue
} catch (error) {
log.error({
module: 'ACL matrix'
}, error)
}
} else {
sanitised[key] = value[key]
}

return sanitised
}, {})
}

formattedResource[type] = value || false
})

output[resource] = formattedResource
Expand All @@ -34,22 +76,72 @@ Matrix.prototype.format = function () {
}, {})
}

/**
* Returns the access matrix formatted for insertion in the database.
*
* @param {Object} map
* @return {Object}
*/
Matrix.prototype._formatMatrixForInput = function (matrix) {
return Object.keys(matrix).reduce((sanitised, accessType) => {
if (typeof matrix[accessType] === 'object') {
sanitised[accessType] = Object.keys(matrix[accessType]).reduce((value, key) => {
value[key] = typeof matrix[accessType][key] === 'object'
? JSON.stringify(matrix[accessType][key])
: matrix[accessType][key]

return value
}, {})
} else {
sanitised[accessType] = matrix[accessType]
}

return sanitised
}, {})
}

/**
* Returns the access matrix for a particular resource.
*
* @param {String} name
* @param {String} name The name of the resource to retrieve
* @param {Boolean} options.formatForInput Whether to format the result for input
* @param {Boolean} options.formatForOutput} Whether to format the result for input
* @return {Object}
*/
Matrix.prototype.get = function (name) {
return this.map[name]
Matrix.prototype.get = function (name, {
formatForInput,
formatForOutput
} = {}) {
let map = this.map

if (formatForInput) {
map = this._formatForInput(map)
} else if (formatForOutput) {
map = this._formatForOutput(map)
}

return map[name]
}

/**
* Returns the entire resource map.
*
* @param {Boolean} options.formatForInput Whether to format the result for input
* @param {Boolean} options.formatForOutput} Whether to format the result for input
* @return {Object}
*/
Matrix.prototype.getAll = function () {
Matrix.prototype.getAll = function ({
formatForInput,
formatForOutput
} = {}) {
if (formatForInput) {
return this._formatForInput(this.map)
}

if (formatForOutput) {
return this._formatForOutput(this.map)
}

return this.map
}

Expand Down
12 changes: 9 additions & 3 deletions dadi/lib/model/acl/role.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ Role.prototype.resourceAdd = function (role, resource, access) {
},
rawOutput: true,
update: {
resources: resources.getAll()
resources: resources.getAll({
formatForInput: true
})
},
validate: false
})
Expand Down Expand Up @@ -273,7 +275,9 @@ Role.prototype.resourceUpdate = function (role, resource, access) {
},
rawOutput: true,
update: {
resources: resources.getAll()
resources: resources.getAll({
formatForInput: true
})
},
validate: false
})
Expand All @@ -300,7 +304,9 @@ Role.prototype.sanitise = function (role) {
if (key === 'resources') {
let resources = new ACLMatrix(output[key])

output[key] = resources.format()
output[key] = resources.getAll({
formatForOutput: true
})
}
}

Expand Down

0 comments on commit be5de8b

Please sign in to comment.