Skip to content

Commit 579b7ed

Browse files
committed
Add ResourceHandler
1 parent 8ba2057 commit 579b7ed

File tree

9 files changed

+82
-59
lines changed

9 files changed

+82
-59
lines changed

play2-oauth2-provider/src/main/scala/scalaoauth2/provider/OAuth2Provider.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ trait OAuth2Provider extends OAuth2BaseProvider {
138138
* @return Authentication is successful then the response use your API result.
139139
* Authentication is failed then return BadRequest or Unauthorized status to client with cause into the JSON.
140140
*/
141-
def authorize[A, U](dataHandler: DataHandler[U], timeout: Duration = 60.seconds)(callback: AuthInfo[U] => Result)(implicit request: Request[A]): Result = {
141+
def authorize[A, U](dataHandler: ResourceHandler[U], timeout: Duration = 60.seconds)(callback: AuthInfo[U] => Result)(implicit request: Request[A]): Result = {
142142
val f = protectedResource.handleRequest(request, dataHandler).map {
143143
case Left(e) if e.statusCode == 400 => BadRequest.withHeaders(responseOAuthErrorHeader(e))
144144
case Left(e) if e.statusCode == 401 => Unauthorized.withHeaders(responseOAuthErrorHeader(e))
@@ -209,7 +209,7 @@ trait OAuth2AsyncProvider extends OAuth2BaseProvider {
209209
* @return Authentication is successful then the response use your API result.
210210
* Authentication is failed then return BadRequest or Unauthorized status to client with cause into the JSON.
211211
*/
212-
def authorize[A, U](dataHandler: DataHandler[U])(callback: AuthInfo[U] => Future[Result])(implicit request: Request[A]): Future[Result] = {
212+
def authorize[A, U](dataHandler: ResourceHandler[U])(callback: AuthInfo[U] => Future[Result])(implicit request: Request[A]): Future[Result] = {
213213
protectedResource.handleRequest(request, dataHandler).flatMap {
214214
case Left(e) if e.statusCode == 400 => Future.successful(BadRequest.withHeaders(responseOAuthErrorHeader(e)))
215215
case Left(e) if e.statusCode == 401 => Future.successful(Unauthorized.withHeaders(responseOAuthErrorHeader(e)))

project/Build.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Keys._
44
object ScalaOAuth2Build extends Build {
55

66
lazy val _organization = "com.nulab-inc"
7-
lazy val _version = "0.10.0"
7+
lazy val _version = "0.11.1-SNAPSHOT"
88
lazy val _playVersion = "2.3.4"
99

1010
val _scalaVersion = "2.10.4"

scala-oauth2-core/src/main/scala/scalaoauth2/provider/DataHandler.scala

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,17 @@ import scala.concurrent.Future
1212
* @param expiresIn Expiration date of access token. Unit is seconds.
1313
* @param createdAt Access token is created date.
1414
*/
15-
case class AccessToken(token: String, refreshToken: Option[String], scope: Option[String], expiresIn: Option[Long], createdAt: Date)
15+
case class AccessToken(token: String, refreshToken: Option[String], scope: Option[String], expiresIn: Option[Long], createdAt: Date) {
16+
17+
/**
18+
* Check expiration.
19+
*/
20+
def isExpired: Boolean = expiresIn.exists { expiresIn =>
21+
val now = System.currentTimeMillis()
22+
createdAt.getTime + expiresIn * 1000 <= now
23+
}
24+
25+
}
1626

1727
/**
1828
* Authorized information
@@ -65,13 +75,7 @@ case class AuthInfo[+U](user: U, clientId: Option[String], scope: Option[String]
6575
* <li>refreshAccessToken(authInfo, token)
6676
* <li>createAccessToken(authInfo)</li>
6777
* </ul>
68-
*
69-
* <h3>[Access to Protected Resource phase]</h3>
70-
* <ul>
71-
* <li>findAccessToken(token)</li>
72-
* <li>isAccessTokenExpired(token)</li>
73-
* <li>findAuthInfoByAccessToken(token)</li>
74-
* </ul>
78+
*
7579
*/
7680
trait DataHandler[U] {
7781

@@ -150,33 +154,4 @@ trait DataHandler[U] {
150154
*/
151155
def findClientUser(clientCredential: ClientCredential, scope: Option[String]): Future[Option[U]]
152156

153-
/**
154-
* Find AccessToken object by access token code.
155-
*
156-
* @param token Client sends access token which is created by system.
157-
* @return Return access token that matched the token.
158-
*/
159-
def findAccessToken(token: String): Future[Option[AccessToken]]
160-
161-
/**
162-
* Find authorized information by access token.
163-
*
164-
* @param accessToken This value is AccessToken.
165-
* @return Return authorized information if the parameter is available.
166-
*/
167-
def findAuthInfoByAccessToken(accessToken: AccessToken): Future[Option[AuthInfo[U]]]
168-
169-
/**
170-
* Check expiration.
171-
*
172-
* @param accessToken accessToken
173-
* @return true if accessToken expired
174-
*/
175-
def isAccessTokenExpired(accessToken: AccessToken): Boolean = {
176-
accessToken.expiresIn.exists { expiresIn =>
177-
val now = System.currentTimeMillis()
178-
accessToken.createdAt.getTime + expiresIn * 1000 <= now
179-
}
180-
}
181-
182157
}

scala-oauth2-core/src/main/scala/scalaoauth2/provider/GrantHandler.scala

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@ trait GrantHandler {
1717

1818
/**
1919
* Returns valid access token.
20-
*
21-
* @param dataHandler
22-
* @param authInfo
23-
* @return
2420
*/
2521
def issueAccessToken[U](dataHandler: DataHandler[U], authInfo: AuthInfo[U]): Future[GrantHandlerResult] = {
2622
dataHandler.getStoredAccessToken(authInfo).flatMap { optionalAccessToken =>
2723
(optionalAccessToken match {
28-
case Some(token) if dataHandler.isAccessTokenExpired(token) => {
29-
token.refreshToken.map(dataHandler.refreshAccessToken(authInfo, _)).getOrElse(dataHandler.createAccessToken(authInfo))
24+
case Some(token) if token.isExpired => token.refreshToken.map {
25+
dataHandler.refreshAccessToken(authInfo, _)
26+
}.getOrElse {
27+
dataHandler.createAccessToken(authInfo)
3028
}
3129
case Some(token) => Future.successful(token)
3230
case None => dataHandler.createAccessToken(authInfo)
@@ -41,6 +39,7 @@ trait GrantHandler {
4139
}
4240
}
4341
}
42+
4443
}
4544

4645
class RefreshToken extends GrantHandler {

scala-oauth2-core/src/main/scala/scalaoauth2/provider/ProtectedResource.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ trait ProtectedResource {
77

88
val fetchers = Seq(AuthHeader, RequestParameter)
99

10-
def handleRequest[U](request: ProtectedResourceRequest, dataHandler: DataHandler[U]): Future[Either[OAuthError, AuthInfo[U]]] = try {
10+
def handleRequest[U](request: ProtectedResourceRequest, dataHandler: ResourceHandler[U]): Future[Either[OAuthError, AuthInfo[U]]] = try {
1111
fetchers.find { fetcher =>
1212
fetcher.matches(request)
1313
}.map { fetcher =>
1414
val result = fetcher.fetch(request)
1515
dataHandler.findAccessToken(result.token).flatMap { maybeToken =>
1616
val token = maybeToken.getOrElse(throw new InvalidToken("The access token is not found"))
17-
if (dataHandler.isAccessTokenExpired(token)) {
17+
if (token.isExpired) {
1818
throw new ExpiredToken()
1919
}
2020

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package scalaoauth2.provider
2+
3+
import scala.concurrent.Future
4+
5+
/**
6+
*
7+
* Provide accessing to data storage for using OAuth 2.0.
8+
*
9+
* <h3>[Access to Protected Resource phase]</h3>
10+
* <ul>
11+
* <li>findAccessToken(token)</li>
12+
* <li>findAuthInfoByAccessToken(token)</li>
13+
* </ul>
14+
*/
15+
trait ResourceHandler[+U] {
16+
17+
/**
18+
* Find authorized information by access token.
19+
*
20+
* @param accessToken This value is AccessToken.
21+
* @return Return authorized information if the parameter is available.
22+
*/
23+
def findAuthInfoByAccessToken(accessToken: AccessToken): Future[Option[AuthInfo[U]]]
24+
25+
/**
26+
* Find AccessToken object by access token code.
27+
*
28+
* @param token Client sends access token which is created by system.
29+
* @return Return access token that matched the token.
30+
*/
31+
def findAccessToken(token: String): Future[Option[AccessToken]]
32+
33+
}

scala-oauth2-core/src/main/scala/scalaoauth2/provider/TokenEndpoint.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ trait TokenEndpoint {
77
val fetcher = ClientCredentialFetcher
88

99
val handlers = Map(
10-
"authorization_code" -> new AuthorizationCode(),
11-
"refresh_token" -> new RefreshToken(),
12-
"client_credentials" -> new ClientCredentials(),
13-
"password" -> new Password()
10+
OAuthGrantType.AUTHORIZATION_CODE -> new AuthorizationCode(),
11+
OAuthGrantType.REFRESH_TOKEN -> new RefreshToken(),
12+
OAuthGrantType.CLIENT_CREDENTIALS -> new ClientCredentials(),
13+
OAuthGrantType.PASSWORD -> new Password()
1414
)
1515

1616
def handleRequest[U](request: AuthorizationRequest, dataHandler: DataHandler[U]): Future[Either[OAuthError, GrantHandlerResult]] = try {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package scalaoauth2
2+
3+
/**
4+
* @author dbalduini
5+
*/
6+
package object provider {
7+
8+
object OAuthGrantType {
9+
val AUTHORIZATION_CODE = "authorization_code"
10+
val REFRESH_TOKEN = "refresh_token"
11+
val CLIENT_CREDENTIALS = "client_credentials"
12+
val PASSWORD = "password"
13+
}
14+
15+
16+
}

scala-oauth2-core/src/test/scala/scalaoauth2/provider/ProtectedResourceSpec.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import scala.concurrent.Future
1111

1212
class ProtectedResourceSpec extends FlatSpec with ScalaFutures {
1313

14-
def successfulDataHandler() = new MockDataHandler() {
14+
def successfulResourceHandler() = new ResourceHandler[User] {
1515

1616
override def findAccessToken(token: String): Future[Option[AccessToken]] = Future.successful(Some(AccessToken("token1", Some("refreshToken1"), Some("all"), Some(3600), new Date())))
1717

@@ -27,7 +27,7 @@ class ProtectedResourceSpec extends FlatSpec with ScalaFutures {
2727
Map("username" -> Seq("user"), "password" -> Seq("pass"), "scope" -> Seq("all"))
2828
)
2929

30-
val dataHandler = successfulDataHandler()
30+
val dataHandler = successfulResourceHandler()
3131
ProtectedResource.handleRequest(request, dataHandler).map(_ should be ('right))
3232
}
3333

@@ -37,7 +37,7 @@ class ProtectedResourceSpec extends FlatSpec with ScalaFutures {
3737
Map("access_token" -> Seq("token1"), "username" -> Seq("user"), "password" -> Seq("pass"), "scope" -> Seq("all"))
3838
)
3939

40-
val dataHandler = successfulDataHandler()
40+
val dataHandler = successfulResourceHandler()
4141
ProtectedResource.handleRequest(request, dataHandler).map(_ should be ('right))
4242
}
4343

@@ -47,7 +47,7 @@ class ProtectedResourceSpec extends FlatSpec with ScalaFutures {
4747
Map("username" -> Seq("user"), "password" -> Seq("pass"), "scope" -> Seq("all"))
4848
)
4949

50-
val dataHandler = new MockDataHandler() {
50+
val dataHandler = new ResourceHandler[User] {
5151

5252
override def findAccessToken(token: String): Future[Option[AccessToken]] = Future.successful(Some(AccessToken("token1", Some("refreshToken1"), Some("all"), Some(3600), new Date(new Date().getTime() - 4000 * 1000))))
5353

@@ -75,7 +75,7 @@ class ProtectedResourceSpec extends FlatSpec with ScalaFutures {
7575
Map("username" -> Seq("user"), "password" -> Seq("pass"), "scope" -> Seq("all"))
7676
)
7777

78-
val dataHandler = successfulDataHandler()
78+
val dataHandler = successfulResourceHandler()
7979
val f = ProtectedResource.handleRequest(request, dataHandler)
8080

8181
whenReady(f) { result =>
@@ -95,7 +95,7 @@ class ProtectedResourceSpec extends FlatSpec with ScalaFutures {
9595
Map("username" -> Seq("user"), "password" -> Seq("pass"), "scope" -> Seq("all"))
9696
)
9797

98-
val dataHandler = new MockDataHandler() {
98+
val dataHandler = new ResourceHandler[User] {
9999

100100
override def findAccessToken(token: String): Future[Option[AccessToken]] = Future.successful(None)
101101

@@ -122,7 +122,7 @@ class ProtectedResourceSpec extends FlatSpec with ScalaFutures {
122122
Map("username" -> Seq("user"), "password" -> Seq("pass"), "scope" -> Seq("all"))
123123
)
124124

125-
val dataHandler = new MockDataHandler() {
125+
val dataHandler = new ResourceHandler[User] {
126126

127127
override def findAccessToken(token: String): Future[Option[AccessToken]] = Future.successful(Some(AccessToken("token1", Some("refreshToken1"), Some("all"), Some(3600), new Date())))
128128

0 commit comments

Comments
 (0)