Add identity provider config to ledger client (#16625)

* IdentityProviderConfigService through ledger client: create config

* IdentityProviderConfigService through ledger client: get config

* IdentityProviderConfigService through ledger client: list configs

* IdentityProviderConfigService through ledger client: delete config
This commit is contained in:
Brian Healey 2023-03-30 03:47:05 -04:00 committed by GitHub
parent ddf192c707
commit 6c874e8bd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 190 additions and 0 deletions

View File

@ -4,6 +4,7 @@
package com.daml.ledger.client
import com.daml.ledger.api.domain
import com.daml.ledger.api.domain.{IdentityProviderConfig, IdentityProviderId, JwksUrl}
import com.daml.ledger.api.testing.utils.{AkkaBeforeAndAfterAll, SuiteResourceManagementAroundEach}
import com.daml.ledger.client.configuration.{
CommandClientConfiguration,
@ -13,6 +14,7 @@ import com.daml.ledger.client.configuration.{
import com.daml.ledger.runner.common.Config
import com.daml.lf.data.Ref
import com.daml.platform.sandbox.fixture.SandboxFixture
import com.google.protobuf.field_mask.FieldMask
import io.grpc.ManagedChannel
import org.scalatest.Inside
import org.scalatest.matchers.should.Matchers
@ -75,6 +77,90 @@ final class LedgerClientIT
}
}
"identity provider config" should {
val config = IdentityProviderConfig(
IdentityProviderId.Id(Ref.LedgerString.assertFromString("abcd")),
isDeactivated = false,
JwksUrl.assertFromString("http://jwks.some.domain:9999/jwks"),
"SomeUser",
None, // setting this to any value does not appear to work
)
val updatedConfig = config.copy(
isDeactivated = true,
jwksUrl = JwksUrl("http://someotherurl"),
issuer = "ANewIssuer",
) // updating audience value does not appear to work
"create an identity provider" in {
for {
client <- LedgerClient(channel, ClientConfiguration)
createdConfig <- client.identityProviderConfigClient.createIdentityProviderConfig(
config,
None,
)
} yield {
createdConfig should be(config)
}
}
"get an identity provider" in {
for {
client <- LedgerClient(channel, ClientConfiguration)
_ <- client.identityProviderConfigClient.createIdentityProviderConfig(config, None)
respConfig <- client.identityProviderConfigClient.getIdentityProviderConfig(
config.identityProviderId,
None,
)
} yield {
respConfig should be(config)
}
}
"update an identity provider" in {
for {
client <- LedgerClient(channel, ClientConfiguration)
_ <- client.identityProviderConfigClient.createIdentityProviderConfig(config, None)
respConfig <- client.identityProviderConfigClient.updateIdentityProviderConfig(
updatedConfig,
FieldMask(Seq("is_deactivated", "jwks_url", "issuer")),
None,
)
} yield {
respConfig should be(updatedConfig)
}
}
"list identity providers" in {
for {
client <- LedgerClient(channel, ClientConfiguration)
config1 <- client.identityProviderConfigClient.createIdentityProviderConfig(config, None)
config2 <- client.identityProviderConfigClient.createIdentityProviderConfig(
updatedConfig.copy(identityProviderId =
IdentityProviderId.Id(Ref.LedgerString.assertFromString("AnotherIdentityProvider"))
),
None,
)
respConfig <- client.identityProviderConfigClient.listIdentityProviderConfigs(None)
} yield {
respConfig.toSet should contain theSameElementsAs (Set(config2, config1))
}
}
"delete identity provider" in {
for {
client <- LedgerClient(channel, ClientConfiguration)
config1 <- client.identityProviderConfigClient.createIdentityProviderConfig(config, None)
_ <- client.identityProviderConfigClient.deleteIdentityProviderConfig(
config1.identityProviderId,
None,
)
respConfig <- client.identityProviderConfigClient.listIdentityProviderConfigs(None)
} yield {
respConfig.toSet should be(Set.empty)
}
}
}
"shut down the channel when closed" in {
for {
client <- LedgerClient(channel, ClientConfiguration)

View File

@ -8,6 +8,7 @@ import com.daml.grpc.adapter.ExecutionSequencerFactory
import com.daml.ledger.api.auth.client.LedgerCallCredentials.authenticatingStub
import com.daml.ledger.api.domain.LedgerId
import com.daml.ledger.api.v1.active_contracts_service.ActiveContractsServiceGrpc
import com.daml.ledger.api.v1.admin.identity_provider_config_service.IdentityProviderConfigServiceGrpc
import com.daml.ledger.api.v1.admin.package_management_service.PackageManagementServiceGrpc
import com.daml.ledger.api.v1.admin.participant_pruning_service.ParticipantPruningServiceGrpc
import com.daml.ledger.api.v1.admin.party_management_service.PartyManagementServiceGrpc
@ -25,6 +26,7 @@ import com.daml.ledger.client.configuration.{
}
import com.daml.ledger.client.services.acs.ActiveContractSetClient
import com.daml.ledger.client.services.admin.{
IdentityProviderConfigClient,
PackageManagementClient,
ParticipantPruningManagementClient,
PartyManagementClient,
@ -67,6 +69,11 @@ final class LedgerClient private (
val commandServiceClient: SynchronousCommandClient =
new SynchronousCommandClient(LedgerClient.stub(CommandServiceGrpc.stub(channel), config.token))
val identityProviderConfigClient: IdentityProviderConfigClient =
new IdentityProviderConfigClient(
LedgerClient.stub(IdentityProviderConfigServiceGrpc.stub(channel), config.token)
)
val packageClient: PackageClient =
new PackageClient(ledgerId, LedgerClient.stub(PackageServiceGrpc.stub(channel), config.token))

View File

@ -0,0 +1,97 @@
// Copyright (c) 2023 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.ledger.client.services.admin
import com.daml.ledger.api.domain.{IdentityProviderConfig, IdentityProviderId, JwksUrl}
import com.daml.ledger.api.v1.admin.identity_provider_config_service.IdentityProviderConfigServiceGrpc.IdentityProviderConfigServiceStub
import com.daml.ledger.api.v1.admin.{identity_provider_config_service => proto}
import com.daml.ledger.client.LedgerClient
import com.daml.lf.data.Ref
import com.google.protobuf.field_mask.FieldMask
import scala.concurrent.{ExecutionContext, Future}
final class IdentityProviderConfigClient(service: IdentityProviderConfigServiceStub)(implicit
ec: ExecutionContext
) {
import IdentityProviderConfigClient._
def createIdentityProviderConfig(
config: IdentityProviderConfig,
token: Option[String],
): Future[IdentityProviderConfig] = {
val request = proto.CreateIdentityProviderConfigRequest(
Some(IdentityProviderConfigClient.toProtoConfig(config))
)
LedgerClient
.stub(service, token)
.createIdentityProviderConfig(request)
.map(res => fromProtoConfig(res.getIdentityProviderConfig))
}
def getIdentityProviderConfig(
identityProviderId: IdentityProviderId.Id,
token: Option[String],
): Future[IdentityProviderConfig] = {
val request = proto.GetIdentityProviderConfigRequest(identityProviderId.toRequestString)
LedgerClient
.stub(service, token)
.getIdentityProviderConfig(request)
.map(res => fromProtoConfig(res.getIdentityProviderConfig))
}
def updateIdentityProviderConfig(
config: IdentityProviderConfig,
updateMask: FieldMask,
token: Option[String],
): Future[IdentityProviderConfig] = {
val request = proto.UpdateIdentityProviderConfigRequest(
Some(IdentityProviderConfigClient.toProtoConfig(config)),
Some(updateMask),
)
LedgerClient
.stub(service, token)
.updateIdentityProviderConfig(request)
.map(res => fromProtoConfig(res.getIdentityProviderConfig))
}
def listIdentityProviderConfigs(token: Option[String]): Future[Seq[IdentityProviderConfig]] = {
val request = proto.ListIdentityProviderConfigsRequest()
LedgerClient
.stub(service, token)
.listIdentityProviderConfigs(request)
.map(res => res.identityProviderConfigs.map(fromProtoConfig))
}
def deleteIdentityProviderConfig(
identityProviderId: IdentityProviderId.Id,
token: Option[String],
): Future[Unit] = {
val request = proto.DeleteIdentityProviderConfigRequest(identityProviderId.toRequestString)
LedgerClient
.stub(service, token)
.deleteIdentityProviderConfig(request)
.map(_ => ())
}
}
object IdentityProviderConfigClient {
private def toProtoConfig(config: IdentityProviderConfig): proto.IdentityProviderConfig =
proto.IdentityProviderConfig(
config.identityProviderId.toRequestString,
config.isDeactivated,
config.issuer,
config.jwksUrl.value,
config.audience.getOrElse(""),
)
private def fromProtoConfig(config: proto.IdentityProviderConfig) =
IdentityProviderConfig(
IdentityProviderId.Id(Ref.LedgerString.assertFromString(config.identityProviderId)),
config.isDeactivated,
JwksUrl.assertFromString(config.jwksUrl),
config.issuer,
Option(config.audience).filter(_.trim.nonEmpty),
)
}