More unit test for access and entitlement.
- Change type of namespace in binding to EntityName since packages may not nest.
- Entity[Name,Path] and Doc[Id,Rev]: Remove apply() as String conversion in favor of asString.
- Subject: Remove apply() as String conversion in favor of asString.
diff --git a/tests/src/whisk/core/admin/WskAdminTests.scala b/tests/src/whisk/core/admin/WskAdminTests.scala
index 8b8ee24..73ee31a 100644
--- a/tests/src/whisk/core/admin/WskAdminTests.scala
+++ b/tests/src/whisk/core/admin/WskAdminTests.scala
@@ -41,7 +41,7 @@
it should "CRD a subject" in {
val wskadmin = new RunWskAdminCmd {}
val auth = WhiskAuth(Subject(), AuthKey())
- val subject = auth.subject()
+ val subject = auth.subject.asString
println(s"CRD subject: $subject")
val create = wskadmin.cli(Seq("user", "create", subject))
diff --git a/tests/src/whisk/core/controller/test/ActionsApiTests.scala b/tests/src/whisk/core/controller/test/ActionsApiTests.scala
index c2b6d18..03da7a7 100644
--- a/tests/src/whisk/core/controller/test/ActionsApiTests.scala
+++ b/tests/src/whisk/core/controller/test/ActionsApiTests.scala
@@ -56,7 +56,7 @@
behavior of "Actions API"
val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val namespace = EntityPath(creds.subject())
+ val namespace = EntityPath(creds.subject.asString)
val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
def aname = MakeName.next("action_tests")
setVerbosity(InfoLevel)
@@ -664,7 +664,7 @@
val sequence = Vector(stringToFullyQualifiedName(s"$namespace/${entity.name}"))
val content = WhiskActionPut(Some(Exec.sequence(sequence)))
- Put(s"$collectionPath/${aname()}", content) ~> sealRoute(routes(creds)) ~> check {
+ Put(s"$collectionPath/$aname", content) ~> sealRoute(routes(creds)) ~> check {
status should be(InternalServerError)
responseAs[ErrorResponse].error shouldBe Messages.corruptedEntity
}
diff --git a/tests/src/whisk/core/controller/test/ActivationsApiTests.scala b/tests/src/whisk/core/controller/test/ActivationsApiTests.scala
index e078b0b..0780316 100644
--- a/tests/src/whisk/core/controller/test/ActivationsApiTests.scala
+++ b/tests/src/whisk/core/controller/test/ActivationsApiTests.scala
@@ -49,7 +49,7 @@
behavior of "Activations API"
val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val namespace = EntityPath(creds.subject())
+ val namespace = EntityPath(creds.subject.asString)
val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
def aname = MakeName.next("activations_tests")
@@ -59,7 +59,7 @@
// create two sets of activation records, and check that only one set is served back
val creds1 = WhiskAuth(Subject(), AuthKey())
(1 to 2).map { i =>
- WhiskActivation(EntityPath(creds1.subject()), aname, creds1.subject, ActivationId(), start = Instant.now, end = Instant.now)
+ WhiskActivation(EntityPath(creds1.subject.asString), aname, creds1.subject, ActivationId(), start = Instant.now, end = Instant.now)
} foreach { put(entityStore, _) }
val actionName = aname
@@ -75,7 +75,7 @@
val response = responseAs[List[JsObject]]
activations.length should be(response.length)
activations forall { a => response contains a.summaryAsJson } should be(true)
- rawResponse forall { a => a.getFields("for") match { case Seq(JsString(n)) => n == actionName() case _ => false } }
+ rawResponse forall { a => a.getFields("for") match { case Seq(JsString(n)) => n == actionName.asString case _ => false } }
}
}
@@ -87,7 +87,7 @@
val response = responseAs[List[JsObject]]
activations.length should be(response.length)
activations forall { a => response contains a.summaryAsJson } should be(true)
- rawResponse forall { a => a.getFields("for") match { case Seq(JsString(n)) => n == actionName() case _ => false } }
+ rawResponse forall { a => a.getFields("for") match { case Seq(JsString(n)) => n == actionName.asString case _ => false } }
}
}
@@ -104,7 +104,7 @@
// create two sets of activation records, and check that only one set is served back
val creds1 = WhiskAuth(Subject(), AuthKey())
(1 to 2).map { i =>
- WhiskActivation(EntityPath(creds1.subject()), aname, creds1.subject, ActivationId(), start = Instant.now, end = Instant.now)
+ WhiskActivation(EntityPath(creds1.subject.asString), aname, creds1.subject, ActivationId(), start = Instant.now, end = Instant.now)
} foreach { put(entityStore, _) }
val actionName = aname
@@ -130,7 +130,7 @@
// create two sets of activation records, and check that only one set is served back
val creds1 = WhiskAuth(Subject(), AuthKey())
(1 to 2).map { i =>
- WhiskActivation(EntityPath(creds1.subject()), aname, creds1.subject, ActivationId(), start = Instant.now, end = Instant.now)
+ WhiskActivation(EntityPath(creds1.subject.asString), aname, creds1.subject, ActivationId(), start = Instant.now, end = Instant.now)
} foreach { put(entityStore, _) }
val actionName = aname
@@ -193,7 +193,7 @@
// create two sets of activation records, and check that only one set is served back
val creds1 = WhiskAuth(Subject(), AuthKey())
(1 to 2).map { i =>
- WhiskActivation(EntityPath(creds1.subject()), aname, creds1.subject, ActivationId(), start = Instant.now, end = Instant.now)
+ WhiskActivation(EntityPath(creds1.subject.asString), aname, creds1.subject, ActivationId(), start = Instant.now, end = Instant.now)
} foreach { put(entityStore, _) }
val activations = (1 to 2).map { i =>
@@ -344,7 +344,7 @@
status should be(InternalServerError)
val error = responseAs[ErrorResponse].error
error should include("missing required member")
- Seq(entity.name(), "annotations", "parameters", "exec", "trigger", "action", "rules", "binding", "response").map {
+ Seq(entity.name.asString, "annotations", "parameters", "exec", "trigger", "action", "rules", "binding", "response").map {
error should not include (_)
}
}
diff --git a/tests/src/whisk/core/controller/test/AuthorizeTests.scala b/tests/src/whisk/core/controller/test/AuthorizeTests.scala
deleted file mode 100644
index bcaafa4..0000000
--- a/tests/src/whisk/core/controller/test/AuthorizeTests.scala
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright 2015-2016 IBM Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package whisk.core.controller.test
-
-import scala.concurrent.Await
-import scala.concurrent.duration.DurationInt
-import scala.language.postfixOps
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-
-import whisk.core.controller.Authenticate
-import whisk.core.controller.RejectRequest
-import whisk.core.entitlement._
-import whisk.core.entitlement.Privilege._
-import whisk.core.entity._
-
-/**
- * Tests authorization handler which guards resources.
- *
- * Unit tests of the controller service as a standalone component.
- * 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 ~>"
- */
-@RunWith(classOf[JUnitRunner])
-class AuthorizeTests extends ControllerTestCommon with Authenticate {
-
- behavior of "Authorize"
-
- val requestTimeout = 1 second
- val someUser = Subject().toIdentity(AuthKey())
- val adminUser = Subject("admin").toIdentity(AuthKey())
- val guestUser = Subject("anonym").toIdentity(AuthKey())
-
- it should "authorize a user to only read from their collection" in {
- 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.result(entitlementProvider.check(someUser, READ, r), requestTimeout) should be(true)
- Await.result(entitlementProvider.check(someUser, PUT, r), requestTimeout) should be(false)
- Await.result(entitlementProvider.check(someUser, DELETE, r), requestTimeout) should be(false)
- Await.result(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout) should be(false)
- Await.result(entitlementProvider.check(someUser, REJECT, r), requestTimeout) should be(false)
- }
- }
-
- it should "not authorize a user to list someone else's collection or access it by other other right" in {
- 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 =>
- // it is permissible to list packages in any namespace (provided they are either owned by
- // the subject requesting access or the packages are public); that is, the entitlement is more
- // fine grained and applies to public vs private private packages (hence permit READ on PACKAGES to
- // be true
- Await.result(entitlementProvider.check(guestUser, READ, r), requestTimeout) should be(r.collection == PACKAGES)
- Await.result(entitlementProvider.check(guestUser, PUT, r), requestTimeout) should be(false)
- Await.result(entitlementProvider.check(guestUser, DELETE, r), requestTimeout) should be(false)
- Await.result(entitlementProvider.check(guestUser, ACTIVATE, r), requestTimeout) should be(false)
- Await.result(entitlementProvider.check(guestUser, REJECT, r), requestTimeout) should be(false)
- }
- }
-
- it should "authorize a user to CRUD or activate (if supported) an entity in a collection" in {
- implicit val tid = transid()
- // packages are tested separately
- val collections = Seq(ACTIONS, RULES, TRIGGERS)
- val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) }
- resources foreach { r =>
- Await.result(entitlementProvider.check(someUser, READ, r), requestTimeout) should be(true)
- Await.result(entitlementProvider.check(someUser, PUT, r), requestTimeout) should be(true)
- Await.result(entitlementProvider.check(someUser, DELETE, r), requestTimeout) should be(true)
- Await.result(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout) should be(true)
- }
- }
-
- it should "not authorize a user to CRUD an entity in a collection if authkey has no CRUD rights" in {
- implicit val tid = transid()
- val subject = Subject()
- val someUser = Identity(subject, EntityName(subject()), AuthKey(), Set(Privilege.ACTIVATE))
- val collections = Seq(ACTIONS, RULES, TRIGGERS)
- val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) }
- resources foreach { r =>
- a[RejectRequest] should be thrownBy {
- Await.result(entitlementProvider.check(someUser, READ, r), requestTimeout)
- }
- a[RejectRequest] should be thrownBy {
- Await.result(entitlementProvider.check(someUser, PUT, r), requestTimeout)
- }
- a[RejectRequest] should be thrownBy {
- Await.result(entitlementProvider.check(someUser, DELETE, r), requestTimeout)
- }
- Await.result(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout) should be(true)
- }
- }
-
- it should "not authorize a user to CRUD or activate an entity in a collection that does not support CRUD or activate" in {
- implicit val tid = transid()
- val collections = Seq(NAMESPACES, ACTIVATIONS)
- val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) }
- resources foreach { r =>
- Await.result(entitlementProvider.check(someUser, READ, r), requestTimeout) should be(true)
- Await.result(entitlementProvider.check(someUser, PUT, r), requestTimeout) should be(false)
- Await.result(entitlementProvider.check(someUser, DELETE, r), requestTimeout) should be(false)
- Await.result(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout) should be(false)
- }
- }
-
- it should "not authorize a user to CRUD or activate an entity in someone else's collection" in {
- implicit val tid = transid()
- val collections = Seq(ACTIONS, RULES, TRIGGERS, PACKAGES)
- val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) }
- resources foreach { r =>
- Await.result(entitlementProvider.check(guestUser, READ, r), requestTimeout) should be(false)
- Await.result(entitlementProvider.check(guestUser, PUT, r), requestTimeout) should be(false)
- Await.result(entitlementProvider.check(guestUser, DELETE, r), requestTimeout) should be(false)
- Await.result(entitlementProvider.check(guestUser, ACTIVATE, r), requestTimeout) should be(false)
- }
- }
-
- it should "authorize a user to list, create/update/delete a package" in {
- implicit val tid = transid()
- val collections = Seq(PACKAGES)
- val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) }
- resources foreach { r =>
- a[RejectRequest] should be thrownBy {
- // read should fail because the lookup for the package will fail
- Await.result(entitlementProvider.check(someUser, READ, r), requestTimeout)
- }
- // create/put/delete should be allowed
- Await.result(entitlementProvider.check(someUser, PUT, r), requestTimeout) should be(true)
- Await.result(entitlementProvider.check(someUser, DELETE, r), requestTimeout) should be(true)
- // activate is not allowed on a package
- Await.result(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout) should be(false)
- }
- }
-
- it should "grant access to entire collection to another user" in {
- implicit val tid = transid()
- val all = Resource(someUser.namespace.toPath, ACTIONS, None)
- val one = Resource(someUser.namespace.toPath, ACTIONS, Some("xyz"))
- Await.result(entitlementProvider.check(adminUser, READ, all), requestTimeout) should not be (true)
- Await.result(entitlementProvider.check(adminUser, READ, one), requestTimeout) should not be (true)
- Await.result(entitlementProvider.grant(adminUser.subject, READ, all), requestTimeout) // granted
- Await.result(entitlementProvider.check(adminUser, READ, all), requestTimeout) should be(true)
- Await.result(entitlementProvider.check(adminUser, READ, one), requestTimeout) should be(true)
- Await.result(entitlementProvider.revoke(adminUser.subject, READ, all), requestTimeout) // revoked
- }
-
- it should "grant access to specific resource to a user" in {
- implicit val tid = transid()
- val all = Resource(someUser.namespace.toPath, ACTIONS, None)
- val one = Resource(someUser.namespace.toPath, ACTIONS, Some("xyz"))
- Await.result(entitlementProvider.check(adminUser, READ, all), requestTimeout) should not be (true)
- Await.result(entitlementProvider.check(adminUser, READ, one), requestTimeout) should not be (true)
- Await.result(entitlementProvider.check(adminUser, DELETE, one), requestTimeout) should not be (true)
- Await.result(entitlementProvider.grant(adminUser.subject, READ, one), requestTimeout) // granted
- Await.result(entitlementProvider.check(adminUser, READ, all), requestTimeout) should not be (true)
- Await.result(entitlementProvider.check(adminUser, READ, one), requestTimeout) should be(true)
- Await.result(entitlementProvider.check(adminUser, DELETE, one), requestTimeout) should not be (true)
- Await.result(entitlementProvider.revoke(adminUser.subject, READ, one), requestTimeout) // revoked
- }
-}
diff --git a/tests/src/whisk/core/controller/test/EntitlementProviderTests.scala b/tests/src/whisk/core/controller/test/EntitlementProviderTests.scala
new file mode 100644
index 0000000..c9400c6
--- /dev/null
+++ b/tests/src/whisk/core/controller/test/EntitlementProviderTests.scala
@@ -0,0 +1,621 @@
+/*
+ * Copyright 2015-2016 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package whisk.core.controller.test
+
+import scala.concurrent.Await
+import scala.concurrent.duration.DurationInt
+import scala.language.postfixOps
+
+import org.junit.runner.RunWith
+import org.scalatest.concurrent.ScalaFutures
+import org.scalatest.junit.JUnitRunner
+
+import spray.http.StatusCodes._
+import whisk.core.controller.RejectRequest
+import whisk.core.entitlement._
+import whisk.core.entitlement.Privilege._
+import whisk.core.entity._
+import whisk.http.Messages
+
+/**
+ * Tests authorization handler which guards resources.
+ *
+ * Unit tests of the controller service as a standalone component.
+ * 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 ~>"
+ */
+@RunWith(classOf[JUnitRunner])
+class EntitlementProviderTests
+ extends ControllerTestCommon
+ with ScalaFutures {
+
+ behavior of "Entitlement Provider"
+
+ val requestTimeout = 1 second
+ val someUser = Subject().toIdentity(AuthKey())
+ val adminUser = Subject("admin").toIdentity(AuthKey())
+ val guestUser = Subject("anonym").toIdentity(AuthKey())
+
+ it should "authorize a user to only read from their collection" in {
+ 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.result(entitlementProvider.check(someUser, READ, r), requestTimeout) should be(true)
+ Await.result(entitlementProvider.check(someUser, PUT, r), requestTimeout) should be(false)
+ Await.result(entitlementProvider.check(someUser, DELETE, r), requestTimeout) should be(false)
+ Await.result(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout) should be(false)
+ Await.result(entitlementProvider.check(someUser, REJECT, r), requestTimeout) should be(false)
+ }
+ }
+
+ it should "not authorize a user to list someone else's collection or access it by other other right" in {
+ 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 =>
+ // it is permissible to list packages in any namespace (provided they are either owned by
+ // the subject requesting access or the packages are public); that is, the entitlement is more
+ // fine grained and applies to public vs private private packages (hence permit READ on PACKAGES to
+ // be true
+ Await.result(entitlementProvider.check(guestUser, READ, r), requestTimeout) should be(r.collection == PACKAGES)
+ Await.result(entitlementProvider.check(guestUser, PUT, r), requestTimeout) should be(false)
+ Await.result(entitlementProvider.check(guestUser, DELETE, r), requestTimeout) should be(false)
+ Await.result(entitlementProvider.check(guestUser, ACTIVATE, r), requestTimeout) should be(false)
+ Await.result(entitlementProvider.check(guestUser, REJECT, r), requestTimeout) should be(false)
+ }
+ }
+
+ it should "authorize a user to CRUD or activate (if supported) an entity in a collection" in {
+ implicit val tid = transid()
+ // packages are tested separately
+ val collections = Seq(ACTIONS, RULES, TRIGGERS)
+ val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) }
+ resources foreach { r =>
+ Await.result(entitlementProvider.check(someUser, READ, r), requestTimeout) should be(true)
+ Await.result(entitlementProvider.check(someUser, PUT, r), requestTimeout) should be(true)
+ Await.result(entitlementProvider.check(someUser, DELETE, r), requestTimeout) should be(true)
+ Await.result(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout) should be(true)
+ }
+ }
+
+ it should "not authorize a user to CRUD an entity in a collection if authkey has no CRUD rights" in {
+ implicit val tid = transid()
+ val subject = Subject()
+ val someUser = Identity(subject, EntityName(subject.asString), AuthKey(), Set(Privilege.ACTIVATE))
+ val collections = Seq(ACTIONS, RULES, TRIGGERS)
+ val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) }
+ resources foreach { r =>
+ a[RejectRequest] should be thrownBy {
+ Await.result(entitlementProvider.check(someUser, READ, r), requestTimeout)
+ }
+ a[RejectRequest] should be thrownBy {
+ Await.result(entitlementProvider.check(someUser, PUT, r), requestTimeout)
+ }
+ a[RejectRequest] should be thrownBy {
+ Await.result(entitlementProvider.check(someUser, DELETE, r), requestTimeout)
+ }
+ Await.result(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout) should be(true)
+ }
+ }
+
+ it should "not authorize a user to CRUD or activate an entity in a collection that does not support CRUD or activate" in {
+ implicit val tid = transid()
+ val collections = Seq(NAMESPACES, ACTIVATIONS)
+ val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) }
+ resources foreach { r =>
+ Await.result(entitlementProvider.check(someUser, READ, r), requestTimeout) should be(true)
+ Await.result(entitlementProvider.check(someUser, PUT, r), requestTimeout) should be(false)
+ Await.result(entitlementProvider.check(someUser, DELETE, r), requestTimeout) should be(false)
+ Await.result(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout) should be(false)
+ }
+ }
+
+ it should "not authorize a user to CRUD or activate an entity in someone else's collection" in {
+ implicit val tid = transid()
+ val collections = Seq(ACTIONS, RULES, TRIGGERS, PACKAGES)
+ val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) }
+ resources foreach { r =>
+ Await.result(entitlementProvider.check(guestUser, READ, r), requestTimeout) should be(false)
+ Await.result(entitlementProvider.check(guestUser, PUT, r), requestTimeout) should be(false)
+ Await.result(entitlementProvider.check(guestUser, DELETE, r), requestTimeout) should be(false)
+ Await.result(entitlementProvider.check(guestUser, ACTIVATE, r), requestTimeout) should be(false)
+ }
+ }
+
+ it should "authorize a user to list, create/update/delete a package" in {
+ implicit val tid = transid()
+ val collections = Seq(PACKAGES)
+ val resources = collections map { Resource(someUser.namespace.toPath, _, Some("xyz")) }
+ resources foreach { r =>
+ a[RejectRequest] should be thrownBy {
+ // read should fail because the lookup for the package will fail
+ Await.result(entitlementProvider.check(someUser, READ, r), requestTimeout)
+ }
+ // create/put/delete should be allowed
+ Await.result(entitlementProvider.check(someUser, PUT, r), requestTimeout) should be(true)
+ Await.result(entitlementProvider.check(someUser, DELETE, r), requestTimeout) should be(true)
+ // activate is not allowed on a package
+ Await.result(entitlementProvider.check(someUser, ACTIVATE, r), requestTimeout) should be(false)
+ }
+ }
+
+ it should "grant access to entire collection to another user" in {
+ implicit val tid = transid()
+ val all = Resource(someUser.namespace.toPath, ACTIONS, None)
+ val one = Resource(someUser.namespace.toPath, ACTIONS, Some("xyz"))
+ Await.result(entitlementProvider.check(adminUser, READ, all), requestTimeout) should not be (true)
+ Await.result(entitlementProvider.check(adminUser, READ, one), requestTimeout) should not be (true)
+ Await.result(entitlementProvider.grant(adminUser.subject, READ, all), requestTimeout) // granted
+ Await.result(entitlementProvider.check(adminUser, READ, all), requestTimeout) should be(true)
+ Await.result(entitlementProvider.check(adminUser, READ, one), requestTimeout) should be(true)
+ Await.result(entitlementProvider.revoke(adminUser.subject, READ, all), requestTimeout) // revoked
+ }
+
+ it should "grant access to specific resource to a user" in {
+ implicit val tid = transid()
+ val all = Resource(someUser.namespace.toPath, ACTIONS, None)
+ val one = Resource(someUser.namespace.toPath, ACTIONS, Some("xyz"))
+ Await.result(entitlementProvider.check(adminUser, READ, all), requestTimeout) should not be (true)
+ Await.result(entitlementProvider.check(adminUser, READ, one), requestTimeout) should not be (true)
+ Await.result(entitlementProvider.check(adminUser, DELETE, one), requestTimeout) should not be (true)
+ Await.result(entitlementProvider.grant(adminUser.subject, READ, one), requestTimeout) // granted
+ Await.result(entitlementProvider.check(adminUser, READ, all), requestTimeout) should not be (true)
+ Await.result(entitlementProvider.check(adminUser, READ, one), requestTimeout) should be(true)
+ Await.result(entitlementProvider.check(adminUser, DELETE, one), requestTimeout) should not be (true)
+ Await.result(entitlementProvider.revoke(adminUser.subject, READ, one), requestTimeout) // revoked
+ }
+
+ behavior of "Package Collection"
+
+ it should "only allow read access for listing package collection" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ val paths = Seq(
+ (READ, someUser, Right(true)),
+ (PUT, someUser, Right(false)),
+ (DELETE, someUser, Right(false)),
+ (ACTIVATE, someUser, Right(false)),
+ (REJECT, someUser, Right(false)),
+
+ (READ, guestUser, Right(true)),
+ (PUT, guestUser, Right(false)),
+ (DELETE, guestUser, Right(false)),
+ (ACTIVATE, guestUser, Right(false)),
+ (REJECT, guestUser, Right(false)))
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new PackageCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ // any user can list any namespace packages
+ // (because this performs a db view lookup which is later filtered)
+ Resource(someUser.namespace.toPath, PACKAGES, None))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ it should "reject entitlement if package doesn't exist" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ val paths = Seq(
+ (READ, someUser, Left(RejectRequest(NotFound))), // for owner, give more information
+ (PUT, someUser, Right(true)),
+ (DELETE, someUser, Right(true)),
+ (ACTIVATE, someUser, Right(false)),
+ (REJECT, someUser, Right(false)),
+
+ (READ, guestUser, Right(false)),
+ (PUT, guestUser, Right(false)),
+ (DELETE, guestUser, Right(false)),
+ (ACTIVATE, guestUser, Right(false)),
+ (REJECT, guestUser, Right(false)))
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new PackageCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(someUser.namespace.toPath, PACKAGES, Some("xyz")))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ it should "reject entitlement if package doesn't deserialize" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ val paths = Seq(
+ (READ, someUser, Left(RejectRequest(Conflict, Messages.conformanceMessage))), // for owner, give more information
+ (PUT, someUser, Right(true)),
+ (DELETE, someUser, Right(true)),
+ (ACTIVATE, someUser, Right(false)),
+ (REJECT, someUser, Right(false)),
+
+ (READ, guestUser, Right(false)),
+ (PUT, guestUser, Right(false)),
+ (DELETE, guestUser, Right(false)),
+ (ACTIVATE, guestUser, Right(false)),
+ (REJECT, guestUser, Right(false)))
+
+ // this forces a doc mismatch error
+ val action = WhiskAction(someUser.namespace.toPath, MakeName.next(), Exec.js(""))
+ put(entityStore, action)
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new PackageCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(someUser.namespace.toPath, PACKAGES, Some(action.name.asString)))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ it should "not allow guest access to private package" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next())
+ put(entityStore, provider)
+
+ val paths = Seq(
+ (READ, someUser, Right(true)),
+ (PUT, someUser, Right(true)),
+ (DELETE, someUser, Right(true)),
+ (ACTIVATE, someUser, Right(false)),
+ (REJECT, someUser, Right(false)),
+
+ (READ, guestUser, Right(false)),
+ (PUT, guestUser, Right(false)),
+ (DELETE, guestUser, Right(false)),
+ (ACTIVATE, guestUser, Right(false)),
+ (REJECT, guestUser, Right(false)))
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new PackageCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(someUser.namespace.toPath, PACKAGES, Some(provider.name.asString)))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ it should "not allow guest access to binding of private package" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ // simulate entitlement change on package for which binding was once entitled
+ val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next())
+ val binding = WhiskPackage(guestUser.namespace.toPath, MakeName.next(), provider.bind)
+ put(entityStore, provider, false)
+ put(entityStore, binding)
+
+ val paths = Seq(
+ (READ, someUser, Right(false)),
+ (PUT, someUser, Right(false)),
+ (DELETE, someUser, Right(false)),
+ (ACTIVATE, someUser, Right(false)),
+ (REJECT, someUser, Right(false)),
+
+ (READ, guestUser, Right(false)), // not allowed to read referenced package
+ (PUT, guestUser, Right(true)), // can update
+ (DELETE, guestUser, Right(true)), // and delete the binding however
+ (ACTIVATE, guestUser, Right(false)),
+ (REJECT, guestUser, Right(false)))
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new PackageCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(guestUser.namespace.toPath, PACKAGES, Some(binding.name.asString)))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+
+ // simulate package deletion for which binding was once entitled
+ deletePackage(provider.docid)
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new PackageCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(guestUser.namespace.toPath, PACKAGES, Some(binding.name.asString)))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ it should "not allow guest access to public binding of package" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ // simulate entitlement change on package for which binding was once entitled
+ val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), None, publish = true)
+ val binding = WhiskPackage(guestUser.namespace.toPath, MakeName.next(), provider.bind, publish = true)
+ put(entityStore, provider)
+ put(entityStore, binding)
+
+ val paths = Seq(
+ (READ, someUser, Right(false)), // cannot access a public binding
+ (PUT, someUser, Right(false)),
+ (DELETE, someUser, Right(false)),
+ (ACTIVATE, someUser, Right(false)),
+ (REJECT, someUser, Right(false)),
+
+ (READ, guestUser, Right(true)), // can read
+ (PUT, guestUser, Right(true)), // can update
+ (DELETE, guestUser, Right(true)), // and delete the binding
+ (ACTIVATE, guestUser, Right(false)),
+ (REJECT, guestUser, Right(false)))
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new PackageCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(guestUser.namespace.toPath, PACKAGES, Some(binding.name.asString)))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ it should "allow guest access to binding of public package" in {
+ 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)
+ put(entityStore, provider)
+ put(entityStore, binding)
+
+ val paths = Seq(
+ (READ, someUser, Right(false)),
+ (PUT, someUser, Right(false)),
+ (DELETE, someUser, Right(false)),
+ (ACTIVATE, someUser, Right(false)),
+ (REJECT, someUser, Right(false)),
+
+ (READ, guestUser, Right(true)), // can read package + binding
+ (PUT, guestUser, Right(true)), // can update
+ (DELETE, guestUser, Right(true)), // and delete the binding
+ (ACTIVATE, guestUser, Right(false)),
+ (REJECT, guestUser, Right(false)))
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new PackageCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(guestUser.namespace.toPath, PACKAGES, Some(binding.name.asString)))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ behavior of "Action Collection"
+
+ it should "only allow read access for listing action collection" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ val paths = Seq(
+ (READ, someUser, Right(true)),
+ (PUT, someUser, Right(false)),
+ (DELETE, someUser, Right(false)),
+ (ACTIVATE, someUser, Right(false)),
+ (REJECT, someUser, Right(false)),
+
+ (READ, guestUser, Right(false)),
+ (PUT, guestUser, Right(false)),
+ (DELETE, guestUser, Right(false)),
+ (ACTIVATE, guestUser, Right(false)),
+ (REJECT, guestUser, Right(false)))
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new ActionCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ // any user can list any namespace packages
+ // (because this performs a db view lookup which is later filtered)
+ Resource(someUser.namespace.toPath, ACTIONS, None))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ it should "allow guest access to read or activate an action in a package if package is public" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ 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, Right(true)),
+ (PUT, guestUser, Right(false)),
+ (DELETE, guestUser, Right(false)),
+ (ACTIVATE, guestUser, Right(true)),
+ (REJECT, guestUser, Right(false)))
+
+ val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), None, publish = true)
+ val action = WhiskAction(provider.fullPath, MakeName.next(), Exec.js(""))
+ put(entityStore, provider)
+ put(entityStore, action)
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new ActionCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(action.namespace, ACTIONS, Some(action.name.asString)))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ it should "reject guest access to read or activate an action in a package if package is private" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ 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, Right(false)),
+ (PUT, guestUser, Right(false)),
+ (DELETE, guestUser, Right(false)),
+ (ACTIVATE, guestUser, Right(false)),
+ (REJECT, guestUser, Right(false)))
+
+ val provider = WhiskPackage(someUser.namespace.toPath, MakeName.next(), None, publish = false)
+ val action = WhiskAction(provider.fullPath, MakeName.next(), Exec.js(""))
+ put(entityStore, provider)
+ put(entityStore, action)
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new ActionCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(action.namespace, ACTIONS, Some(action.name.asString)))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ it should "allow guest access to read or activate an action in a package binding if package is public" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ val paths = Seq(
+ (READ, someUser, Right(false)),
+ (PUT, someUser, Right(false)),
+ (DELETE, someUser, Right(false)),
+ (ACTIVATE, someUser, Right(false)),
+ (REJECT, someUser, Right(false)),
+
+ (READ, guestUser, Right(true)),
+ (PUT, guestUser, Right(true)),
+ (DELETE, guestUser, Right(true)),
+ (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(), Exec.js(""))
+ put(entityStore, provider)
+ put(entityStore, binding)
+ put(entityStore, action)
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new ActionCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(action.namespace, ACTIONS, Some(action.name.asString)))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ it should "reject guest access to read or activate an action in a package binding if package is private" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ val paths = Seq(
+ (READ, someUser, Right(false)),
+ (PUT, someUser, Right(false)),
+ (DELETE, someUser, Right(false)),
+ (ACTIVATE, someUser, Right(false)),
+ (REJECT, someUser, Right(false)),
+
+ (READ, guestUser, Right(false)),
+ (PUT, guestUser, Right(true)),
+ (DELETE, guestUser, Right(true)),
+ (ACTIVATE, guestUser, Right(false)),
+ (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(), Exec.js(""))
+ put(entityStore, provider)
+ put(entityStore, binding)
+ put(entityStore, action)
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new ActionCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(action.namespace, ACTIONS, Some(action.name.asString)))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+
+ it should "reject guest access to read or activate an action in default package" in {
+ implicit val tid = transid()
+ implicit val ep = entitlementProvider
+
+ 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, Right(false)),
+ (PUT, guestUser, Right(false)),
+ (DELETE, guestUser, Right(false)),
+ (ACTIVATE, guestUser, Right(false)),
+ (REJECT, guestUser, Right(false)))
+
+ val action = WhiskAction(someUser.namespace.toPath, MakeName.next(), Exec.js(""))
+ put(entityStore, action)
+
+ paths foreach {
+ case (priv, who, expected) =>
+ val check = new ActionCollection(entityStore).implicitRights(
+ who,
+ Set(who.namespace.asString),
+ priv,
+ Resource(action.namespace, ACTIONS, Some(action.name.asString)))
+ Await.ready(check, requestTimeout).eitherValue.get shouldBe expected
+ }
+ }
+}
diff --git a/tests/src/whisk/core/controller/test/MetaApiTests.scala b/tests/src/whisk/core/controller/test/MetaApiTests.scala
index fde7146..96f9e2c 100644
--- a/tests/src/whisk/core/controller/test/MetaApiTests.scala
+++ b/tests/src/whisk/core/controller/test/MetaApiTests.scala
@@ -59,14 +59,14 @@
override val apiversion = "v1"
val subject = Subject()
- override val systemId = subject()
+ override val systemId = subject.asString
override lazy val systemKey = Future.successful(WhiskAuth(subject, AuthKey()).toIdentity)
/** Meta API tests */
behavior of "Meta API"
val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val namespace = EntityPath(creds.subject())
+ val namespace = EntityPath(creds.subject.asString)
setVerbosity(InfoLevel)
val packages = Seq(
@@ -186,7 +186,7 @@
}
it should "resolve a meta package into the systemId namespace" in {
- resolvePackageName(EntityName("foo")).fullPath() shouldBe s"$systemId/foo"
+ resolvePackageName(EntityName("foo")).fullPath.asString shouldBe s"$systemId/foo"
}
it should "reject unsupported http verbs" in {
diff --git a/tests/src/whisk/core/controller/test/NamespacesApiTests.scala b/tests/src/whisk/core/controller/test/NamespacesApiTests.scala
index e56dc41..9da4029 100644
--- a/tests/src/whisk/core/controller/test/NamespacesApiTests.scala
+++ b/tests/src/whisk/core/controller/test/NamespacesApiTests.scala
@@ -54,14 +54,14 @@
val collectionPath = s"/${collection.path}"
val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val namespace = EntityPath(creds.subject())
+ val namespace = EntityPath(creds.subject.asString)
it should "list namespaces for subject" in {
implicit val tid = transid()
Get(collectionPath) ~> sealRoute(routes(creds)) ~> check {
status should be(OK)
val ns = responseAs[List[EntityPath]]
- ns should be(List(EntityPath(creds.subject())))
+ ns should be(List(EntityPath(creds.subject.asString)))
}
}
@@ -70,13 +70,13 @@
Get(s"$collectionPath/") ~> sealRoute(routes(creds)) ~> check {
status should be(OK)
val ns = responseAs[List[EntityPath]]
- ns should be(List(EntityPath(creds.subject())))
+ ns should be(List(EntityPath(creds.subject.asString)))
}
}
it should "get namespace entities for subject" in {
implicit val tid = transid()
- Get(s"$collectionPath/${creds.subject()}") ~> sealRoute(routes(creds)) ~> check {
+ Get(s"$collectionPath/${creds.subject}") ~> sealRoute(routes(creds)) ~> check {
status should be(OK)
val ns = responseAs[JsObject]
ns should be(JsObject(Namespaces.emptyNamespace map { kv => (kv._1, JsArray()) }))
@@ -86,28 +86,28 @@
it should "reject get namespace entities for unauthorized subject" in {
implicit val tid = transid()
val anothercred = WhiskAuth(Subject(), AuthKey())
- Get(s"$collectionPath/${anothercred.subject()}") ~> sealRoute(routes(creds)) ~> check {
+ Get(s"$collectionPath/${anothercred.subject}") ~> sealRoute(routes(creds)) ~> check {
status should be(Forbidden)
}
}
it should "reject request with put" in {
implicit val tid = transid()
- Put(s"$collectionPath/${creds.subject()}") ~> sealRoute(routes(creds)) ~> check {
+ Put(s"$collectionPath/${creds.subject}") ~> sealRoute(routes(creds)) ~> check {
status should be(MethodNotAllowed)
}
}
it should "reject request with post" in {
implicit val tid = transid()
- Post(s"$collectionPath/${creds.subject()}") ~> sealRoute(routes(creds)) ~> check {
+ Post(s"$collectionPath/${creds.subject}") ~> sealRoute(routes(creds)) ~> check {
status should be(MethodNotAllowed)
}
}
it should "reject request with delete" in {
implicit val tid = transid()
- Delete(s"$collectionPath/${creds.subject()}") ~> sealRoute(routes(creds)) ~> check {
+ Delete(s"$collectionPath/${creds.subject}") ~> sealRoute(routes(creds)) ~> check {
status should be(MethodNotAllowed)
}
}
diff --git a/tests/src/whisk/core/controller/test/PackageActionsApiTests.scala b/tests/src/whisk/core/controller/test/PackageActionsApiTests.scala
index 6b27a1e..8a9c5f5 100644
--- a/tests/src/whisk/core/controller/test/PackageActionsApiTests.scala
+++ b/tests/src/whisk/core/controller/test/PackageActionsApiTests.scala
@@ -51,7 +51,7 @@
behavior of "Package Actions API"
val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val namespace = EntityPath(creds.subject())
+ val namespace = EntityPath(creds.subject.asString)
val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
def aname = MakeName.next("package_action_tests")
@@ -160,7 +160,7 @@
}
}
- it should "reject put action in package binding" in {
+ it should "reject put action in package binding where package doesn't exist" in {
implicit val tid = transid()
val provider = WhiskPackage(namespace, aname, None, publish = true)
val binding = WhiskPackage(namespace, aname, provider.bind)
@@ -171,9 +171,21 @@
}
}
+ it should "reject put action in package binding" in {
+ implicit val tid = transid()
+ val provider = WhiskPackage(namespace, aname, None, publish = true)
+ val binding = WhiskPackage(namespace, aname, provider.bind)
+ val content = WhiskActionPut(Some(Exec.js("??")))
+ put(entityStore, provider)
+ put(entityStore, binding)
+ Put(s"$collectionPath/${binding.name}/$aname", content) ~> sealRoute(routes(creds)) ~> check {
+ status should be(BadRequest)
+ }
+ }
+
it should "reject put action in package owned by different subject" in {
implicit val tid = transid()
- val provider = WhiskPackage(EntityPath(Subject()()), aname, publish = true)
+ val provider = WhiskPackage(EntityPath(Subject().asString), aname, publish = true)
val content = WhiskActionPut(Some(Exec.js("??")))
put(entityStore, provider)
Put(s"/${provider.namespace}/${collection.path}/${provider.name}/$aname", content) ~> sealRoute(routes(creds)) ~> check {
@@ -222,7 +234,7 @@
}
}
- it should "reject delete action in package binding" in {
+ it should "reject delete action in package binding where package doesn't exist" in {
implicit val tid = transid()
val provider = WhiskPackage(namespace, aname, None, publish = true)
val binding = WhiskPackage(namespace, aname, provider.bind)
@@ -233,6 +245,29 @@
}
}
+ it should "reject delete action in package binding" in {
+ implicit val tid = transid()
+ val provider = WhiskPackage(namespace, aname, None, publish = true)
+ val binding = WhiskPackage(namespace, aname, provider.bind)
+ val content = WhiskActionPut(Some(Exec.js("??")))
+ put(entityStore, provider)
+ put(entityStore, binding)
+ Delete(s"$collectionPath/${binding.name}/$aname") ~> sealRoute(routes(creds)) ~> check {
+ status should be(BadRequest)
+ }
+ }
+
+ it should "reject delete action in package owned by different subject" in {
+ implicit val tid = transid()
+ val provider = WhiskPackage(EntityPath(Subject().asString), aname, publish = true)
+ val action = WhiskAction(provider.fullPath, aname, Exec.js("??"))
+ put(entityStore, provider)
+ put(entityStore, action)
+ Delete(s"/${provider.namespace}/${collection.path}/${provider.name}/${action.name}") ~> sealRoute(routes(creds)) ~> check {
+ status should be(Forbidden)
+ }
+ }
+
//// GET /actions/package/name
it should "get action in package" in {
implicit val tid = transid()
@@ -253,7 +288,7 @@
implicit val tid = transid()
val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
val provider = WhiskPackage(namespace, aname, None, publish = true)
- val binding = WhiskPackage(EntityPath(auser.subject()), aname, provider.bind, Parameters("b", "B"))
+ val binding = WhiskPackage(EntityPath(auser.subject.asString), aname, provider.bind, Parameters("b", "B"))
val action = WhiskAction(provider.fullPath, aname, Exec.js("??"))
put(entityStore, provider)
put(entityStore, binding)
@@ -271,7 +306,7 @@
implicit val tid = transid()
val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
val provider = WhiskPackage(namespace, aname, None, Parameters("p", "P"), publish = true)
- val binding = WhiskPackage(EntityPath(auser.subject()), aname, provider.bind, Parameters("b", "B"))
+ val binding = WhiskPackage(EntityPath(auser.subject.asString), aname, provider.bind, Parameters("b", "B"))
val action = WhiskAction(provider.fullPath, aname, Exec.js("??"), Parameters("a", "A") ++ Parameters("b", "b"))
put(entityStore, provider)
put(entityStore, binding)
@@ -291,12 +326,12 @@
implicit val tid = transid()
val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
val provider = WhiskPackage(namespace, aname, None, Parameters("p", "P"), publish = false)
- val binding = WhiskPackage(EntityPath(auser.subject()), aname, provider.bind, Parameters("b", "B"))
+ val binding = WhiskPackage(EntityPath(auser.subject.asString), aname, provider.bind, Parameters("b", "B"))
val action = WhiskAction(provider.fullPath, aname, Exec.js("??"), Parameters("a", "A"))
put(entityStore, provider)
put(entityStore, binding)
put(entityStore, action)
- val pkgaccess = Resource(provider.namespace, PACKAGES, Some(provider.name()))
+ val pkgaccess = Resource(provider.namespace, PACKAGES, Some(provider.name.asString))
Await.result(entitlementProvider.grant(auser.subject, READ, pkgaccess), 1 second)
Get(s"$collectionPath/${binding.name}/${action.name}") ~> sealRoute(routes(auser)) ~> check {
status should be(OK)
@@ -330,7 +365,7 @@
val name = aname
val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
val provider = WhiskPackage(namespace, aname, None, Parameters("p", "P"), publish = true)
- val binding = WhiskPackage(EntityPath(auser.subject()), aname, provider.bind, Parameters("b", "B"))
+ val binding = WhiskPackage(EntityPath(auser.subject.asString), aname, provider.bind, Parameters("b", "B"))
val action = WhiskAction(provider.fullPath, aname, Exec.js("??"), Parameters("a", "A"))
put(entityStore, provider)
put(entityStore, action)
@@ -344,7 +379,7 @@
val name = aname
val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
val provider = WhiskPackage(namespace, aname, None, Parameters("p", "P"), publish = true)
- val binding = WhiskPackage(EntityPath(auser.subject()), aname, provider.bind, Parameters("b", "B"))
+ val binding = WhiskPackage(EntityPath(auser.subject.asString), aname, provider.bind, Parameters("b", "B"))
val action = WhiskAction(provider.fullPath, aname, Exec.js("??"), Parameters("a", "A"))
put(entityStore, binding)
put(entityStore, action)
@@ -358,7 +393,7 @@
val name = aname
val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
val provider = WhiskPackage(namespace, aname, None, Parameters("p", "P"), publish = true)
- val binding = WhiskPackage(EntityPath(auser.subject()), aname, provider.bind, Parameters("b", "B"))
+ val binding = WhiskPackage(EntityPath(auser.subject.asString), aname, provider.bind, Parameters("b", "B"))
val action = WhiskAction(provider.fullPath, aname, Exec.js("??"), Parameters("a", "A"))
put(entityStore, provider)
put(entityStore, binding)
@@ -371,7 +406,7 @@
implicit val tid = transid()
val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
val provider = WhiskPackage(namespace, aname, None, Parameters("p", "P"), publish = false)
- val binding = WhiskPackage(EntityPath(auser.subject()), aname, provider.bind, Parameters("b", "B"))
+ val binding = WhiskPackage(EntityPath(auser.subject.asString), aname, provider.bind, Parameters("b", "B"))
val action = WhiskAction(provider.fullPath, aname, Exec.js("??"), Parameters("a", "A"))
put(entityStore, provider)
put(entityStore, binding)
@@ -415,7 +450,7 @@
implicit val tid = transid()
val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
val provider = WhiskPackage(namespace, aname, publish = true)
- val reference = WhiskPackage(EntityPath(auser.subject()), aname, provider.bind)
+ val reference = WhiskPackage(EntityPath(auser.subject.asString), aname, provider.bind)
val action = WhiskAction(provider.fullPath, aname, Exec.js("??"))
val content = JsObject("x" -> "x".toJson, "z" -> "Z".toJson)
put(entityStore, provider)
@@ -434,13 +469,13 @@
implicit val tid = transid()
val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
val provider = WhiskPackage(namespace, aname, publish = false)
- val reference = WhiskPackage(EntityPath(auser.subject()), aname, provider.bind)
+ val reference = WhiskPackage(EntityPath(auser.subject.asString), aname, provider.bind)
val action = WhiskAction(provider.fullPath, aname, Exec.js("??"))
val content = JsObject("x" -> "x".toJson, "z" -> "Z".toJson)
put(entityStore, provider)
put(entityStore, reference)
put(entityStore, action)
- val pkgaccess = Resource(provider.namespace, PACKAGES, Some(provider.name()))
+ val pkgaccess = Resource(provider.namespace, PACKAGES, Some(provider.name.asString))
Await.result(entitlementProvider.grant(auser.subject, ACTIVATE, pkgaccess), 1 second)
Post(s"$collectionPath/${reference.name}/${action.name}", content) ~> sealRoute(routes(auser)) ~> check {
status should be(Accepted)
@@ -489,7 +524,7 @@
implicit val tid = transid()
val auser = WhiskAuth(Subject(), AuthKey()).toIdentity
val provider = WhiskPackage(namespace, aname, publish = false)
- val reference = WhiskPackage(EntityPath(auser.subject()), aname, provider.bind)
+ val reference = WhiskPackage(EntityPath(auser.subject.asString), aname, provider.bind)
val action = WhiskAction(provider.fullPath, aname, Exec.js("??"))
val content = JsObject("x" -> "x".toJson, "z" -> "Z".toJson)
put(entityStore, provider)
diff --git a/tests/src/whisk/core/controller/test/PackagesApiTests.scala b/tests/src/whisk/core/controller/test/PackagesApiTests.scala
index 465c2e0..0263cc6 100644
--- a/tests/src/whisk/core/controller/test/PackagesApiTests.scala
+++ b/tests/src/whisk/core/controller/test/PackagesApiTests.scala
@@ -48,7 +48,7 @@
behavior of "Packages API"
val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val namespace = EntityPath(creds.subject())
+ val namespace = EntityPath(creds.subject.asString)
val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
def aname = MakeName.next("packages_tests")
val entityTooBigRejectionMessage = "request entity too large"
@@ -66,7 +66,7 @@
if (i % 2 == 0) {
WhiskPackage(namespace, aname, None)
} else {
- val binding = Some(Binding(namespace, aname))
+ val binding = Some(Binding(namespace.root, aname))
WhiskPackage(namespace, aname, binding)
}
}.toList
@@ -246,7 +246,7 @@
it should "not get package reference for a private package in other namespace" in {
implicit val tid = transid()
val privateCreds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val privateNamespace = EntityPath(privateCreds.subject())
+ val privateNamespace = EntityPath(privateCreds.subject.asString)
val provider = WhiskPackage(privateNamespace, aname)
val reference = WhiskPackage(namespace, aname, provider.bind)
@@ -306,7 +306,7 @@
it should "not get package reference with its actions and feeds from private package" in {
implicit val tid = transid()
val privateCreds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val privateNamespace = EntityPath(privateCreds.subject())
+ val privateNamespace = EntityPath(privateCreds.subject.asString)
val provider = WhiskPackage(privateNamespace, aname)
val reference = WhiskPackage(namespace, aname, provider.bind)
val action = WhiskAction(provider.namespace.addPath(provider.name), aname, Exec.js("??"))
@@ -368,7 +368,7 @@
it should "not create package reference from private package in another namespace" in {
implicit val tid = transid()
val privateCreds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val privateNamespace = EntityPath(privateCreds.subject())
+ val privateNamespace = EntityPath(privateCreds.subject.asString)
val provider = WhiskPackage(privateNamespace, aname)
val reference = WhiskPackage(namespace, aname, provider.bind)
@@ -384,7 +384,7 @@
it should "create package reference with implicit namespace" in {
implicit val tid = transid()
val provider = WhiskPackage(namespace, aname)
- val reference = WhiskPackage(namespace, aname, Some(Binding(EntityPath.DEFAULT, provider.name)))
+ val reference = WhiskPackage(namespace, aname, Some(Binding(EntityPath.DEFAULT.root, provider.name)))
val content = WhiskPackagePut(reference.binding)
put(entityStore, provider)
Put(s"$collectionPath/${reference.name}", content) ~> sealRoute(routes(creds)) ~> check {
@@ -400,7 +400,7 @@
it should "reject create package reference when referencing non-existent package in same namespace" in {
implicit val tid = transid()
- val binding = Some(Binding(namespace, aname))
+ val binding = Some(Binding(namespace.root, aname))
val content = WhiskPackagePut(binding)
Put(s"$collectionPath/$aname", content) ~> sealRoute(routes(creds)) ~> check {
status should be(BadRequest)
@@ -411,9 +411,9 @@
it should "reject create package reference when referencing non-existent package in another namespace" in {
implicit val tid = transid()
val privateCreds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val privateNamespace = EntityPath(privateCreds.subject())
+ val privateNamespace = EntityPath(privateCreds.subject.asString)
- val binding = Some(Binding(privateNamespace, aname))
+ val binding = Some(Binding(privateNamespace.root, aname))
val content = WhiskPackagePut(binding)
Put(s"$collectionPath/$aname", content) ~> sealRoute(routes(creds)) ~> check {
status should be(Forbidden)
@@ -424,7 +424,7 @@
implicit val tid = transid()
val provider = WhiskPackage(namespace, aname)
val reference = WhiskPackage(namespace, aname, provider.bind)
- val content = WhiskPackagePut(Some(Binding(reference.namespace, reference.name)))
+ val content = WhiskPackagePut(Some(Binding(reference.namespace.root, reference.name)))
put(entityStore, provider)
put(entityStore, reference)
Put(s"$collectionPath/$aname", content) ~> sealRoute(routes(creds)) ~> check {
@@ -549,7 +549,7 @@
it should "reject update package reference when new binding refers to non-existent package in another namespace" in {
implicit val tid = transid()
val privateCreds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val privateNamespace = EntityPath(privateCreds.subject())
+ val privateNamespace = EntityPath(privateCreds.subject.asString)
val provider = WhiskPackage(privateNamespace, aname)
val reference = WhiskPackage(namespace, aname, provider.bind)
@@ -563,7 +563,7 @@
it should "reject update package reference when new binding refers to private package in another namespace" in {
implicit val tid = transid()
val privateCreds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val privateNamespace = EntityPath(privateCreds.subject())
+ val privateNamespace = EntityPath(privateCreds.subject.asString)
val provider = WhiskPackage(privateNamespace, aname)
val reference = WhiskPackage(namespace, aname, provider.bind)
@@ -648,7 +648,7 @@
it should "reject bind to non-package" in {
implicit val tid = transid()
val action = WhiskAction(namespace, aname, Exec.js("??"))
- val reference = WhiskPackage(namespace, aname, Some(Binding(action.namespace, action.name)))
+ val reference = WhiskPackage(namespace, aname, Some(Binding(action.namespace.root, action.name)))
val content = WhiskPackagePut(reference.binding)
put(entityStore, action)
diff --git a/tests/src/whisk/core/controller/test/RulesApiTests.scala b/tests/src/whisk/core/controller/test/RulesApiTests.scala
index 70a1ad0..d88dad8 100644
--- a/tests/src/whisk/core/controller/test/RulesApiTests.scala
+++ b/tests/src/whisk/core/controller/test/RulesApiTests.scala
@@ -51,7 +51,7 @@
behavior of "Rules API"
val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val namespace = EntityPath(creds.subject())
+ val namespace = EntityPath(creds.subject.asString)
def aname() = MakeName.next("rules_tests")
def afullname(namespace: EntityPath, name: String) = FullyQualifiedEntityName(namespace, EntityName(name))
val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
@@ -291,7 +291,7 @@
val rule = WhiskRule(namespace, aname(), FullyQualifiedEntityName(namespace, aname()), FullyQualifiedEntityName(namespace, aname()))
val trigger = WhiskTrigger(rule.trigger.path, rule.trigger.name)
val action = WhiskAction(rule.action.path, rule.action.name, Exec.js("??"))
- val content = JsObject("trigger" -> JsString(s"/_/${trigger.name()}"), "action" -> JsString(s"/_/${action.name()}"))
+ val content = JsObject("trigger" -> JsString(s"/_/${trigger.name.asString}"), "action" -> JsString(s"/_/${action.name.asString}"))
put(entityStore, trigger, false)
put(entityStore, action)
diff --git a/tests/src/whisk/core/controller/test/SequenceApiTests.scala b/tests/src/whisk/core/controller/test/SequenceApiTests.scala
index aa7baf8..525a9f3 100644
--- a/tests/src/whisk/core/controller/test/SequenceApiTests.scala
+++ b/tests/src/whisk/core/controller/test/SequenceApiTests.scala
@@ -47,7 +47,7 @@
val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val namespace = EntityPath(creds.subject())
+ val namespace = EntityPath(creds.subject.asString)
val defaultNamespace = EntityPath.DEFAULT
def aname() = MakeName.next("sequence_tests")
val allowedActionDuration = 120 seconds
@@ -63,7 +63,7 @@
put(entityStore, component)
// create exec sequence that will violate max length
val limit = whiskConfig.actionSequenceLimit.toInt + 1 // one more than allowed
- val sequence = for (i <- 1 to limit) yield stringToFullyQualifiedName(component.docid())
+ val sequence = for (i <- 1 to limit) yield stringToFullyQualifiedName(component.docid.asString)
val content = WhiskActionPut(Some(Exec.sequence(sequence.toVector)))
// create an action sequence
@@ -109,7 +109,7 @@
put(entityStore, component)
val seqName = s"${aname()}_cyclic"
- val sSeq = makeSimpleSequence(seqName, namespace, Vector(component.name(), seqName, component.name()), false)
+ val sSeq = makeSimpleSequence(seqName, namespace, Vector(component.name.asString, seqName, component.name.asString), false)
// create an action sequence
val content = WhiskActionPut(Some(sSeq.exec))
@@ -126,7 +126,7 @@
val component = WhiskAction(namespace, aname(), Exec.js("??"))
put(entityStore, component)
// create valid exec sequence initially
- val sequence = for (i <- 1 to 2) yield stringToFullyQualifiedName(component.docid())
+ val sequence = for (i <- 1 to 2) yield stringToFullyQualifiedName(component.docid.asString)
val content = WhiskActionPut(Some(Exec.sequence(sequence.toVector)))
// create a valid action sequence first
@@ -154,7 +154,7 @@
put(entityStore, component)
// create valid exec sequence
val limit = whiskConfig.actionSequenceLimit.toInt
- val sequence = for (i <- 1 to limit) yield stringToFullyQualifiedName(component.docid())
+ val sequence = for (i <- 1 to limit) yield stringToFullyQualifiedName(component.docid.asString)
val content = WhiskActionPut(Some(Exec.sequence(sequence.toVector)))
// create an action sequence
@@ -201,7 +201,7 @@
// put the action in the entity store so it's found
val component = WhiskAction(namespace, aname(), Exec.js("??"))
put(entityStore, component)
- val sequence = for (i <- 1 to 2) yield stringToFullyQualifiedName(component.docid())
+ val sequence = for (i <- 1 to 2) yield stringToFullyQualifiedName(component.docid.asString)
// create package
val pkg = s"${aname()}_pkg"
diff --git a/tests/src/whisk/core/controller/test/TriggersApiTests.scala b/tests/src/whisk/core/controller/test/TriggersApiTests.scala
index ee5e4e3..cff5a8c 100644
--- a/tests/src/whisk/core/controller/test/TriggersApiTests.scala
+++ b/tests/src/whisk/core/controller/test/TriggersApiTests.scala
@@ -53,7 +53,7 @@
behavior of "Triggers API"
val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val namespace = EntityPath(creds.subject())
+ val namespace = EntityPath(creds.subject.asString)
val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
def aname = MakeName.next("triggers_tests")
val entityTooBigRejectionMessage = "request entity too large"
diff --git a/tests/src/whisk/core/controller/test/migration/SequenceActionApiMigrationTests.scala b/tests/src/whisk/core/controller/test/migration/SequenceActionApiMigrationTests.scala
index def4ea8..da8b5dd 100644
--- a/tests/src/whisk/core/controller/test/migration/SequenceActionApiMigrationTests.scala
+++ b/tests/src/whisk/core/controller/test/migration/SequenceActionApiMigrationTests.scala
@@ -57,7 +57,7 @@
behavior of "Sequence Action API Migration"
val creds = WhiskAuth(Subject(), AuthKey()).toIdentity
- val namespace = EntityPath(creds.subject())
+ val namespace = EntityPath(creds.subject.asString)
val collectionPath = s"/${EntityPath.DEFAULT}/${collection.path}"
def aname = MakeName.next("seq_migration_tests")
diff --git a/tests/src/whisk/core/database/test/DbUtils.scala b/tests/src/whisk/core/database/test/DbUtils.scala
index 687f9fa..d19adfc 100644
--- a/tests/src/whisk/core/database/test/DbUtils.scala
+++ b/tests/src/whisk/core/database/test/DbUtils.scala
@@ -47,6 +47,12 @@
import whisk.core.entity.types.AuthStore
import whisk.core.entity.types.EntityStore
+/**
+ * WARNING: the put/get/del operations in this trait operate directly on the datastore,
+ * and in the presence of a cache, there will be inconsistencies if one mixes these
+ * operations with those that flow through the cache. To mitigate this, use unique asset
+ * names in tests, and defer all cleanup to the end of a test suite.
+ */
trait DbUtils extends TransactionCounter {
implicit val dbOpTimeout = 15 seconds
val docsToDelete = ListBuffer[(ArtifactStore[_], DocInfo)]()
@@ -191,7 +197,7 @@
def putGetCheck[A, Au >: A](db: ArtifactStore[Au], entity: A, factory: DocumentFactory[A], gc: Boolean = true)(
implicit transid: TransactionId, timeout: Duration = 10 seconds, ma: Manifest[A]): (DocInfo, A) = {
val doc = put(db, entity, gc)
- assert(doc != null && doc.id() != null && doc.rev() != null)
+ assert(doc != null && doc.id.asString != null && doc.rev.asString != null)
val future = factory.get(db, doc.id, doc.rev)
val dbEntity = Await.result(future, timeout)
assert(dbEntity != null)
diff --git a/tests/src/whisk/core/dispatcher/test/DispatcherTests.scala b/tests/src/whisk/core/dispatcher/test/DispatcherTests.scala
index baf621a..1dff473 100644
--- a/tests/src/whisk/core/dispatcher/test/DispatcherTests.scala
+++ b/tests/src/whisk/core/dispatcher/test/DispatcherTests.scala
@@ -61,7 +61,7 @@
val content = JsObject("payload" -> JsNumber(count))
val user = WhiskAuth(Subject(), AuthKey()).toIdentity
val path = FullyQualifiedEntityName(EntityPath("test"), EntityName(s"count-$count"), Some(SemVer()))
- val msg = Message(TransactionId.testing, path, DocRevision(), user, ActivationId(), EntityPath(user.subject()), Some(content))
+ val msg = Message(TransactionId.testing, path, DocRevision(), user, ActivationId(), EntityPath(user.subject.asString), Some(content))
connector.send(msg)
}
diff --git a/tests/src/whisk/core/entity/test/SchemaTests.scala b/tests/src/whisk/core/entity/test/SchemaTests.scala
index b287d78..4b7418f 100644
--- a/tests/src/whisk/core/entity/test/SchemaTests.scala
+++ b/tests/src/whisk/core/entity/test/SchemaTests.scala
@@ -33,6 +33,7 @@
import spray.json._
import spray.json.DefaultJsonProtocol._
+import whisk.core.entitlement.Privilege
import whisk.core.entity._
import whisk.core.entity.size.SizeInt
@@ -57,12 +58,20 @@
}
}
+ behavior of "Privilege"
+
+ it should "serdes a right" in {
+ Privilege.serdes.read("READ".toJson) shouldBe Privilege.READ
+ Privilege.serdes.read("read".toJson) shouldBe Privilege.READ
+ a[DeserializationException] should be thrownBy Privilege.serdes.read("???".toJson)
+ }
+
behavior of "Identity"
it should "serdes an identity" in {
val i = WhiskAuth(Subject(), AuthKey()).toIdentity
val expected = JsObject(
- "subject" -> i.subject().toJson,
+ "subject" -> i.subject.asString.toJson,
"namespace" -> i.namespace.toJson,
"authkey" -> i.authkey.compact.toJson,
"rights" -> Array("READ", "PUT", "DELETE", "ACTIVATE").toJson)
@@ -75,7 +84,7 @@
it should "accept well formed doc info" in {
Seq("a", " a", "a ").foreach { i =>
val d = DocInfo(i)
- assert(d.id() == i.trim)
+ assert(d.id.asString == i.trim)
}
}
@@ -202,23 +211,15 @@
it should "desiarilize legacy format" in {
val names = Seq(
- JsObject("path" -> "a".toJson, "name" -> "b".toJson),
- JsObject("path" -> "a".toJson, "name" -> "b".toJson, "version" -> "0.0.1".toJson),
- JsString("a/b"),
JsObject("namespace" -> "a".toJson, "name" -> "b".toJson),
- JsObject("namespace" -> "a".toJson, "path" -> "a".toJson, "name" -> "b".toJson),
- JsObject("name" -> "b".toJson),
JsObject(),
+ JsObject("name" -> "b".toJson),
JsNull)
- //Binding.optionalBindingDeserializer.read(names(0)) shouldBe Some(Binding(EntityPath("a"), EntityName("b")))
- //Binding.optionalBindingDeserializer.read(names(1)) shouldBe Some(Binding(EntityPath("a"), EntityName("b"), Some(SemVer())))
- //Binding.optionalBindingDeserializer.read(names(2)) shouldBe Some(Binding(EntityPath("a"), EntityName("b")))
- Binding.optionalBindingDeserializer.read(names(3)) shouldBe Some(Binding(EntityPath("a"), EntityName("b")))
- Binding.optionalBindingDeserializer.read(names(6)) shouldBe None
- //a[DeserializationException] should be thrownBy Binding.optionalBindingDeserializer.read(names(4))
- a[DeserializationException] should be thrownBy Binding.optionalBindingDeserializer.read(names(5))
- a[DeserializationException] should be thrownBy Binding.optionalBindingDeserializer.read(names(7))
+ Binding.optionalBindingDeserializer.read(names(0)) shouldBe Some(Binding(EntityName("a"), EntityName("b")))
+ Binding.optionalBindingDeserializer.read(names(1)) shouldBe None
+ a[DeserializationException] should be thrownBy Binding.optionalBindingDeserializer.read(names(2))
+ a[DeserializationException] should be thrownBy Binding.optionalBindingDeserializer.read(names(3))
}
it should "serialize optional binding to empty object" in {
@@ -256,7 +257,7 @@
}
it should "serialize and deserialize package binding" in {
- val pkg = WhiskPackage(EntityPath("a"), EntityName("b"), Some(Binding(EntityPath("x"), EntityName("y"))))
+ val pkg = WhiskPackage(EntityPath("a"), EntityName("b"), Some(Binding(EntityName("x"), EntityName("y"))))
val pkgAsJson = JsObject(
"namespace" -> "a".toJson,
"name" -> "b".toJson,
diff --git a/tests/src/whisk/core/entity/test/ViewTests.scala b/tests/src/whisk/core/entity/test/ViewTests.scala
index 11533a4..89f0cf6 100644
--- a/tests/src/whisk/core/entity/test/ViewTests.scala
+++ b/tests/src/whisk/core/entity/test/ViewTests.scala
@@ -75,10 +75,10 @@
}
val creds1 = WhiskAuth(Subject("s12345"), AuthKey())
- val namespace1 = EntityPath(creds1.subject())
+ val namespace1 = EntityPath(creds1.subject.asString)
val creds2 = WhiskAuth(Subject("t12345"), AuthKey())
- val namespace2 = EntityPath(creds2.subject())
+ val namespace2 = EntityPath(creds2.subject.asString)
val config = new WhiskConfig(WhiskEntityStore.requiredProperties)
val datastore = WhiskEntityStore.datastore(config)
@@ -196,8 +196,8 @@
WhiskRule(namespace1, aname, trigger = afullname(namespace1), action = afullname(namespace1)),
WhiskPackage(namespace1, aname),
WhiskPackage(namespace1, aname),
- WhiskPackage(namespace1, aname, Some(Binding(namespace2, aname))),
- WhiskPackage(namespace1, aname, Some(Binding(namespace2, aname))),
+ WhiskPackage(namespace1, aname, Some(Binding(namespace2.root, aname))),
+ WhiskPackage(namespace1, aname, Some(Binding(namespace2.root, aname))),
WhiskActivation(namespace1, aname, Subject(), ActivationId(), start = now, end = now),
WhiskActivation(namespace1, aname, Subject(), ActivationId(), start = now, end = now),
@@ -213,8 +213,8 @@
WhiskRule(namespace2, aname, trigger = afullname(namespace2), action = afullname(namespace2)),
WhiskPackage(namespace2, aname),
WhiskPackage(namespace2, aname),
- WhiskPackage(namespace2, aname, Some(Binding(namespace1, aname))),
- WhiskPackage(namespace2, aname, Some(Binding(namespace1, aname))),
+ WhiskPackage(namespace2, aname, Some(Binding(namespace1.root, aname))),
+ WhiskPackage(namespace2, aname, Some(Binding(namespace1.root, aname))),
WhiskActivation(namespace2, aname, Subject(), ActivationId(), start = now, end = now),
WhiskActivation(namespace2, actionName, Subject(), ActivationId(), start = now, end = now),
WhiskActivation(namespace2, actionName, Subject(), ActivationId(), start = now, end = now))
@@ -297,13 +297,13 @@
implicit val entities = Seq(
WhiskPackage(namespace1, aname, publish = true),
WhiskPackage(namespace1, aname, publish = false),
- WhiskPackage(namespace1, aname, Some(Binding(namespace2, aname)), publish = true),
- WhiskPackage(namespace1, aname, Some(Binding(namespace2, aname))),
+ WhiskPackage(namespace1, aname, Some(Binding(namespace2.root, aname)), publish = true),
+ WhiskPackage(namespace1, aname, Some(Binding(namespace2.root, aname))),
WhiskPackage(namespace2, aname, publish = true),
WhiskPackage(namespace2, aname, publish = false),
- WhiskPackage(namespace2, aname, Some(Binding(namespace1, aname)), publish = true),
- WhiskPackage(namespace2, aname, Some(Binding(namespace1, aname))))
+ WhiskPackage(namespace2, aname, Some(Binding(namespace1.root, aname)), publish = true),
+ WhiskPackage(namespace2, aname, Some(Binding(namespace1.root, aname))))
entities foreach { put(datastore, _) }
waitOnView(datastore, namespace1, entities.length / 2)