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 #109 from akkie/master
Browse files Browse the repository at this point in the history
A better fix for #104
  • Loading branch information
fernandoacorreia committed Feb 18, 2014
2 parents 189f061 + 6682fbd commit adb0c2e
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 347 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,31 @@
*/
package com.mohiva.play.silhouette.contrib.daos

import com.mohiva.play.silhouette.core.LoginInfo
import com.mohiva.play.silhouette.core.providers.OAuth1Info
import scala.concurrent.Future
import com.mohiva.play.silhouette.core.LoginInfo
import com.mohiva.play.silhouette.core.services.AuthInfo

/**
* The DAO to store the OAuth1 information.
* The DAO to persist the auth info.
*
* @tparam T The type of the auth info to store.
*/
trait OAuth1InfoDAO {
trait AuthInfoDAO[T <: AuthInfo] {

/**
* Saves the OAuth1 info.
* Saves the auth info.
*
* @param loginInfo The login info for which the auth info should be saved.
* @param authInfo The OAuth1 info to save.
* @return The saved OAuth1 info or None if the OAuth1 info couldn't be saved.
* @param authInfo The auth info to save.
* @return The saved auth info.
*/
def save(loginInfo: LoginInfo, authInfo: OAuth1Info): Future[Option[OAuth1Info]]
def save(loginInfo: LoginInfo, authInfo: T): Future[T]

/**
* Finds the OAuth1 info which is linked with the specified login info.
*
* @param loginInfo The linked login info.
* @return The retrieved OAuth1 info or None if no OAuth1 info could be retrieved for the given login info.
* @return The retrieved auth info or None if no auth info could be retrieved for the given login info.
*/
def find(loginInfo: LoginInfo): Future[Option[OAuth1Info]]
def find(loginInfo: LoginInfo): Future[Option[T]]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* 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.contrib.daos

import scala.reflect.ClassTag
import com.mohiva.play.silhouette.core.services.AuthInfo

/**
* An implementation of the auth info DAO.
*
* This abstract implementation of the [[com.mohiva.play.silhouette.contrib.daos.AuthInfoDAO]] trait
* allows us to get the class tag of the auth info he is responsible for. On the base of this tag
* the [[com.mohiva.play.silhouette.contrib.services.DelegableAuthInfoService]] class can delegate
* operations to the DAO which is responsible for the currently handled auth info.
*
* @param classTag The class tag for the type parameter.
* @tparam T The type of the auth info to store.
*/
abstract class DelegableAuthInfoDAO[T <: AuthInfo](implicit val classTag: ClassTag[T]) extends AuthInfoDAO[T]
43 changes: 0 additions & 43 deletions app/com/mohiva/play/silhouette/contrib/daos/OAuth2InfoDAO.scala

This file was deleted.

43 changes: 0 additions & 43 deletions app/com/mohiva/play/silhouette/contrib/daos/PasswordInfoDAO.scala

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,27 @@
*/
package com.mohiva.play.silhouette.contrib.services

import javax.inject.Inject
import scala.reflect.ClassTag
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import com.mohiva.play.silhouette.core.LoginInfo
import com.mohiva.play.silhouette.core.services.{ AuthInfo, AuthInfoService }
import com.mohiva.play.silhouette.core.providers.{ OAuth2Info, OAuth1Info, PasswordInfo }
import com.mohiva.play.silhouette.contrib.daos.{ OAuth2InfoDAO, OAuth1InfoDAO, PasswordInfoDAO }
import DefaultAuthInfoService._
import com.mohiva.play.silhouette.contrib.daos.{ DelegableAuthInfoDAO, AuthInfoDAO }
import DelegableAuthInfoService._

/**
* An implementation of the auth info service which stores the different auth info instances with the help of
* different DAOs.
* An implementation of the auth info service which delegates the storage of an auth info instance to its
* appropriate DAO.
*
* Due the nature of the different auth information it is hard to persist the data in a single data structure,
* expect the data gets stored in a serialized format. With this implementation it is possible to store the
* different auth info in different backing stores. If we speak of a relational database, then the auth info
* can be stored in different tables. And the tables represents the internal data structure of each auth info
* object.
*
* @param passwordInfoDAO The password info DAO implementation.
* @param oauth1InfoDAO The OAuth1 info DAO implementation.
* @param oauth2InfoDAO The OAuth2 info DAO implementation.
* @param daos The auth info DAO implementations.
*/
class DefaultAuthInfoService @Inject() (
passwordInfoDAO: PasswordInfoDAO,
oauth1InfoDAO: OAuth1InfoDAO,
oauth2InfoDAO: OAuth2InfoDAO) extends AuthInfoService {
class DelegableAuthInfoService(daos: DelegableAuthInfoDAO[_]*) extends AuthInfoService {

/**
* Saves auth info.
Expand All @@ -55,13 +48,13 @@ class DefaultAuthInfoService @Inject() (
*
* @param loginInfo The login info for which the auth info should be saved.
* @param authInfo The auth info to save.
* @return The saved auth info or None if the auth info couldn't be saved.
* @return The saved auth info.
*/
def save[T <: AuthInfo](loginInfo: LoginInfo, authInfo: T): Future[Option[T]] = authInfo match {
case a: PasswordInfo => passwordInfoDAO.save(loginInfo, a).map(_.map(_.asInstanceOf[T]))
case a: OAuth1Info => oauth1InfoDAO.save(loginInfo, a).map(_.map(_.asInstanceOf[T]))
case a: OAuth2Info => oauth2InfoDAO.save(loginInfo, a).map(_.map(_.asInstanceOf[T]))
case a => throw new Exception(SaveError.format(a.getClass))
def save[T <: AuthInfo](loginInfo: LoginInfo, authInfo: T): Future[T] = {
daos.find(_.classTag.runtimeClass == authInfo.getClass) match {
case Some(dao) => dao.asInstanceOf[AuthInfoDAO[T]].save(loginInfo, authInfo)
case _ => throw new Exception(SaveError.format(authInfo.getClass))
}
}

/**
Expand All @@ -71,18 +64,18 @@ class DefaultAuthInfoService @Inject() (
* @param tag The class tag of the auth info.
* @return The retrieved auth info or None if no auth info could be retrieved for the given login info.
*/
def retrieve[T <: AuthInfo](loginInfo: LoginInfo)(implicit tag: ClassTag[T]): Future[Option[T]] = tag match {
case a if a.runtimeClass == classOf[PasswordInfo] => passwordInfoDAO.find(loginInfo).map(_.map(_.asInstanceOf[T]))
case a if a.runtimeClass == classOf[OAuth1Info] => oauth1InfoDAO.find(loginInfo).map(_.map(_.asInstanceOf[T]))
case a if a.runtimeClass == classOf[OAuth2Info] => oauth2InfoDAO.find(loginInfo).map(_.map(_.asInstanceOf[T]))
case a => throw new Exception(RetrieveError.format(a.runtimeClass))
def retrieve[T <: AuthInfo](loginInfo: LoginInfo)(implicit tag: ClassTag[T]): Future[Option[T]] = {
daos.find(_.classTag == tag) match {
case Some(dao) => dao.find(loginInfo).map(_.map(_.asInstanceOf[T]))
case _ => throw new Exception(RetrieveError.format(tag.runtimeClass))
}
}
}

/**
* The companion object.
*/
object DefaultAuthInfoService {
object DelegableAuthInfoService {

/**
* The error messages.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ trait AuthInfoService {
*
* @param loginInfo The login info for which the auth info should be saved.
* @param authInfo The auth info to save.
* @return The saved auth info or None if the auth info couldn't be saved.
* @return The saved auth info.
*/
def save[T <: AuthInfo](loginInfo: LoginInfo, authInfo: T): Future[Option[T]]
def save[T <: AuthInfo](loginInfo: LoginInfo, authInfo: T): Future[T]

/**
* Retrieves the auth info which is linked with the specified login info.
Expand Down
4 changes: 3 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ libraryDependencies ++= Seq(
cache,
"org.mindrot" % "jbcrypt" % "0.3m",
"javax.inject" % "javax.inject" % "1",
"org.mockito" % "mockito-core" % "1.9.5" % "test"
"org.mockito" % "mockito-core" % "1.9.5" % "test",
"com.google.inject" % "guice" % "4.0-beta" % "test",
"net.codingwell" %% "scala-guice" % "4.0.0-beta" % "test"
)

parallelExecution in Test := false
Expand Down

0 comments on commit adb0c2e

Please sign in to comment.