From 1371578bdb2f79de10a1323131fd8b1ce8106221 Mon Sep 17 00:00:00 2001 From: jimmymintzer Date: Wed, 7 Mar 2018 18:42:14 -0500 Subject: [PATCH] Nested Teams Endpoint (#477) * add nested teams to udaru core * add nested endpoint * add e2e test for nested team limit * updating version and changes.md, updated pbac to 0.3.0 * use the buildParams directly to create base resource for user requests * return 404 if nested team is not found --- CHANGES.md | 6 ++ docs/swagger/swagger-json.js | 2 +- lib/config/auth.js | 1 + lib/core/index.js | 3 +- lib/core/lib/mapping.js | 14 +++ lib/core/lib/ops/teamOps.js | 52 +++++++++ lib/core/lib/ops/validation.js | 6 ++ lib/plugin/routes/public/teams.js | 43 ++++++++ lib/plugin/security/hapi-auth-validation.js | 12 +-- lib/plugin/swagger.js | 15 +++ package-lock.json | 26 +++-- package.json | 4 +- test/integration/endToEnd/teams.test.js | 111 ++++++++++++++++++++ test/integration/teamOps.test.js | 97 +++++++++++++++++ 14 files changed, 369 insertions(+), 23 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 36d6d3b7..8714919f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,9 @@ +## 4.2.0 - February 15, 2018 +Features, enhancements: +- Nested teams endpoint [commit] (https://github.com/nearform/udaru/pull/477) +- Team search endpoint [commit] (https://github.com/nearform/udaru/pull/473) +- Updated PBAC to version 0.3.0 (lodash vulnerability) + ## 4.0.1 - February 15, 2018 Fixes: - Migration scripts 006 & 007 (removed public schema) diff --git a/docs/swagger/swagger-json.js b/docs/swagger/swagger-json.js index a2695266..a1d35152 100644 --- a/docs/swagger/swagger-json.js +++ b/docs/swagger/swagger-json.js @@ -1 +1 @@ -var swaggerJSON = {"swagger":"2.0","host":"localhost:8080","basePath":"/","schemes":["http"],"info":{"title":"Udaru API Documentation","version":"3.2.0","description":"This page documents Udaru's API endpoints, along with their various inputs and outputs. For more information about Udaru please see the Documentation Site."},"tags":[{"name":"policies","description":"Manage policy objects"},{"name":"organizations","description":"Manage organizations"},{"name":"teams","description":"Manage teams within an organization"},{"name":"users","description":"Manage users within an organization"},{"name":"authorization","description":"Manage the actions a user can perform against a resource"},{"name":"private","description":"Endpoints that require a service key"},{"name":"monitoring","description":"Endpoints for monitoring and uptime"}],"paths":{"/ping":{"get":{"summary":"Ping endpoint","operationId":"getPing","description":"The GET /ping endpoint will return 200 if the server is up and running.","tags":["monitoring"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/authorization/organizations":{"get":{"summary":"List all the organizations","operationId":"getAuthorizationOrganizations","description":"The GET /authorization/organizations endpoint returns a list of all organizations.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedOrganizations"},"description":"Successful"}}},"post":{"summary":"Create an organization","operationId":"postAuthorizationOrganizations","description":"The POST /authorization/organizations endpoint creates a new organization, the default organization admin policy and (if provided) its admin.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"in":"body","name":"body","schema":{"$ref":"#/definitions/CreateOrgPayload"}}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/OrganizationAndUser"},"description":"Successful"}}}},"/authorization/policies":{"get":{"summary":"Fetch all the defined policies","operationId":"getAuthorizationPolicies","description":"The GET /authorization/policies endpoint returns a list of all the defined policies\nthe policies will contain only the ID, version and name. No statements.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["policies"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedPolicies"},"description":"Successful"}}},"post":{"summary":"Create a policy for the current user organization","operationId":"postAuthorizationPolicies","description":"The POST /authorization/policies endpoint is a private endpoint. It can be accessed only using a service key.\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","name":"sig","in":"query","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/CreatePolicyPayload"}}],"tags":["policies","private"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}}},"/authorization/shared-policies":{"get":{"summary":"Fetch all the defined shared policies","operationId":"getAuthorizationSharedpolicies","description":"The GET /authorization/shared-policies endpoint returns a list of all the defined policies\nthe policies will contain only the ID, version and name. No statements.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["policies"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedPolicies"},"description":"Successful"}}},"post":{"summary":"Create a policy shared across organizations","operationId":"postAuthorizationSharedpolicies","description":"The POST /authorization/shared-policies endpoint is a private endpoint. It can be accessed only using a service key.\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","name":"sig","in":"query","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/CreateSharedPoliciesPayload"}}],"tags":["policies","private"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}}},"/authorization/teams":{"get":{"summary":"Fetch all teams from the current user organization","operationId":"getAuthorizationTeams","description":"The GET /authorization/teams endpoint returns a list of all teams from the current organization.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["teams"],"responses":{"200":{"description":"Note: teams users and policies are not populated in paged teams list","schema":{"$ref":"#/definitions/PagedTeams"}}}},"post":{"summary":"Create a team","operationId":"postAuthorizationTeams","description":"The POST /authorization/teams endpoint creates a new team from its payload data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"in":"body","name":"body","schema":{"$ref":"#/definitions/CreateTeamPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}},"/authorization/users":{"get":{"summary":"Fetch all users from the current user organization","operationId":"getAuthorizationUsers","description":"The GET /authorization/users endpoint returns a list of all users from the current organization.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedUsers"},"description":"Successful"}}},"post":{"summary":"Create a new user","operationId":"postAuthorizationUsers","description":"The POST /authorization/users endpoint creates a new user given its data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"in":"body","name":"body","schema":{"$ref":"#/definitions/CreateUserPayload"}}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}}},"/authorization/list/{userId}":{"get":{"summary":"List all the actions a user can perform on a list of resources","operationId":"getAuthorizationListUserid","description":"The GET /authorization/list/{userId} endpoint returns a list of all the actions a user\ncan perform on a given list of resources.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"userId","in":"path","required":true},{"type":"array","description":"A list of Resources","x-constraint":{"single":true},"items":{"type":"string","description":"A single resource"},"collectionFormat":"multi","name":"resources","in":"query","required":true}],"tags":["authorization"],"responses":{"200":{"schema":{"$ref":"#/definitions/UserActionsOnResources","type":"array"},"description":"Successful"}}}},"/authorization/organizations/{id}":{"get":{"summary":"Get organization","operationId":"getAuthorizationOrganizationsId","description":"The GET /authorization/organizations/{id} endpoint returns a single organization data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/Organization"},"description":"Successful"}}},"delete":{"summary":"DELETE an organization","operationId":"deleteAuthorizationOrganizationsId","description":"The DELETE /authorization/organizations/{id} endpoint will delete an organization.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["organizations"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Update an organization","operationId":"putAuthorizationOrganizationsId","description":"The PUT /authorization/organizations/{id} endpoint will update an organization name and description","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/UpdateOrgPayload"}}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/Organization"},"description":"Successful"}}}},"/authorization/policies/{id}":{"get":{"summary":"Fetch a single policy by ID","operationId":"getAuthorizationPoliciesId","description":"The GET /authorization/policies/{id} endpoint returns a policy based on its ID.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["policies"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}},"delete":{"summary":"Delete a policy","operationId":"deleteAuthorizationPoliciesId","description":"The DELETE /authorization/policies/{id} endpoint is a private endpoint. It can be accessed only using a service key.\n\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","name":"sig","in":"query","required":true}],"tags":["policies","private"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Update a policy of the current user organization","operationId":"putAuthorizationPoliciesId","description":"The PUT /authorization/policies/{id} endpoint is a private endpoint. It can be accessed only using a service key.\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","name":"sig","in":"query","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/UpdatePolicyPayload"}}],"tags":["policies","private"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}}},"/authorization/shared-policies/{id}":{"get":{"summary":"Fetch a single shared policy","operationId":"getAuthorizationSharedpoliciesId","description":"The GET /authorization/shared-policies/{id} endpoint returns a policy based on its ID.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["policies"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}},"delete":{"summary":"Delete a shared policy","operationId":"deleteAuthorizationSharedpoliciesId","description":"The DELETE /authorization/shared-policies/{id} endpoint is a private endpoint. It can be accessed only using a service key.\n\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","name":"sig","in":"query","required":true}],"tags":["policies","private"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Update a shared policy","operationId":"putAuthorizationSharedpoliciesId","description":"The PUT /authorization/shared-policies/{id} endpoint is a private endpoint. It can be accessed only using a service key.\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","name":"sig","in":"query","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/UpdateSharedPolicyPayload"}}],"tags":["policies","private"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}}},"/authorization/teams/{id}":{"get":{"summary":"Fetch a team given its identifier","operationId":"getAuthorizationTeamsId","description":"The GET /authorization/teams/{id} endpoint returns a single team data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}},"delete":{"summary":"Delete a team","operationId":"deleteAuthorizationTeamsId","description":"The DELETE /authorization/teams endpoint deletes a team.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["teams"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Update a team","operationId":"putAuthorizationTeamsId","description":"The PUT /authorization/teams/{id} endpoint updates a team data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/UpdateTeamPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}},"/authorization/users/{id}":{"get":{"summary":"Fetch a user given its identifier","operationId":"getAuthorizationUsersId","description":"The GET /authorization/users/{id} endpoint returns a single user data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}},"delete":{"summary":"Delete a user","operationId":"deleteAuthorizationUsersId","description":"The DELETE /authorization/users/{id} endpoint deletes a user.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["users"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Update a user","operationId":"putAuthorizationUsersId","description":"The PUT /authorization/users/{id} endpoint updates the user data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/UpdateUserPayload"}}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}}},"/authorization/list/{userId}/{resource*}":{"get":{"summary":"List all the actions a user can perform on a resource","operationId":"getAuthorizationListUseridResource","description":"The GET /authorization/list/{userId}/{resource} endpoint returns a list of all the actions a user\ncan perform on a given resource.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"userId","in":"path","required":true},{"type":"string","description":"The resource that the user wants to perform the action on","name":"resource","in":"path","required":true}],"tags":["authorization"],"responses":{"200":{"schema":{"$ref":"#/definitions/UserActions"},"description":"Successful"}}}},"/authorization/teams/{id}/users":{"get":{"summary":"Fetch team users given its identifier","operationId":"getAuthorizationTeamsIdUsers","description":"The GET /authorization/teams/{id}/users endpoint returns the team users and pagination metadata.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedUsers"},"description":"Successful"}}},"post":{"summary":"Replace team users with the given ones","operationId":"postAuthorizationTeamsIdUsers","description":"The POST /authorization/teams/{id}/users endpoint replaces all team users. Existing team users are removed.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/ReplaceTeamUsersPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}},"delete":{"summary":"Delete all team users","operationId":"deleteAuthorizationTeamsIdUsers","description":"The DELETE /authorization/teams/{id}/users endpoint removes all team users.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["teams"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Add team users","operationId":"putAuthorizationTeamsIdUsers","description":"The PUT /authorization/teams/{id}/users endpoint adds one or more team users.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/AddTeamUsersPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}},"/authorization/users/{id}/teams":{"get":{"summary":"Fetch all teams to which the user belongs to. Does not fetch parent teams.","operationId":"getAuthorizationUsersIdTeams","description":"The GET /authorization/users/{id}/teams endpoint returns a list of teams to which the user belongs to.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedTeamRefs"},"description":"Successful"}}},"post":{"summary":"Clear and replace user teams","operationId":"postAuthorizationUsersIdTeams","description":"The POST /authorization/users/{id}/teams endpoint replaces all the user teams. This can be use to move a user from a team to another (or a set of teams to another).\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/ReplaceUserTeamsPayload"}}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}},"delete":{"summary":"Delete teams for a user","operationId":"deleteAuthorizationUsersIdTeams","description":"The DELETE /authorization/users/{id}/teams endpoint deletes user from all her teams.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}}},"/authorization/access/{userId}/{action}/{resource*}":{"get":{"summary":"Authorize user action against a resource","operationId":"getAuthorizationAccessUseridActionResource","description":"The GET /authorization/access/{userId}/{action}/{resource} endpoint answers if a user can perform an action\non a resource.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"userId","in":"path","required":true},{"type":"string","description":"The action to check","name":"action","in":"path","required":true},{"type":"string","description":"The resource that the user wants to perform the action on","name":"resource","in":"path","required":true}],"tags":["authorization"],"responses":{"200":{"schema":{"$ref":"#/definitions/Access"},"description":"Successful"}}}},"/authorization/organizations/{id}/policies":{"post":{"summary":"Clear and replace the policies of an organization","operationId":"postAuthorizationOrganizationsIdPolicies","description":"The POST /authorization/organizations/{id}/policies endpoint replaces all the organization policies. The existing organization policies are removed.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/ReplaceOrgPoliciesPayload"}}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/Organization"},"description":"Successful"}}},"delete":{"summary":"Clear all policies of the organization","operationId":"deleteAuthorizationOrganizationsIdPolicies","description":"The DELETE /authorization/organizations/{id}/policies endpoint removes all the organization policies.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["organizations"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Add one or more policies to an organization","operationId":"putAuthorizationOrganizationsIdPolicies","description":"The PUT /authorization/organizations/{id}/policies endpoint adds one or more policies to an organization.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/AddPoliciesToOrgPayload"}}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/Organization"},"description":"Successful"}}}},"/authorization/teams/{id}/policies":{"post":{"summary":"Clear and replace policies for a team","operationId":"postAuthorizationTeamsIdPolicies","description":"The POST /authorization/teams/{id}/policies endpoint replaces all the team policies. Existing policies are removed.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/ReplaceTeamPoliciesPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}},"delete":{"summary":"Clear all team policies","operationId":"deleteAuthorizationTeamsIdPolicies","description":"The DELETE /authorization/teams/{id}/policies endpoint removes all the team policies.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["teams"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Add one or more policies to a team","operationId":"putAuthorizationTeamsIdPolicies","description":"The PUT /authorization/teams/{id}/policies endpoint adds one or more new policies to a team.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/AddPoliciesToTeamPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}},"/authorization/users/{id}/policies":{"post":{"summary":"Clear and replace policies for a user","operationId":"postAuthorizationUsersIdPolicies","description":"The POST /authorization/users/{id}/policies endpoint replaces all the user policies. Existing user policies are removed.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/ReplaceUserPoliciesPayload"}}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}},"delete":{"summary":"Clear all user's policies","operationId":"deleteAuthorizationUsersIdPolicies","description":"The DELETE /authorization/users/{id}/policies endpoint removes all the user policies.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["users"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Add one or more policies to a user","operationId":"putAuthorizationUsersIdPolicies","description":"The PUT /authorization/users/{id}/policies endpoint adds one or more policies to a user.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/AddUserPoliciesPayload"}}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}}},"/authorization/organizations/{id}/policies/{policyId}":{"delete":{"summary":"Remove a policy from one organization","operationId":"deleteAuthorizationOrganizationsIdPoliciesPolicyid","description":"The DELETE /authorization/organizations/{id}/policies/{policyId} endpoint removes a specific policy from the organization.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","description":"Policy ID","maxLength":128,"name":"policyId","in":"path","required":true}],"tags":["organizations"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/authorization/teams/{teamId}/policies/{policyId}":{"delete":{"summary":"Remove a team policy","operationId":"deleteAuthorizationTeamsTeamidPoliciesPolicyid","description":"The DELETE /authorization/teams/{teamId}/policies/{policyId} endpoint removes a specific team policy.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"teamId","in":"path","required":true},{"type":"string","description":"Policy ID","maxLength":128,"name":"policyId","in":"path","required":true}],"tags":["teams"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/authorization/teams/{id}/users/{userId}":{"delete":{"summary":"Delete one team member","operationId":"deleteAuthorizationTeamsIdUsersUserid","description":"The DELETE /authorization/teams/{id}/users/{userId} endpoint removes one user from a team.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","description":"User ID","maxLength":128,"name":"userId","in":"path","required":true}],"tags":["teams"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/authorization/users/{userId}/policies/{policyId}":{"delete":{"summary":"Remove a user's policy","operationId":"deleteAuthorizationUsersUseridPoliciesPolicyid","description":"The DELETE /authorization/users/{userId}/policies/{policyId} endpoint removes a specific user's policy.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"userId","in":"path","required":true},{"type":"string","description":"Policy ID","maxLength":128,"name":"policyId","in":"path","required":true}],"tags":["users"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/authorization/teams/{id}/unnest":{"put":{"summary":"Unnest a team","operationId":"putAuthorizationTeamsIdUnnest","description":"The PUT /authorization/teams/{id}/unnest endpoint unnests a team.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}},"/authorization/teams/{id}/nest":{"put":{"summary":"Nest a team","operationId":"putAuthorizationTeamsIdNest","description":"The PUT /authorization/teams/{id}/nest endpoint nests a team.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/NestTeamPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}}},"definitions":{"MetaData":{"type":"object"},"Variables":{"type":"object"},"PolicyRef":{"type":"object","properties":{"id":{"type":"string","description":"Policy ID"},"version":{"type":"string","description":"Policy version"},"name":{"type":"string","description":"Policy name"},"variables":{"$ref":"#/definitions/Variables"}}},"PolicyRefs":{"type":"array","description":"Policy Refs","items":{"$ref":"#/definitions/PolicyRef"}},"Organization":{"type":"object","properties":{"id":{"type":"string","description":"Organization ID"},"name":{"type":"string","description":"Organization name"},"description":{"type":"string","description":"Organization description"},"metadata":{"$ref":"#/definitions/MetaData"},"policies":{"$ref":"#/definitions/PolicyRefs","type":"array"}}},"Organizations":{"type":"array","description":"items","items":{"$ref":"#/definitions/Organization"}},"PagedOrganizations":{"type":"object","properties":{"page":{"type":"integer","description":"Page number, starts from 1","minimum":1},"limit":{"type":"integer","description":"Items per page","minimum":1},"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/Organizations","type":"array"}}},"Actions":{"type":"array","description":"Action to perform on resource","items":{"type":"string"}},"Resources":{"type":"array","description":"Resource that the statement covers","items":{"type":"string"}},"Condition":{"type":"object"},"Statement":{"type":"object","properties":{"Effect":{"type":"string","description":"Statement result","enum":["Allow","Deny"]},"Action":{"$ref":"#/definitions/Actions","type":"array"},"Resource":{"$ref":"#/definitions/Resources","type":"array"},"Sid":{"type":"string","description":"Statement ID"},"Condition":{"$ref":"#/definitions/Condition"}}},"Statements":{"type":"array","items":{"$ref":"#/definitions/Statement"}},"PolicyStatements":{"type":"object","properties":{"Statement":{"$ref":"#/definitions/Statements","type":"array"}}},"Policy":{"type":"object","properties":{"id":{"type":"string","description":"Policy ID"},"version":{"type":"string","description":"Policy version"},"name":{"type":"string","description":"Policy name"},"statements":{"$ref":"#/definitions/PolicyStatements"}}},"Policies":{"type":"array","description":"items","items":{"$ref":"#/definitions/Policy"}},"PagedPolicies":{"type":"object","properties":{"page":{"type":"integer","description":"Page number, starts from 1","minimum":1},"limit":{"type":"integer","description":"Items per page","minimum":1},"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/Policies","type":"array"}}},"UserRef":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"name":{"type":"string","description":"User name"}}},"UserRefs":{"type":"array","description":"User refs","items":{"$ref":"#/definitions/UserRef"}},"Team":{"type":"object","properties":{"id":{"type":"string","description":"Team ID"},"name":{"type":"string","description":"Team name"},"description":{"type":"string","description":"Team description"},"path":{"type":"string"},"metadata":{"$ref":"#/definitions/MetaData"},"users":{"$ref":"#/definitions/UserRefs","type":"array"},"policies":{"$ref":"#/definitions/PolicyRefs","type":"array"},"organizationId":{"type":"string","description":"Organization ID to which the team belongs to"},"usersCount":{"type":"number","description":"Number of team users. Sub team users not counted."}}},"Teams":{"type":"array","description":"items","items":{"$ref":"#/definitions/Team"}},"PagedTeams":{"type":"object","description":"Note: teams users and policies are not populated in paged teams list","properties":{"page":{"type":"integer","description":"Page number, starts from 1","minimum":1},"limit":{"type":"integer","description":"Items per page","minimum":1},"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/Teams","type":"array"}}},"TeamRef":{"type":"object","properties":{"id":{"type":"string","description":"Team ID"},"name":{"type":"string","description":"Team name"}}},"TeamRefs":{"type":"array","description":"Team refs","items":{"$ref":"#/definitions/TeamRef"}},"User":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"name":{"type":"string","description":"User name"},"organizationId":{"type":"string","description":"Organization ID to which the user belongs to"},"metadata":{"$ref":"#/definitions/MetaData"},"teams":{"$ref":"#/definitions/TeamRefs","type":"array"},"policies":{"$ref":"#/definitions/PolicyRefs","type":"array"}}},"Users":{"type":"array","description":"items","items":{"$ref":"#/definitions/User"}},"PagedUsers":{"type":"object","properties":{"page":{"type":"integer","description":"Page number, starts from 1","minimum":1},"limit":{"type":"integer","description":"Items per page","minimum":1},"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/Users","type":"array"}}},"UserActionsArray":{"type":"array","items":{"type":"string"}},"UserActionOnResource":{"type":"object","properties":{"resource":{"type":"string"},"actions":{"$ref":"#/definitions/UserActionsArray","type":"array"}}},"UserActionsOnResources":{"type":"array","items":{"$ref":"#/definitions/UserActionOnResource"}},"UserActions":{"type":"object","properties":{"actions":{"$ref":"#/definitions/UserActionsArray","type":"array"}}},"PagedTeamRefs":{"type":"object","properties":{"page":{"type":"integer","description":"Page number, starts from 1","minimum":1},"limit":{"type":"integer","description":"Items per page","minimum":1},"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/TeamRefs","type":"array"}}},"Access":{"type":"object","properties":{"access":{"type":"boolean"}}},"UserPayload":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"name":{"type":"string","description":"User name"}},"required":["name"]},"CreateOrgPayload":{"type":"object","properties":{"id":{"type":"string","description":"Organization ID","maxLength":128},"name":{"type":"string","description":"Name","maxLength":64},"description":{"type":"string","description":"Description"},"metadata":{"$ref":"#/definitions/MetaData"},"user":{"$ref":"#/definitions/UserPayload"}},"required":["name","description"]},"OrganizationAndUser":{"type":"object","properties":{"organization":{"$ref":"#/definitions/Organization"},"user":{"$ref":"#/definitions/UserRef"}}},"Action":{"type":"array","minItems":1,"items":{"type":"string"}},"Resource":{"type":"array","minItems":1,"items":{"type":"string"}},"StatementObject":{"type":"object","properties":{"Effect":{"type":"string","enum":["Allow","Deny"]},"Action":{"$ref":"#/definitions/Action","type":"array"},"Resource":{"$ref":"#/definitions/Resource","type":"array"},"Sid":{"type":"string"},"Condition":{"$ref":"#/definitions/Condition"}}},"StatementsArray":{"type":"array","minItems":1,"items":{"$ref":"#/definitions/StatementObject"}},"StatementsObject":{"type":"object","properties":{"Statement":{"$ref":"#/definitions/StatementsArray","type":"array"}}},"CreatePolicyPayload":{"type":"object","properties":{"id":{"type":"string","description":"Policy ID","maxLength":128},"name":{"type":"string","description":"Name","maxLength":64},"version":{"type":"string","description":"Version number"},"statements":{"$ref":"#/definitions/StatementsObject"}},"required":["name","version","statements"]},"CreateSharedPoliciesPayload":{"type":"object","properties":{"id":{"type":"string","description":"Policy ID","maxLength":128},"name":{"type":"string","description":"Name","maxLength":64},"version":{"type":"string","description":"Version number"},"statements":{"$ref":"#/definitions/StatementsObject"}},"required":["name","version"]},"CreateTeamPayload":{"type":"object","properties":{"id":{"type":"string","description":"The ID to be used for the new team. Only alphanumeric characters and underscore are supported","maxLength":128,"pattern":"/^[0-9a-zA-Z_]+$/"},"name":{"type":"string","description":"Name","maxLength":30},"description":{"type":"string","description":"Description"},"metadata":{"$ref":"#/definitions/MetaData"},"user":{"$ref":"#/definitions/UserPayload"}},"required":["name","description"]},"CreateUserPayload":{"type":"object","properties":{"id":{"type":"string","description":"User ID","maxLength":128},"name":{"type":"string","description":"Name","maxLength":255},"metadata":{"$ref":"#/definitions/MetaData"}},"required":["name"]},"PolicyIdsArray":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","minItems":1,"items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString","PolicyIdObject"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"ReplaceOrgPoliciesPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/PolicyIdsArray","type":"array"}},"required":["policies"]},"Model 1":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"ReplaceTeamPoliciesPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/Model 1","type":"array"}},"required":["policies"]},"UsersArray":{"type":"array","description":"User IDs","items":{"type":"string"}},"ReplaceTeamUsersPayload":{"type":"object","properties":{"users":{"$ref":"#/definitions/UsersArray","type":"array"}},"required":["users"]},"Model 2":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"ReplaceUserPoliciesPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/Model 2","type":"array"}},"required":["policies"]},"TeamsArray":{"type":"array","description":"Teams IDs","items":{"type":"string"}},"ReplaceUserTeamsPayload":{"type":"object","properties":{"teams":{"$ref":"#/definitions/TeamsArray","type":"array"}},"required":["teams"]},"UpdateOrgPayload":{"type":"object","properties":{"name":{"type":"string","description":"Name","maxLength":64},"description":{"type":"string","description":"Description"},"metadata":{"$ref":"#/definitions/MetaData"}},"required":["name","description"]},"UpdatePolicyPayload":{"type":"object","properties":{"version":{"type":"string","description":"Version number"},"name":{"type":"string","description":"Name","maxLength":64},"statements":{"$ref":"#/definitions/StatementsObject"}},"required":["version","name"]},"UpdateSharedPolicyPayload":{"type":"object","properties":{"version":{"type":"string","description":"Version number"},"name":{"type":"string","description":"Name","maxLength":64},"statements":{"$ref":"#/definitions/StatementsObject"}},"required":["version","name"]},"UpdateTeamPayload":{"type":"object","properties":{"name":{"type":"string","description":"Name","maxLength":30},"description":{"type":"string","description":"Description"},"metadata":{"$ref":"#/definitions/MetaData"}}},"UpdateUserPayload":{"type":"object","properties":{"name":{"type":"string","description":"Name","maxLength":255},"metadata":{"$ref":"#/definitions/MetaData"}},"required":["name"]},"Model 3":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"AddPoliciesToOrgPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/Model 3","type":"array"}},"required":["policies"]},"Model 4":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"AddPoliciesToTeamPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/Model 4","type":"array"}},"required":["policies"]},"AddTeamUsersPayload":{"type":"object","properties":{"users":{"$ref":"#/definitions/UsersArray","type":"array"}},"required":["users"]},"NestTeamPayload":{"type":"object","properties":{"parentId":{"type":"string","description":"Parent ID"}},"required":["parentId"]},"Model 5":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"AddUserPoliciesPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/Model 5","type":"array"}},"required":["policies"]}},"x-alt-definitions":{"variables":{"type":"object"},"PolicyIdObject":{"type":"object","description":"Policy Id Object","properties":{"id":{"type":"string","description":"Policy Id String","maxLength":128},"variables":{"$ref":"#/x-alt-definitions/variables"}},"required":["id"]}}} \ No newline at end of file +var swaggerJSON = {"swagger":"2.0","host":"localhost:8080","basePath":"/","schemes":["http"],"info":{"title":"Udaru API Documentation","version":"4.2.0","description":"This page documents Udaru's API endpoints, along with their various inputs and outputs. For more information about Udaru please see the Documentation Site."},"tags":[{"name":"policies","description":"Manage policy objects"},{"name":"organizations","description":"Manage organizations"},{"name":"teams","description":"Manage teams within an organization"},{"name":"users","description":"Manage users within an organization"},{"name":"authorization","description":"Manage the actions a user can perform against a resource"},{"name":"private","description":"Endpoints that require a service key"},{"name":"monitoring","description":"Endpoints for monitoring and uptime"}],"paths":{"/ping":{"get":{"summary":"Ping endpoint","operationId":"getPing","description":"The GET /ping endpoint will return 200 if the server is up and running.","tags":["monitoring"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/authorization/organizations":{"get":{"summary":"List all the organizations","operationId":"getAuthorizationOrganizations","description":"The GET /authorization/organizations endpoint returns a list of all organizations.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedOrganizations"},"description":"Successful"}}},"post":{"summary":"Create an organization","operationId":"postAuthorizationOrganizations","description":"The POST /authorization/organizations endpoint creates a new organization, the default organization admin policy and (if provided) its admin.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"in":"body","name":"body","schema":{"$ref":"#/definitions/CreateOrgPayload"}}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/OrganizationAndUser"},"description":"Successful"}}}},"/authorization/policies":{"get":{"summary":"Fetch all the defined policies","operationId":"getAuthorizationPolicies","description":"The GET /authorization/policies endpoint returns a list of all the defined policies\nthe policies will contain only the ID, version and name. No statements.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["policies"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedPolicies"},"description":"Successful"}}},"post":{"summary":"Create a policy for the current user organization","operationId":"postAuthorizationPolicies","description":"The POST /authorization/policies endpoint is a private endpoint. It can be accessed only using a service key.\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","name":"sig","in":"query","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/CreatePolicyPayload"}}],"tags":["policies","private"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}}},"/authorization/shared-policies":{"get":{"summary":"Fetch all the defined shared policies","operationId":"getAuthorizationSharedpolicies","description":"The GET /authorization/shared-policies endpoint returns a list of all the defined policies\nthe policies will contain only the ID, version and name. No statements.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["policies"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedPolicies"},"description":"Successful"}}},"post":{"summary":"Create a policy shared across organizations","operationId":"postAuthorizationSharedpolicies","description":"The POST /authorization/shared-policies endpoint is a private endpoint. It can be accessed only using a service key.\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","name":"sig","in":"query","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/CreateSharedPoliciesPayload"}}],"tags":["policies","private"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}}},"/authorization/teams":{"get":{"summary":"Fetch all teams from the current user organization","operationId":"getAuthorizationTeams","description":"The GET /authorization/teams endpoint returns a list of all teams from the current organization.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["teams"],"responses":{"200":{"description":"Note: teams users and policies are not populated in paged teams list","schema":{"$ref":"#/definitions/PagedTeams"}}}},"post":{"summary":"Create a team","operationId":"postAuthorizationTeams","description":"The POST /authorization/teams endpoint creates a new team from its payload data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"in":"body","name":"body","schema":{"$ref":"#/definitions/CreateTeamPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}},"/authorization/users":{"get":{"summary":"Fetch all users from the current user organization","operationId":"getAuthorizationUsers","description":"The GET /authorization/users endpoint returns a list of all users from the current organization.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedUsers"},"description":"Successful"}}},"post":{"summary":"Create a new user","operationId":"postAuthorizationUsers","description":"The POST /authorization/users endpoint creates a new user given its data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"in":"body","name":"body","schema":{"$ref":"#/definitions/CreateUserPayload"}}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}}},"/authorization/list/{userId}":{"get":{"summary":"List all the actions a user can perform on a list of resources","operationId":"getAuthorizationListUserid","description":"The GET /authorization/list/{userId} endpoint returns a list of all the actions a user\ncan perform on a given list of resources.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"userId","in":"path","required":true},{"type":"array","description":"A list of Resources","x-constraint":{"single":true},"items":{"type":"string","description":"A single resource"},"collectionFormat":"multi","name":"resources","in":"query","required":true}],"tags":["authorization"],"responses":{"200":{"schema":{"$ref":"#/definitions/UserActionsOnResources","type":"array"},"description":"Successful"}}}},"/authorization/organizations/{id}":{"get":{"summary":"Get organization","operationId":"getAuthorizationOrganizationsId","description":"The GET /authorization/organizations/{id} endpoint returns a single organization data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/Organization"},"description":"Successful"}}},"delete":{"summary":"DELETE an organization","operationId":"deleteAuthorizationOrganizationsId","description":"The DELETE /authorization/organizations/{id} endpoint will delete an organization.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["organizations"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Update an organization","operationId":"putAuthorizationOrganizationsId","description":"The PUT /authorization/organizations/{id} endpoint will update an organization name and description","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/UpdateOrgPayload"}}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/Organization"},"description":"Successful"}}}},"/authorization/policies/{id}":{"get":{"summary":"Fetch a single policy by ID","operationId":"getAuthorizationPoliciesId","description":"The GET /authorization/policies/{id} endpoint returns a policy based on its ID.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["policies"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}},"delete":{"summary":"Delete a policy","operationId":"deleteAuthorizationPoliciesId","description":"The DELETE /authorization/policies/{id} endpoint is a private endpoint. It can be accessed only using a service key.\n\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","name":"sig","in":"query","required":true}],"tags":["policies","private"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Update a policy of the current user organization","operationId":"putAuthorizationPoliciesId","description":"The PUT /authorization/policies/{id} endpoint is a private endpoint. It can be accessed only using a service key.\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","name":"sig","in":"query","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/UpdatePolicyPayload"}}],"tags":["policies","private"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}}},"/authorization/shared-policies/{id}":{"get":{"summary":"Fetch a single shared policy","operationId":"getAuthorizationSharedpoliciesId","description":"The GET /authorization/shared-policies/{id} endpoint returns a policy based on its ID.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["policies"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}},"delete":{"summary":"Delete a shared policy","operationId":"deleteAuthorizationSharedpoliciesId","description":"The DELETE /authorization/shared-policies/{id} endpoint is a private endpoint. It can be accessed only using a service key.\n\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","name":"sig","in":"query","required":true}],"tags":["policies","private"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Update a shared policy","operationId":"putAuthorizationSharedpoliciesId","description":"The PUT /authorization/shared-policies/{id} endpoint is a private endpoint. It can be accessed only using a service key.\nThis service key needs to be passed as a query string in the form \"sig=\"\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Policy ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","name":"sig","in":"query","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/UpdateSharedPolicyPayload"}}],"tags":["policies","private"],"responses":{"200":{"schema":{"$ref":"#/definitions/Policy"},"description":"Successful"}}}},"/authorization/teams/search":{"get":{"summary":"Search for teams from the current user organization","operationId":"getAuthorizationTeamsSearch","description":"The GET /authorization/teams/search endpoint returns a filtered list of teams from the current organization.\n\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","name":"query","in":"query","required":true}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/FilteredTeams"},"description":"Successful"}}}},"/authorization/teams/{id}":{"get":{"summary":"Fetch a team given its identifier","operationId":"getAuthorizationTeamsId","description":"The GET /authorization/teams/{id} endpoint returns a single team data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}},"delete":{"summary":"Delete a team","operationId":"deleteAuthorizationTeamsId","description":"The DELETE /authorization/teams endpoint deletes a team.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["teams"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Update a team","operationId":"putAuthorizationTeamsId","description":"The PUT /authorization/teams/{id} endpoint updates a team data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/UpdateTeamPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}},"/authorization/users/{id}":{"get":{"summary":"Fetch a user given its identifier","operationId":"getAuthorizationUsersId","description":"The GET /authorization/users/{id} endpoint returns a single user data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}},"delete":{"summary":"Delete a user","operationId":"deleteAuthorizationUsersId","description":"The DELETE /authorization/users/{id} endpoint deletes a user.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["users"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Update a user","operationId":"putAuthorizationUsersId","description":"The PUT /authorization/users/{id} endpoint updates the user data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/UpdateUserPayload"}}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}}},"/authorization/list/{userId}/{resource*}":{"get":{"summary":"List all the actions a user can perform on a resource","operationId":"getAuthorizationListUseridResource","description":"The GET /authorization/list/{userId}/{resource} endpoint returns a list of all the actions a user\ncan perform on a given resource.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"userId","in":"path","required":true},{"type":"string","description":"The resource that the user wants to perform the action on","name":"resource","in":"path","required":true}],"tags":["authorization"],"responses":{"200":{"schema":{"$ref":"#/definitions/UserActions"},"description":"Successful"}}}},"/authorization/teams/{id}/users":{"get":{"summary":"Fetch team users given its identifier","operationId":"getAuthorizationTeamsIdUsers","description":"The GET /authorization/teams/{id}/users endpoint returns the team users and pagination metadata.\n\nThe results are paginated. Page numbering and page limit start from 1.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedUsers"},"description":"Successful"}}},"post":{"summary":"Replace team users with the given ones","operationId":"postAuthorizationTeamsIdUsers","description":"The POST /authorization/teams/{id}/users endpoint replaces all team users. Existing team users are removed.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/ReplaceTeamUsersPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}},"delete":{"summary":"Delete all team users","operationId":"deleteAuthorizationTeamsIdUsers","description":"The DELETE /authorization/teams/{id}/users endpoint removes all team users.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["teams"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Add team users","operationId":"putAuthorizationTeamsIdUsers","description":"The PUT /authorization/teams/{id}/users endpoint adds one or more team users.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/AddTeamUsersPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}},"/authorization/teams/{id}/nested":{"get":{"summary":"Fetch a nested team given its identifier","operationId":"getAuthorizationTeamsIdNested","description":"The GET /authorization/teams/{id}/nested endpoint returns a list of team data.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["teams"],"responses":{"200":{"description":"Note: teams users and policies are not populated in nested paged teams list","schema":{"$ref":"#/definitions/NestedPagedTeams"}}}}},"/authorization/users/{id}/teams":{"get":{"summary":"Fetch all teams to which the user belongs to. Does not fetch parent teams.","operationId":"getAuthorizationUsersIdTeams","description":"The GET /authorization/users/{id}/teams endpoint returns a list of teams to which the user belongs to.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"integer","description":"Page number, starts from 1","minimum":1,"name":"page","in":"query"},{"type":"integer","description":"Items per page","minimum":1,"name":"limit","in":"query"}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/PagedTeamRefs"},"description":"Successful"}}},"post":{"summary":"Clear and replace user teams","operationId":"postAuthorizationUsersIdTeams","description":"The POST /authorization/users/{id}/teams endpoint replaces all the user teams. This can be use to move a user from a team to another (or a set of teams to another).\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/ReplaceUserTeamsPayload"}}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}},"delete":{"summary":"Delete teams for a user","operationId":"deleteAuthorizationUsersIdTeams","description":"The DELETE /authorization/users/{id}/teams endpoint deletes user from all her teams.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}}},"/authorization/access/{userId}/{action}/{resource*}":{"get":{"summary":"Authorize user action against a resource","operationId":"getAuthorizationAccessUseridActionResource","description":"The GET /authorization/access/{userId}/{action}/{resource} endpoint answers if a user can perform an action\non a resource.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"userId","in":"path","required":true},{"type":"string","description":"The action to check","name":"action","in":"path","required":true},{"type":"string","description":"The resource that the user wants to perform the action on","name":"resource","in":"path","required":true}],"tags":["authorization"],"responses":{"200":{"schema":{"$ref":"#/definitions/Access"},"description":"Successful"}}}},"/authorization/organizations/{id}/policies":{"post":{"summary":"Clear and replace the policies of an organization","operationId":"postAuthorizationOrganizationsIdPolicies","description":"The POST /authorization/organizations/{id}/policies endpoint replaces all the organization policies. The existing organization policies are removed.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/ReplaceOrgPoliciesPayload"}}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/Organization"},"description":"Successful"}}},"delete":{"summary":"Clear all policies of the organization","operationId":"deleteAuthorizationOrganizationsIdPolicies","description":"The DELETE /authorization/organizations/{id}/policies endpoint removes all the organization policies.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["organizations"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Add one or more policies to an organization","operationId":"putAuthorizationOrganizationsIdPolicies","description":"The PUT /authorization/organizations/{id}/policies endpoint adds one or more policies to an organization.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/AddPoliciesToOrgPayload"}}],"tags":["organizations"],"responses":{"200":{"schema":{"$ref":"#/definitions/Organization"},"description":"Successful"}}}},"/authorization/teams/{id}/policies":{"post":{"summary":"Clear and replace policies for a team","operationId":"postAuthorizationTeamsIdPolicies","description":"The POST /authorization/teams/{id}/policies endpoint replaces all the team policies. Existing policies are removed.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/ReplaceTeamPoliciesPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}},"delete":{"summary":"Clear all team policies","operationId":"deleteAuthorizationTeamsIdPolicies","description":"The DELETE /authorization/teams/{id}/policies endpoint removes all the team policies.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["teams"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Add one or more policies to a team","operationId":"putAuthorizationTeamsIdPolicies","description":"The PUT /authorization/teams/{id}/policies endpoint adds one or more new policies to a team.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/AddPoliciesToTeamPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}},"/authorization/users/{id}/policies":{"post":{"summary":"Clear and replace policies for a user","operationId":"postAuthorizationUsersIdPolicies","description":"The POST /authorization/users/{id}/policies endpoint replaces all the user policies. Existing user policies are removed.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/ReplaceUserPoliciesPayload"}}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}},"delete":{"summary":"Clear all user's policies","operationId":"deleteAuthorizationUsersIdPolicies","description":"The DELETE /authorization/users/{id}/policies endpoint removes all the user policies.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["users"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"put":{"summary":"Add one or more policies to a user","operationId":"putAuthorizationUsersIdPolicies","description":"The PUT /authorization/users/{id}/policies endpoint adds one or more policies to a user.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/AddUserPoliciesPayload"}}],"tags":["users"],"responses":{"200":{"schema":{"$ref":"#/definitions/User"},"description":"Successful"}}}},"/authorization/organizations/{id}/policies/{policyId}":{"delete":{"summary":"Remove a policy from one organization","operationId":"deleteAuthorizationOrganizationsIdPoliciesPolicyid","description":"The DELETE /authorization/organizations/{id}/policies/{policyId} endpoint removes a specific policy from the organization.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Organization ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","description":"Policy ID","maxLength":128,"name":"policyId","in":"path","required":true}],"tags":["organizations"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/authorization/teams/{teamId}/policies/{policyId}":{"delete":{"summary":"Remove a team policy","operationId":"deleteAuthorizationTeamsTeamidPoliciesPolicyid","description":"The DELETE /authorization/teams/{teamId}/policies/{policyId} endpoint removes a specific team policy.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"teamId","in":"path","required":true},{"type":"string","description":"Policy ID","maxLength":128,"name":"policyId","in":"path","required":true}],"tags":["teams"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/authorization/teams/{id}/users/{userId}":{"delete":{"summary":"Delete one team member","operationId":"deleteAuthorizationTeamsIdUsersUserid","description":"The DELETE /authorization/teams/{id}/users/{userId} endpoint removes one user from a team.","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"type":"string","description":"User ID","maxLength":128,"name":"userId","in":"path","required":true}],"tags":["teams"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/authorization/users/{userId}/policies/{policyId}":{"delete":{"summary":"Remove a user's policy","operationId":"deleteAuthorizationUsersUseridPoliciesPolicyid","description":"The DELETE /authorization/users/{userId}/policies/{policyId} endpoint removes a specific user's policy.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"User ID","maxLength":128,"name":"userId","in":"path","required":true},{"type":"string","description":"Policy ID","maxLength":128,"name":"policyId","in":"path","required":true}],"tags":["users"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/authorization/teams/{id}/unnest":{"put":{"summary":"Unnest a team","operationId":"putAuthorizationTeamsIdUnnest","description":"The PUT /authorization/teams/{id}/unnest endpoint unnests a team.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}},"/authorization/teams/{id}/nest":{"put":{"summary":"Nest a team","operationId":"putAuthorizationTeamsIdNest","description":"The PUT /authorization/teams/{id}/nest endpoint nests a team.\n","parameters":[{"type":"string","description":"User ID of the enpoint caller","name":"authorization","in":"header","required":true},{"type":"string","description":"Specify a different organization for the user who is calling the endpoint (works only for SuperUser, it's like impersonation).","name":"org","in":"header"},{"type":"string","description":"Team ID","maxLength":128,"name":"id","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/NestTeamPayload"}}],"tags":["teams"],"responses":{"200":{"schema":{"$ref":"#/definitions/Team"},"description":"Successful"}}}}},"definitions":{"MetaData":{"type":"object"},"Variables":{"type":"object"},"PolicyRef":{"type":"object","properties":{"id":{"type":"string","description":"Policy ID"},"version":{"type":"string","description":"Policy version"},"name":{"type":"string","description":"Policy name"},"variables":{"$ref":"#/definitions/Variables"}}},"PolicyRefs":{"type":"array","description":"Policy Refs","items":{"$ref":"#/definitions/PolicyRef"}},"Organization":{"type":"object","properties":{"id":{"type":"string","description":"Organization ID"},"name":{"type":"string","description":"Organization name"},"description":{"type":"string","description":"Organization description"},"metadata":{"$ref":"#/definitions/MetaData"},"policies":{"$ref":"#/definitions/PolicyRefs","type":"array"}}},"Organizations":{"type":"array","description":"items","items":{"$ref":"#/definitions/Organization"}},"PagedOrganizations":{"type":"object","properties":{"page":{"type":"integer","description":"Page number, starts from 1","minimum":1},"limit":{"type":"integer","description":"Items per page","minimum":1},"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/Organizations","type":"array"}}},"Actions":{"type":"array","description":"Action to perform on resource","items":{"type":"string"}},"Resources":{"type":"array","description":"Resource that the statement covers","items":{"type":"string"}},"Condition":{"type":"object"},"Statement":{"type":"object","properties":{"Effect":{"type":"string","description":"Statement result","enum":["Allow","Deny"]},"Action":{"$ref":"#/definitions/Actions","type":"array"},"Resource":{"$ref":"#/definitions/Resources","type":"array"},"Sid":{"type":"string","description":"Statement ID"},"Condition":{"$ref":"#/definitions/Condition"}}},"Statements":{"type":"array","items":{"$ref":"#/definitions/Statement"}},"PolicyStatements":{"type":"object","properties":{"Statement":{"$ref":"#/definitions/Statements","type":"array"}}},"Policy":{"type":"object","properties":{"id":{"type":"string","description":"Policy ID"},"version":{"type":"string","description":"Policy version"},"name":{"type":"string","description":"Policy name"},"statements":{"$ref":"#/definitions/PolicyStatements"}}},"Policies":{"type":"array","description":"items","items":{"$ref":"#/definitions/Policy"}},"PagedPolicies":{"type":"object","properties":{"page":{"type":"integer","description":"Page number, starts from 1","minimum":1},"limit":{"type":"integer","description":"Items per page","minimum":1},"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/Policies","type":"array"}}},"UserRef":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"name":{"type":"string","description":"User name"}}},"UserRefs":{"type":"array","description":"User refs","items":{"$ref":"#/definitions/UserRef"}},"Team":{"type":"object","properties":{"id":{"type":"string","description":"Team ID"},"name":{"type":"string","description":"Team name"},"description":{"type":"string","description":"Team description"},"path":{"type":"string"},"metadata":{"$ref":"#/definitions/MetaData"},"users":{"$ref":"#/definitions/UserRefs","type":"array"},"policies":{"$ref":"#/definitions/PolicyRefs","type":"array"},"organizationId":{"type":"string","description":"Organization ID to which the team belongs to"},"usersCount":{"type":"number","description":"Number of team users. Sub team users not counted."}}},"Teams":{"type":"array","description":"items","items":{"$ref":"#/definitions/Team"}},"PagedTeams":{"type":"object","description":"Note: teams users and policies are not populated in paged teams list","properties":{"page":{"type":"integer","description":"Page number, starts from 1","minimum":1},"limit":{"type":"integer","description":"Items per page","minimum":1},"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/Teams","type":"array"}}},"TeamRef":{"type":"object","properties":{"id":{"type":"string","description":"Team ID"},"name":{"type":"string","description":"Team name"}}},"TeamRefs":{"type":"array","description":"Team refs","items":{"$ref":"#/definitions/TeamRef"}},"User":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"name":{"type":"string","description":"User name"},"organizationId":{"type":"string","description":"Organization ID to which the user belongs to"},"metadata":{"$ref":"#/definitions/MetaData"},"teams":{"$ref":"#/definitions/TeamRefs","type":"array"},"policies":{"$ref":"#/definitions/PolicyRefs","type":"array"}}},"Users":{"type":"array","description":"items","items":{"$ref":"#/definitions/User"}},"PagedUsers":{"type":"object","properties":{"page":{"type":"integer","description":"Page number, starts from 1","minimum":1},"limit":{"type":"integer","description":"Items per page","minimum":1},"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/Users","type":"array"}}},"UserActionsArray":{"type":"array","items":{"type":"string"}},"UserActionOnResource":{"type":"object","properties":{"resource":{"type":"string"},"actions":{"$ref":"#/definitions/UserActionsArray","type":"array"}}},"UserActionsOnResources":{"type":"array","items":{"$ref":"#/definitions/UserActionOnResource"}},"Short Team":{"type":"object","properties":{"id":{"type":"string","description":"Team ID"},"name":{"type":"string","description":"Team name"},"description":{"type":"string","description":"Team description"},"path":{"type":"string"},"organizationId":{"type":"string","description":"Organization ID to which the team belongs to"}}},"Data":{"type":"array","items":{"$ref":"#/definitions/Short Team"}},"FilteredTeams":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/Data","type":"array"}}},"UserActions":{"type":"object","properties":{"actions":{"$ref":"#/definitions/UserActionsArray","type":"array"}}},"Nested Team":{"type":"object","properties":{"id":{"type":"string","description":"Team ID"},"name":{"type":"string","description":"Team name"},"description":{"type":"string","description":"Team description"},"parentId":{"type":"string","description":"Parent Team ID"},"path":{"type":"string"},"organizationId":{"type":"string","description":"Organization ID to which the team belongs to"},"usersCount":{"type":"number","description":"Number of team users. Sub team users not counted."}}},"Nested Teams":{"type":"array","description":"items","items":{"$ref":"#/definitions/Nested Team"}},"NestedPagedTeams":{"type":"object","description":"Note: teams users and policies are not populated in nested paged teams list","properties":{"page":{"type":"integer","description":"Page number, starts from 1","minimum":1},"limit":{"type":"integer","description":"Items per page","minimum":1},"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/Nested Teams","type":"array"}}},"PagedTeamRefs":{"type":"object","properties":{"page":{"type":"integer","description":"Page number, starts from 1","minimum":1},"limit":{"type":"integer","description":"Items per page","minimum":1},"total":{"type":"integer","description":"Total number of entries matched by the query"},"data":{"$ref":"#/definitions/TeamRefs","type":"array"}}},"Access":{"type":"object","properties":{"access":{"type":"boolean"}}},"UserPayload":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"name":{"type":"string","description":"User name"}},"required":["name"]},"CreateOrgPayload":{"type":"object","properties":{"id":{"type":"string","description":"Organization ID","maxLength":128},"name":{"type":"string","description":"Name","maxLength":64},"description":{"type":"string","description":"Description"},"metadata":{"$ref":"#/definitions/MetaData"},"user":{"$ref":"#/definitions/UserPayload"}},"required":["name","description"]},"OrganizationAndUser":{"type":"object","properties":{"organization":{"$ref":"#/definitions/Organization"},"user":{"$ref":"#/definitions/UserRef"}}},"Action":{"type":"array","minItems":1,"items":{"type":"string"}},"Resource":{"type":"array","minItems":1,"items":{"type":"string"}},"StatementObject":{"type":"object","properties":{"Effect":{"type":"string","enum":["Allow","Deny"]},"Action":{"$ref":"#/definitions/Action","type":"array"},"Resource":{"$ref":"#/definitions/Resource","type":"array"},"Sid":{"type":"string"},"Condition":{"$ref":"#/definitions/Condition"}}},"StatementsArray":{"type":"array","minItems":1,"items":{"$ref":"#/definitions/StatementObject"}},"StatementsObject":{"type":"object","properties":{"Statement":{"$ref":"#/definitions/StatementsArray","type":"array"}}},"CreatePolicyPayload":{"type":"object","properties":{"id":{"type":"string","description":"Policy ID","maxLength":128},"name":{"type":"string","description":"Name","maxLength":64},"version":{"type":"string","description":"Version number"},"statements":{"$ref":"#/definitions/StatementsObject"}},"required":["name","version","statements"]},"CreateSharedPoliciesPayload":{"type":"object","properties":{"id":{"type":"string","description":"Policy ID","maxLength":128},"name":{"type":"string","description":"Name","maxLength":64},"version":{"type":"string","description":"Version number"},"statements":{"$ref":"#/definitions/StatementsObject"}},"required":["name","version"]},"CreateTeamPayload":{"type":"object","properties":{"id":{"type":"string","description":"The ID to be used for the new team. Only alphanumeric characters and underscore are supported","maxLength":128,"pattern":"/^[0-9a-zA-Z_]+$/"},"name":{"type":"string","description":"Name","maxLength":30},"description":{"type":"string","description":"Description"},"metadata":{"$ref":"#/definitions/MetaData"},"user":{"$ref":"#/definitions/UserPayload"}},"required":["name","description"]},"CreateUserPayload":{"type":"object","properties":{"id":{"type":"string","description":"User ID","maxLength":128},"name":{"type":"string","description":"Name","maxLength":255},"metadata":{"$ref":"#/definitions/MetaData"}},"required":["name"]},"PolicyIdsArray":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","minItems":1,"items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString","PolicyIdObject"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"ReplaceOrgPoliciesPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/PolicyIdsArray","type":"array"}},"required":["policies"]},"Model 1":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"ReplaceTeamPoliciesPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/Model 1","type":"array"}},"required":["policies"]},"UsersArray":{"type":"array","description":"User IDs","items":{"type":"string"}},"ReplaceTeamUsersPayload":{"type":"object","properties":{"users":{"$ref":"#/definitions/UsersArray","type":"array"}},"required":["users"]},"Model 2":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"ReplaceUserPoliciesPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/Model 2","type":"array"}},"required":["policies"]},"TeamsArray":{"type":"array","description":"Teams IDs","items":{"type":"string"}},"ReplaceUserTeamsPayload":{"type":"object","properties":{"teams":{"$ref":"#/definitions/TeamsArray","type":"array"}},"required":["teams"]},"UpdateOrgPayload":{"type":"object","properties":{"name":{"type":"string","description":"Name","maxLength":64},"description":{"type":"string","description":"Description"},"metadata":{"$ref":"#/definitions/MetaData"}},"required":["name","description"]},"UpdatePolicyPayload":{"type":"object","properties":{"version":{"type":"string","description":"Version number"},"name":{"type":"string","description":"Name","maxLength":64},"statements":{"$ref":"#/definitions/StatementsObject"}},"required":["version","name"]},"UpdateSharedPolicyPayload":{"type":"object","properties":{"version":{"type":"string","description":"Version number"},"name":{"type":"string","description":"Name","maxLength":64},"statements":{"$ref":"#/definitions/StatementsObject"}},"required":["version","name"]},"UpdateTeamPayload":{"type":"object","properties":{"name":{"type":"string","description":"Name","maxLength":30},"description":{"type":"string","description":"Description"},"metadata":{"$ref":"#/definitions/MetaData"}}},"UpdateUserPayload":{"type":"object","properties":{"name":{"type":"string","description":"Name","maxLength":255},"metadata":{"$ref":"#/definitions/MetaData"}},"required":["name"]},"Model 3":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"AddPoliciesToOrgPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/Model 3","type":"array"}},"required":["policies"]},"Model 4":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"AddPoliciesToTeamPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/Model 4","type":"array"}},"required":["policies"]},"AddTeamUsersPayload":{"type":"object","properties":{"users":{"$ref":"#/definitions/UsersArray","type":"array"}},"required":["users"]},"NestTeamPayload":{"type":"object","properties":{"parentId":{"type":"string","description":"Parent ID"}},"required":["parentId"]},"Model 5":{"type":"array","description":"Array of Policy ID Objects {id, variables} OR Policy ID strings","items":{"type":"string","description":"Policy Id String","maxLength":128,"required":["PolicyIdString"],"x-alternatives":[{"type":"string","description":"Policy Id String","maxLength":128},{"$ref":"#/x-alt-definitions/PolicyIdObject"}]}},"AddUserPoliciesPayload":{"type":"object","properties":{"policies":{"$ref":"#/definitions/Model 5","type":"array"}},"required":["policies"]}},"x-alt-definitions":{"variables":{"type":"object"},"PolicyIdObject":{"type":"object","description":"Policy Id Object","properties":{"id":{"type":"string","description":"Policy Id String","maxLength":128},"variables":{"$ref":"#/x-alt-definitions/variables"}},"required":["id"]}}} \ No newline at end of file diff --git a/lib/config/auth.js b/lib/config/auth.js index 3d489a39..c565bc88 100644 --- a/lib/config/auth.js +++ b/lib/config/auth.js @@ -41,6 +41,7 @@ const Actions = { ReplaceTeamMember: 'authorization:teams:user:replace', RemoveTeamMember: 'authorization:teams:user:remove', AllTeam: 'authorization:teams:*', + ListNestedTeams: 'authorization:teams:nestedlist', // user CreateUser: 'authorization:users:create', diff --git a/lib/core/index.js b/lib/core/index.js index b3aacdd4..f662611d 100644 --- a/lib/core/index.js +++ b/lib/core/index.js @@ -70,7 +70,8 @@ function buildUdaruCore (dbPool, config) { replaceUsers: teamOps.replaceUsersInTeam, deleteMembers: teamOps.deleteTeamMembers, deleteMember: teamOps.deleteTeamMember, - search: teamOps.search + search: teamOps.search, + listNestedTeams: teamOps.listNestedTeams }, users: { diff --git a/lib/core/lib/mapping.js b/lib/core/lib/mapping.js index 4bf1c223..abd06db8 100644 --- a/lib/core/lib/mapping.js +++ b/lib/core/lib/mapping.js @@ -120,6 +120,20 @@ function mapTeamSimple (row) { mapTeam.simple = mapTeamSimple +function mapNestedTeam (row) { + return { + id: row.id, + name: row.name, + description: row.description, + parentId: row.parent_id, + path: row.path, + organizationId: row.org_id, + usersCount: parseInt(row.users_count, 10) + } +} + +mapTeam.listNestedTeam = mapNestedTeam + module.exports = { organization: mapOrganization, policy: mapPolicy, diff --git a/lib/core/lib/ops/teamOps.js b/lib/core/lib/ops/teamOps.js index 355b01d6..70da78fe 100644 --- a/lib/core/lib/ops/teamOps.js +++ b/lib/core/lib/ops/teamOps.js @@ -510,6 +510,57 @@ function buildTeamOps (db, config) { cb() }) }, + /** + * List a nested team in an organization + * + * @param {Object} params { organizationId, id, limit, page } where page is 1-indexed + * @param {Function} cb + */ + listNestedTeams: function listNestedTeams (params, cb) { + let { organizationId, id, limit, page } = params + + Joi.validate({ organizationId, id, page, limit }, validationRules.listNestedTeams, function (err) { + if (err) return cb(Boom.badRequest(err)) + + let sqlQuery = SQL` + WITH total AS ( + SELECT COUNT(*) AS cnt + FROM teams + WHERE org_id = ${organizationId} AND team_parent_id = ${id} + ) + SELECT + teams.id, + teams.name, + teams.description, + teams.team_parent_id as parent_id, + teams.path, + teams.org_id, + t.cnt::INTEGER AS total, + COUNT(team_members.team_id) AS users_count + FROM teams + LEFT JOIN team_members ON team_members.team_id = teams.id + INNER JOIN total AS t ON 1=1 + WHERE org_id = ${organizationId} AND team_parent_id = ${id} + GROUP BY teams.id, teams.name, teams.description, teams.team_parent_id, teams.path, teams.org_id, t.cnt + ORDER BY UPPER(name) + ` + + if (limit) { + sqlQuery.append(SQL` LIMIT ${limit}`) + } + if (limit && page) { + let offset = (page - 1) * limit + sqlQuery.append(SQL` OFFSET ${offset}`) + } + + db.query(sqlQuery, function (err, result) { + if (err) return cb(Boom.badImplementation(err)) + + let total = result.rows.length > 0 ? result.rows[0].total : 0 + return cb(null, result.rows.map(mapping.team.listNestedTeam), total) + }) + }) + }, /** * Nest/Un-nest a team @@ -855,6 +906,7 @@ function buildTeamOps (db, config) { teamOps.deleteTeam.validate = validationRules.deleteTeam teamOps.moveTeam.validate = validationRules.moveTeam teamOps.addTeamPolicies.validate = validationRules.addTeamPolicies + teamOps.listNestedTeams.validate = validationRules.listNestedTeams return teamOps } diff --git a/lib/core/lib/ops/validation.js b/lib/core/lib/ops/validation.js index 0d609dad..0df73e8d 100644 --- a/lib/core/lib/ops/validation.js +++ b/lib/core/lib/ops/validation.js @@ -137,6 +137,12 @@ const teams = { limit: validationRules.limit, organizationId: validationRules.organizationId }, + listNestedTeams: { + page: validationRules.page, + limit: validationRules.limit, + organizationId: validationRules.organizationId, + id: validationRules.teamId + }, createTeam: { id: Joi.string().regex(/^[0-9a-zA-Z_]+$/).max(128).description('The ID to be used for the new team. Only alphanumeric characters and underscore are supported'), parentId: validationRules.teamId.optional().allow(null), diff --git a/lib/plugin/routes/public/teams.js b/lib/plugin/routes/public/teams.js index 5671d6bf..700ed0c6 100644 --- a/lib/plugin/routes/public/teams.js +++ b/lib/plugin/routes/public/teams.js @@ -598,6 +598,49 @@ exports.register = function (server, options, next) { } }) + server.route({ + method: 'GET', + path: '/authorization/teams/{id}/nested', + handler: function (request, reply) { + const { organizationId } = request.udaru + const limit = request.query.limit || server.udaruConfig.get('authorization.defaultPageSize') + const page = request.query.page || 1 + const { id } = request.params + + request.udaruCore.teams.read({ id, organizationId }, (err, data) => { + if (err) return reply(err) + + request.udaruCore.teams.listNestedTeams({ organizationId, id, limit, page }, (err, data, total) => { + reply(err, err + ? null + : { + data, + total, + page: page, + limit: limit + }) + }) + }) + }, + config: { + validate: { + query: _.pick(validation.listNestedTeams, ['page', 'limit']), + params: _.pick(validation.listNestedTeams, ['id']), + headers + }, + description: 'Fetch a nested team given its identifier', + notes: 'The GET /authorization/teams/{id}/nested endpoint returns a list of team data.\n', + tags: ['api', 'teams'], + plugins: { + auth: { + action: Action.ListNestedTeams, + getParams: (request) => ({ teamId: request.params.id }) + } + }, + response: { schema: swagger.NestedPagedTeams } + } + }) + next() } diff --git a/lib/plugin/security/hapi-auth-validation.js b/lib/plugin/security/hapi-auth-validation.js index aefd1aec..b76429d3 100644 --- a/lib/plugin/security/hapi-auth-validation.js +++ b/lib/plugin/security/hapi-auth-validation.js @@ -43,16 +43,10 @@ function buildAuthValidation (authorization) { }) } - function buildResourcesForUser (udaru, builder, userId, organizationId, done) { - const buildParams = { - userId, - teamId: '*', - organizationId - } - + function buildResourcesForUser (udaru, builder, buildParams, organizationId, done) { const resources = [builder(buildParams)] - udaru.users.read({ id: userId, organizationId: organizationId }, (err, user) => { + udaru.users.read({ id: buildParams.userId, organizationId: organizationId }, (err, user) => { if (err && err.output.statusCode === 404) return done(null, resources) if (err) return done(err) @@ -83,7 +77,7 @@ function buildAuthValidation (authorization) { const buildParams = Object.assign({}, { organizationId }, requestParams) if (resourceType === 'users' && buildParams.userId) { - return buildResourcesForUser(udaru, resourceBuilder, buildParams.userId, organizationId, done) + return buildResourcesForUser(udaru, resourceBuilder, buildParams, organizationId, done) } done(null, [resourceBuilder(buildParams)]) diff --git a/lib/plugin/swagger.js b/lib/plugin/swagger.js index 8dd56067..55976cca 100644 --- a/lib/plugin/swagger.js +++ b/lib/plugin/swagger.js @@ -64,6 +64,18 @@ const Team = Joi.object({ const Teams = Joi.array().items(Team).description('items').label('Teams') +const NestedTeam = Joi.object({ + id: Joi.string().description('Team ID'), + name: Joi.string().description('Team name'), + description: Joi.string().description('Team description'), + parentId: Joi.string().description('Parent Team ID'), + path: Joi.string(), + organizationId: Joi.string().description('Organization ID to which the team belongs to'), + usersCount: Joi.number().description('Number of team users. Sub team users not counted.') +}).label('Nested Team') + +const NestedTeams = Joi.array().items(NestedTeam).description('items').label('Nested Teams') + const User = Joi.object({ id: Joi.string().description('User ID'), name: Joi.string().description('User name'), @@ -99,6 +111,7 @@ const List = (data) => { const PagedPolicies = List(Policies).label('PagedPolicies') const PagedTeams = List(Teams).label('PagedTeams').description('Note: teams users and policies are not populated in paged teams list') +const NestedPagedTeams = List(NestedTeams).label('NestedPagedTeams').description('Note: teams users and policies are not populated in nested paged teams list') const PagedTeamRefs = List(TeamRefs).label('PagedTeamRefs') const PagedUsers = List(Users).label('PagedUsers') const PagedOrganizations = List(Organizations).label('PagedOrganizations') @@ -131,10 +144,12 @@ module.exports = { UserActions, UserActionsOnResources, Team, + NestedTeam, TeamRef, Policy, PagedPolicies, PagedTeams, + NestedPagedTeams, PagedTeamRefs, PagedUsers, PagedOrganizations, diff --git a/package-lock.json b/package-lock.json index a9bfaa77..cf3ecf6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "udaru", - "version": "4.0.1", + "version": "4.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -5360,19 +5360,25 @@ } }, "pbac": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/pbac/-/pbac-0.2.0.tgz", - "integrity": "sha512-Y9hTjLq7iO/aoM6veGNbtksjZnTk9inhAJ/gQLwYiVXKScxFNdXMCGyYrNQwO8uSeRKMnaUrbEI1c2Rg3yW3SQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/pbac/-/pbac-0.3.0.tgz", + "integrity": "sha512-PWSdXR1fc7iqsKaJueakBARoI2w0WMKQUVSQXfCD2fcITHTvUo9KYLa+urJNLX+6YYP6kHEsFlPq+UjosLWn8A==", "requires": { "ipcheck": "0.1.0", - "lodash": "3.10.1", - "z-schema": "3.19.0" + "lodash": "4.17.5", + "z-schema": "3.19.1" }, "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + "z-schema": { + "version": "3.19.1", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.19.1.tgz", + "integrity": "sha512-jPNzqmOu3+AGbb4krDODqo4QBzwUGDVzyfGyy1HtWaUnafltQotatSpxxWd6Mp0iSZOUwHU5sqKYi+U8HsHMkg==", + "requires": { + "commander": "2.13.0", + "lodash.get": "4.4.2", + "lodash.isequal": "4.5.0", + "validator": "9.2.0" + } } } }, diff --git a/package.json b/package.json index 1c7a805b..3af9f153 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "udaru", - "version": "4.0.1", + "version": "4.2.0", "description": "A policy based authorization module", "license": "MIT", "author": "nearForm Ltd", @@ -70,7 +70,7 @@ "jsonfile": "^3.0.1", "lodash": "^4.17.5", "minimist": "^1.2.0", - "pbac": "0.2.0", + "pbac": "0.3.0", "pg": "^7.4.1", "pino": "^4.10.3", "postgrator": "^2.10.3", diff --git a/test/integration/endToEnd/teams.test.js b/test/integration/endToEnd/teams.test.js index e693bf80..9752a252 100644 --- a/test/integration/endToEnd/teams.test.js +++ b/test/integration/endToEnd/teams.test.js @@ -1142,4 +1142,115 @@ lab.experiment('Teams - checking org_id scoping', () => { done() }) }) + + lab.test('get error if team does not exist', (done) => { + const options = utils.requestOptions({ + method: 'GET', + url: `/authorization/teams/IDONTEXIST/nested` + }) + + server.inject(options, (response) => { + const result = response.result + + expect(result.statusCode).to.equal(404) + expect(result.error).to.exist() + expect(result.message).to.include('not').include('found') + + done() + }) + }) + + lab.test('get nested team list with default paging', (done) => { + const options = utils.requestOptions({ + method: 'GET', + url: '/authorization/teams/3/nested' + }) + + server.inject(options, (response) => { + const result = response.result + + expect(response.statusCode).to.equal(200) + expect(result.page).to.equal(1) + expect(result.limit).to.greaterThan(1) + expect(result.total).to.equal(1) + expect(result.data).to.equal([ + { + id: '6', + name: 'Company Lawyer', + description: 'Author of legal documents', + parentId: '3', + path: '6', + organizationId: 'WONKA', + usersCount: 0 + } + ]) + + done() + }) + }) + + lab.test('get nested team list with paging', (done) => { + const options = utils.requestOptions({ + method: 'GET', + url: '/authorization/teams/3/nested?limit=1&page=1' + }) + + server.inject(options, (response) => { + const result = response.result + + expect(response.statusCode).to.equal(200) + expect(result.page).to.equal(1) + expect(result.limit).to.equal(1) + expect(result.total).to.equal(1) + expect(result.data).to.equal([ + { + id: '6', + name: 'Company Lawyer', + description: 'Author of legal documents', + parentId: '3', + path: '6', + organizationId: 'WONKA', + usersCount: 0 + } + ]) + + done() + }) + }) + + lab.test('get nested team list with bad paging param', (done) => { + const options = utils.requestOptions({ + method: 'GET', + url: '/authorization/teams/3/nested?limit=1&page=0' + }) + + server.inject(options, (response) => { + const result = response.result + + expect(response.statusCode).to.equal(400) + expect(result.error).to.equal('Bad Request') + expect(result.message).to.exist() + expect(result.data).to.not.exist() + + done() + }) + }) + + lab.test('get nested team list with bad limit param', (done) => { + const options = utils.requestOptions({ + method: 'GET', + url: '/authorization/teams/3/nested?limit=0&page=1' + }) + + server.inject(options, (response) => { + const result = response.result + + expect(response.statusCode).to.equal(400) + expect(result.error).to.equal('Bad Request') + expect(result.message).to.exist() + expect(result.data).to.not.exist() + + done() + }) + }) }) diff --git a/test/integration/teamOps.test.js b/test/integration/teamOps.test.js index 2ed3ab8a..6181249b 100644 --- a/test/integration/teamOps.test.js +++ b/test/integration/teamOps.test.js @@ -1022,6 +1022,103 @@ lab.experiment('TeamOps', () => { }) }) + lab.experiment('nested teams', () => { + lab.test('list an existing nested team', (done) => { + udaru.teams.listNestedTeams({ organizationId: 'WONKA', id: '4' }, (err, result, total) => { + expect(err).to.not.exist() + expect(result).to.exist() + expect(total).to.exist() + expect(total).to.equal(1) + + expect(_.map(result, 'name')).contains(['Personnel Managers']) + done() + }) + }) + + lab.test('list an existing nested team with paging', (done) => { + udaru.teams.listNestedTeams({ organizationId: 'WONKA', id: '4', page: 1, limit: 1 }, (err, result, total) => { + expect(err).to.not.exist() + expect(result).to.exist() + expect(total).to.exist() + expect(total).to.equal(1) + + expect(_.map(result, 'name')).contains(['Personnel Managers']) + done() + }) + }) + + lab.test('nested team with bad page param', (done) => { + udaru.teams.listNestedTeams({ organizationId: 'WONKA', id: '4', page: 0, limit: 1 }, (err, result, total) => { + expect(err).to.exist() + + done() + }) + }) + + lab.test('nested team with bad limit param', (done) => { + udaru.teams.listNestedTeams({ organizationId: 'WONKA', id: '4', page: 1, limit: 0 }, (err, result, total) => { + expect(err).to.exist() + + done() + }) + }) + + lab.test('nested team not found', (done) => { + udaru.teams.listNestedTeams({ organizationId: 'WONKA', id: 'IDONTEXIST' }, (err, result, total) => { + expect(err).to.not.exist() + expect(result).to.exist() + expect(total).to.exist() + expect(total).to.equal(0) + expect(result.length).to.equal(0) + + done() + }) + }) + + lab.test('nested team with bad organization', (done) => { + udaru.teams.listNestedTeams({ organizationId: 'IDONTEXIST', id: '4' }, (err, result, total) => { + expect(err).to.not.exist() + expect(result).to.exist() + expect(total).to.exist() + expect(total).to.equal(0) + expect(result.length).to.equal(0) + + done() + }) + }) + + lab.test('nested team with bad team id', (done) => { + udaru.teams.listNestedTeams({ organizationId: 'WONKA', id: 4 }, (err, result, total) => { + expect(err).to.exist() + + done() + }) + }) + + lab.test('nested team sql injection org_id sanity check', (done) => { + udaru.teams.listNestedTeams({ organizationId: 'WONKA||org_id<>-1', id: '4' }, (err, result, total) => { + expect(err).to.not.exist() + expect(total).to.exist() + expect(result).to.exist() + expect(total).to.equal(0) + expect(result.length).to.equal(0) + + done() + }) + }) + + lab.test('Search sql injection query sanity check', (done) => { + udaru.teams.listNestedTeams({ id: '4\'); drop database authorization;', organizationId: 'WONKA' }, (err, result, total) => { + expect(err).to.not.exist() + expect(total).to.exist() + expect(result).to.exist() + expect(total).to.equal(0) + expect(result.length).to.equal(0) + + done() + }) + }) + }) lab.test('Search for Authors', (done) => { udaru.teams.search({ query: 'Authors', organizationId: 'WONKA' }, (err, data, total) => { expect(err).to.not.exist()