Skip to content

Commit 664bab1

Browse files
committed
OAuth2AsyncProvider become default provider #41
1 parent bf75f4b commit 664bab1

File tree

4 files changed

+82
-61
lines changed

4 files changed

+82
-61
lines changed

README.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,13 @@ For more details, refer to Scaladoc of ```DataHandler```.
8989
```DataHandler``` returns ```AuthInfo``` as authorized information.
9090
```AuthInfo``` is made up of the following fields.
9191

92-
```
93-
case class AuthInfo[User](user: User, clientId: Option[String], scope: Option[String], redirectUri: Option[String])
92+
```scala
93+
case class AuthInfo[User](
94+
user: User,
95+
clientId: Option[String],
96+
scope: Option[String],
97+
redirectUri: Option[String]
98+
)
9499
```
95100

96101
- user
@@ -113,17 +118,27 @@ You should follow three steps below to work with Playframework.
113118
* Access to an authorized resource
114119

115120
First, define your own controller with mixining ```OAuth2Provider``` trait provided by this library to issue access token.
116-
Asynchronous result is used in your controller then you can use ```OAuth2AsyncProvider```, which supports returning ```Future[Result]```.
117121

118122
```scala
119123
import scalaoauth2.provider._
120124
object OAuth2Controller extends Controller with OAuth2Provider {
121-
def accessToken = Action { implicit request =>
125+
def accessToken = Action.async { implicit request =>
122126
issueAccessToken(new MyDataHandler())
123127
}
124128
}
125129
```
126130

131+
NOTE: If your controller supports returning synchronous result, use ```await``` method which is package object of scalaoauth2.provider.
132+
133+
```scala
134+
import scalaoauth2.provider._
135+
object OAuth2Controller extends Controller with OAuth2Provider {
136+
def accessToken = Action { implicit request =>
137+
await(issueAccessToken(new MyDataHandler()))
138+
}
139+
}
140+
```
141+
127142
Then, assign a route to the controller that OAuth clients will access to.
128143

129144
```
@@ -135,7 +150,7 @@ Finally, you can access to an authorized resource like this:
135150
```scala
136151
import scalaoauth2.provider._
137152
object MyController extends Controller with OAuth2Provider {
138-
def list = Action { implicit request =>
153+
def list = Action.async { implicit request =>
139154
authorize(new MyDataHandler()) { authInfo =>
140155
val user = authInfo.user // User is defined on your system
141156
// access resource for the user
@@ -160,7 +175,7 @@ class MyTokenEndpoint extends TokenEndpoint {
160175
}
161176

162177
override val handlers = Map(
163-
"password" -> passwordNoCred
178+
OAuthGrantType.PASSWORD -> passwordNoCred
164179
)
165180
}
166181
```

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

Lines changed: 13 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package scalaoauth2.provider
22

3-
import play.api.mvc._
43
import play.api.libs.json._
5-
import scala.concurrent.Await
6-
import scala.concurrent.Future
4+
import play.api.mvc._
5+
76
import scala.concurrent.ExecutionContext.Implicits.global
7+
import scala.concurrent.Future
88
import scala.language.implicitConversions
9-
import scala.concurrent.duration._
109

1110
/**
1211
* Basic OAuth2 provider trait.
@@ -83,7 +82,7 @@ trait OAuth2BaseProvider extends Results {
8382
* <h3>Create controller for issue access token</h3>
8483
* <code>
8584
* object OAuth2Controller extends Controller with OAuth2Provider {
86-
* def accessToken = Action { implicit request =>
85+
* def accessToken = Action.async { implicit request =>
8786
* issueAccessToken(new MyDataHandler())
8887
* }
8988
* }
@@ -98,7 +97,7 @@ trait OAuth2BaseProvider extends Results {
9897
* <code>
9998
* import scalaoauth2.provider._
10099
* object BookController extends Controller with OAuthProvider {
101-
* def list = Action { implicit request =>
100+
* def list = Action.async { implicit request =>
102101
* authorize(new MyDataHandler()) { authInfo =>
103102
* val user = authInfo.user // User is defined on your system
104103
* // access resource for the user
@@ -118,14 +117,12 @@ trait OAuth2Provider extends OAuth2BaseProvider {
118117
* @return Request is successful then return JSON to client in OAuth 2.0 format.
119118
* Request is failed then return BadRequest or Unauthorized status to client with cause into the JSON.
120119
*/
121-
def issueAccessToken[A, U](handler: AuthorizationHandler[U], timeout: Duration = 60.seconds)(implicit request: Request[A]): Result = {
122-
val f = tokenEndpoint.handleRequest(request, handler).map {
120+
def issueAccessToken[A, U](handler: AuthorizationHandler[U])(implicit request: Request[A]): Future[Result] = {
121+
tokenEndpoint.handleRequest(request, handler).map {
123122
case Left(e) if e.statusCode == 400 => BadRequest(responseOAuthErrorJson(e)).withHeaders(responseOAuthErrorHeader(e))
124123
case Left(e) if e.statusCode == 401 => Unauthorized(responseOAuthErrorJson(e)).withHeaders(responseOAuthErrorHeader(e))
125124
case Right(r) => Ok(Json.toJson(responseAccessToken(r))).withHeaders("Cache-Control" -> "no-store", "Pragma" -> "no-cache")
126125
}
127-
128-
Await.result(f, timeout)
129126
}
130127

131128
/**
@@ -138,14 +135,12 @@ trait OAuth2Provider extends OAuth2BaseProvider {
138135
* @return Authentication is successful then the response use your API result.
139136
* Authentication is failed then return BadRequest or Unauthorized status to client with cause into the JSON.
140137
*/
141-
def authorize[A, U](handler: ProtectedResourceHandler[U], timeout: Duration = 60.seconds)(callback: AuthInfo[U] => Result)(implicit request: Request[A]): Result = {
142-
val f = protectedResource.handleRequest(request, handler).map {
143-
case Left(e) if e.statusCode == 400 => BadRequest.withHeaders(responseOAuthErrorHeader(e))
144-
case Left(e) if e.statusCode == 401 => Unauthorized.withHeaders(responseOAuthErrorHeader(e))
138+
def authorize[A, U](handler: ProtectedResourceHandler[U])(callback: AuthInfo[U] => Future[Result])(implicit request: Request[A]): Future[Result] = {
139+
protectedResource.handleRequest(request, handler).flatMap {
140+
case Left(e) if e.statusCode == 400 => Future.successful(BadRequest.withHeaders(responseOAuthErrorHeader(e)))
141+
case Left(e) if e.statusCode == 401 => Future.successful(Unauthorized.withHeaders(responseOAuthErrorHeader(e)))
145142
case Right(authInfo) => callback(authInfo)
146143
}
147-
148-
Await.result(f, timeout)
149144
}
150145

151146
}
@@ -180,41 +175,5 @@ trait OAuth2Provider extends OAuth2BaseProvider {
180175
* }
181176
* </code>
182177
*/
183-
trait OAuth2AsyncProvider extends OAuth2BaseProvider {
184-
185-
/**
186-
* Issue access token in AuthorizationHandler process and return the response to client.
187-
*
188-
* @param handler Implemented AuthorizationHandler for register access token to your system.
189-
* @param request Playframework is provided HTTP request interface.
190-
* @tparam A play.api.mvc.Request has type.
191-
* @return Request is successful then return JSON to client in OAuth 2.0 format.
192-
* Request is failed then return BadRequest or Unauthorized status to client with cause into the JSON.
193-
*/
194-
def issueAccessToken[A, U](handler: AuthorizationHandler[U])(implicit request: Request[A]): Future[Result] = {
195-
tokenEndpoint.handleRequest(request, handler).map {
196-
case Left(e) if e.statusCode == 400 => BadRequest(responseOAuthErrorJson(e)).withHeaders(responseOAuthErrorHeader(e))
197-
case Left(e) if e.statusCode == 401 => Unauthorized(responseOAuthErrorJson(e)).withHeaders(responseOAuthErrorHeader(e))
198-
case Right(r) => Ok(Json.toJson(responseAccessToken(r))).withHeaders("Cache-Control" -> "no-store", "Pragma" -> "no-cache")
199-
}
200-
}
201-
202-
/**
203-
* Authorize to already created access token in ProtectedResourceHandler process and return the response to client.
204-
*
205-
* @param handler Implemented ProtectedResourceHandler for authenticate to your system.
206-
* @param callback Callback is called when authentication is successful.
207-
* @param request Playframework is provided HTTP request interface.
208-
* @tparam A play.api.mvc.Request has type.
209-
* @return Authentication is successful then the response use your API result.
210-
* Authentication is failed then return BadRequest or Unauthorized status to client with cause into the JSON.
211-
*/
212-
def authorize[A, U](handler: ProtectedResourceHandler[U])(callback: AuthInfo[U] => Future[Result])(implicit request: Request[A]): Future[Result] = {
213-
protectedResource.handleRequest(request, handler).flatMap {
214-
case Left(e) if e.statusCode == 400 => Future.successful(BadRequest.withHeaders(responseOAuthErrorHeader(e)))
215-
case Left(e) if e.statusCode == 401 => Future.successful(Unauthorized.withHeaders(responseOAuthErrorHeader(e)))
216-
case Right(authInfo) => callback(authInfo)
217-
}
218-
}
219-
220-
}
178+
@deprecated("Use OAuth2Provider", "0.12.0")
179+
trait OAuth2AsyncProvider extends OAuth2Provider
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package scalaoauth2
2+
3+
import play.api.mvc.Result
4+
5+
import scala.concurrent.duration._
6+
import scala.concurrent.{Await, Future}
7+
8+
package object provider {
9+
10+
/**
11+
* Support synchronous Result for Playframework
12+
*
13+
* <h3>Create controller for issue access token</h3>
14+
* <code>
15+
* import scalaoauth2.provider._
16+
* object OAuth2Controller extends Controller with OAuth2Provider {
17+
* def accessToken = Action { implicit request =>
18+
* await(issueAccessToken(new MyDataHandler()))
19+
* }
20+
* }
21+
* </code>
22+
*
23+
* <h3>Register routes</h3>
24+
* <code>
25+
* POST /oauth2/access_token controllers.OAuth2Controller.accessToken
26+
* </code>
27+
*
28+
* <h3>Authorized</h3>
29+
* <code>
30+
* import scalaoauth2.provider._
31+
* object BookController extends Controller with OAuthProvider {
32+
* def list = Action { implicit request =>
33+
* await(authorize(new MyDataHandler()) { authInfo =>
34+
* val user = authInfo.user // User is defined on your system
35+
* // access resource for the user
36+
* Future.successful(Ok)
37+
* })
38+
* }
39+
* }
40+
* </code>
41+
* @param f callback
42+
* @param timeout maximum wait time
43+
* @return Await and return the result.
44+
*/
45+
def await(f: Future[Result], timeout: Duration = 60.seconds): Result = Await.result(f, timeout)
46+
47+
}

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.11.0"
7+
lazy val _version = "0.12.0-SNAPSHOT"
88
lazy val _playVersion = "2.3.4"
99

1010
val _scalaVersion = "2.10.4"

0 commit comments

Comments
 (0)