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>'].

Reply via email to