This repository has been archived by the owner on Sep 12, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 142
/
DelegableAuthInfoRepository.scala
133 lines (123 loc) · 5.71 KB
/
DelegableAuthInfoRepository.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/**
* Copyright 2015 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.persistence.repositories
import com.mohiva.play.silhouette.api.exceptions.ConfigurationException
import com.mohiva.play.silhouette.api.repositories.AuthInfoRepository
import com.mohiva.play.silhouette.api.{ AuthInfo, LoginInfo }
import com.mohiva.play.silhouette.persistence.daos.{ AuthInfoDAO, DelegableAuthInfoDAO }
import com.mohiva.play.silhouette.persistence.repositories.DelegableAuthInfoRepository._
import scala.concurrent.{ ExecutionContext, Future }
import scala.reflect.ClassTag
/**
* An implementation of the auth info repository 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 daos The auth info DAO implementations.
* @param ec The execution context to handle the asynchronous operations.
*/
class DelegableAuthInfoRepository(daos: DelegableAuthInfoDAO[_]*)(implicit ec: ExecutionContext) extends AuthInfoRepository {
/**
* Finds the auth info which is linked with the specified login info.
*
* @param loginInfo The linked login info.
* @param tag The class tag of the auth info.
* @tparam T The type of the auth info to handle.
* @return The found auth info or None if no auth info could be found for the given login info.
*/
override def find[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 ConfigurationException(FindError.format(tag.runtimeClass))
}
}
/**
* Adds new auth info for the given login info.
*
* @param loginInfo The login info for which the auth info should be saved.
* @param authInfo The auth info to save.
* @tparam T The type of the auth info to handle.
* @return The saved auth info.
*/
override def add[T <: AuthInfo](loginInfo: LoginInfo, authInfo: T): Future[T] = {
daos.find(_.classTag.runtimeClass == authInfo.getClass) match {
case Some(dao) => dao.asInstanceOf[AuthInfoDAO[T]].add(loginInfo, authInfo)
case _ => throw new ConfigurationException(AddError.format(authInfo.getClass))
}
}
/**
* Updates the auth info for the given login info.
*
* @param loginInfo The login info for which the auth info should be updated.
* @param authInfo The auth info to update.
* @tparam T The type of the auth info to handle.
* @return The updated auth info.
*/
override def update[T <: AuthInfo](loginInfo: LoginInfo, authInfo: T): Future[T] = {
daos.find(_.classTag.runtimeClass == authInfo.getClass) match {
case Some(dao) => dao.asInstanceOf[AuthInfoDAO[T]].update(loginInfo, authInfo)
case _ => throw new ConfigurationException(UpdateError.format(authInfo.getClass))
}
}
/**
* Updates the auth info for the given login info.
*
* This method either adds the auth info if it doesn't exists or it updates the auth info if it already exists.
*
* @param loginInfo The login info for which the auth info should be saved.
* @param authInfo The auth info to save.
* @tparam T The type of the auth info to handle.
* @return The updated auth info.
*/
override 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 ConfigurationException(SaveError.format(authInfo.getClass))
}
}
/**
* Removes the auth info for the given login info.
*
* @param loginInfo The login info for which the auth info should be removed.
* @param tag The class tag of the auth info.
* @tparam T The type of the auth info to handle.
* @return A future to wait for the process to be completed.
*/
override def remove[T <: AuthInfo](loginInfo: LoginInfo)(implicit tag: ClassTag[T]): Future[Unit] = {
daos.find(_.classTag == tag) match {
case Some(dao) => dao.remove(loginInfo)
case _ => throw new ConfigurationException(RemoveError.format(tag.runtimeClass))
}
}
}
/**
* The companion object.
*/
object DelegableAuthInfoRepository {
/**
* The error messages.
*/
val AddError = "Cannot add auth info of type: %s; Please configure the DAO for this type"
val FindError = "Cannot find auth info of type: %s; Please configure the DAO for this type"
val UpdateError = "Cannot update auth info of type: %s; Please configure the DAO for this type"
val SaveError = "Cannot save auth info of type: %s; Please configure the DAO for this type"
val RemoveError = "Cannot remove auth info of type: %s; Please configure the DAO for this type"
}