From ad35c21ce138af2afff386a46b9205436f6c622a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Miguel=20Cisneros=20Le=C3=B3n?= Date: Mon, 9 Oct 2017 15:26:00 +0200 Subject: [PATCH 1/2] Add Token Exchange --- README.md | 3 ++ .../scala/kiambogo/scrava/ClientFactory.scala | 33 +++++++++++++++++++ .../scrava/models/TokenExchange.scala | 3 ++ .../kiambogo/scrava/IntegrationTest.scala | 19 +++++++++++ 4 files changed, 58 insertions(+) create mode 100644 src/main/scala/kiambogo/scrava/models/TokenExchange.scala diff --git a/README.md b/README.md index 5cd730c..4c74c23 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,9 @@ Scrava is currently built for Scala 2.11 and 2.12. To use scrava in an sbt proje val client = new ScravaClient("[accessToken]") val athlete = client.retrieveAthlete() +###Build Client without token + val (client, athlete) = clientFactory.instance("[APP_ID]", "[APP_SECRET]", "[CODE]") + **Note:** Most functions have optional ID parameters (i.e, `retrieveAthlete()`). If no ID is provided, the function will operate based on the currently authenticated user. Therefore, `retrieveAthlete()` will return the athlete profile of the currently authenticated user (based on the access token provided), and `listAthleteFriends()` will return the list of friends of the currently authenticated athlete. To retrieve perform these functions for a particular athlete/activity/etc, simply pass in the respective ID: `retrieveAthlete(Some([athleteID]))` or `listAthleteFriends(Some([athleteID]))`. diff --git a/src/main/scala/kiambogo/scrava/ClientFactory.scala b/src/main/scala/kiambogo/scrava/ClientFactory.scala index be56143..fa95b9a 100644 --- a/src/main/scala/kiambogo/scrava/ClientFactory.scala +++ b/src/main/scala/kiambogo/scrava/ClientFactory.scala @@ -1,9 +1,42 @@ package kiambogo.scrava + +import kiambogo.scrava.models._ +import net.liftweb.json.parse + +import scala.util.{Failure, Success, Try} +import scalaj.http.Http + trait ClientFactory { def instance(token: String): Client + + def instance(client_id: String, client_secret: String, code: String): (Client, AthleteSummary) } class ClientFactoryImpl extends ClientFactory { + override def instance(token: String): Client = new ScravaClient(token) + + /** + * Return a StravaClient from http://strava.github.io/api/v3/oauth/#post-token + * + * @param client_id application’s ID, obtained during registration + * @param client_secret application’s secret, obtained during registration + * @param code authorization code (from callback URL) + * @return a ScravaClient and the AthleteSummary returned by the API. + */ + override def instance(client_id: String, client_secret: String, code: String): (Client, AthleteSummary) = { + val request = Http(s"https://www.strava.com/oauth/token").method("post") + .postForm(Seq(("client_id", client_id), ("client_secret", client_secret), ("code", code))) + implicit val formats = net.liftweb.json.DefaultFormats + + Try { + parse(request.asString.body).extract[TokenExchange] + } match { + case Success(TokenExchange(access_token, token_type, athlete)) => + (new ScravaClient(access_token), athlete) + case Failure(error) => + throw new RuntimeException(s"Could not get Token Exchange Athlete: $error") + } + } } diff --git a/src/main/scala/kiambogo/scrava/models/TokenExchange.scala b/src/main/scala/kiambogo/scrava/models/TokenExchange.scala new file mode 100644 index 0000000..63a346f --- /dev/null +++ b/src/main/scala/kiambogo/scrava/models/TokenExchange.scala @@ -0,0 +1,3 @@ +package kiambogo.scrava.models + +class TokenExchange(access_token:String, token_type:String, athlete: AthleteSummary) diff --git a/src/test/scala/kiambogo/scrava/IntegrationTest.scala b/src/test/scala/kiambogo/scrava/IntegrationTest.scala index c4ff37b..7d42eae 100644 --- a/src/test/scala/kiambogo/scrava/IntegrationTest.scala +++ b/src/test/scala/kiambogo/scrava/IntegrationTest.scala @@ -151,4 +151,23 @@ class IntegrationTest extends FlatSpec with Matchers { stream(0).asInstanceOf[LatLng].resolution should equal(Some("high")) stream(1).asInstanceOf[Distance].original_size should equal(Some(114)) } + + /** + * Need to provide a valid APP_ID, Secret and Code + * The code can be generate with + * https://www.strava.com/oauth/authorize?client_id=APP_ID&response_type=code&redirect_uri=http://127.0.0.1/token_exchange&scope=write&state=mystate&approval_prompt=force + */ + ignore should "Make a Token Exchange" in { + + val clientFactory = new ClientFactoryImpl + val clientId = "APP_ID" + val client_secret = "SEEEECRET" + val code = "CODE" + val (client, athlete) = clientFactory.instance(clientId, client_secret, code) + + athlete.firstname should equal("Luis Miguel") + client.listAthleteClubs + + } + } From db71a2e9965ef1ef829d2ce64ac731f1e77c5f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Miguel=20Cisneros=20Le=C3=B3n?= Date: Mon, 9 Oct 2017 15:28:47 +0200 Subject: [PATCH 2/2] Add Token Exchange --- src/main/scala/kiambogo/scrava/models/TokenExchange.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/kiambogo/scrava/models/TokenExchange.scala b/src/main/scala/kiambogo/scrava/models/TokenExchange.scala index 63a346f..dfa54ca 100644 --- a/src/main/scala/kiambogo/scrava/models/TokenExchange.scala +++ b/src/main/scala/kiambogo/scrava/models/TokenExchange.scala @@ -1,3 +1,3 @@ package kiambogo.scrava.models -class TokenExchange(access_token:String, token_type:String, athlete: AthleteSummary) +case class TokenExchange(access_token:String, token_type:String, athlete: AthleteSummary)