This is an automated email from the ASF dual-hosted git repository. dubeejw pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git
The following commit(s) were added to refs/heads/master by this push: new 4e5a811 Better error controller message for authorization failure (#2877) 4e5a811 is described below commit 4e5a8117f6c19776f3bcafcfe04e55f49ca843e8 Author: Mark Deuser <mdeu...@us.ibm.com> AuthorDate: Wed Nov 15 15:31:30 2017 -0500 Better error controller message for authorization failure (#2877) * Add resource name to Forbidden error message * Comment updates and test case updates * Fix scalafmt issue * Reformat using scalafmt plugin * Fix two more failing test cases * Comment updates * Compiles but tests are broken * Add Set[Resources] test * Comment updates * Comment updates --- .../src/main/scala/whisk/http/ErrorResponse.scala | 3 + .../controller/AuthorizedRouteDispatcher.scala | 19 ++- .../scala/whisk/core/entitlement/Entitlement.scala | 60 ++++++--- .../test/scala/system/basic/WskBasicTests.scala | 5 +- .../controller/test/EntitlementProviderTests.scala | 144 ++++++++++++++------- .../controller/test/PackageActionsApiTests.scala | 2 +- 6 files changed, 167 insertions(+), 66 deletions(-) diff --git a/common/scala/src/main/scala/whisk/http/ErrorResponse.scala b/common/scala/src/main/scala/whisk/http/ErrorResponse.scala index f8d948d..7486cd9 100644 --- a/common/scala/src/main/scala/whisk/http/ErrorResponse.scala +++ b/common/scala/src/main/scala/whisk/http/ErrorResponse.scala @@ -64,6 +64,7 @@ object Messages { /** Standard message for resource not found. */ val resourceDoesNotExist = "The requested resource does not exist." + def resourceDoesntExist(value: String) = s"The requested resource '$value' does not exist." /** Standard message for too many activation requests within a rolling time window. */ def tooManyRequests(count: Int, allowed: Int) = @@ -78,6 +79,8 @@ object Messages { /** Standard message when supplied authkey is not authorized for an operation. */ val notAuthorizedtoOperateOnResource = "The supplied authentication is not authorized to access this resource." + def notAuthorizedtoAccessResource(value: String) = + s"The supplied authentication is not authorized to access '$value'." /** Standard error message for malformed fully qualified entity names. */ val malformedFullyQualifiedEntityName = diff --git a/core/controller/src/main/scala/whisk/core/controller/AuthorizedRouteDispatcher.scala b/core/controller/src/main/scala/whisk/core/controller/AuthorizedRouteDispatcher.scala index 54219ac..9288707 100644 --- a/core/controller/src/main/scala/whisk/core/controller/AuthorizedRouteDispatcher.scala +++ b/core/controller/src/main/scala/whisk/core/controller/AuthorizedRouteDispatcher.scala @@ -26,6 +26,8 @@ import scala.concurrent.Future import akka.http.scaladsl.server.Directives import akka.http.scaladsl.model.HttpMethod +import akka.http.scaladsl.model.StatusCodes.Forbidden +import akka.http.scaladsl.model.StatusCodes.NotFound import akka.http.scaladsl.server.RequestContext import akka.http.scaladsl.server.RouteResult import akka.http.scaladsl.model.StatusCodes.InternalServerError @@ -37,6 +39,7 @@ import whisk.core.entitlement._ import whisk.core.entitlement.Resource import whisk.core.entity._ import whisk.core.entity.size._ +import whisk.http.ErrorResponse import whisk.http.ErrorResponse.terminate import whisk.http.Messages @@ -71,7 +74,21 @@ trait BasicAuthorizedRouteProvider extends Directives { onComplete(entitlementProvider.check(user, right, resource)) { case Success(_) => dispatchOp(user, right, resource) - case Failure(t) => handleEntitlementFailure(t) + case Failure(t) => + t match { + case (r: RejectRequest) => + r.code match { + case Forbidden => + handleEntitlementFailure( + RejectRequest( + Forbidden, + Some(ErrorResponse(Messages.notAuthorizedtoAccessResource(resource.fqname), transid)))) + case NotFound => + handleEntitlementFailure( + RejectRequest(NotFound, Some(ErrorResponse(Messages.resourceDoesntExist(resource.fqname), transid)))) + case _ => handleEntitlementFailure(t) + } + } } } diff --git a/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala b/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala index c068281..6dfbf76 100644 --- a/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala +++ b/core/controller/src/main/scala/whisk/core/entitlement/Entitlement.scala @@ -18,6 +18,8 @@ package whisk.core.entitlement import scala.collection.concurrent.TrieMap +import scala.collection.immutable.Set +import scala.collection.mutable.ListBuffer import scala.concurrent.Future import scala.util.Failure import scala.util.Success @@ -35,6 +37,8 @@ import whisk.core.WhiskConfig import whisk.core.controller.RejectRequest import whisk.core.entity._ import whisk.core.loadBalancer.LoadBalancer +import whisk.http.ErrorResponse +import whisk.http.Messages import whisk.http.Messages._ package object types { @@ -56,6 +60,7 @@ protected[core] case class Resource(namespace: EntityPath, env: Option[Parameters] = None) { def parent = collection.path + EntityPath.PATHSEP + namespace def id = parent + (entity map { EntityPath.PATHSEP + _ } getOrElse ("")) + def fqname = namespace.asString + (entity map { EntityPath.PATHSEP + _ } getOrElse ("")) override def toString = id } @@ -195,21 +200,37 @@ protected[core] abstract class EntitlementProvider(config: WhiskConfig, loadBala protected[core] def check(user: Identity, right: Privilege, resources: Set[Resource])( implicit transid: TransactionId): Future[Unit] = { val subject = user.subject + val inaccessibleResources = ListBuffer[Resource]() val entitlementCheck: Future[Boolean] = if (user.rights.contains(right)) { if (resources.nonEmpty) { - logging.info(this, s"checking user '$subject' has privilege '$right' for '${resources.mkString(",")}'") + logging.info(this, s"checking user '$subject' has privilege '$right' for '${resources.mkString(", ")}'") checkSystemOverload(right) .flatMap(_ => checkUserThrottle(user, right, resources)) .flatMap(_ => checkConcurrentUserThrottle(user, right, resources)) .flatMap(_ => checkPrivilege(user, right, resources)) + .flatMap(resourcePrivSet => { + resourcePrivSet.map { resourcePriv => + if (!resourcePriv._2) inaccessibleResources += resourcePriv._1 + } + Future.successful(inaccessibleResources.length == 0) + }) } else Future.successful(true) } else if (right != REJECT) { + resources.map(r => inaccessibleResources += r) logging.info( this, - s"supplied authkey for user '$subject' does not have privilege '$right' for '${resources.mkString(",")}'") - Future.failed(RejectRequest(Forbidden)) + s"supplied authkey for user '$subject' does not have privilege '$right' for '${resources.mkString(", ")}'") + Future.failed( + RejectRequest( + Forbidden, + Some( + ErrorResponse( + Messages.notAuthorizedtoAccessResource( + inaccessibleResources.map(r => r.fqname).sorted.toSet.mkString(", ")), + transid)))) } else { + resources.map(r => inaccessibleResources += r) Future.successful(false) } entitlementCheck andThen { @@ -221,7 +242,16 @@ protected[core] abstract class EntitlementProvider(config: WhiskConfig, loadBala logging.error(this, s"failed while checking entitlement: ${t.getMessage}") } flatMap { isAuthorized => if (isAuthorized) Future.successful({}) - else Future.failed(RejectRequest(Forbidden)) + else { + Future.failed( + RejectRequest( + Forbidden, + Some( + ErrorResponse( + Messages.notAuthorizedtoAccessResource( + inaccessibleResources.map(r => r.fqname).sorted.toSet.mkString(", ")), + transid)))) + } } } @@ -232,23 +262,23 @@ protected[core] abstract class EntitlementProvider(config: WhiskConfig, loadBala * and the referenced package. */ protected def checkPrivilege(user: Identity, right: Privilege, resources: Set[Resource])( - implicit transid: TransactionId): Future[Boolean] = { + implicit transid: TransactionId): Future[Set[(Resource, Boolean)]] = { // check the default namespace first, bypassing additional checks if permitted val defaultNamespaces = Set(user.namespace.asString) implicit val es = this - Future - .sequence { - resources.map { resource => - resource.collection.implicitRights(user, defaultNamespaces, right, resource) flatMap { - case true => Future.successful(true) - case false => - logging.info(this, "checking explicit grants") - entitled(user.subject, right, resource) - } + Future.sequence { + resources.map { resource => + resource.collection.implicitRights(user, defaultNamespaces, right, resource) flatMap { + case true => Future.successful(resource -> true) + case false => + logging.info(this, "checking explicit grants") + entitled(user.subject, right, resource) flatMap { + case b => Future.successful(resource -> b) + } } } - .map { _.forall(identity) } + } } /** diff --git a/tests/src/test/scala/system/basic/WskBasicTests.scala b/tests/src/test/scala/system/basic/WskBasicTests.scala index 9e52694..d5faee9 100644 --- a/tests/src/test/scala/system/basic/WskBasicTests.scala +++ b/tests/src/test/scala/system/basic/WskBasicTests.scala @@ -36,6 +36,8 @@ import spray.json._ import spray.json.DefaultJsonProtocol._ import spray.json.pimpAny +import whisk.http.Messages + @RunWith(classOf[JUnitRunner]) class WskBasicTests extends TestHelpers with WskTestHelpers { @@ -168,8 +170,9 @@ class WskBasicTests extends TestHelpers with WskTestHelpers { it should "reject get of package that does not exist" in { val name = "nonexistentPackage" + val ns = wsk.namespace.whois() val stderr = wsk.pkg.get(name, expectedExitCode = NOT_FOUND).stderr - stderr should include regex (s"""Unable to get package '$name': The requested resource does not exist. \\(code \\d+\\)""") + stderr should include regex (s"""Unable to get package '$name': ${Messages.resourceDoesntExist(s"${ns}/${name}")} \\(code \\d+\\)""") } behavior of "Wsk Action CLI" diff --git a/tests/src/test/scala/whisk/core/controller/test/EntitlementProviderTests.scala b/tests/src/test/scala/whisk/core/controller/test/EntitlementProviderTests.scala index 1c225b9..65e810b 100644 --- a/tests/src/test/scala/whisk/core/controller/test/EntitlementProviderTests.scala +++ b/tests/src/test/scala/whisk/core/controller/test/EntitlementProviderTests.scala @@ -17,6 +17,7 @@ package whisk.core.controller.test +import scala.collection.mutable.ListBuffer import scala.concurrent.Await import scala.concurrent.duration.DurationInt @@ -39,7 +40,6 @@ import whisk.http.Messages * These tests exercise a fresh instance of the service object in memory -- these * tests do NOT communication with a whisk deployment. * - * * @Idioglossia * "using Specification DSL to write unit tests, as in should, must, not, be" * "using Specs2RouteTest DSL to chain HTTP requests for unit testing, as in ~>" @@ -51,6 +51,7 @@ class EntitlementProviderTests extends ControllerTestCommon with ScalaFutures { val requestTimeout = 10.seconds val someUser = WhiskAuthHelpers.newIdentity() + val anotherUser = WhiskAuthHelpers.newIdentity() val adminUser = WhiskAuthHelpers.newIdentity(Subject("admin")) val guestUser = WhiskAuthHelpers.newIdentity(Subject("anonym")) @@ -58,17 +59,58 @@ class EntitlementProviderTests extends ControllerTestCommon with ScalaFutures { implicit val tid = transid() val collections = Seq(ACTIONS, RULES, TRIGGERS, PACKAGES, ACTIVATIONS, NAMESPACES) val resources = collections map { Resource(someUser.namespace.toPath, _, None) } + resources foreach { r => Await.ready(entitlementProvider.check(someUser, READ, r), requestTimeout).eitherValue.get shouldBe Right({}) Await.ready(entitlementProvider.check(someUser, PUT, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(someUser, DELETE, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(someUser, REJECT, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) + } + } + + it should "authorize a user to only read from their set of collections" in { + implicit val tid = transid() + val collections = Seq(ACTIONS, RULES, TRIGGERS, PACKAGES, ACTIVATIONS, NAMESPACES) + val resources = collections map { c: Collection => + c match { + case RULES => Resource(anotherUser.namespace.toPath, c, None) + case NAMESPACES => Resource(anotherUser.namespace.toPath, c, None) + case _ => Resource(someUser.namespace.toPath, c, None) + } } + + // Sets aren't ordered, but we need to compared an ordered list of namespaces in the output; so + // create a sorted list of namespaces per the iterated through the set. The output list of namespaces + // will also be in sorted order. + val resourcesSet = resources.toSet + val resourcesList = ListBuffer[Resource]() + resourcesSet.map(r => resourcesList += r) + val resourceNames = resourcesList.map(r => r.fqname).sorted.toSet.mkString(", ") + val resourceOtherNames = Seq( + Resource(anotherUser.namespace.toPath, RULES, None), + Resource(anotherUser.namespace.toPath, NAMESPACES, None)).map(r => r.fqname).toSet.mkString(", ") + + Await.ready(entitlementProvider.check(someUser, READ, resourcesSet), requestTimeout).eitherValue.get shouldBe Left( + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceOtherNames))) + Await.ready(entitlementProvider.check(someUser, PUT, resourcesSet), requestTimeout).eitherValue.get shouldBe Left( + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceNames))) + Await + .ready(entitlementProvider.check(someUser, DELETE, resourcesSet), requestTimeout) + .eitherValue + .get shouldBe Left(RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceNames))) + Await + .ready(entitlementProvider.check(someUser, ACTIVATE, resourcesSet), requestTimeout) + .eitherValue + .get shouldBe Left(RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceNames))) + Await + .ready(entitlementProvider.check(someUser, REJECT, resourcesSet), requestTimeout) + .eitherValue + .get shouldBe Left(RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceNames))) } it should "not authorize a user to list someone else's collection or access it by other other right" in { @@ -84,16 +126,16 @@ class EntitlementProviderTests extends ControllerTestCommon with ScalaFutures { Await.ready(entitlementProvider.check(guestUser, READ, r), requestTimeout).eitherValue.get shouldBe Right({}) } else { Await.ready(entitlementProvider.check(guestUser, READ, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) } Await.ready(entitlementProvider.check(guestUser, PUT, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(guestUser, DELETE, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(guestUser, ACTIVATE, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(guestUser, REJECT, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) } } @@ -118,11 +160,11 @@ class EntitlementProviderTests extends ControllerTestCommon with ScalaFutures { val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) } resources foreach { r => Await.ready(entitlementProvider.check(someUser, READ, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(someUser, PUT, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(someUser, DELETE, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout).eitherValue.get shouldBe Right({}) } } @@ -134,11 +176,11 @@ class EntitlementProviderTests extends ControllerTestCommon with ScalaFutures { resources foreach { r => Await.ready(entitlementProvider.check(someUser, READ, r), requestTimeout).eitherValue.get shouldBe Right({}) Await.ready(entitlementProvider.check(someUser, PUT, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(someUser, DELETE, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) } } @@ -148,13 +190,13 @@ class EntitlementProviderTests extends ControllerTestCommon with ScalaFutures { val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) } resources foreach { r => Await.ready(entitlementProvider.check(guestUser, READ, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(guestUser, PUT, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(guestUser, DELETE, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) Await.ready(entitlementProvider.check(guestUser, ACTIVATE, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) } } @@ -171,7 +213,7 @@ class EntitlementProviderTests extends ControllerTestCommon with ScalaFutures { Await.ready(entitlementProvider.check(someUser, DELETE, r), requestTimeout).eitherValue.get shouldBe Right({}) // activate is not allowed on a package Await.ready(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout).eitherValue.get shouldBe Left( - RejectRequest(Forbidden)) + RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(r.fqname))) } } @@ -502,23 +544,25 @@ class EntitlementProviderTests extends ControllerTestCommon with ScalaFutures { implicit val tid = transid() implicit val ep = entitlementProvider + val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), None, publish = false) + val action = WhiskAction(provider.fullPath, MakeName.next(), jsDefault("")) + put(entityStore, provider) + put(entityStore, action) + + val resourceName = provider.fullyQualifiedName(false).asString + val paths = Seq( (READ, someUser, Right(true)), (PUT, someUser, Right(true)), (DELETE, someUser, Right(true)), (ACTIVATE, someUser, Right(true)), (REJECT, someUser, Right(false)), - (READ, guestUser, Left(RejectRequest(Forbidden))), + (READ, guestUser, Left(RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceName)))), (PUT, guestUser, Right(false)), (DELETE, guestUser, Right(false)), - (ACTIVATE, guestUser, Left(RejectRequest(Forbidden))), + (ACTIVATE, guestUser, Left(RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceName)))), (REJECT, guestUser, Right(false))) - val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), None, publish = false) - val action = WhiskAction(provider.fullPath, MakeName.next(), jsDefault("")) - put(entityStore, provider) - put(entityStore, action) - paths foreach { case (priv, who, expected) => val check = new ActionCollection(entityStore).implicitRights( @@ -534,11 +578,20 @@ class EntitlementProviderTests extends ControllerTestCommon with ScalaFutures { implicit val tid = transid() implicit val ep = entitlementProvider + val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), None, publish = true) + val binding = WhiskPackage(guestUser.namespace.toPath, MakeName.next(), provider.bind) + val action = WhiskAction(binding.fullPath, MakeName.next(), jsDefault("")) + put(entityStore, provider) + put(entityStore, binding) + put(entityStore, action) + + val resourceName = binding.fullyQualifiedName(false).asString + val paths = Seq( - (READ, someUser, Left(RejectRequest(Forbidden))), + (READ, someUser, Left(RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceName)))), (PUT, someUser, Right(false)), (DELETE, someUser, Right(false)), - (ACTIVATE, someUser, Left(RejectRequest(Forbidden))), + (ACTIVATE, someUser, Left(RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceName)))), (REJECT, someUser, Right(false)), (READ, guestUser, Right(true)), (PUT, guestUser, Right(true)), @@ -546,13 +599,6 @@ class EntitlementProviderTests extends ControllerTestCommon with ScalaFutures { (ACTIVATE, guestUser, Right(true)), (REJECT, guestUser, Right(false))) - val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), None, publish = true) - val binding = WhiskPackage(guestUser.namespace.toPath, MakeName.next(), provider.bind) - val action = WhiskAction(binding.fullPath, MakeName.next(), jsDefault("")) - put(entityStore, provider) - put(entityStore, binding) - put(entityStore, action) - paths foreach { case (priv, who, expected) => val check = new ActionCollection(entityStore).implicitRights( @@ -568,25 +614,27 @@ class EntitlementProviderTests extends ControllerTestCommon with ScalaFutures { implicit val tid = transid() implicit val ep = entitlementProvider + val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), None, publish = false) + val binding = WhiskPackage(guestUser.namespace.toPath, MakeName.next(), provider.bind) + val action = WhiskAction(binding.fullPath, MakeName.next(), jsDefault("")) + put(entityStore, provider) + put(entityStore, binding) + put(entityStore, action) + + val resourceName = binding.fullyQualifiedName(false).asString + val paths = Seq( - (READ, someUser, Left(RejectRequest(Forbidden))), + (READ, someUser, Left(RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceName)))), (PUT, someUser, Right(false)), (DELETE, someUser, Right(false)), - (ACTIVATE, someUser, Left(RejectRequest(Forbidden))), + (ACTIVATE, someUser, Left(RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceName)))), (REJECT, someUser, Right(false)), - (READ, guestUser, Left(RejectRequest(Forbidden))), + (READ, guestUser, Left(RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceName)))), (PUT, guestUser, Right(true)), (DELETE, guestUser, Right(true)), - (ACTIVATE, guestUser, Left(RejectRequest(Forbidden))), + (ACTIVATE, guestUser, Left(RejectRequest(Forbidden, Messages.notAuthorizedtoAccessResource(resourceName)))), (REJECT, guestUser, Right(false))) - val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), None, publish = false) - val binding = WhiskPackage(guestUser.namespace.toPath, MakeName.next(), provider.bind) - val action = WhiskAction(binding.fullPath, MakeName.next(), jsDefault("")) - put(entityStore, provider) - put(entityStore, binding) - put(entityStore, action) - paths foreach { case (priv, who, expected) => val check = new ActionCollection(entityStore).implicitRights( diff --git a/tests/src/test/scala/whisk/core/controller/test/PackageActionsApiTests.scala b/tests/src/test/scala/whisk/core/controller/test/PackageActionsApiTests.scala index 24d19b6..e8082af 100644 --- a/tests/src/test/scala/whisk/core/controller/test/PackageActionsApiTests.scala +++ b/tests/src/test/scala/whisk/core/controller/test/PackageActionsApiTests.scala @@ -591,7 +591,7 @@ class PackageActionsApiTests extends ControllerTestCommon with WhiskActionsApi { val auser = WhiskAuthHelpers.newIdentity() Get(s"/${provider.namespace}/${collection.path}/${provider.name}/${entity.name}") ~> Route.seal(routes(auser)) ~> check { status should be(Forbidden) - responseAs[ErrorResponse].error shouldBe Messages.notAuthorizedtoOperateOnResource + responseAs[ErrorResponse].error shouldBe Messages.notAuthorizedtoAccessResource(s"$namespace/${provider.name}") } } -- To stop receiving notification emails like this one, please contact ['"commits@openwhisk.apache.org" <commits@openwhisk.apache.org>'].