Skip to content
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

Add inherited and auth-domain properties #1316

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions src/main/resources/swagger/api-docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4385,17 +4385,32 @@ components:
type: string
description: resourceId of the resource
policies:
type: string
type: array
items:
type: string
description: policies the user is a part of on the resource
roles:
type: string
type: array
items:
type: string
description: roles the user has on the resource
actions:
type: string
type: array
items:
type: string
description: actions the user has on the resource
isPublic:
type: string
description: isPublic is the resource public or not
inherited:
type: boolean
description: is this resource policy inherited from a parent resource
authDomain:
type: string
description: The auth domain of the policy
inAuthDomain:
type: boolean
description: Is the user in the auth domain of the policy
FilteredHierarchicalResource:
type: object
properties:
Expand All @@ -4410,6 +4425,12 @@ components:
description: Policies on the resource
items:
$ref: '#/components/schemas/FilteredHierarchicalResourcePolicy'
authDomain:
type: string
description: The auth domain of the policy
inAuthDomain:
type: boolean
description: Is the user in the auth domain of the policy
FilteredHierarchicalResourcePolicy:
type: object
properties:
Expand All @@ -4429,6 +4450,9 @@ components:
isPublic:
type: boolean
description: Is this policy on the resource a public policy?
inherited:
type: boolean
description: Is this policy inherited from an parent resource?
FilteredHierarchicalResourceRole:
type: object
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1704,6 +1704,9 @@ class PostgresAccessPolicyDAO(
val roleAction = RoleActionTable.syntax("roleAction")
val resourceAction = ResourceActionTable.syntax("resourceAction")
val resource = ResourceTable.syntax("resource")
val authDomain = AuthDomainTable.syntax("authDomain")
val authDomainGroup = GroupTable.syntax("authDomainGroup")
val authDomainGroupMemberFlat = GroupMemberFlatTable.syntax("authDomainGroupMemberFlat")

val resourceTypeConstraint =
if (resourceTypeNames.nonEmpty) samsqls"and ${resource.resourceTypeId} in (${resourceTypeNames.flatMap(resourceTypePKsByName.get)})"
Expand All @@ -1714,7 +1717,7 @@ class PostgresAccessPolicyDAO(

val policyRoleActionQuery =
samsqls"""
select ${resource.result.name}, ${resource.result.resourceTypeId}, ${resourcePolicy.result.name}, ${resourceRole.result.role}, ${resourceAction.result.action}, ${resourcePolicy.result.public}
select ${resource.result.name}, ${resource.result.resourceTypeId}, ${resourcePolicy.result.name}, ${resourceRole.result.role}, ${resourceAction.result.action}, ${resourcePolicy.result.public}, ${authDomainGroup.result.name}, ${authDomainGroupMemberFlat.memberUserId} is not null as in_auth_domain, ${resourcePolicy.resourceId} != ${resource.id} as inherited
from ${GroupMemberFlatTable as groupMemberFlat}
left join ${PolicyTable as resourcePolicy} on ${groupMemberFlat.groupId} = ${resourcePolicy.groupId}
left join ${EffectiveResourcePolicyTable as effectiveResourcePolicy} on ${resourcePolicy.id} = ${effectiveResourcePolicy.sourcePolicyId}
Expand All @@ -1723,28 +1726,34 @@ class PostgresAccessPolicyDAO(
left join ${RoleActionTable as roleAction} on ${effectivePolicyRole.resourceRoleId} = ${roleAction.resourceRoleId}
left join ${ResourceActionTable as resourceAction} on ${roleAction.resourceActionId} = ${resourceAction.id}
left join ${ResourceTable as resource} on ${effectiveResourcePolicy.resourceId} = ${resource.id}
left join ${AuthDomainTable as authDomain} on ${authDomain.resourceId} = ${resource.id}
left join ${GroupTable as authDomainGroup} on ${authDomainGroup.id} = ${authDomain.groupId}
left join ${GroupMemberFlatTable as authDomainGroupMemberFlat} on ${authDomainGroup.id} = ${authDomainGroupMemberFlat.groupId} and ${authDomainGroupMemberFlat.memberUserId} = ${samUser.id}
where ${groupMemberFlat.memberUserId} = ${samUser.id}
$resourceTypeConstraint
$policyConstraint
$roleConstraint
$actionConstraint"""
val policyActionQuery =
samsqls"""
select ${resource.result.name}, ${resource.result.resourceTypeId}, ${resourcePolicy.result.name}, null as ${resourceRole.resultName.role}, ${resourceAction.result.action}, ${resourcePolicy.result.public}
select ${resource.result.name}, ${resource.result.resourceTypeId}, ${resourcePolicy.result.name}, null as ${resourceRole.resultName.role}, ${resourceAction.result.action}, ${resourcePolicy.result.public}, ${authDomainGroup.result.name}, ${authDomainGroupMemberFlat.memberUserId} is not null as in_auth_domain, ${resourcePolicy.resourceId} != ${resource.id} as inherited
from ${GroupMemberFlatTable as groupMemberFlat}
left join ${PolicyTable as resourcePolicy} on ${groupMemberFlat.groupId} = ${resourcePolicy.groupId}
left join ${EffectiveResourcePolicyTable as effectiveResourcePolicy} on ${resourcePolicy.id} = ${effectiveResourcePolicy.sourcePolicyId}
left join ${EffectivePolicyActionTable as effectivePolicyAction} on ${effectiveResourcePolicy.id} = ${effectivePolicyAction.effectiveResourcePolicyId}
left join ${ResourceActionTable as resourceAction} on ${effectivePolicyAction.resourceActionId} = ${resourceAction.id}
left join ${ResourceTable as resource} on ${effectiveResourcePolicy.resourceId} = ${resource.id}
left join ${AuthDomainTable as authDomain} on ${authDomain.resourceId} = ${resource.id}
left join ${GroupTable as authDomainGroup} on ${authDomainGroup.id} = ${authDomain.groupId}
left join ${GroupMemberFlatTable as authDomainGroupMemberFlat} on ${authDomainGroup.id} = ${authDomainGroupMemberFlat.groupId} and ${authDomainGroupMemberFlat.memberUserId} = ${samUser.id}
where ${groupMemberFlat.memberUserId} = ${samUser.id}
$resourceTypeConstraint
$policyConstraint
$actionConstraint"""

val publicRoleActionQuery =
samsqls"""
select ${resource.result.name}, ${resource.result.resourceTypeId}, ${resourcePolicy.result.name}, ${resourceRole.result.role}, ${resourceAction.result.action}, ${resourcePolicy.result.public}
select ${resource.result.name}, ${resource.result.resourceTypeId}, ${resourcePolicy.result.name}, ${resourceRole.result.role}, ${resourceAction.result.action}, ${resourcePolicy.result.public}, null as ${authDomainGroup.resultName.name}, null as in_auth_domain, ${resourcePolicy.resourceId} != ${resource.id} as inherited
from ${PolicyTable as resourcePolicy}
left join ${EffectiveResourcePolicyTable as effectiveResourcePolicy} on ${resourcePolicy.id} = ${effectiveResourcePolicy.sourcePolicyId} and ${resourcePolicy.public}
left join ${EffectivePolicyRoleTable as effectivePolicyRole} on ${effectiveResourcePolicy.id} = ${effectivePolicyRole.effectiveResourcePolicyId}
Expand All @@ -1759,7 +1768,7 @@ class PostgresAccessPolicyDAO(
$actionConstraint"""
val publicPolicyActionQuery =
samsqls"""
select ${resource.result.name}, ${resource.result.resourceTypeId}, ${resourcePolicy.result.name}, null as ${resourceRole.resultName.role}, ${resourceAction.result.action}, ${resourcePolicy.result.public}
select ${resource.result.name}, ${resource.result.resourceTypeId}, ${resourcePolicy.result.name}, null as ${resourceRole.resultName.role}, ${resourceAction.result.action}, ${resourcePolicy.result.public}, null as ${authDomainGroup.resultName.name}, null as in_auth_domain, ${resourcePolicy.resourceId} != ${resource.id} as inherited
from ${PolicyTable as resourcePolicy}
left join ${EffectiveResourcePolicyTable as effectiveResourcePolicy} on ${resourcePolicy.id} = ${effectiveResourcePolicy.sourcePolicyId} and ${resourcePolicy.public}
left join ${EffectivePolicyActionTable as effectivePolicyAction} on ${effectiveResourcePolicy.id} = ${effectivePolicyAction.effectiveResourcePolicyId}
Expand Down Expand Up @@ -1788,7 +1797,10 @@ class PostgresAccessPolicyDAO(
rs.stringOpt(resourcePolicy.resultName.name).map(AccessPolicyName(_)),
rs.stringOpt(resourceRole.resultName.role).map(ResourceRoleName(_)),
rs.stringOpt(resourceAction.resultName.action).map(ResourceAction(_)),
rs.get[Boolean](resourcePolicy.resultName.public)
rs.get[Boolean](resourcePolicy.resultName.public),
rs.stringOpt(authDomainGroup.resultName.name).map(WorkbenchGroupName(_)),
rs.booleanOpt("in_auth_domain").getOrElse(false),
rs.booleanOpt("inherited").getOrElse(false)
)
)
.list()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package org.broadinstitute.dsde.workbench.sam.model

import org.broadinstitute.dsde.workbench.model.WorkbenchGroupName

case class FilterResourcesResult(
resourceId: ResourceId,
resourceTypeName: ResourceTypeName,
policy: Option[AccessPolicyName],
role: Option[ResourceRoleName],
action: Option[ResourceAction],
isPublic: Boolean
isPublic: Boolean,
authDomain: Option[WorkbenchGroupName],
inAuthDomain: Boolean,
inherited: Boolean
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.broadinstitute.dsde.workbench.sam.model.api

import org.broadinstitute.dsde.workbench.model.WorkbenchGroupName
import org.broadinstitute.dsde.workbench.sam.model.{AccessPolicyName, ResourceAction, ResourceId, ResourceRoleName, ResourceTypeName}
import spray.json.DefaultJsonProtocol.jsonFormat1
import spray.json.RootJsonFormat
Expand All @@ -15,7 +16,7 @@ case class FilteredResourcesFlat(resources: Set[FilteredResourceFlat]) extends F
}

object FilteredResourceFlat {
implicit val FilteredResourceFlatFormat: RootJsonFormat[FilteredResourceFlat] = jsonFormat6(FilteredResourceFlat.apply)
implicit val FilteredResourceFlatFormat: RootJsonFormat[FilteredResourceFlat] = jsonFormat7(FilteredResourceFlat.apply)

}
case class FilteredResourceFlat(
Expand All @@ -24,5 +25,8 @@ case class FilteredResourceFlat(
policies: Set[AccessPolicyName],
roles: Set[ResourceRoleName],
actions: Set[ResourceAction],
isPublic: Boolean
isPublic: Boolean,
inherited: Boolean,
authDomain: Option[WorkbenchGroupName],
inAuthDomain: Boolean
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.broadinstitute.dsde.workbench.sam.model.api

import org.broadinstitute.dsde.workbench.model.WorkbenchGroupName
import org.broadinstitute.dsde.workbench.sam.model.api.SamJsonSupport._
import org.broadinstitute.dsde.workbench.sam.model._
import spray.json.DefaultJsonProtocol._
Expand All @@ -13,15 +14,16 @@ case class FilteredResourcesHierarchical(resources: Set[FilteredResourceHierarch
override def format: String = "hierarchical"
}
case object FilteredResourceHierarchicalPolicy {
implicit val filteredResourceHierarchicalPolicyFormat: RootJsonFormat[FilteredResourceHierarchicalPolicy] = jsonFormat4(
implicit val filteredResourceHierarchicalPolicyFormat: RootJsonFormat[FilteredResourceHierarchicalPolicy] = jsonFormat5(
FilteredResourceHierarchicalPolicy.apply
)
}
case class FilteredResourceHierarchicalPolicy(
policy: AccessPolicyName,
roles: Set[FilteredResourceHierarchicalRole],
actions: Set[ResourceAction],
isPublic: Boolean
isPublic: Boolean,
inherited: Boolean
)

case object FilteredResourceHierarchicalRole {
Expand All @@ -31,11 +33,13 @@ case object FilteredResourceHierarchicalRole {
case class FilteredResourceHierarchicalRole(role: ResourceRoleName, actions: Set[ResourceAction])

case object FilteredResourceHierarchical {
implicit val filteredResourceHierarchicalFormat: RootJsonFormat[FilteredResourceHierarchical] = jsonFormat3(FilteredResourceHierarchical.apply)
implicit val filteredResourceHierarchicalFormat: RootJsonFormat[FilteredResourceHierarchical] = jsonFormat5(FilteredResourceHierarchical.apply)

}
case class FilteredResourceHierarchical(
resourceType: ResourceTypeName,
resourceId: ResourceId,
policies: Set[FilteredResourceHierarchicalPolicy]
policies: Set[FilteredResourceHierarchicalPolicy],
authDomain: Option[WorkbenchGroupName],
inAuthDomain: Boolean
)
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,10 @@ class ResourceService(
policies = v.flatMap(_.policy).toSet,
roles = v.flatMap(_.role).toSet,
actions = v.flatMap(_.action).toSet,
isPublic = v.map(_.isPublic).head
isPublic = v.map(_.isPublic).head,
inherited = v.map(_.inherited).head,
authDomain = v.map(_.authDomain).head,
inAuthDomain = v.map(_.inAuthDomain).head
)
}
.toSet
Expand Down Expand Up @@ -935,7 +938,9 @@ class ResourceService(
FilteredResourceHierarchical(
resourceId = resourceId,
resourceType = resourceRows.head.resourceTypeName,
policies = policies
policies = policies,
authDomain = resourceRows.head.authDomain,
inAuthDomain = resourceRows.head.inAuthDomain
)
}
.toSet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,51 @@ class ResourceServiceUnitSpec extends AnyFlatSpec with Matchers with ScalaFuture
Some(AccessPolicyName(UUID.randomUUID().toString)),
Some(readerRoleName),
Some(readAction),
true
true,
None,
false,
false
),
FilterResourcesResult(
ResourceId(UUID.randomUUID().toString),
resourceTypeName,
Some(AccessPolicyName(UUID.randomUUID().toString)),
None,
None,
true,
None,
false,
false
),
FilterResourcesResult(ResourceId(UUID.randomUUID().toString), resourceTypeName, Some(AccessPolicyName(UUID.randomUUID().toString)), None, None, true),
FilterResourcesResult(
ResourceId(UUID.randomUUID().toString),
resourceTypeName,
Some(AccessPolicyName(UUID.randomUUID().toString)),
Some(readerRoleName),
Some(readAction),
false,
None,
false,
false
),
FilterResourcesResult(
ResourceId(UUID.randomUUID().toString),
resourceTypeName,
Some(AccessPolicyName(UUID.randomUUID().toString)),
None,
None,
false,
None,
false,
false
),
FilterResourcesResult(ResourceId(UUID.randomUUID().toString), resourceTypeName, Some(AccessPolicyName(UUID.randomUUID().toString)), None, None, false),
// Testable DB Results
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy1), Some(readerRoleName), Some(readAction), false),
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy2), Some(nothingRoleName), None, true),
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy3), None, None, false),
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy4), Some(ownerRoleName), Some(readAction), false),
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy4), Some(ownerRoleName), Some(writeAction), false),
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy5), None, Some(readAction), true)
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy1), Some(readerRoleName), Some(readAction), false, None, false, false),
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy2), Some(nothingRoleName), None, true, None, false, false),
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy3), None, None, false, None, false, false),
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy4), Some(ownerRoleName), Some(readAction), false, None, false, false),
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy4), Some(ownerRoleName), Some(writeAction), false, None, false, false),
FilterResourcesResult(testResourceId, resourceTypeName, Some(testPolicy5), None, Some(readAction), true, None, false, false)
)

val mockAccessPolicyDAO = mock[AccessPolicyDAO]
Expand Down
Loading