mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
Add security evidence for auth middleware (#13424)
changelog_begin changelog_end
This commit is contained in:
parent
4b71431b20
commit
ad4ed5c4b2
@ -3,6 +3,7 @@
|
||||
## Authorization:
|
||||
- Updating the package service fails with insufficient authorization: [AuthorizationTest.scala](ledger-service/http-json/src/it/scala/http/AuthorizationTest.scala#L81)
|
||||
- Updating the package service succeeds with sufficient authorization: [AuthorizationTest.scala](ledger-service/http-json/src/it/scala/http/AuthorizationTest.scala#L89)
|
||||
- accept user tokens: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L151)
|
||||
- badly-authorized create is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L61)
|
||||
- badly-authorized create is rejected: [AbstractHttpServiceIntegrationTest.scala](ledger-service/http-json/src/itlib/scala/http/AbstractHttpServiceIntegrationTest.scala#L1778)
|
||||
- badly-authorized exercise is rejected: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L159)
|
||||
@ -27,6 +28,13 @@
|
||||
- refresh a token after expiry on the server side: [TriggerServiceTest.scala](triggers/service/src/test/scala/com/digitalasset/daml/lf/engine/trigger/TriggerServiceTest.scala#L718)
|
||||
- reject requests with missing auth header: [AbstractHttpServiceIntegrationTest.scala](ledger-service/http-json/src/itlib/scala/http/AbstractHttpServiceIntegrationTest.scala#L1272)
|
||||
- request a fresh token after expiry on user request: [TriggerServiceTest.scala](triggers/service/src/test/scala/com/digitalasset/daml/lf/engine/trigger/TriggerServiceTest.scala#L703)
|
||||
- return the token from a cookie: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L95)
|
||||
- return unauthorized on an expired token: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L138)
|
||||
- return unauthorized on an invalid token: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L127)
|
||||
- return unauthorized on insufficient app id claims: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L108)
|
||||
- return unauthorized without cookie: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L86)
|
||||
- the /login endpoint with an oauth server checking claims should not authorize disallowed admin claims: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L342)
|
||||
- the /login endpoint with an oauth server checking claims should not authorize unauthorized parties: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L335)
|
||||
- websocket request with invalid protocol token should be denied: [AbstractWebsocketServiceIntegrationTest.scala](ledger-service/http-json/src/itlib/scala/http/AbstractWebsocketServiceIntegrationTest.scala#L91)
|
||||
- websocket request with valid protocol token should allow client subscribe to stream: [AbstractWebsocketServiceIntegrationTest.scala](ledger-service/http-json/src/itlib/scala/http/AbstractWebsocketServiceIntegrationTest.scala#L79)
|
||||
- websocket request without protocol token should be denied: [AbstractWebsocketServiceIntegrationTest.scala](ledger-service/http-json/src/itlib/scala/http/AbstractWebsocketServiceIntegrationTest.scala#L101)
|
||||
@ -179,6 +187,18 @@
|
||||
- restart triggers after shutdown: [TriggerServiceTest.scala](triggers/service/src/test/scala/com/digitalasset/daml/lf/engine/trigger/TriggerServiceTest.scala#L578)
|
||||
- restart triggers with initialization errors: [TriggerServiceTest.scala](triggers/service/src/test/scala/com/digitalasset/daml/lf/engine/trigger/TriggerServiceTest.scala#L466)
|
||||
- restart triggers with update errors: [TriggerServiceTest.scala](triggers/service/src/test/scala/com/digitalasset/daml/lf/engine/trigger/TriggerServiceTest.scala#L482)
|
||||
- the /auth endpoint given claim token should return unauthorized on insufficient party claims: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L291)
|
||||
- the /login endpoint should redirect and set the cookie: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L166)
|
||||
- the /login endpoint should return OK and set cookie without redirectUri: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L195)
|
||||
- the /login endpoint with an oauth server checking claims should redirect to the configured middleware callback URI: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L397)
|
||||
- the /login endpoint with an oauth server checking claims should refuse requests when max capacity is reached: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L424)
|
||||
- the /login endpoint with an oauth server checking claims should refuse requests when max capacity is reached: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L472)
|
||||
- the /refresh endpoint should fail on an invalid refresh token: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L260)
|
||||
- the /refresh endpoint should return a new access token: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L225)
|
||||
- the TestMiddlewareClientAutoRedirectToLogin client should not redirect to /login for JSON request: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L634)
|
||||
- the TestMiddlewareClientAutoRedirectToLogin client should redirect to /login for HTML request: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L616)
|
||||
- the TestMiddlewareClientNoRedirectToLogin client should not redirect to /login: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L533)
|
||||
- the TestMiddlewareClientYesRedirectToLogin client should redirect to /login: [TestMiddleware.scala](triggers/service/auth/src/test/scala/com/daml/auth/middleware/oauth2/TestMiddleware.scala#L583)
|
||||
|
||||
## Performance:
|
||||
- Tail call optimization: Tail recursion does not blow the scala JVM stack.: [TailCallTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/TailCallTest.scala#L16)
|
||||
|
@ -83,6 +83,7 @@ abstract class TestMiddleware
|
||||
}
|
||||
}
|
||||
"the /auth endpoint" should {
|
||||
// TEST_EVIDENCE: Authorization: return unauthorized without cookie
|
||||
"return unauthorized without cookie" in {
|
||||
val claims = Request.Claims(actAs = List(Party("Alice")))
|
||||
for {
|
||||
@ -91,6 +92,7 @@ abstract class TestMiddleware
|
||||
assert(result == None)
|
||||
}
|
||||
}
|
||||
// TEST_EVIDENCE: Authorization: return the token from a cookie
|
||||
"return the token from a cookie" in {
|
||||
val claims = Request.Claims(actAs = List(Party("Alice")))
|
||||
val token = makeToken(claims)
|
||||
@ -103,6 +105,7 @@ abstract class TestMiddleware
|
||||
assert(auth.refreshToken == token.refreshToken)
|
||||
}
|
||||
}
|
||||
// TEST_EVIDENCE: Authorization: return unauthorized on insufficient app id claims
|
||||
"return unauthorized on insufficient app id claims" in {
|
||||
val claims = Request.Claims(
|
||||
actAs = List(ApiTypes.Party("Alice")),
|
||||
@ -121,6 +124,7 @@ abstract class TestMiddleware
|
||||
assert(result == None)
|
||||
}
|
||||
}
|
||||
// TEST_EVIDENCE: Authorization: return unauthorized on an invalid token
|
||||
"return unauthorized on an invalid token" in {
|
||||
val claims = Request.Claims(actAs = List(ApiTypes.Party("Alice")))
|
||||
val token = makeToken(claims, "wrong-secret")
|
||||
@ -131,6 +135,7 @@ abstract class TestMiddleware
|
||||
assert(result == None)
|
||||
}
|
||||
}
|
||||
// TEST_EVIDENCE: Authorization: return unauthorized on an expired token
|
||||
"return unauthorized on an expired token" in {
|
||||
val claims = Request.Claims(actAs = List(ApiTypes.Party("Alice")))
|
||||
val token = makeToken(claims, expiresIn = Some(Duration.ZERO))
|
||||
@ -143,6 +148,7 @@ abstract class TestMiddleware
|
||||
}
|
||||
}
|
||||
|
||||
// TEST_EVIDENCE: Authorization: accept user tokens
|
||||
"accept user tokens" in {
|
||||
import com.daml.auth.middleware.oauth2.Server.rightsProvideClaims
|
||||
rightsProvideClaims(
|
||||
@ -157,6 +163,7 @@ abstract class TestMiddleware
|
||||
}
|
||||
}
|
||||
"the /login endpoint" should {
|
||||
// TEST_EVIDENCE: Semantics: the /login endpoint should redirect and set the cookie
|
||||
"redirect and set cookie" in {
|
||||
val claims = Request.Claims(actAs = List(Party("Alice")))
|
||||
val req = HttpRequest(uri = middlewareClientRoutes.loginUri(claims, None))
|
||||
@ -185,6 +192,7 @@ abstract class TestMiddleware
|
||||
assert(token.tokenType == "bearer")
|
||||
}
|
||||
}
|
||||
// TEST_EVIDENCE: Semantics: the /login endpoint should return OK and set cookie without redirectUri
|
||||
"return OK and set cookie without redirectUri" in {
|
||||
val claims = Request.Claims(actAs = List(Party("Alice")))
|
||||
val req = HttpRequest(uri = middlewareClientRoutes.loginUri(claims, None, redirect = false))
|
||||
@ -214,6 +222,7 @@ abstract class TestMiddleware
|
||||
}
|
||||
}
|
||||
"the /refresh endpoint" should {
|
||||
// TEST_EVIDENCE: Semantics: the /refresh endpoint should return a new access token
|
||||
"return a new access token" in {
|
||||
val claims = Request.Claims(actAs = List(Party("Alice")))
|
||||
val loginReq = HttpRequest(uri = middlewareClientRoutes.loginUri(claims, None))
|
||||
@ -248,6 +257,7 @@ abstract class TestMiddleware
|
||||
assert(authorize.refreshToken.get != refreshToken)
|
||||
}
|
||||
}
|
||||
// TEST_EVIDENCE: Semantics: the /refresh endpoint should fail on an invalid refresh token
|
||||
"fail on an invalid refresh token" in {
|
||||
for {
|
||||
exception <- middlewareClient.requestRefresh(RefreshToken("made-up-token")).transform {
|
||||
@ -278,6 +288,7 @@ class TestMiddlewareClaimsToken extends TestMiddleware {
|
||||
)
|
||||
|
||||
"the /auth endpoint given claim token" should {
|
||||
// TEST_EVIDENCE: Semantics: the /auth endpoint given claim token should return unauthorized on insufficient party claims
|
||||
"return unauthorized on insufficient party claims" in {
|
||||
val claims = Request.Claims(actAs = List(Party("Bob")))
|
||||
def r(actAs: String*)(readAs: String*) =
|
||||
@ -321,12 +332,14 @@ class TestMiddlewareClaimsToken extends TestMiddleware {
|
||||
}
|
||||
|
||||
"the /login endpoint with an oauth server checking claims" should {
|
||||
// TEST_EVIDENCE: Authorization: the /login endpoint with an oauth server checking claims should not authorize unauthorized parties
|
||||
"not authorize unauthorized parties" in {
|
||||
server.revokeParty(Party("Eve"))
|
||||
val claims = Request.Claims(actAs = List(Party("Eve")))
|
||||
ensureDisallowed(claims)
|
||||
}
|
||||
|
||||
// TEST_EVIDENCE: Authorization: the /login endpoint with an oauth server checking claims should not authorize disallowed admin claims
|
||||
"not authorize disallowed admin claims" in {
|
||||
server.revokeAdmin()
|
||||
val claims = Request.Claims(admin = true)
|
||||
@ -381,6 +394,7 @@ class TestMiddlewareCallbackUriOverride
|
||||
with SuiteResourceManagementAroundAll {
|
||||
override protected val middlewareCallbackUri = Some(Uri("http://localhost/MIDDLEWARE_CALLBACK"))
|
||||
"the /login endpoint" should {
|
||||
// TEST_EVIDENCE: Semantics: the /login endpoint with an oauth server checking claims should redirect to the configured middleware callback URI
|
||||
"redirect to the configured middleware callback URI" in {
|
||||
val claims = Request.Claims(actAs = List(Party("Alice")))
|
||||
val req = HttpRequest(uri = middlewareClientRoutes.loginUri(claims, None))
|
||||
@ -407,6 +421,7 @@ class TestMiddlewareLimitedCallbackStore
|
||||
with SuiteResourceManagementAroundAll {
|
||||
override protected val maxMiddlewareLogins = 2
|
||||
"the /login endpoint" should {
|
||||
// TEST_EVIDENCE: Semantics: the /login endpoint with an oauth server checking claims should refuse requests when max capacity is reached
|
||||
"refuse requests when max capacity is reached" in {
|
||||
def login(actAs: Party) = {
|
||||
val claims = Request.Claims(actAs = List(actAs))
|
||||
@ -454,6 +469,7 @@ class TestMiddlewareClientLimitedCallbackStore
|
||||
with SuiteResourceManagementAroundAll {
|
||||
override protected val maxClientAuthCallbacks = 2
|
||||
"the /login client" should {
|
||||
// TEST_EVIDENCE: Semantics: the /login endpoint with an oauth server checking claims should refuse requests when max capacity is reached
|
||||
"refuse requests when max capacity is reached" in {
|
||||
def login(actAs: Party) = {
|
||||
val claims = Request.Claims(actAs = List(actAs))
|
||||
@ -514,6 +530,7 @@ class TestMiddlewareClientNoRedirectToLogin
|
||||
with SuiteResourceManagementAroundAll {
|
||||
override protected val redirectToLogin: Client.RedirectToLogin = Client.RedirectToLogin.No
|
||||
"the authorize client" should {
|
||||
// TEST_EVIDENCE: Semantics: the TestMiddlewareClientNoRedirectToLogin client should not redirect to /login
|
||||
"not redirect to /login" in {
|
||||
import com.daml.auth.middleware.api.JsonProtocol.responseAuthenticateChallengeFormat
|
||||
val claims = Request.Claims(actAs = List(Party("Alice")))
|
||||
@ -563,6 +580,7 @@ class TestMiddlewareClientYesRedirectToLogin
|
||||
with SuiteResourceManagementAroundAll {
|
||||
override protected val redirectToLogin: Client.RedirectToLogin = Client.RedirectToLogin.Yes
|
||||
"the authorize client" should {
|
||||
// TEST_EVIDENCE: Semantics: the TestMiddlewareClientYesRedirectToLogin client should redirect to /login
|
||||
"redirect to /login" in {
|
||||
val claims = Request.Claims(actAs = List(Party("Alice")))
|
||||
val host = middlewareClientBinding.localAddress
|
||||
@ -595,6 +613,7 @@ class TestMiddlewareClientAutoRedirectToLogin
|
||||
with SuiteResourceManagementAroundAll {
|
||||
override protected val redirectToLogin: Client.RedirectToLogin = Client.RedirectToLogin.Auto
|
||||
"the authorize client" should {
|
||||
// TEST_EVIDENCE: Semantics: the TestMiddlewareClientAutoRedirectToLogin client should redirect to /login for HTML request
|
||||
"redirect to /login for HTML request" in {
|
||||
val claims = Request.Claims(actAs = List(Party("Alice")))
|
||||
val host = middlewareClientBinding.localAddress
|
||||
@ -612,6 +631,7 @@ class TestMiddlewareClientAutoRedirectToLogin
|
||||
assert(resp.status == StatusCodes.Found)
|
||||
}
|
||||
}
|
||||
// TEST_EVIDENCE: Semantics: the TestMiddlewareClientAutoRedirectToLogin client should not redirect to /login for JSON request
|
||||
"not redirect to /login for JSON request" in {
|
||||
val claims = Request.Claims(actAs = List(Party("Alice")))
|
||||
val host = middlewareClientBinding.localAddress
|
||||
|
Loading…
Reference in New Issue
Block a user