Skip to content
Snippets Groups Projects
Commit ea42cf88 authored by Markus Thoemmes's avatar Markus Thoemmes
Browse files

Migrate Controller's authentication to the new schema

1. Add the new view
2. Make the Controller read from the view
3. Thread the namespace extracted from the view through the API

The general "_" case now resolves to the namespace infered from the key vs. defaulting to the subject's name. For migration of the API, the "old" keys' namespace default to the subject name which preserves previous behaviour.

- Loosen test to reflect reality in the controller
- Add migration entities and test, to be elevated incrementally
- Rename iam.Identities to NamespaceProvider to be more clear
parent ad28bb66
No related branches found
No related tags found
No related merge requests found
......@@ -34,7 +34,6 @@ import whisk.common.TransactionCounter
import whisk.core.controller.Authenticate
import whisk.core.controller.AuthenticatedRoute
import whisk.core.entity.AuthKey
import whisk.core.entity.DocId
import whisk.core.entity.Secret
import whisk.core.entity.Subject
import whisk.core.entity.UUID
......@@ -85,25 +84,6 @@ class AuthenticateTests extends ControllerTestCommon with Authenticate {
cachedUser.get should be(creds.toIdentity)
stream.toString should include regex (s"serving from cache: ${creds.uuid()}")
stream.reset()
// revoke key and invalidate cache
val newCreds = {
implicit val tid = transid()
val newCreds = creds.revoke
val prevRecord = get(authStore, DocId(creds.subject()), WhiskAuth, false)
Await.result(WhiskAuth.put(authStore, newCreds.revision[WhiskAuth](prevRecord.docinfo.rev)), dbOpTimeout)
newCreds
}
stream.toString should include regex (s"invalidating*.*${creds.uuid()}")
stream.toString should include regex (s"caching*.*${creds.uuid()}")
stream.reset()
// repeat query, should be served from cache correctly
val newPass = UserPass(newCreds.uuid(), newCreds.key())
val refetchedUser = Await.result(validateCredentials(Some(newPass))(transid()), dbOpTimeout)
stream.toString should include regex (s"serving from cache: ${creds.uuid()}")
refetchedUser.isDefined should be(true)
refetchedUser.get should be(newCreds.toIdentity)
} finally {
authStore.outputStream = savedstream
stream.close()
......
/*
* 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 org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import spray.routing.authentication.UserPass
import whisk.core.controller.Authenticate
import whisk.core.entity.AuthKey
import whisk.core.entity.Subject
import whisk.core.entity.WhiskAuthV2
import whisk.core.entity.WhiskNamespace
import whisk.core.entitlement.Privilege
import whisk.core.entity.Identity
import whisk.core.entity.Util
/**
* Tests authentication handler which guards API.
*
* 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 AuthenticateV2Tests extends ControllerTestCommon with Authenticate {
// Interface to store WhiskAuthV2 entries
val authStoreV2 = Util.makeStore[WhiskAuthV2](whiskConfig, _.dbAuths)
// Creates a new unique name each time its called
def aname = MakeName.next("authenticatev2_tests")
behavior of "Authenticate V2"
it should "authorize a known user using the new database schema in different namespaces" in {
implicit val tid = transid()
val subject = Subject()
val namespaces = Set(
WhiskNamespace(aname, AuthKey()),
WhiskNamespace(aname, AuthKey()))
val entry = WhiskAuthV2(subject, namespaces)
put(authStoreV2, entry)
// Try to login with each specific namespace
namespaces.foreach { ns =>
println(s"Trying to login to $ns")
val pass = UserPass(ns.authkey.uuid(), ns.authkey.key())
val user = Await.result(validateCredentials(Some(pass)), dbOpTimeout)
user.get shouldBe Identity(subject, ns.name, ns.authkey, Privilege.ALL)
}
}
}
......@@ -39,8 +39,7 @@ import whisk.core.database.test.DbUtils
import whisk.core.entitlement.{ Collection, EntitlementService, LocalEntitlementService }
import whisk.core.entity._
import whisk.core.loadBalancer.LoadBalancer
import whisk.core.iam.Identities
import whisk.core.iam.NamespaceProvider
protected trait ControllerTestCommon
extends FlatSpec
......@@ -64,7 +63,7 @@ protected trait ControllerTestCommon
assert(whiskConfig.isValid)
override val loadBalancer = new DegenerateLoadBalancerService(whiskConfig, InfoLevel)
override val iam = new Identities(whiskConfig, forceLocal = true)
override val iam = new NamespaceProvider(whiskConfig, forceLocal = true)
override val entitlementService: EntitlementService = new LocalEntitlementService(whiskConfig, loadBalancer, iam)
override val activationId = new ActivationId.ActivationIdGenerator() {
......@@ -174,8 +173,8 @@ class DegenerateLoadBalancerService(config: WhiskConfig, verbosity: LogLevel)
override def publish(msg: ActivationMessage, timeout: FiniteDuration)(implicit transid: TransactionId): (Future[Unit], Future[WhiskActivation]) =
(Future.successful {},
whiskActivationStub map {
activation => Future.successful(activation)
} getOrElse Future.failed(new IllegalArgumentException("Unit test does not need fast path")))
whiskActivationStub map {
activation => Future.successful(activation)
} getOrElse Future.failed(new IllegalArgumentException("Unit test does not need fast path")))
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment