Skip to content

Commit

Permalink
Support authentication via Kong consumer headers (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
rromanowski-figure authored Aug 11, 2023
1 parent 23e5efc commit 17c198e
Show file tree
Hide file tree
Showing 81 changed files with 298 additions and 199 deletions.
1 change: 1 addition & 0 deletions .sdkmanrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
java=11.0.20-tem
17 changes: 8 additions & 9 deletions dc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ function up {
docker-compose -p p8e-contract-execution-environment -f service/docker/dependencies.yaml up --build -d

sleep 2
sh service/docker/vault/init-and-unseal.sh 'http://127.0.0.1:8200' 'kv2_originations'

sleep 2

export VAULT_ADDR="http://127.0.0.1:8200"
SECRET_PATH=kv2_originations
sh service/docker/vault/init-and-unseal.sh $VAULT_ADDR $SECRET_PATH

until vault status; do echo "Awaiting vault to be unsealed..."; sleep 5; done

# local-originator
cat service/docker/vault/secrets/local-originator.json | vault kv put $SECRET_PATH/originators/00000000-0000-0000-0000-000000000001 - > /dev/null
cat service/docker/vault/secrets/local-originator.json | vault kv put $SECRET_PATH/originators/tp1qy2mqx5x22a400pgd5p6u7mq9shxzvh767jar0 - > /dev/null
Expand Down Expand Up @@ -120,11 +120,10 @@ function build_classification() {
}

function setup() {
brew install docker
brew tap hashicorp/tap
brew install hashicorp/tap/vault
brew install rust
brew install jq
which -s docker || brew install docker
which -s vault || { brew tap hashicorp/tap; brew install hashicorp/tap/vault; }
which -s rust || brew install rust
which -s jq || brew install jq
brew install coreutils
}

Expand Down
27 changes: 27 additions & 0 deletions models/src/main/kotlin/io/provenance/api/models/entity/EntityID.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.provenance.api.models.entity

import java.util.UUID

sealed interface Entity { val id: String }

/**
* Kong consumer
*
* @property id
* @property username - will be null for consumers created for delegated keys
* @property customId - contains granter address for delegated keys
* @constructor Create empty Kong consumer
*/
data class KongConsumer(
val entityId: String,
val username: String?,
val customId: String,
) : Entity {
override val id: String
get() = entityId
}

data class MemberUUID(val value: UUID) : Entity {
override val id: String
get() = value.toString()
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package io.provenance.api.models.p8e.query

import io.provenance.api.models.entity.Entity
import java.util.UUID

data class QueryScopeRequest(
val uuid: UUID,
val entity: Entity,
val scopeUuid: UUID,
val chainId: String,
val nodeEndpoint: String,
Expand Down
2 changes: 1 addition & 1 deletion service/docker/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ services:
- provenance:/provenance

vault:
image: vault:latest
image: hashicorp/vault:latest
container_name: vault-cee
networks:
- p8e-network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class ApproveContractBatchExecution(
val responses = mutableListOf<ApproveContractExecutionResponse>()
val errors = mutableListOf<ApproveContractExecutionErrorResponse>()
val executionResults = mutableListOf<Pair<Envelopes.EnvelopeState, List<Tx.MsgGrant>>>()
val signer = getSigner.execute(GetSignerRequest(args.uuid, args.request.account))
createClient.execute(CreateClientRequest(args.uuid, args.request.account, args.request.client)).use { client ->
val signer = getSigner.execute(GetSignerRequest(args.entity, args.request.account))
createClient.execute(CreateClientRequest(args.entity, args.request.account, args.request.client)).use { client ->

args.request.approvals.forEach {
val envelope = Envelopes.Envelope.newBuilder().mergeFrom(it.envelope).build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ class ApproveContractExecution(
) : AbstractUseCase<ApproveContractRequestWrapper, ApproveContractExecutionResponse>() {
override suspend fun execute(args: ApproveContractRequestWrapper): ApproveContractExecutionResponse {
val envelope = Envelopes.Envelope.newBuilder().mergeFrom(args.request.approval.envelope).build()
createClient.execute(CreateClientRequest(args.uuid, args.request.account, args.request.client)).use { client ->
createClient.execute(CreateClientRequest(args.entity, args.request.account, args.request.client)).use { client ->

val result = client.execute(envelope)
if (result is FragmentResult) {
val tx = client.approveScopeUpdate(result.envelopeState, args.request.approval.expiration).let {
val signer = getSigner.execute(GetSignerRequest(args.uuid, args.request.account))
val signer = getSigner.execute(GetSignerRequest(args.entity, args.request.account))
provenance.executeTransaction(args.request.provenanceConfig, it.toAny(), signer)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.provenance.api.domain.usecase.cee.approve.models

import io.provenance.api.models.entity.Entity
import io.provenance.api.models.cee.approve.ApproveContractBatchRequest
import java.util.UUID

data class ApproveContractBatchRequestWrapper(
val uuid: UUID,
val entity: Entity,
val request: ApproveContractBatchRequest
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.provenance.api.domain.usecase.cee.approve.models

import io.provenance.api.models.entity.Entity
import io.provenance.api.models.cee.approve.ApproveContractRequest
import java.util.UUID

data class ApproveContractRequestWrapper(
val uuid: UUID,
val entity: Entity,
val request: ApproveContractRequest
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import io.provenance.api.models.account.Participant
import io.provenance.api.models.cee.ParserConfig
import io.provenance.api.models.cee.execute.ExecuteContractConfig
import io.provenance.api.models.cee.execute.ScopeInfo
import io.provenance.api.models.entity.Entity
import io.provenance.api.models.p8e.PermissionInfo
import io.provenance.client.protobuf.extensions.isSet
import io.provenance.metadata.v1.ScopeResponse
Expand All @@ -20,11 +21,10 @@ import io.provenance.scope.contract.spec.P8eContract
import io.provenance.scope.encryption.util.toJavaPublicKey
import io.provenance.scope.sdk.Client
import io.provenance.scope.sdk.Session
import java.util.UUID
import kotlin.reflect.KType
import kotlin.reflect.full.functions
import mu.KotlinLogging
import org.springframework.stereotype.Component
import kotlin.reflect.KType
import kotlin.reflect.full.functions

@Component
class ContractUtilities(
Expand All @@ -36,12 +36,12 @@ class ContractUtilities(
) {
private val log = KotlinLogging.logger { }

suspend fun createClient(uuid: UUID, permissions: PermissionInfo?, participants: List<Participant>, config: ExecuteContractConfig): Client {
suspend fun createClient(entity: Entity, permissions: PermissionInfo?, participants: List<Participant>, config: ExecuteContractConfig): Client {
val audiences = entityManager.hydrateKeys(permissions, participants)
return createClient.execute(CreateClientRequest(uuid, config.account, config.client, audiences))
return createClient.execute(CreateClientRequest(entity, config.account, config.client, audiences))
}

suspend fun createSession(uuid: UUID, client: Client, permissions: PermissionInfo?, participants: List<Participant>, config: ExecuteContractConfig, records: Map<String, Any>, scopes: List<ScopeInfo>): List<Session> {
suspend fun createSession(client: Client, permissions: PermissionInfo?, participants: List<Participant>, config: ExecuteContractConfig, records: Map<String, Any>, scopes: List<ScopeInfo>): List<Session> {
val audiences = entityManager.hydrateKeys(permissions, participants)
val contract = contractService.getContract(config.contract.contractName)
val parsedRecords = getRecords(contractParser, records, contract, config.contract.parserConfig)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ class CreateClient(
private val entityManager: EntityManager,
) : AbstractUseCase<CreateClientRequest, Client>() {
override suspend fun execute(args: CreateClientRequest): Client {
val originator = entityManager.getEntity(KeyManagementConfigWrapper(args.uuid.toString(), args.account.keyManagementConfig))
val originator = entityManager.getEntity(
KeyManagementConfigWrapper(
entityId = args.entity.id,
config = args.account.keyManagementConfig
)
)
val affiliate = Affiliate(
signingKeyRef = originator.getKeyRef(KeyType.SIGNING),
encryptionKeyRef = originator.getKeyRef(KeyType.ENCRYPTION),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package io.provenance.api.domain.usecase.cee.common.client.model

import io.provenance.api.models.entity.Entity
import io.provenance.api.models.account.AccountInfo
import io.provenance.api.models.eos.ObjectStoreConfig
import io.provenance.api.models.p8e.AudienceKeyPair
import java.util.UUID

data class CreateClientRequest(
val uuid: UUID,
val entity: Entity,
val account: AccountInfo = AccountInfo(),
val client: ObjectStoreConfig,
val affiliates: Set<AudienceKeyPair> = emptySet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,16 @@ class ExecuteContract(
) : AbstractUseCase<ExecuteContractRequestWrapper, ContractExecutionResponse>() {

override suspend fun execute(args: ExecuteContractRequestWrapper): ContractExecutionResponse {
val signer = getSigner.execute(GetSignerRequest(args.uuid, args.request.config.account))
contractUtilities.createClient(args.uuid, args.request.permissions, args.request.additionalParticipants, args.request.config).use { client ->
val session = contractUtilities.createSession(args.uuid, client, args.request.permissions, args.request.additionalParticipants, args.request.config, args.request.records, listOf(args.request.scope)).single()
val signer = getSigner.execute(GetSignerRequest(args.entity, args.request.config.account))
contractUtilities.createClient(args.entity, args.request.permissions, args.request.additionalParticipants, args.request.config).use { client ->
val session = contractUtilities.createSession(
client = client,
permissions = args.request.permissions,
participants = args.request.additionalParticipants,
config = args.request.config,
records = args.request.records,
scopes = listOf(args.request.scope)
).single()

return when (val result = contractService.executeContract(client, session)) {
is SignedResult -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,10 @@ class ExecuteContractBatch(
val pending = mutableListOf<ContractExecutionResponse>()
val errors = mutableListOf<ContractExecutionErrorResponse>()
val results = mutableListOf<Pair<UUID, ExecutionResult>>()
val signer = getSigner.execute(GetSignerRequest(args.uuid, args.request.config.account))
contractUtilities.createClient(args.uuid, args.request.permissions, args.request.additionalParticipants, args.request.config).use { client ->
val signer = getSigner.execute(GetSignerRequest(args.entity, args.request.config.account))
contractUtilities.createClient(args.entity, args.request.permissions, args.request.additionalParticipants, args.request.config).use { client ->

contractUtilities.createSession(
args.uuid,
client,
args.request.permissions,
args.request.additionalParticipants,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.provenance.api.domain.usecase.cee.execute.model

import io.provenance.api.models.entity.Entity
import io.provenance.api.models.cee.execute.ExecuteContractBatchRequest
import java.util.UUID

data class ExecuteContractBatchRequestWrapper(
val uuid: UUID,
val entity: Entity,
val request: ExecuteContractBatchRequest,
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.provenance.api.domain.usecase.cee.execute.model

import io.provenance.api.models.entity.Entity
import io.provenance.api.models.cee.execute.ExecuteContractRequest
import java.util.UUID

data class ExecuteContractRequestWrapper(
val uuid: UUID,
val entity: Entity,
val request: ExecuteContractRequest,
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class RejectContractBatchExecution(
private val createClient: CreateClient
) : AbstractUseCase<RejectContractBatchRequestWrapper, Unit>() {
override suspend fun execute(args: RejectContractBatchRequestWrapper) {
createClient.execute(CreateClientRequest(args.uuid, args.request.account, args.request.client)).use { client ->
createClient.execute(CreateClientRequest(args.entity, args.request.account, args.request.client)).use { client ->
args.request.rejection.forEach {
val error = Envelopes.EnvelopeError.newBuilder().mergeFrom(it).build()
client.respondWithError(error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class RejectContractExecution(

override suspend fun execute(args: RejectContractExecutionRequestWrapper) {
val error = Envelopes.EnvelopeError.newBuilder().mergeFrom(args.request.rejection).build()
createClient.execute(CreateClientRequest(args.uuid, args.request.account, args.request.client)).use { client ->
createClient.execute(CreateClientRequest(args.entity, args.request.account, args.request.client)).use { client ->
client.respondWithError(error)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.provenance.api.domain.usecase.cee.reject.models

import io.provenance.api.models.entity.Entity
import io.provenance.api.models.cee.reject.RejectContractBatchRequest
import java.util.UUID

class RejectContractBatchRequestWrapper(
val uuid: UUID,
val entity: Entity,
val request: RejectContractBatchRequest,
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.provenance.api.domain.usecase.cee.reject.models

import io.provenance.api.models.entity.Entity
import io.provenance.api.models.cee.reject.RejectContractRequest
import java.util.UUID

data class RejectContractExecutionRequestWrapper(
val uuid: UUID,
val entity: Entity,
val request: RejectContractRequest
)
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SubmitContractBatchExecutionResult(
val signedResults = mutableListOf<Pair<UUID, SignedResult>>()
val response = mutableListOf<SubmitContractBatchExecutionResultResponse>()
val errors = mutableListOf<SubmitContractBatchErrorResponse>()
val signer = getSigner.execute(GetSignerRequest(args.uuid, args.request.account))
val signer = getSigner.execute(GetSignerRequest(args.entity, args.request.account))

args.request.submission.forEach {
val envelope = Envelopes.Envelope.newBuilder().mergeFrom(it.envelope).build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class SubmitContractExecutionResult(
private val getSigner: GetSigner,
) : AbstractUseCase<SubmitContractExecutionResultRequestWrapper, TxResponse>() {
override suspend fun execute(args: SubmitContractExecutionResultRequestWrapper): TxResponse {
val signer = getSigner.execute(GetSignerRequest(args.uuid, args.request.account))
val signer = getSigner.execute(GetSignerRequest(args.entity, args.request.account))

val envelope = Envelopes.Envelope.newBuilder().mergeFrom(args.request.submission.envelope).build()
val state = Envelopes.EnvelopeState.newBuilder().mergeFrom(args.request.submission.state).build()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.provenance.api.domain.usecase.cee.submit.models

import io.provenance.api.models.entity.Entity
import io.provenance.api.models.cee.submit.SubmitContractBatchExecutionResultRequest
import java.util.UUID

data class SubmitContractBatchExecutionResultRequestWrapper(
val uuid: UUID,
val entity: Entity,
val request: SubmitContractBatchExecutionResultRequest
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.provenance.api.domain.usecase.cee.submit.models

import io.provenance.api.models.entity.Entity
import io.provenance.api.models.cee.submit.SubmitContractExecutionResultRequest
import java.util.UUID

data class SubmitContractExecutionResultRequestWrapper(
val uuid: UUID,
val entity: Entity,
val request: SubmitContractExecutionResultRequest
)
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ class EntityManager(
fun getEntity(args: KeyManagementConfigWrapper): KeyEntity {
val config = args.config ?: KeyManagementConfig(
pluginConfig = VaultConfig(
"${vaultProperties.address}/${args.entity}",
"${vaultProperties.address}/${args.entityId}",
vaultProperties.tokenPath,
)
)

val plugin = Class.forName(config.plugin).asSubclass(Plugin::class.java).kotlin.createInstance()
manager.register(plugin)
return manager.get(args.entity, config.pluginConfig)
return manager.get(args.entityId, config.pluginConfig)
}

fun hydrateKeys(permissions: PermissionInfo?, participants: List<Participant> = emptyList(), keyManagementConfig: KeyManagementConfig? = null): Set<AudienceKeyPair> {
Expand All @@ -53,8 +53,8 @@ class EntityManager(

// Populate the audiences into the audience list
permissions?.audiences?.forEach {
it.uuid?.let { entity ->
val keyEntity = getEntity(KeyManagementConfigWrapper(entity.toString(), keyManagementConfig))
it.uuid?.let { uuid ->
val keyEntity = getEntity(KeyManagementConfigWrapper(uuid.toString(), keyManagementConfig))

additionalAudiences.add(
AudienceKeyPair(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package io.provenance.api.domain.usecase.common.originator.models
import io.provenance.api.models.account.KeyManagementConfig

data class KeyManagementConfigWrapper(
val entity: String,
val entityId: String,
val config: KeyManagementConfig?
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class GetFile(
override suspend fun execute(args: GetFileRequestWrapper): Any {
getObject.execute(
RetrieveAndDecryptRequest(
args.uuid,
args.entity,
args.request.objectStoreAddress,
args.request.hash,
args.request.accountInfo.keyManagementConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class GetObject(
private val provenanceProperties: ProvenanceProperties,
) : AbstractUseCase<RetrieveAndDecryptRequest, ByteArray>() {
override suspend fun execute(args: RetrieveAndDecryptRequest): ByteArray {
val entity = entityManager.getEntity(KeyManagementConfigWrapper(args.uuid.toString(), args.keyManagementConfig))
val entity = entityManager.getEntity(KeyManagementConfigWrapper(args.entity.id, args.keyManagementConfig))

if (args.useObjectStoreGateway) {
GatewayClient(ClientConfig(URI.create(args.objectStoreAddress), provenanceProperties.mainnet))
Expand Down
Loading

0 comments on commit 17c198e

Please sign in to comment.