-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ID-1306 CBAS Submission, Filtering by Resource Parent, and Getting Resource Creator #1457
base: develop
Are you sure you want to change the base?
Changes from all commits
3b39942
baa8e9e
841ebda
db530e1
202abe2
fe69c54
4bf26dc
ac3d8cf
95d22bf
7b79df6
655a99d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
<databaseChangeLog logicalFilePath="dummy" | ||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog" | ||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd"> | ||
|
||
<changeSet logicalFilePath="dummy" author="tlangs" id="resource_created_by"> | ||
<addColumn tableName="sam_resource"> | ||
<column name="created_by" type="VARCHAR"> | ||
<constraints nullable="true"/> | ||
</column> | ||
</addColumn> | ||
<addForeignKeyConstraint baseTableName="sam_resource" baseColumnNames="created_by" constraintName="FK_SR_CREATOR" referencedTableName="SAM_USER" referencedColumnNames="id" onDelete="SET NULL" /> | ||
</changeSet> | ||
|
||
</databaseChangeLog> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -172,6 +172,7 @@ resourceTypes = { | |
wds-instance = ["owner"] | ||
kubernetes-app = ["manager"] | ||
kubernetes-app-shared = ["owner", "user"] | ||
cbas-submission = ["reader"] | ||
} | ||
} | ||
application = { | ||
|
@@ -188,6 +189,7 @@ resourceTypes = { | |
google-project = ["pet-creator"] | ||
wds-instance = ["writer"] | ||
kubernetes-app-shared = ["user"] | ||
cbas-submission = ["reader"] | ||
} | ||
} | ||
reader = { | ||
|
@@ -198,6 +200,7 @@ resourceTypes = { | |
google-project = ["pet-creator"] | ||
wds-instance = ["reader"] | ||
kubernetes-app-shared = ["user"] | ||
cbas-submission = ["reader"] | ||
} | ||
} | ||
discoverer = { | ||
|
@@ -1674,6 +1677,35 @@ resourceTypes = { | |
allowLeaving = false | ||
reuseIds = true | ||
} | ||
|
||
cbas-submission = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will allow CBAS to no longer need to store Sam User IDs! |
||
actionPatterns = { | ||
abort = { | ||
description = "Abort this cbas-submission" | ||
} | ||
read = { | ||
description = "read information about the submission" | ||
} | ||
create_with_parent = { | ||
description = "Enables creating the request object with a parent" | ||
} | ||
read_creator = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This resource action will allow those who have it to be able to get the resource creator's email. This is similar to |
||
description = "Enables reading the creator of the resource" | ||
} | ||
} | ||
ownerRoleName = "owner" | ||
roles = { | ||
owner = { | ||
roleActions = ["abort", "create_with_parent"] | ||
includedRoles = ["reader"] | ||
} | ||
Comment on lines
+1698
to
+1701
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How hard is it to change these after creation if we wanted to (say) have a "canceller" role separate from the owner/creator? |
||
reader = { | ||
roleActions = ["read", "read_creator"] | ||
} | ||
} | ||
allowLeaving = false | ||
reuseIds = false | ||
} | ||
} | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1739,7 +1739,7 @@ paths: | |
This endpoint is ONLY for determining the state of the user's permissions. | ||
It does not take into account enabled status, or Terms of Service Compliance, nor does it take into account Auth Domains. | ||
To check if a user is allowed to execute an action on a resource, use /api/resources/v2/{resourceTypeName}/{resourceId}/action/{action} | ||
By default, public resources are not included. Including public resources incurs a 3x cost of DB performance. | ||
By default, public resources are not included. Including public resources might incur a 3x cost of DB performance. | ||
operationId: listResourcesV2 | ||
parameters: | ||
- name: format | ||
|
@@ -1789,6 +1789,15 @@ paths: | |
type: array | ||
items: | ||
type: string | ||
- name: parentResources | ||
in: query | ||
description: Fully Qualified Resource IDs of parent resources to filter on. Formatted as `resourceTypeName:resourceId`. | ||
required: false | ||
explode: false | ||
schema: | ||
type: array | ||
items: | ||
type: string | ||
- name: includePublic | ||
in: query | ||
description: Include public resources in the response | ||
|
@@ -2976,6 +2985,44 @@ paths: | |
application/json: | ||
schema: | ||
$ref: '#/components/schemas/ErrorReport' | ||
/api/resources/v2/{resourceTypeName}/{resourceId}/creator: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is fine but it's probably more helpful to have a way to batch the lookup of |
||
get: | ||
tags: | ||
- Resources | ||
summary: Get the creator of a resource | ||
operationId: getResourceCreator | ||
parameters: | ||
- name: resourceTypeName | ||
in: path | ||
description: Type of resource to query | ||
required: true | ||
schema: | ||
type: string | ||
- name: resourceId | ||
in: path | ||
description: Id of resource to query | ||
required: true | ||
schema: | ||
type: string | ||
responses: | ||
200: | ||
description: email address of the creator of this resource | ||
content: | ||
application/json: | ||
schema: | ||
type: string | ||
403: | ||
description: You do not have permission get the creator of this resource | ||
content: { } | ||
404: | ||
description: You do not have access to this resource or it does not exist | ||
content: { } | ||
500: | ||
description: Internal Server Error | ||
content: | ||
application/json: | ||
schema: | ||
$ref: '#/components/schemas/ErrorReport' | ||
/api/users/v1/{email}: | ||
get: | ||
tags: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -252,6 +252,16 @@ trait ResourceRoutes extends SamUserDirectives with SecurityDirectives with SamM | |
} | ||
} | ||
} | ||
} ~ | ||
pathPrefix("creator") { | ||
requireAction(resource, SamResourceActions.readCreator, samUser.id, samRequestContext) { | ||
pathEndOrSingleSlash { | ||
complete(resourceService.getResourceCreator(resource, samRequestContext).map { | ||
case Some(response) => StatusCodes.OK -> response.email | ||
case None => throw new WorkbenchExceptionWithErrorReport(ErrorReport(StatusCodes.NotFound, "resource creator not found")) | ||
}) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
@@ -605,38 +615,65 @@ trait ResourceRoutes extends SamUserDirectives with SecurityDirectives with SamM | |
"policies".as[String].?, | ||
"roles".as[String].?, | ||
"actions".as[String].?, | ||
"parentResources".as[String].?, | ||
"includePublic" ? false, | ||
"format".as[String] ? "hierarchical" | ||
) { (resourceTypes: Option[String], policies: Option[String], roles: Option[String], actions: Option[String], includePublic: Boolean, format: String) => | ||
format match { | ||
case "flat" => | ||
complete { | ||
resourceService | ||
.listResourcesFlat( | ||
samUser.id, | ||
resourceTypes.map(_.split(",").map(ResourceTypeName(_)).toSet).getOrElse(Set.empty), | ||
policies.map(_.split(",").map(AccessPolicyName(_)).toSet).getOrElse(Set.empty), | ||
roles.map(_.split(",").map(ResourceRoleName(_)).toSet).getOrElse(Set.empty), | ||
actions.map(_.split(",").map(ResourceAction(_)).toSet).getOrElse(Set.empty), | ||
includePublic, | ||
samRequestContext | ||
) | ||
.map(StatusCodes.OK -> _) | ||
} | ||
case "hierarchical" => | ||
complete { | ||
resourceService | ||
.listResourcesHierarchical( | ||
samUser.id, | ||
resourceTypes.map(_.split(",").map(ResourceTypeName(_)).toSet).getOrElse(Set.empty), | ||
policies.map(_.split(",").map(AccessPolicyName(_)).toSet).getOrElse(Set.empty), | ||
roles.map(_.split(",").map(ResourceRoleName(_)).toSet).getOrElse(Set.empty), | ||
actions.map(_.split(",").map(ResourceAction(_)).toSet).getOrElse(Set.empty), | ||
includePublic, | ||
samRequestContext | ||
) | ||
.map(StatusCodes.OK -> _) | ||
} | ||
} | ||
) { | ||
( | ||
resourceTypes: Option[String], | ||
policies: Option[String], | ||
roles: Option[String], | ||
actions: Option[String], | ||
parentResources: Option[String], | ||
includePublic: Boolean, | ||
format: String | ||
) => | ||
val parsedResourceTypes = resourceTypes.map(_.split(",").map(ResourceTypeName(_)).toSet).getOrElse(Set.empty) | ||
val parsedPolicies = policies.map(_.split(",").map(AccessPolicyName(_)).toSet).getOrElse(Set.empty) | ||
val parsedRoles = roles.map(_.split(",").map(ResourceRoleName(_)).toSet).getOrElse(Set.empty) | ||
val parsedActions = actions.map(_.split(",").map(ResourceAction(_)).toSet).getOrElse(Set.empty) | ||
val parsedParentResourceIds = parentResources | ||
Comment on lines
+631
to
+635
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a little cleanup here to keep our code DRY |
||
.map( | ||
_.split(",") | ||
.map { r => | ||
val splitted = r.split(":") | ||
FullyQualifiedResourceId(ResourceTypeName(splitted(0)), ResourceId(splitted(1))) | ||
} | ||
.toSet | ||
) | ||
.getOrElse(Set.empty) | ||
format match { | ||
case "flat" => | ||
complete { | ||
resourceService | ||
.listResourcesFlat( | ||
samUser.id, | ||
parsedResourceTypes, | ||
parsedPolicies, | ||
parsedRoles, | ||
parsedActions, | ||
parsedParentResourceIds, | ||
includePublic, | ||
samRequestContext | ||
) | ||
.map(StatusCodes.OK -> _) | ||
} | ||
case "hierarchical" => | ||
complete { | ||
resourceService | ||
.listResourcesHierarchical( | ||
samUser.id, | ||
parsedResourceTypes, | ||
parsedPolicies, | ||
parsedRoles, | ||
parsedActions, | ||
parsedParentResourceIds, | ||
includePublic, | ||
samRequestContext | ||
) | ||
.map(StatusCodes.OK -> _) | ||
} | ||
} | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -197,6 +197,7 @@ trait UserRoutesV2 extends SamUserDirectives with SamRequestContextDirectives { | |
Set.empty, | ||
Set(ResourceRoleName("user")), | ||
Set.empty, | ||
Set.empty, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Listing all user resources doesn't need to filter on parent, so an empty set is provided here. |
||
includePublic = false, | ||
samRequestContext | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding the column
created_by
isn't just useful for submissions. Its really odd that Sam doesn't know what user created a resource!