Skip to content
This repository has been archived by the owner on Aug 19, 2022. It is now read-only.

Policy endpoints #518

Merged
merged 5 commits into from
Apr 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Features, enhancements:
- Hooks support [commit](https://github.com/nearform/udaru/pull/503)
- Policy instance now returned when associating policy with user,team,org, which can be passed as param to DELETE to delete a specific instance
- Policy context variables added, which can be used in policy resources and policy condition elements
- Policy search endpoint added
- GET Policy variables endpoint added
- GET Policy endpoints added to users, teams and organizations

## 4.1.0 - March 12, 2018
Features, enhancements:
Expand Down
3 changes: 3 additions & 0 deletions docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ A brief overview of the Management API calls are as follows, see the [Swagger Do
|/authorization/organizations/{id}|DELETE|DELETE an organization|
|/authorization/organizations/{id}|GET|Get organization|
|/authorization/organizations/{id}|PUT|Update an organization|
|/authorization/organizations/{id}/policies|GET|List an organization's policies|
|/authorization/organizations/{id}/policies|DELETE|Clear all policies of the organization|
|/authorization/organizations/{id}/policies|POST|Clear and replace the policies of an organization|
|/authorization/organizations/{id}/policies|PUT|Add one or more policies to an organization|
Expand All @@ -61,6 +62,7 @@ A brief overview of the Management API calls are as follows, see the [Swagger Do
|/authorization/teams/{id}|GET|Fetch a team given its identifier|
|/authorization/teams/{id}/nest|PUT|Nest a team|
|/authorization/teams/{id}/nested|GET|Fetch a nested team given its identifier|
|/authorization/teams/{id}/policies|GET|List a team's policies|
|/authorization/teams/{id}/policies|PUT|Add one or more policies to a team|
|/authorization/teams/{id}/policies|DELETE|Clear all team policies|
|/authorization/teams/{id}/policies|POST|Clear and replace policies for a team|
Expand All @@ -78,6 +80,7 @@ A brief overview of the Management API calls are as follows, see the [Swagger Do
|/authorization/users/{id}|GET|Fetch a user given its identifier|
|/authorization/users/{id}|DELETE|Delete a user|
|/authorization/users/{id}|PUT|Update a user|
|/authorization/users/{id}/policies|GET|List a user's policies|
|/authorization/users/{id}/policies|DELETE|Clear all user's policies|
|/authorization/users/{id}/policies|PUT|Add one or more policies to a user|
|/authorization/users/{id}/policies|POST|Clear and replace policies for a user|
Expand Down
2 changes: 1 addition & 1 deletion docs/swagger/swagger-json.js

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions docs/swagger/swagger-ui-bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/swagger/swagger-ui-bundle.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/swagger/swagger-ui.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/swagger/swagger-ui.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/swagger/swagger.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
"pre-commit": [
"test:commit-check"
],
"dependencies": {},
"dependencies": {
},
"devDependencies": {
"depcheck": "^0.6.9",
"joi": "^13.1.2",
Expand Down
3 changes: 3 additions & 0 deletions packages/udaru-core/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const Actions = {
AddOrganizationPolicy: 'authorization:organizations:policy:add',
ReplaceOrganizationPolicy: 'authorization:organizations:policy:replace',
RemoveOrganizationPolicy: 'authorization:organizations:policy:remove',
ListOrganizationPolicies: 'authorization:organizations:policies',
AllOrganization: 'authorization:organizations:*',

// team
Expand All @@ -43,6 +44,7 @@ const Actions = {
RemoveTeamMember: 'authorization:teams:user:remove',
AllTeam: 'authorization:teams:*',
ListNestedTeams: 'authorization:teams:nestedlist',
ListTeamPolicies: 'authorization:teams:policies',

// user
CreateUser: 'authorization:users:create',
Expand All @@ -58,6 +60,7 @@ const Actions = {
ReplaceUserTeams: 'authorization:users:teams:replace',
DeleteUserTeams: 'authorization:users:teams:remove',
AllUser: 'authorization:users:*',
ListUserPolicies: 'authorization:users:policies',

// policy
CreatePolicy: 'authorization:policies:create',
Expand Down
6 changes: 6 additions & 0 deletions packages/udaru-core/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ const defaultConfig = {
Effect: 'Allow',
Action: [Action.ReadPolicyVariables],
Resource: [resources.policies({ organizationId: ':organizationId' })]
},
{
Effect: 'Allow',
Action: [Action.ListPolicies],
Resource: [resources.policies({ organizationId: ':organizationId' })]
}
]
}
Expand Down Expand Up @@ -105,6 +110,7 @@ const defaultConfig = {
Action.UpdateTeam,
Action.AddTeamMember,
Action.ReplaceTeamMember,
Action.ListTeamPolicies,
Action.RemoveTeamMember
],
Resource: [
Expand Down
9 changes: 6 additions & 3 deletions packages/udaru-core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ function buildUdaruCore (dbPool, config) {
addPolicies: hooks.wrap('organization:addPolicies', organizationOps.addOrganizationPolicies),
replacePolicies: hooks.wrap('organization:replacePolicies', organizationOps.replaceOrganizationPolicies),
deletePolicies: hooks.wrap('organization:deletePolicies', organizationOps.deleteOrganizationAttachedPolicies),
deletePolicy: hooks.wrap('organization:deletePolicy', organizationOps.deleteOrganizationAttachedPolicy)
deletePolicy: hooks.wrap('organization:deletePolicy', organizationOps.deleteOrganizationAttachedPolicy),
listPolicies: hooks.wrap('team:listPolicies', organizationOps.listOrganizationPolicies)
},

policies: {
Expand Down Expand Up @@ -87,7 +88,8 @@ function buildUdaruCore (dbPool, config) {
deleteMember: hooks.wrap('team:deleteMember', teamOps.deleteTeamMember),
listNestedTeams: hooks.wrap('team:listNestedTeams', teamOps.listNestedTeams),
search: hooks.wrap('team:search', teamOps.search),
searchUsers: hooks.wrap('team:searchUsers', teamOps.searchUsers)
searchUsers: hooks.wrap('team:searchUsers', teamOps.searchUsers),
listPolicies: hooks.wrap('team:listPolicies', teamOps.listTeamPolicies)
},

users: {
Expand All @@ -103,7 +105,8 @@ function buildUdaruCore (dbPool, config) {
listUserTeams: hooks.wrap('users:listUserTeams', userOps.listUserTeams),
replaceTeams: hooks.wrap('users:replaceTeams', userOps.replaceUserTeams),
deleteTeams: hooks.wrap('users:deleteTeams', userOps.deleteUserFromTeams),
search: hooks.wrap('users:search', userOps.search)
search: hooks.wrap('users:search', userOps.search),
listPolicies: hooks.wrap('users:listPolicies', userOps.listUserPolicies)
}
}
}
Expand Down
67 changes: 67 additions & 0 deletions packages/udaru-core/lib/ops/organizationOps.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,33 @@ function buildOrganizationOps (db, config) {
})
}

function loadOrganizationPolicies (job, next) {
const { id, offset, limit } = job

const sql = SQL`
SELECT pol.id, pol.name, pol.version, opol.variables, opol.policy_instance, COUNT(*) OVER() AS total_policies_count
FROM organization_policies opol, policies pol
WHERE opol.org_id = ${id}
AND opol.policy_id = pol.id
ORDER BY UPPER(pol.name)
`
if (limit) {
sql.append(SQL` LIMIT ${limit}`)
}
if (offset) {
sql.append(SQL` OFFSET ${offset}`)
}

job.client.query(sql, function (err, result) {
if (err) return next(Boom.badImplementation(err))

job.totalPoliciesCount = result.rowCount > 0 ? parseInt(result.rows[0].total_policies_count, 10) : 0
job.organization.policiesCount = result.rowCount
job.organization.policies = result.rows.map(mapping.policy.simple)
next()
})
}

/**
* Insert a new user and attach to it the organization admin policy
*
Expand Down Expand Up @@ -579,6 +606,45 @@ function buildOrganizationOps (db, config) {

client.query(sqlQuery, utils.boomErrorWrapper(cb))

return promise
},

/**
* List an organizations policies
*
* @param {Object} params { id, organizationId, limit, page }
* @param {Function} cb
*/
listOrganizationPolicies: function listOrganizationPolicies ({ id, organizationId, page = 1, limit }, cb) {
let promise = null
if (typeof cb !== 'function') [promise, cb] = asyncify()

Joi.validate({ id, organizationId, page, limit }, validationRules.listOrganizationPolicies, function (err) {
if (err) return cb(Boom.badRequest(err))

const offset = (page - 1) * limit
const job = {
id,
organizationId,
offset,
limit,
organization: {},
client: db
}

loadOrganizationPolicies(job, (err) => {
if (err) return cb(err)
const pageSize = limit || job.totalPoliciesCount
const result = {
page: page,
limit: pageSize,
total: job.totalPoliciesCount,
data: job.organization.policies
}
return cb(null, result)
})
})

return promise
}
}
Expand All @@ -592,6 +658,7 @@ function buildOrganizationOps (db, config) {
organizationOps.replaceOrganizationPolicies.validate = validationRules.replaceOrganizationPolicies
organizationOps.deleteOrganizationAttachedPolicies.validate = validationRules.deleteOrganizationPolicies
organizationOps.deleteOrganizationAttachedPolicy.validate = validationRules.deleteOrganizationPolicy
organizationOps.listOrganizationPolicies.validate = validationRules.listOrganizationPolicies

return organizationOps
}
Expand Down
55 changes: 53 additions & 2 deletions packages/udaru-core/lib/ops/teamOps.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,17 +270,26 @@ function buildTeamOps (db, config) {
}

function loadTeamPolicies (job, next) {
const { id } = job
const { id, offset, limit } = job

const sql = SQL`
SELECT pol.id, pol.name, pol.version, tpol.variables, tpol.policy_instance
SELECT pol.id, pol.name, pol.version, tpol.variables, tpol.policy_instance, COUNT(*) OVER() AS total_policies_count
FROM team_policies tpol, policies pol
WHERE tpol.team_id = ${id}
AND tpol.policy_id = pol.id
ORDER BY UPPER(pol.name)
`
if (limit) {
sql.append(SQL` LIMIT ${limit}`)
}
if (offset) {
sql.append(SQL` OFFSET ${offset}`)
}

job.client.query(sql, function (err, result) {
if (err) return next(Boom.badImplementation(err))

job.totalPoliciesCount = result.rowCount > 0 ? parseInt(result.rows[0].total_policies_count, 10) : 0
job.team.policies = result.rows.map(mapping.policy.simple)
next()
})
Expand Down Expand Up @@ -429,6 +438,47 @@ function buildTeamOps (db, config) {
return promise
},

/**
* Fetch a team's policies
*
* @param {params} params { id, page, limit }
* @param {Function} cb
*/
listTeamPolicies: function listTeamPolicies ({ id, page = 1, limit, organizationId }, cb) {
let promise = null
if (typeof cb !== 'function') [promise, cb] = asyncify()

Joi.validate({ id, page, limit, organizationId }, validationRules.listTeamPolicies, function (err) {
if (err) return cb(Boom.badRequest(err))

const pageLimit = limit || _.get(config, 'authorization.defaultPageSize')
const offset = (page - 1) * pageLimit

const job = {
id: id,
organizationId: organizationId,
offset: offset,
limit: pageLimit,
team: {},
client: db
}

loadTeamPolicies(job, (err) => {
if (err) return cb(err)
const pageSize = pageLimit || job.totalPoliciesCount
const result = {
page: page,
limit: pageSize,
total: job.totalPoliciesCount,
data: job.team.policies
}
return cb(null, result)
})
})

return promise
},

/**
* Fetch specific team data
*
Expand Down Expand Up @@ -1041,6 +1091,7 @@ function buildTeamOps (db, config) {
teamOps.addTeamPolicies.validate = validationRules.addTeamPolicies
teamOps.listNestedTeams.validate = validationRules.listNestedTeams
teamOps.searchUsers.validate = validationRules.searchUsers
teamOps.listTeamPolicies.validate = validationRules.listTeamPolicies

return teamOps
}
Expand Down
68 changes: 68 additions & 0 deletions packages/udaru-core/lib/ops/userOps.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,33 @@ function buildUserOps (db, config) {
})
}

function readUserPolicies (job, next) {
const { id, offset, limit } = job

const sql = SQL`
SELECT pol.id, pol.name, pol.version, upol.variables, upol.policy_instance, COUNT(*) OVER() AS total_policies_count
FROM user_policies upol, policies pol
WHERE upol.user_id = ${id}
AND upol.policy_id = pol.id
ORDER BY UPPER(pol.name)
`
if (limit) {
sql.append(SQL` LIMIT ${limit}`)
}
if (offset) {
sql.append(SQL` OFFSET ${offset}`)
}

job.client.query(sql, function (err, result) {
if (err) return next(Boom.badImplementation(err))

job.totalPoliciesCount = result.rowCount > 0 ? parseInt(result.rows[0].total_policies_count, 10) : 0
job.user.policiesCount = result.rowCount
job.user.policies = result.rows.map(mapping.policy.simple)
next()
})
}

function clearUserTeams (job, next) {
const { id } = job

Expand Down Expand Up @@ -661,6 +688,46 @@ function buildUserOps (db, config) {
return promise
},

/**
* List a users policies
* Does not go recursively to parent teams
*
* @param {Object} params { id, organizationId, limit, page }
* @param {Function} cb
*/
listUserPolicies: function listUserPolicies ({ id, organizationId, page = 1, limit }, cb) {
let promise = null
if (typeof cb !== 'function') [promise, cb] = asyncify()

Joi.validate({ id, organizationId, page, limit }, validationRules.listUserPolicies, function (err) {
if (err) return cb(Boom.badRequest(err))

const offset = (page - 1) * limit
const job = {
id,
organizationId,
offset,
limit,
user: {},
client: db
}

readUserPolicies(job, (err) => {
if (err) return cb(err)
const pageSize = limit || job.totalPoliciesCount
const result = {
page: page,
limit: pageSize,
total: job.totalPoliciesCount,
data: job.user.policies
}
return cb(null, result)
})
})

return promise
},

/**
* Return the user organizationId
*
Expand Down Expand Up @@ -782,6 +849,7 @@ function buildUserOps (db, config) {
userOps.listUserTeams.validate = validationRules.listUserTeams
userOps.deleteUserFromTeams.validate = validationRules.deleteUserFromTeams
userOps.search.validate = validationRules.searchUser
userOps.listUserPolicies.validate = validationRules.listUserPolicies

return userOps
}
Expand Down
Loading