Merge pull request #6866 from corda/dan/merge-os-4.7-to-4.8-2021-02-08

NOTICK OS 4.7 to 4.8 2021-02-08
This commit is contained in:
Dan Newton 2021-02-08 15:31:43 +00:00 committed by GitHub
commit 4f336a1a67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 9 deletions

View File

@ -61,6 +61,38 @@ class FlowWithClientIdTest {
} }
} }
@Test(timeout = 300_000)
fun `start flow with client id permissions`() {
val user = User("TonyStark", "I AM IRONMAN", setOf("StartFlow.net.corda.node.flows.FlowWithClientIdTest\$ResultFlow"))
driver(DriverParameters(startNodesInProcess = true, cordappsForAllNodes = emptySet())) {
val nodeA = startNode(rpcUsers = listOf(user)).getOrThrow()
nodeA.rpc.startFlowWithClientId(UUID.randomUUID().toString(), ::ResultFlow, 5).returnValue.getOrThrow(20.seconds)
nodeA.rpc.startFlowDynamicWithClientId(
UUID.randomUUID().toString(),
ResultFlow::class.java,
5
).returnValue.getOrThrow(20.seconds)
}
}
@Test(timeout = 300_000)
fun `start flow with client id without permissions`() {
val user = User("TonyStark", "I AM IRONMAN", setOf())
driver(DriverParameters(startNodesInProcess = true, cordappsForAllNodes = emptySet())) {
val nodeA = startNode(rpcUsers = listOf(user)).getOrThrow()
assertFailsWith<PermissionException> {
nodeA.rpc.startFlowWithClientId(UUID.randomUUID().toString(), ::ResultFlow, 5).returnValue.getOrThrow(20.seconds)
}
assertFailsWith<PermissionException> {
nodeA.rpc.startFlowDynamicWithClientId(
UUID.randomUUID().toString(),
ResultFlow::class.java,
5
).returnValue.getOrThrow(20.seconds)
}
}
}
@Test(timeout = 300_000) @Test(timeout = 300_000)
fun `remove client id`() { fun `remove client id`() {
val clientId = UUID.randomUUID().toString() val clientId = UUID.randomUUID().toString()

View File

@ -27,7 +27,12 @@ internal object AuthenticatedRpcOpsProxy {
private val namedInterfaces = setOf( private val namedInterfaces = setOf(
net.corda.core.messaging.CordaRPCOps::class.java) net.corda.core.messaging.CordaRPCOps::class.java)
private val namedMethods = setOf("startFlowDynamic", "startTrackedFlowDynamic") private val namedMethods = mapOf(
"startFlowDynamic" to 0,
"startTrackedFlowDynamic" to 0,
"startFlowDynamicWithClientId" to 1
)
override fun invoke(proxy: Any, method: Method, arguments: Array<out Any?>?): Any? { override fun invoke(proxy: Any, method: Method, arguments: Array<out Any?>?): Any? {
@ -36,14 +41,17 @@ internal object AuthenticatedRpcOpsProxy {
return super.invoke(proxy, method, arguments) return super.invoke(proxy, method, arguments)
} }
val importantArgs = if (clazz in namedInterfaces && method.name in namedMethods) { val importantArgs = if (clazz in namedInterfaces) {
// Normally list of arguments makes no difference when checking entitlements, however when starting flows // Normally list of arguments makes no difference when checking entitlements, however when starting flows the first or
// first argument represents a class name of the flow to be started and special handling applies in this case with // second argument (depending on whether started with a client id) represents the class name of the flow to be started
// name of the class extracted and passed into `guard` method for entitlements check. // and special handling applies in this case with name of the class extracted and passed into `guard` method for
// entitlements check.
namedMethods[method.name]?.let { index ->
val nonNullArgs = requireNotNull(arguments) val nonNullArgs = requireNotNull(arguments)
require(nonNullArgs.isNotEmpty()) require(nonNullArgs.isNotEmpty())
val firstArgClass = requireNotNull(nonNullArgs[0] as? Class<*>) val className = requireNotNull(nonNullArgs[index] as? Class<*>)
listOf(firstArgClass) listOf(className)
} ?: emptyList()
} else emptyList() } else emptyList()
return guard(method, importantArgs, ::rpcContext) { super.invoke(proxy, method, arguments) } return guard(method, importantArgs, ::rpcContext) { super.invoke(proxy, method, arguments) }