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

CORE-20721: RBAC Group Resource DB implementation #6257

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package net.corda.libs.permissions.common.exception

import net.corda.v5.base.exceptions.CordaRuntimeException

class IllegalEntityStateException(message: String) : CordaRuntimeException(message)
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ enum class RestPermissionOperation {
ADD_PROPERTY_TO_GROUP,
DELETE_PERMISSION_FROM_ROLE,
DELETE_ROLE_FROM_USER,
DELETE_ROLE_FROM_GROUP,
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ interface GroupEndpoint : RestResource {

@HttpGET(
path = "{groupId}",
description = "This method retrieves the content of a specified group.",
description = "This method retrieves the content of a specified group, " +
"including users and groups with this group as parent.",
responseDescription = """
The content of the specified group with the following attributes:
id: Unique server generated identifier for the group
Expand All @@ -114,7 +115,10 @@ interface GroupEndpoint : RestResource {
name: The name of the group
parentGroupId: The ID of the parent group
properties: An optional set of key/value properties associated with a group
roleAssociations: A set of roles associated with the group"""
roleAssociations: A set of roles associated with the group
users: A set of users which have this group as their parent group
subgroups: A set of groups which have this group as their parent group
"""
)
fun getGroupContent(
@RestPathParameter(description = "ID of the group to get content.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ class PermissionStorageReaderImpl(
publisher.publish(listOf(Record(REST_PERM_ENTITY_TOPIC, key = permission.id, value = permission))).single().getOrThrow()
}

override fun publishNewGroup(group: AvroGroup) {
publishUpdatedGroup(group)
}

override fun publishUpdatedGroup(group: AvroGroup) {
publisher.publish(listOf(Record(REST_PERM_GROUP_TOPIC, key = group.id, value = group))).single().getOrThrow()
}

override fun publishDeletedGroup(id: String) {
publisher.publish(listOf(Record(REST_PERM_GROUP_TOPIC, key = id, value = null))).single().getOrThrow()
}

override fun publishGroups(ids: List<String>) {
publisher.publish(createGroupRecords(permissionRepository.findAllGroups(ids)))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.corda.libs.permissions.storage.reader

import net.corda.lifecycle.Resource
import net.corda.data.permissions.Group as AvroGroup
import net.corda.data.permissions.Permission as AvroPermission
import net.corda.data.permissions.Role as AvroRole
import net.corda.data.permissions.User as AvroUser
Expand Down Expand Up @@ -58,6 +59,27 @@ interface PermissionStorageReader : Resource {
*/
fun publishNewPermission(permission: AvroPermission)

/**
* Broadcasts a new group onto the messaging bus.
*
* @param group The group to be published.
*/
fun publishNewGroup(group: AvroGroup)

/**
* Broadcasts an updated group onto the messaging bus.
*
* @param group The group to be published.
*/
fun publishUpdatedGroup(group: AvroGroup)

/**
* Broadcasts the deleted group onto the messaging bus.
*
* @param id The id of the group to be deleted.
*/
fun publishDeletedGroup(id: String)

/**
* Reads updated groups based on the ids passed into this method and publishes them to the message bus.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import net.corda.data.ExceptionEnvelope
import net.corda.data.permissions.Permission
import net.corda.data.permissions.management.PermissionManagementRequest
import net.corda.data.permissions.management.PermissionManagementResponse
import net.corda.data.permissions.management.group.AddRoleToGroupRequest
import net.corda.data.permissions.management.group.ChangeGroupParentIdRequest
import net.corda.data.permissions.management.group.CreateGroupRequest
import net.corda.data.permissions.management.group.DeleteGroupRequest
import net.corda.data.permissions.management.group.RemoveRoleFromGroupRequest
import net.corda.data.permissions.management.permission.BulkCreatePermissionsRequest
import net.corda.data.permissions.management.permission.BulkCreatePermissionsResponse
import net.corda.data.permissions.management.permission.CreatePermissionRequest
Expand All @@ -17,6 +22,7 @@ import net.corda.data.permissions.management.user.DeleteUserRequest
import net.corda.data.permissions.management.user.RemoveRoleFromUserRequest
import net.corda.libs.permissions.storage.reader.PermissionStorageReader
import net.corda.libs.permissions.storage.writer.PermissionStorageWriterProcessor
import net.corda.libs.permissions.storage.writer.impl.group.GroupWriter
import net.corda.libs.permissions.storage.writer.impl.permission.PermissionWriter
import net.corda.libs.permissions.storage.writer.impl.role.RoleWriter
import net.corda.libs.permissions.storage.writer.impl.user.UserWriter
Expand All @@ -28,14 +34,15 @@ class PermissionStorageWriterProcessorImpl(
private val permissionStorageReaderSupplier: Supplier<PermissionStorageReader?>,
private val userWriter: UserWriter,
private val roleWriter: RoleWriter,
private val groupWriter: GroupWriter,
private val permissionWriter: PermissionWriter
) : PermissionStorageWriterProcessor {

private companion object {
val log = LoggerFactory.getLogger(this::class.java.enclosingClass)
}

@Suppress("ComplexMethod")
@Suppress("ComplexMethod", "LongMethod")
override fun onNext(request: PermissionManagementRequest, respFuture: CompletableFuture<PermissionManagementResponse>) {
try {
val permissionStorageReader = requireNotNull(permissionStorageReaderSupplier.get())
Expand Down Expand Up @@ -126,6 +133,34 @@ class PermissionStorageWriterProcessorImpl(
permissionStorageReader.reconcilePermissionSummaries()
avroRole
}
is CreateGroupRequest -> {
val avroGroup = groupWriter.createGroup(permissionRequest, request.requestUserId)
permissionStorageReader.publishNewGroup(avroGroup)
avroGroup
}
is ChangeGroupParentIdRequest -> {
val avroGroup = groupWriter.changeParentGroup(permissionRequest, request.requestUserId)
permissionStorageReader.publishUpdatedGroup(avroGroup)
permissionStorageReader.reconcilePermissionSummaries()
avroGroup
}
is AddRoleToGroupRequest -> {
val avroGroup = groupWriter.addRoleToGroup(permissionRequest, request.requestUserId)
permissionStorageReader.publishUpdatedGroup(avroGroup)
permissionStorageReader.reconcilePermissionSummaries()
avroGroup
}
is RemoveRoleFromGroupRequest -> {
val avroGroup = groupWriter.removeRoleFromGroup(permissionRequest, request.requestUserId)
permissionStorageReader.publishUpdatedGroup(avroGroup)
permissionStorageReader.reconcilePermissionSummaries()
avroGroup
}
is DeleteGroupRequest -> {
val avroGroup = groupWriter.deleteGroup(permissionRequest, request.requestUserId)
permissionStorageReader.publishDeletedGroup(avroGroup.id)
avroGroup
}
else -> throw IllegalArgumentException("Received invalid permission request type: $permissionRequest")
}
respFuture.complete(PermissionManagementResponse(response))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import net.corda.libs.permissions.storage.reader.PermissionStorageReader
import net.corda.libs.permissions.storage.writer.PermissionStorageWriterProcessor
import net.corda.libs.permissions.storage.writer.factory.PermissionStorageWriterProcessorFactory
import net.corda.libs.permissions.storage.writer.impl.PermissionStorageWriterProcessorImpl
import net.corda.libs.permissions.storage.writer.impl.group.impl.GroupWriterImpl
import net.corda.libs.permissions.storage.writer.impl.permission.impl.PermissionWriterImpl
import net.corda.libs.permissions.storage.writer.impl.role.impl.RoleWriterImpl
import net.corda.libs.permissions.storage.writer.impl.user.impl.UserWriterImpl
Expand All @@ -23,6 +24,7 @@ class PermissionStorageWriterProcessorFactoryImpl : PermissionStorageWriterProce
readerSupplier,
UserWriterImpl(entityManagerFactory),
RoleWriterImpl(entityManagerFactory),
GroupWriterImpl(entityManagerFactory),
PermissionWriterImpl(entityManagerFactory)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package net.corda.libs.permissions.storage.writer.impl.group

import net.corda.data.permissions.management.group.AddRoleToGroupRequest
import net.corda.data.permissions.management.group.ChangeGroupParentIdRequest
import net.corda.data.permissions.management.group.CreateGroupRequest
import net.corda.data.permissions.management.group.DeleteGroupRequest
import net.corda.data.permissions.management.group.RemoveRoleFromGroupRequest
import net.corda.data.permissions.Group as AvroGroup

/**
* Interface for writing group operations to data storage.
*/
interface GroupWriter {
/**
* Create and persist a Group entity and return its Avro representation.
*
* @param request CreateGroupRequest containing the information of the Group to create.
* @param requestUserId ID of the user who made the request.
*/
fun createGroup(request: CreateGroupRequest, requestUserId: String): AvroGroup

/**
* Change the parent group of a Group entity and return its Avro representation.
*
* @param request ChangeGroupParentIdRequest containing the information of the Group to change.
* @param requestUserId ID of the user who made the request.
*/
fun changeParentGroup(request: ChangeGroupParentIdRequest, requestUserId: String): AvroGroup

/**
* Associate a Role to a Group and return its Avro representation.
*
* @param request AddRoleToGroupRequest containing the information of the Role and Group to associate.
* @param requestUserId ID of the user who made the request.
*/
fun addRoleToGroup(request: AddRoleToGroupRequest, requestUserId: String): AvroGroup

/**
* Dissociate a Role from a Group and return its Avro representation.
*
* @param request RemoveRoleFromGroupRequest containing the information of the Role and Group to dissociate.
* @param requestUserId ID of the user who made the request.
*/
fun removeRoleFromGroup(request: RemoveRoleFromGroupRequest, requestUserId: String): AvroGroup

/**
* Delete a Group entity and return its Avro representation.
*
* @param request DeleteGroupRequest containing the information of the Group to delete.
* @param requestUserId ID of the user who made the request.
*/
fun deleteGroup(request: DeleteGroupRequest, requestUserId: String): AvroGroup
}
Loading