Skip to content

Commit

Permalink
Do not expose the error codes switching mechanism to the Java bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
tudor-da committed Oct 14, 2021
1 parent 13a8d6b commit 725d718
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 52 deletions.
1 change: 0 additions & 1 deletion language-support/java/bindings-rxjava/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ da_java_library(
deps = [
"//language-support/java/bindings:bindings-java",
"//ledger-api/rs-grpc-bridge",
"//ledger/error",
"//ledger/ledger-api-auth-client",
"@maven//:com_google_api_grpc_proto_google_common_protos",
"@maven//:com_google_protobuf_protobuf_java",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

package com.daml.ledger.rxjava.grpc.helpers

import com.daml.error.ErrorCodesVersionSwitcher

import java.net.{InetSocketAddress, SocketAddress}
import java.time.{Clock, Duration}
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -32,10 +30,10 @@ import com.daml.ledger.api.v1.package_service.{
}
import com.daml.ledger.api.v1.testing.time_service.GetTimeResponse
import com.google.protobuf.empty.Empty

import io.grpc._
import io.grpc.netty.NettyServerBuilder
import io.reactivex.Observable

import scala.concurrent.ExecutionContext.global
import scala.concurrent.{ExecutionContext, Future}

Expand All @@ -47,12 +45,7 @@ final class LedgerServices(val ledgerId: String) {
private val esf: ExecutionSequencerFactory = new SingleThreadExecutionSequencerPool(ledgerId)
private val participantId = "LedgerServicesParticipant"
private val authorizer =
new Authorizer(
() => Clock.systemUTC().instant(),
ledgerId,
participantId,
new ErrorCodesVersionSwitcher(false),
)
new Authorizer(() => Clock.systemUTC().instant(), ledgerId, participantId)

def newServerBuilder(): NettyServerBuilder = NettyServerBuilder.forAddress(nextAddress())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@

package com.daml.ledger

import com.daml.error.ErrorCodesVersionSwitcher

import java.time.Clock
import java.util.UUID

import com.daml.lf.data.Ref
import com.daml.ledger.api.auth.{
AuthServiceStatic,
Expand All @@ -25,12 +24,7 @@ package object rxjava {
throw new UnsupportedOperationException("Untested endpoint, implement if needed")

private[rxjava] val authorizer =
new Authorizer(
() => Clock.systemUTC().instant(),
"testLedgerId",
"testParticipantId",
new ErrorCodesVersionSwitcher(false),
)
new Authorizer(() => Clock.systemUTC().instant(), "testLedgerId", "testParticipantId")

private[rxjava] val emptyToken = "empty"
private[rxjava] val publicToken = "public"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,22 @@ object LedgerApiErrors extends LedgerApiErrorGroup {
case class MissingJwtToken()(implicit
loggingContext: ErrorCodeLoggingContext
) extends LoggingTransactionErrorImpl(
cause = s"The command is missing a JWT token"
cause = "The command is missing a JWT token"
)
}

@Explanation("An internal system authorization error occurred.")
@Resolution("Contact the participant operator.")
object InternalAuthorizationError
extends ErrorCode(
id = "INTERNAL_AUTHORIZATION_ERROR",
ErrorCategory.AuthInterceptorInvalidAuthenticationCredentials,
) {
case class ClaimsFromMetadataExtractionFailed(throwable: Throwable)(implicit
loggingContext: ErrorCodeLoggingContext
) extends LoggingTransactionErrorImpl(
cause = "Failed to get claims from request metadata",
throwableO = Some(throwable),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ final class Authorizer(
now: () => Instant,
ledgerId: String,
participantId: String,
errorCodesVersionSwitcher: ErrorCodesVersionSwitcher,
// Using a default parameter here, since we don't expose the error code switching
// mechanism outside the Ledger API (i.e. rxJava bindings)
errorCodesVersionSwitcher: ErrorCodesVersionSwitcher = new ErrorCodesVersionSwitcher(false),
) {
private val logger = ContextualizedLogger.get(getClass)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@

package com.daml.ledger.api.auth.interceptor

import com.daml.error.definitions.LedgerApiErrors
import com.daml.error.{DamlErrorCodeLoggingContext, ValueSwitch}
import com.daml.ledger.api.auth.{AuthService, ClaimSet}
import io.grpc.{
Context,
Contexts,
Metadata,
ServerCall,
ServerCallHandler,
ServerInterceptor,
Status,
}
import org.slf4j.{Logger, LoggerFactory}
import com.daml.logging.{ContextualizedLogger, LoggingContext}
import io.grpc._

import scala.compat.java8.FutureConverters
import scala.concurrent.ExecutionContext
Expand All @@ -22,13 +16,12 @@ import scala.util.{Failure, Success}
/** This interceptor uses the given [[AuthService]] to get [[Claims]] for the current request,
* and then stores them in the current [[Context]].
*/
final class AuthorizationInterceptor(protected val authService: AuthService, ec: ExecutionContext)
extends ServerInterceptor {

private val logger: Logger = LoggerFactory.getLogger(AuthorizationInterceptor.getClass)
// TODO error codes: Convert to self-service error codes spec
private val internalAuthenticationError =
Status.INTERNAL.withDescription("Failed to get claims from request metadata")
final class AuthorizationInterceptor(
protected val authService: AuthService,
ec: ExecutionContext,
errorCodesStatusSwitcher: ValueSwitch[Status],
) extends ServerInterceptor {
private val logger = ContextualizedLogger.get(getClass)

override def interceptCall[ReqT, RespT](
call: ServerCall[ReqT, RespT],
Expand All @@ -48,8 +41,7 @@ final class AuthorizationInterceptor(protected val authService: AuthService, ec:
.toScala(authService.decodeMetadata(headers))
.onComplete {
case Failure(exception) =>
logger.warn(s"Failed to get claims from request metadata: ${exception.getMessage}")
call.close(internalAuthenticationError, new Metadata())
call.close(internalAuthenticationError(exception), new Metadata())
new ServerCall.Listener[Nothing]() {}
case Success(claimSet) =>
val nextCtx = prevCtx.withValue(AuthorizationInterceptor.contextKeyClaimSet, claimSet)
Expand All @@ -62,6 +54,24 @@ final class AuthorizationInterceptor(protected val authService: AuthService, ec:
}(ec)
}
}

private def internalAuthenticationError(
exception: Throwable
) =
LoggingContext.newLoggingContext { implicit loggingContext: LoggingContext =>
errorCodesStatusSwitcher.choose(
v1 = {
logger.warn(s"Failed to get claims from request metadata: ${exception.getMessage}")
Status.INTERNAL.withDescription("Failed to get claims from request metadata")
},
v2 = LedgerApiErrors.AuthorizationChecks.InternalAuthorizationError
.ClaimsFromMetadataExtractionFailed(exception)(
new DamlErrorCodeLoggingContext(logger, loggingContext, None)
)
.asGrpcError
.getStatus,
)
}
}

object AuthorizationInterceptor {
Expand All @@ -71,7 +81,13 @@ object AuthorizationInterceptor {
def extractClaimSetFromContext(): Option[ClaimSet] =
Option(contextKeyClaimSet.get())

def apply(authService: AuthService, ec: ExecutionContext): AuthorizationInterceptor =
new AuthorizationInterceptor(authService, ec)
def apply(
authService: AuthService,
ec: ExecutionContext,
// Using a default parameter here, since we don't expose the error code switching
// mechanism outside the Ledger API (i.e. rxJava bindings)
errorCodesStatusSwitcher: ValueSwitch[Status] = new ValueSwitch(false),
): AuthorizationInterceptor =
new AuthorizationInterceptor(authService, ec, errorCodesStatusSwitcher)

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import akka.actor.ActorSystem
import akka.stream.Materializer
import com.daml.api.util.TimeProvider
import com.daml.buildinfo.BuildInfo
import com.daml.error.ErrorCodesVersionSwitcher
import com.daml.error.{ErrorCodesVersionSwitcher, ValueSwitch}
import com.daml.ledger.api.auth.interceptor.AuthorizationInterceptor
import com.daml.ledger.api.auth.{AuthService, Authorizer}
import com.daml.ledger.api.domain
Expand Down Expand Up @@ -131,7 +131,11 @@ final class StandaloneApiServer(
config.maxInboundMessageSize,
config.address,
config.tlsConfig,
AuthorizationInterceptor(authService, executionContext) :: otherInterceptors,
AuthorizationInterceptor(
authService,
executionContext,
new ValueSwitch(config.enableSelfServiceErrorCodes),
) :: otherInterceptors,
servicesExecutionContext,
metrics,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ private[apiserver] final class ApiPackageService private (
}
GetPackageResponse(hashF, archive.getPayload, archive.getHash)
}

}

private[platform] object ApiPackageService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
package com.daml.platform.apiserver.services

import com.codahale.metrics.MetricRegistry
import com.daml.error.ErrorCause
import com.daml.error.{ErrorCause, ErrorCodesVersionSwitcher}
import com.daml.ledger.api.domain.{CommandId, Commands, LedgerId, PartyDetails, SubmissionId}
import com.daml.ledger.api.messages.command.submission.SubmitRequest
import com.daml.ledger.api.testing.utils.AkkaBeforeAndAfterAll
Expand All @@ -31,10 +31,10 @@ import com.daml.lf.transaction.{GlobalKey, NodeId, ReplayMismatch}
import com.daml.lf.value.Value
import com.daml.logging.LoggingContext
import com.daml.metrics.Metrics
import com.daml.platform.apiserver.SeedService
import com.daml.platform.apiserver.configuration.LedgerConfigurationSubscription
import com.daml.platform.apiserver.execution.CommandExecutor
import com.daml.platform.apiserver.services.ApiSubmissionServiceSpec._
import com.daml.platform.apiserver.{ErrorCodesVersionSwitcher, SeedService}
import com.daml.telemetry.{NoOpTelemetryContext, TelemetryContext}
import com.google.rpc.status.{Status => RpcStatus}
import io.grpc.Status
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,13 @@

package com.daml.platform.sandbox

import java.io.File
import java.nio.file.Files
import java.time.Instant
import java.util.concurrent.Executors
import akka.actor.ActorSystem
import akka.stream.Materializer
import com.codahale.metrics.MetricRegistry
import com.daml.api.util.TimeProvider
import com.daml.buildinfo.BuildInfo
import com.daml.dec.DirectExecutionContext
import com.daml.error.ErrorCodesVersionSwitcher
import com.daml.error.{ErrorCodesVersionSwitcher, ValueSwitch}
import com.daml.ledger.api.auth.interceptor.AuthorizationInterceptor
import com.daml.ledger.api.auth.{AuthService, AuthServiceWildcard, Authorizer}
import com.daml.ledger.api.domain.LedgerId
Expand Down Expand Up @@ -49,6 +45,10 @@ import com.daml.platform.store.{FlywayMigrations, LfValueTranslationCache}
import com.daml.ports.Port
import scalaz.syntax.tag._

import java.io.File
import java.nio.file.Files
import java.time.Instant
import java.util.concurrent.Executors
import scala.concurrent.duration.DurationInt
import scala.concurrent.{Await, ExecutionContext, Future}
import scala.jdk.CollectionConverters._
Expand Down Expand Up @@ -398,7 +398,11 @@ final class SandboxServer(
config.address,
config.tlsConfig,
List(
AuthorizationInterceptor(authService, executionContext),
AuthorizationInterceptor(
authService,
executionContext,
new ValueSwitch(config.enableSelfServiceErrorCodes),
),
resetService,
),
servicesExecutionContext,
Expand Down

0 comments on commit 725d718

Please sign in to comment.