Skip to content

Commit

Permalink
Merge 0f15996 into d2cb2ce
Browse files Browse the repository at this point in the history
  • Loading branch information
marctalbott committed Sep 28, 2020
2 parents d2cb2ce + 0f15996 commit ad36e9d
Show file tree
Hide file tree
Showing 20 changed files with 751 additions and 285 deletions.
4 changes: 4 additions & 0 deletions docker/run-opendj.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ start() {
CONTAINER_NAME=opendj-${BUILD_TAG}
fi
fi

echo "attempting to remove old $CONTAINER_NAME container..."
docker rm -f $CONTAINER_NAME || echo "docker rm failed. nothing to rm."

echo "starting up container $CONTAINER_NAME..."
docker run --name $CONTAINER_NAME -e ROOTPASS="testtesttest" -e BASE_DN=dc=dsde-dev,dc=broadinstitute,dc=org -v ${PWD}/docker/opendjsetup.sh:/opt/opendj/bootstrap/setup.sh -v ${PWD}/docker/example-v1.json:/opt/example-v1.json -d -p $PORT broadinstitute/openam:opendj
echo "sleeping 40 seconds til opendj is up and happy. This does not check anything."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
<include file="changesets/20200212_identity_concentrator_id.xml" relativeToChangelogFile="true"/>
<include file="changesets/20200424_add_sam_resource_policy_group_id_index.xml" relativeToChangelogFile="true"/>
<include file="changesets/20200714_resource_parent_id.xml" relativeToChangelogFile="true"/>
<include file="changesets/20200901_descendant_permissions.xml" relativeToChangelogFile="true"/>

</databaseChangeLog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?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="mtalbott" id="drop_policy_action_PK">
<dropPrimaryKey tableName="sam_policy_action" constraintName="sam_policy_action_pkey"/>
</changeSet>

<changeSet logicalFilePath="dummy" author="mtalbott" id="descendant_policy_actions">
<addColumn tableName="sam_policy_action">
<column name="descends" type="BOOLEAN" defaultValue="false">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>

<changeSet logicalFilePath="dummy" author="mtalbott" id="re-add_policy_action_PK">
<addPrimaryKey tableName="sam_policy_action" columnNames="resource_policy_id, resource_action_id, descends" constraintName="sam_policy_action_pkey"/>
</changeSet>

<changeSet logicalFilePath="dummy" author="mtalbott" id="drop_policy_role_PK">
<dropPrimaryKey tableName="sam_policy_role" constraintName="sam_policy_role_pkey"/>
</changeSet>

<changeSet logicalFilePath="dummy" author="mtalbott" id="descendant_policy_roles">
<addColumn tableName="sam_policy_role">
<column name="descends" type="BOOLEAN" defaultValue="false">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>

<changeSet logicalFilePath="dummy" author="mtalbott" id="re-add_policy_role_PK">
<addPrimaryKey tableName="sam_policy_role" columnNames="resource_policy_id, resource_role_id, descends" constraintName="sam_policy_role_pkey"/>
</changeSet>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -78,26 +78,35 @@ trait ResourceRoutes extends UserInfoDirectives with SecurityDirectives with Sam
}
} ~ pathPrefix("policies") {
pathEndOrSingleSlash {
getResourcePolicies(resource, userInfo, samRequestContext)
requireActionsForListPolicies(resource, userInfo, samRequestContext) {
complete(resourceService.listResourcePolicies(resource, samRequestContext).map { responseV2 =>
val responseV1 = responseV2.map { responseEntry =>
responseEntry.copy(policy=responseEntry.policy.toV1)
}
StatusCodes.OK -> responseV1.toSet
})
}
} ~ pathPrefix(Segment) { policyName =>
val policyId = FullyQualifiedPolicyId(resource, AccessPolicyName(policyName))

pathEndOrSingleSlash {
getPolicy(policyId, userInfo, samRequestContext) ~
putPolicyOverwrite(resourceType, policyId, userInfo, samRequestContext)
requireActionsForGetPolicy(policyId, userInfo, samRequestContext) {
complete(resourceService.loadResourcePolicy(policyId, samRequestContext).map {
case Some(response) => StatusCodes.OK -> response.toV1
case None => throw new WorkbenchExceptionWithErrorReport(ErrorReport(StatusCodes.NotFound, "policy not found"))
})
} ~
putPolicyOverwrite(resourceType, policyId, userInfo, samRequestContext)

} ~ pathPrefix("memberEmails") {
pathEndOrSingleSlash {
putPolicyMembershipOverwrite(resourceType, policyId, userInfo, samRequestContext)
} ~ pathPrefix(Segment) { email =>
withSubject(WorkbenchEmail(email), samRequestContext) { subject =>
pathEndOrSingleSlash {
requireOneOfAction(
resource,
Set(SamResourceActions.alterPolicies, SamResourceActions.sharePolicy(policyId.accessPolicyName)),
userInfo.userId,
samRequestContext) {
requireActionsForSharePolicy(policyId, userInfo, samRequestContext) {
pathEndOrSingleSlash {
putPolicyMembershipOverwrite(resourceType, policyId, userInfo, samRequestContext)
} ~ pathPrefix(Segment) { email =>
withSubject(WorkbenchEmail(email), samRequestContext) { subject =>
pathEndOrSingleSlash {
putUserInPolicy(policyId, subject, samRequestContext) ~
deleteUserFromPolicy(policyId, subject, samRequestContext)
deleteUserFromPolicy(policyId, subject, samRequestContext)
}
}
}
Expand Down Expand Up @@ -132,20 +141,104 @@ trait ResourceRoutes extends UserInfoDirectives with SecurityDirectives with Sam
requireUserInfo(samRequestContext) { userInfo =>
pathPrefix(Segment) { resourceTypeName =>
withResourceType(ResourceTypeName(resourceTypeName)) { resourceType =>
pathEndOrSingleSlash {
getUserPoliciesForResourceType(resourceType, userInfo, samRequestContext) ~
postResource(resourceType, userInfo, samRequestContext)
} ~
pathPrefix(Segment) { resourceId =>
val resource = FullyQualifiedResourceId(resourceType.name, ResourceId(resourceId))
path("parent") {
getResourceParent(resource, userInfo, samRequestContext) ~
setResourceParent(resource, userInfo, samRequestContext) ~
deleteResourceParent(resource, userInfo, samRequestContext)

pathEndOrSingleSlash {
deleteResource(resource, userInfo, samRequestContext) ~
postDefaultResource(resourceType, resource, userInfo, samRequestContext)
} ~
path("children") {
getResourceChildren(resource, userInfo, samRequestContext)
pathPrefix("action") {
pathPrefix(Segment) { action =>
pathEndOrSingleSlash {
getActionPermissionForUser(resource, userInfo, action, samRequestContext)
} ~
pathPrefix("userEmail") {
pathPrefix(Segment) { userEmail =>
pathEndOrSingleSlash {
getActionPermissionForUserEmail(resource, userInfo, ResourceAction(action), WorkbenchEmail(userEmail), samRequestContext)
}
}
}
}
} ~
pathPrefix("authDomain") {
pathEndOrSingleSlash {
getResourceAuthDomain(resource, userInfo, samRequestContext)
}
} ~
pathPrefix("roles") {
pathEndOrSingleSlash {
getUserResourceRoles(resource, userInfo, samRequestContext)
}
} ~
pathPrefix ("policies" / Segment) { policyName =>
val policyId = FullyQualifiedPolicyId(resource, AccessPolicyName(policyName))
pathPrefix("actions") {
pathEndOrSingleSlash {
deletePolicy(policyId, userInfo, samRequestContext)
listActionsForUser(resource, userInfo, samRequestContext)
}
} ~
pathPrefix("allUsers") {
pathEndOrSingleSlash {
getAllResourceUsers(resource, userInfo, samRequestContext)
}
} ~
pathPrefix("parent") {
pathEndOrSingleSlash {
getResourceParent(resource, userInfo, samRequestContext) ~
setResourceParent(resource, userInfo, samRequestContext) ~
deleteResourceParent(resource, userInfo, samRequestContext)
}
} ~
pathPrefix("children") {
pathEndOrSingleSlash {
getResourceChildren(resource, userInfo, samRequestContext)
}
} ~
pathPrefix ("policies") {
pathEndOrSingleSlash {
requireActionsForListPolicies(resource, userInfo, samRequestContext) {
complete(resourceService.listResourcePolicies(resource, samRequestContext).map { response =>
StatusCodes.OK -> response.toSet
})
}
} ~ pathPrefix(Segment) { policyName =>
val policyId = FullyQualifiedPolicyId(resource, AccessPolicyName(policyName))

pathEndOrSingleSlash {
requireActionsForGetPolicy(policyId, userInfo, samRequestContext) {
complete(resourceService.loadResourcePolicy(policyId, samRequestContext).map {
case Some(response) => StatusCodes.OK -> response
case None => throw new WorkbenchExceptionWithErrorReport(ErrorReport(StatusCodes.NotFound, "policy not found"))
})
} ~
putPolicyOverwrite(resourceType, policyId, userInfo, samRequestContext) ~
deletePolicy(policyId, userInfo, samRequestContext) ~
pathPrefix("memberEmails") {
requireActionsForSharePolicy(policyId, userInfo, samRequestContext) {
pathEndOrSingleSlash {
putPolicyMembershipOverwrite(resourceType, policyId, userInfo, samRequestContext)
} ~
pathPrefix(Segment) { email =>
withSubject(WorkbenchEmail(email), samRequestContext) { subject =>
pathEndOrSingleSlash {
putUserInPolicy(policyId, subject, samRequestContext) ~
deleteUserFromPolicy(policyId, subject, samRequestContext)
}
}
}
}
} ~
pathPrefix("public") {
pathEndOrSingleSlash {
getPublicFlag(policyId, userInfo, samRequestContext) ~
putPublicFlag(policyId, userInfo, samRequestContext)
}
}
}
}
}
}
Expand Down Expand Up @@ -236,41 +329,41 @@ trait ResourceRoutes extends UserInfoDirectives with SecurityDirectives with Sam
}
}

def getResourcePolicies(resource: FullyQualifiedResourceId, userInfo: UserInfo, samRequestContext: SamRequestContext): server.Route =
private def requireActionsForListPolicies(resource: FullyQualifiedResourceId, userInfo: UserInfo, samRequestContext: SamRequestContext)(listResourcePolicies: server.Route): server.Route =
get {
requireAction(resource, SamResourceActions.readPolicies, userInfo.userId, samRequestContext) {
complete(resourceService.listResourcePolicies(resource, samRequestContext).map { response =>
StatusCodes.OK -> response.toSet
})
listResourcePolicies
}
}

def getPolicy(policyId: FullyQualifiedPolicyId, userInfo: UserInfo, samRequestContext: SamRequestContext): server.Route =
private def requireActionsForGetPolicy(policyId: FullyQualifiedPolicyId, userInfo: UserInfo, samRequestContext: SamRequestContext)(loadResourcePolicy: server.Route): server.Route = {
get {
requireOneOfAction(policyId.resource, Set(SamResourceActions.readPolicies, SamResourceActions.readPolicy(policyId.accessPolicyName)), userInfo.userId, samRequestContext) {
complete(resourceService.loadResourcePolicy(policyId, samRequestContext).map {
case Some(response) => StatusCodes.OK -> response
case None => throw new WorkbenchExceptionWithErrorReport(ErrorReport(StatusCodes.NotFound, "policy not found"))
})
loadResourcePolicy
}
}
}

def putPolicyOverwrite(resourceType: ResourceType, policyId: FullyQualifiedPolicyId, userInfo: UserInfo, samRequestContext: SamRequestContext): server.Route =
def putPolicyOverwrite(resourceType: ResourceType, policyId: FullyQualifiedPolicyId, userInfo: UserInfo, samRequestContext: SamRequestContext): server.Route = {
put {
requireAction(policyId.resource, SamResourceActions.alterPolicies, userInfo.userId, samRequestContext) {
entity(as[AccessPolicyMembership]) { membershipUpdate =>
entity(as[AccessPolicyMembership]) { membershipUpdate =>
requireAction(policyId.resource, SamResourceActions.alterPolicies, userInfo.userId, samRequestContext) {
complete(resourceService.overwritePolicy(resourceType, policyId.accessPolicyName, policyId.resource, membershipUpdate, samRequestContext).map(_ => StatusCodes.Created))
}
}
}
}

private def requireActionsForSharePolicy(policyId: FullyQualifiedPolicyId, userInfo: UserInfo, samRequestContext: SamRequestContext)(sharePolicy: server.Route): server.Route =
requireOneOfAction(policyId.resource, Set(SamResourceActions.alterPolicies, SamResourceActions.sharePolicy(policyId.accessPolicyName)), userInfo.userId, samRequestContext) {
sharePolicy
}

def putPolicyMembershipOverwrite(resourceType: ResourceType, policyId: FullyQualifiedPolicyId, userInfo: UserInfo, samRequestContext: SamRequestContext): server.Route =
put {
requireOneOfAction(policyId.resource, Set(SamResourceActions.alterPolicies, SamResourceActions.sharePolicy(policyId.accessPolicyName)), userInfo.userId, samRequestContext) {
entity(as[Set[WorkbenchEmail]]) { membersList =>
complete(
resourceService.overwritePolicyMembers(resourceType, policyId.accessPolicyName, policyId.resource, membersList, samRequestContext).map(_ => StatusCodes.NoContent))
}
entity(as[Set[WorkbenchEmail]]) { membersList =>
complete(
resourceService.overwritePolicyMembers(resourceType, policyId.accessPolicyName, policyId.resource, membersList, samRequestContext).map(_ => StatusCodes.NoContent))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import scalikejdbc._
import org.broadinstitute.dsde.workbench.sam.db.SamTypeBinders

final case class PolicyActionRecord(resourcePolicyId: PolicyPK,
resourceActionId: ResourceActionPK)
resourceActionId: ResourceActionPK,
descends: Boolean)

object PolicyActionTable extends SQLSyntaxSupportWithDefaultSamDB[PolicyActionRecord] {
override def tableName: String = "SAM_POLICY_ACTION"

import SamTypeBinders._
def apply(e: ResultName[PolicyActionRecord])(rs: WrappedResultSet): PolicyActionRecord = PolicyActionRecord(
rs.get(e.resourcePolicyId),
rs.get(e.resourceActionId)
rs.get(e.resourceActionId),
rs.get(e.descends)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import scalikejdbc._
import org.broadinstitute.dsde.workbench.sam.db.SamTypeBinders

final case class PolicyRoleRecord(resourcePolicyId: PolicyPK,
resourceRoleId: ResourceRolePK)
resourceRoleId: ResourceRolePK,
descends: Boolean)

object PolicyRoleTable extends SQLSyntaxSupportWithDefaultSamDB[PolicyRoleRecord] {
override def tableName: String = "SAM_POLICY_ROLE"

import SamTypeBinders._
def apply(e: ResultName[PolicyRoleRecord])(rs: WrappedResultSet): PolicyRoleRecord = PolicyRoleRecord(
rs.get(e.resourcePolicyId),
rs.get(e.resourceRoleId)
rs.get(e.resourceRoleId),
rs.get(e.descends)
)
}
Loading

0 comments on commit ad36e9d

Please sign in to comment.