Skip to content
This repository has been archived by the owner on Sep 12, 2021. It is now read-only.

Commit

Permalink
Merge pull request #235 from akkie/master
Browse files Browse the repository at this point in the history
Add dummy authenticator
  • Loading branch information
akkie committed Dec 16, 2014
2 parents 770ff0a + 8ea5733 commit aa7c65d
Show file tree
Hide file tree
Showing 5 changed files with 307 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## 2.0

- Use lazy val to initialize SecureRandom, so that initialization occurs also async
- Refactor authenticators and add BearerTokenAuthenticator, JWTAuthenticator and SessionAuthenticator
- Refactor authenticators and add BearerTokenAuthenticator, JWTAuthenticator, SessionAuthenticator and DummyAuthenticator
- Better error handling for authenticators
- Authenticators now using an extra backing store instead of only the cache
- Split up SocialProvider.authenticate method into authenticate and retrieveProfile methods
Expand All @@ -12,6 +12,7 @@
- Reorganized the project structure (moved all providers into the "impl" package, moved some classes/traits)
- Add request handlers
- Add request providers in combination with HTTP basic auth provider
- Add Dropbox provider

## 1.0 (2014-06-12)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/**
* Copyright 2014 Mohiva Organisation (license at mohiva dot com)
*
* 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 com.mohiva.play.silhouette.impl.authenticators

import com.mohiva.play.silhouette.api.services.AuthenticatorService
import com.mohiva.play.silhouette.api.{ Authenticator, LoginInfo }
import play.api.mvc.{ RequestHeader, Result }

import scala.concurrent.Future

/**
* An authenticator that can be used if a client doesn't need an authenticator to
* track a user. This can be useful for request providers, because authentication
* may occur here on every request to a protected resource.
*
* @param loginInfo The linked login info for an identity.
*/
case class DummyAuthenticator(loginInfo: LoginInfo) extends Authenticator {

/**
* Authenticator is always valid.
*
* @return True because it's always valid.
*/
def isValid = true
}

/**
* The service that handles the dummy token authenticator.
*/
class DummyAuthenticatorService extends AuthenticatorService[DummyAuthenticator] {

/**
* Creates a new authenticator for the specified login info.
*
* @param loginInfo The login info for which the authenticator should be created.
* @param request The request header.
* @return An authenticator.
*/
def create(loginInfo: LoginInfo)(implicit request: RequestHeader) = {
Future.successful(DummyAuthenticator(loginInfo))
}

/**
* Retrieves the authenticator from request.
*
* Doesn't need to return an authenticator here, because this method will not be called if
* a request provider grants access. If the authentication with a request provider has failed,
* then this method must return None to not grant access to the resource.
*
* @param request The request header.
* @return Always None because .
*/
def retrieve(implicit request: RequestHeader) = Future.successful(None)

/**
* Returns the original result, because we needn't add the authenticator to the result.
*
* @param result The result to manipulate.
* @param request The request header.
* @return The manipulated result.
*/
def init(authenticator: DummyAuthenticator, result: Future[Result])(implicit request: RequestHeader) = {
result
}

/**
* Returns the original request, because we needn't add the authenticator to the request.
*
* @param authenticator The authenticator instance.
* @param request The request header.
* @return The manipulated request header.
*/
def init(authenticator: DummyAuthenticator, request: RequestHeader) = Future.successful(request)

/**
* @inheritdoc
*
* @param authenticator The authenticator to touch.
* @return The touched authenticator on the left or the untouched authenticator on the right.
*/
protected[silhouette] def touch(authenticator: DummyAuthenticator) = Right(authenticator)

/**
* Returns the original request, because we needn't update the authenticator in the result.
*
* @param authenticator The authenticator to update.
* @param result The result to manipulate.
* @param request The request header.
* @return The original or a manipulated result.
*/
protected[silhouette] def update(
authenticator: DummyAuthenticator,
result: Future[Result])(implicit request: RequestHeader) = {

result
}

/**
* Returns the original request, because we needn't renew the authenticator in the result.
*
* @param authenticator The authenticator to update.
* @param result The result to manipulate.
* @param request The request header.
* @return The original or a manipulated result.
*/
protected[silhouette] def renew(
authenticator: DummyAuthenticator,
result: Future[Result])(implicit request: RequestHeader) = {

result
}

/**
* Returns the original request, because we needn't discard the authenticator in the result.
*
* @param result The result to manipulate.
* @param request The request header.
* @return The manipulated result.
*/
protected[silhouette] def discard(
authenticator: DummyAuthenticator,
result: Future[Result])(implicit request: RequestHeader) = {

result
}
}

/**
* The companion object of the authenticator service.
*/
object DummyAuthenticatorService {

/**
* The ID of the authenticator.
*/
val ID = "dummy-authenticator"
}
23 changes: 23 additions & 0 deletions docs/how-it-works/authenticator.rst
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,29 @@ new token will be generated on every update. Make sure your application can hand
.. _JWT: https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-27


.. _dummy_authenticator:

DummyAuthenticator
^^^^^^^^^^^^^^^^^^

.. versionadded:: 2.0

An authenticator that can be used if a client doesn't need an authenticator to track a user.
This can be useful for request providers, because authentication may occur here on every request
to a protected resource.

**Pros**

* Ideal for request providers
* Doesn't have any network throughput or memory footprint compared to other authenticators

**Cons**

* Cannot track users
* Only useful for request providers



.. ========================
Some useful links as reference for the pro and cons sections
Expand Down
3 changes: 3 additions & 0 deletions docs/how-it-works/providers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Request providers are special types of providers. They can be hocked directly in
incoming requests which gets scanned for credentials and either gain or restrict
access to the protected resources. This can be useful for machine authentication.

When using a request provider, you should consider to use the :ref:`dummy authenticator
<dummy_authenticator>`, because it doesn't have any network throughput or memory footprint
compared to other authenticators.

Credentials provider
--------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
* Copyright 2014 Mohiva Organisation (license at mohiva dot com)
*
* 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 com.mohiva.play.silhouette.impl.authenticators

import com.mohiva.play.silhouette.api.LoginInfo
import org.specs2.mock.Mockito
import org.specs2.specification.Scope
import play.api.mvc.Results
import play.api.test.{ FakeRequest, PlaySpecification, WithApplication }

import scala.concurrent.Future

/**
* Test case for the [[com.mohiva.play.silhouette.impl.authenticators.DummyAuthenticator]].
*/
class DummyAuthenticatorSpec extends PlaySpecification with Mockito {

"The `isValid` method of the authenticator" should {
"return true" in new Context {
authenticator.isValid must beTrue
}
}

"The `create` method of the service" should {
"return an authenticator containing the given login info" in new Context {
implicit val request = FakeRequest()

await(service.create(loginInfo)).loginInfo must be equalTo loginInfo
}
}

"The `retrieve` method of the service" should {
"return None" in new Context {
implicit val request = FakeRequest()

await(service.retrieve) must beNone
}
}

"The result `init` method of the service" should {
"return the original response" in new Context {
implicit val request = FakeRequest()
val result = Future.successful(Results.Status(200))

service.init(authenticator, result) must be equalTo result
}
}

"The request `init` method of the service" should {
"return the original request" in new Context {
val request = FakeRequest()

await(service.init(authenticator, request)) must be equalTo request
}
}

"The `touch` method of the service" should {
"not update the authenticator" in new WithApplication with Context {
service.touch(authenticator) must beRight[DummyAuthenticator].like {
case a =>
a.loginInfo must be equalTo loginInfo
}
}
}

"The `update` method of the service" should {
"return the original result" in new Context {
implicit val request = FakeRequest()
val result = Future.successful(Results.Ok)

service.update(authenticator, result) must be equalTo result
}
}

"The `renew` method of the service" should {
"return the original result" in new Context {
implicit val request = FakeRequest()
val result = Future.successful(Results.Ok)

service.renew(authenticator, result) must be equalTo result
}
}

"The `discard` method of the service" should {
"return the original result" in new Context {
implicit val request = FakeRequest()
val result = Future.successful(Results.Ok)

service.discard(authenticator, result) must be equalTo result
}
}

/**
* The context.
*/
trait Context extends Scope {

/**
* The authenticator service instance to test.
*/
lazy val service = new DummyAuthenticatorService()

/**
* The login info.
*/
lazy val loginInfo = LoginInfo("test", "1")

/**
* An authenticator.
*/
lazy val authenticator = new DummyAuthenticator(
loginInfo = LoginInfo("test", "1")
)
}
}

0 comments on commit aa7c65d

Please sign in to comment.