Skip to content

Commit

Permalink
Add test coverage for validateTokenParties (#12370)
Browse files Browse the repository at this point in the history
This is pure refactoring & adding some tests in preparation
for #12368

changelog_begin
changelog_end
  • Loading branch information
cocreature authored Jan 13, 2022
1 parent 6aa9409 commit bb8f455
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -319,45 +319,21 @@ class JsonLedgerClient(
)
}

// Check that the parties in the token provide read claims for the given parties
// and return explicit party specifications if required.
private def validateTokenParties(
parties: OneAnd[Set, Ref.Party],
what: String,
): Future[Option[QueryParties]] = {
val tokenParties = tokenPayload.readAs.toSet union tokenPayload.actAs.toSet
val partiesSet = parties.toSet.toSet[String]
val missingParties = partiesSet diff tokenParties
// First check is just for a nicer error message and would be covered by the second
if (tokenParties.isEmpty) {
Future.failed(
new RuntimeException(
s"Tried to $what as ${parties.toList.mkString(" ")} but token contains no parties."
)
)
} else if (missingParties.nonEmpty) {
Future.failed(new RuntimeException(s"Tried to $what as [${parties.toList
.mkString(", ")}] but token provides claims for [${tokenParties
.mkString(", ")}]. Missing claims: [${missingParties.mkString(", ")}]"))
} else {
import scalaz.std.string._
if (partiesSet === tokenParties) {
// For backwards-compatibility we only set the party set flags when needed
Future.successful(None)
} else {
Future.successful(Some(QueryParties(parties)))
}
}
}
): Future[Option[QueryParties]] =
JsonLedgerClient
.validateTokenParties(parties, what, tokenPayload)
.fold(s => Future.failed(new RuntimeException(s)), Future.successful(_))

private def validateSubmitParties(
actAs: OneAnd[Set, Ref.Party],
readAs: Set[Ref.Party],
): Future[Option[SubmitParties]] = {
): Future[Option[SubmitParties]] =
JsonLedgerClient
.validateSubmitParties(actAs, readAs, tokenPayload)
.fold(s => Future.failed(new RuntimeException(s)), Future.successful(_))
}

private def create(
tplId: Identifier,
Expand Down Expand Up @@ -593,6 +569,36 @@ object JsonLedgerClient {
readers: OneAnd[Set, Ref.Party]
)

// Check that the parties in the token provide read claims for the given parties
// and return explicit party specifications if required.
def validateTokenParties(
parties: OneAnd[Set, Ref.Party],
what: String,
tokenPayload: AuthServiceJWTPayload,
): Either[String, Option[QueryParties]] = {
val tokenParties = tokenPayload.readAs.toSet union tokenPayload.actAs.toSet
val partiesSet = parties.toSet.toSet[String]
val missingParties = partiesSet diff tokenParties
// First check is just for a nicer error message and would be covered by the second
if (tokenParties.isEmpty) {
Left(
s"Tried to $what as ${parties.toList.mkString(" ")} but token contains no parties."
)
} else if (missingParties.nonEmpty) {
Left(s"Tried to $what as [${parties.toList
.mkString(", ")}] but token provides claims for [${tokenParties
.mkString(", ")}]. Missing claims: [${missingParties.mkString(", ")}]")
} else {
import scalaz.std.string._
if (partiesSet === tokenParties) {
// For backwards-compatibility we only set the party set flags when needed
Right(None)
} else {
Right(Some(QueryParties(parties)))
}
}
}

// Validate that the token has the required claims and return
// SubmitParties we need to pass to the JSON API
// if the token has more claims than we need.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,54 @@ final class JsonPartyValidation extends AnyWordSpec with Matchers {
) shouldBe Right(Some(SubmitParties(OneAnd(alice, Set.empty), Set.empty)))
}
}

"validateTokenParties" should {
"handle a single actAs party" in {
validateTokenParties(
OneAnd(alice, Set.empty),
"",
token(List(alice), List()),
) shouldBe Right(None)
}
"handle a single readAs party" in {
validateTokenParties(OneAnd(alice, Set.empty), "", token(List(), List(alice))) shouldBe Right(
None
)
}
"handle duplicate actAs" in {
validateTokenParties(
OneAnd(alice, Set.empty),
"",
token(List(alice, alice), List()),
) shouldBe Right(None)
}
"handle duplicate readAs" in {
validateTokenParties(
OneAnd(alice, Set.empty),
"",
token(List(), List(alice, alice)),
) shouldBe Right(None)
}
"fail for missing readAs party" in {
validateTokenParties(
OneAnd(alice, Set.empty),
"",
token(List(), List()),
) shouldBe a[Left[_, _]]
}
"handle party that is in readAs and actAs" in {
validateTokenParties(
OneAnd(alice, Set.empty),
"",
token(List(alice), List(alice)),
) shouldBe Right(None)
}
"return explicit party specification for constrained parties" in {
validateTokenParties(
OneAnd(alice, Set.empty),
"",
token(List(alice, bob), List()),
) shouldBe Right(Some(QueryParties(OneAnd(alice, Set.empty))))
}
}
}

0 comments on commit bb8f455

Please sign in to comment.