Skip to content

Commit 95c0ca6

Browse files
author
Rafa Paradela
committed
Wip
1 parent 1f4c46b commit 95c0ca6

6 files changed

Lines changed: 80 additions & 9 deletions

File tree

src/main/scala/com/fortysevendeg/github4s/GithubAPIs.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,10 @@ class GHAuth(implicit O : AuthOps[GitHub4s]){
4242
client_id: String,
4343
client_secret: String): GHIO[GHResponse[Authorization]] =
4444
O.newAuth(username, password, scopes, note, client_id, client_secret)
45+
46+
def authorizeUrl(
47+
client_id: String,
48+
redirect_uri: String,
49+
scopes: List[String]): GHIO[GHResponse[Authorize]] =
50+
O.authorizeUrl(client_id, redirect_uri, scopes)
4551
}

src/main/scala/com/fortysevendeg/github4s/GithubResponses.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ object GithubResponses {
5252
case r => UnexpectedException(s"Failed invoking get with status : ${r.code}, body : \n ${r.body}").left[GHResult[Unit]]
5353
}
5454

55-
def toEntityString(s: String): GHResponse[String] = Xor.Right(GHItemResult(s, 0, Map.empty))
56-
5755
private def toLowerCase(headers: Map[String, IndexedSeq[String]]): Map[String, IndexedSeq[String]] = headers.map(e => (e._1.toLowerCase, e._2))
5856

5957

src/main/scala/com/fortysevendeg/github4s/api/Auth.scala

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.fortysevendeg.github4s.api
22

3-
import com.fortysevendeg.github4s.GithubResponses.GHResponse
4-
import com.fortysevendeg.github4s.free.domain.Authorization
3+
import java.util.UUID
4+
5+
import cats.data.Xor
6+
import com.fortysevendeg.github4s.GithubResponses.{GHItemResult, GHResponse}
7+
import com.fortysevendeg.github4s.free.domain._
58
import com.fortysevendeg.github4s.HttpClient
69
import io.circe.generic.auto._
710
import io.circe.syntax._
@@ -12,8 +15,19 @@ object Auth {
1215

1316
protected val httpClient = new HttpClient()
1417

15-
case class NewAuthRequest(scopes: List[String], note: String, client_id: String, client_secret: String)
18+
val authorizeUrl = "https://github.com/login/oauth/authorize?client_id=%s&redirect_uri=%s&scope=%s&state=%s"
1619

20+
/**
21+
* Call to request a new authorization given a basic authentication, the returned object Authorization includes an
22+
* access token
23+
* @param username
24+
* @param password
25+
* @param scopes
26+
* @param note
27+
* @param client_id
28+
* @param client_secret
29+
* @return
30+
*/
1731
def newAuth(
1832
username: String,
1933
password: String,
@@ -26,10 +40,35 @@ object Auth {
2640
headers = Map("Authorization" -> s"Basic ${base64(s"$username:$password")}"),
2741
data = NewAuthRequest(scopes, note, client_id, client_secret).asJson.noSpaces)
2842

43+
44+
/**
45+
* Generates the authorize url with a random state, both are returned within Authorize object
46+
*
47+
* @param client_id
48+
* @param redirect_uri
49+
* @param scopes
50+
* @return
51+
*/
2952
def authorizeUrl(
3053
client_id: String,
3154
redirect_uri: String,
32-
scopes: List[String]): GHResponse[String] = ???
55+
scopes: List[String]): GHResponse[Authorize] = {
56+
val state = UUID.randomUUID().toString
57+
Xor.Right(
58+
GHItemResult(
59+
value = Authorize(authorizeUrl.format(client_id, redirect_uri, scopes.mkString(","), state), state),
60+
statusCode = 200,
61+
headers = Map.empty))
62+
}
63+
64+
65+
def getAccessToken(
66+
client_id: String,
67+
client_secret: String,
68+
code: String,
69+
redirect_uri: String,
70+
state: String): GHResponse[OAuthToken] = ???
71+
)
3372

3473

3574
}

src/main/scala/com/fortysevendeg/github4s/free/algebra/AuthOps.scala

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ package com.fortysevendeg.github4s.free.algebra
22

33
import cats.free.{Free, Inject}
44
import com.fortysevendeg.github4s.GithubResponses._
5-
import com.fortysevendeg.github4s.free.domain.Authorization
5+
import com.fortysevendeg.github4s.free.domain.{Authorize, Authorization}
66

77
/** Auths ops ADT
88
*/
99
sealed trait AuthOp[A]
10+
1011
final case class NewAuth(
1112
username: String,
1213
password: String,
@@ -15,6 +16,11 @@ final case class NewAuth(
1516
client_id: String,
1617
client_secret: String) extends AuthOp[GHResponse[Authorization]]
1718

19+
final case class AuthorizeUrl(
20+
client_id: String,
21+
redirect_uri: String,
22+
scopes: List[String]) extends AuthOp[GHResponse[Authorize]]
23+
1824

1925
/** Exposes Auths operations as a Free monadic algebra that may be combined with other Algebras via
2026
* Coproduct
@@ -30,6 +36,12 @@ class AuthOps[F[_]](implicit I: Inject[AuthOp, F]) {
3036
client_secret: String): Free[F, GHResponse[Authorization]] =
3137
Free.inject[AuthOp, F](NewAuth(username, password, scopes, note, client_id, client_secret))
3238

39+
def authorizeUrl(
40+
client_id: String,
41+
redirect_uri: String,
42+
scopes: List[String]): Free[F, GHResponse[Authorize]] =
43+
Free.inject[AuthOp, F](AuthorizeUrl(client_id, redirect_uri, scopes))
44+
3345
}
3446

3547
/** Default implicit based DI factory from which instances of the AuthOps may be obtained
Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
package com.fortysevendeg.github4s.free.domain
22

3-
case class Authorization (
3+
case class Authorization(
44
id: Int,
55
url: String,
6-
token: String)
6+
token: String)
7+
8+
case class NewAuthRequest(
9+
scopes: List[String],
10+
note: String,
11+
client_id: String,
12+
client_secret: String)
13+
14+
case class Authorize(
15+
url: String,
16+
state: String)
17+
18+
case class OAuthToken(
19+
access_token: String,
20+
token_type: String,
21+
scope: String)

src/main/scala/com/fortysevendeg/github4s/free/interpreters/Interpreters.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ trait Interpreters[M[_]] {
5050
def authOpsInterpreter(implicit A: ApplicativeError[M, Throwable], C : GithubConfig): AuthOp ~> M = new (AuthOp ~> M) {
5151
def apply[A](fa: AuthOp[A]): M[A] = fa match {
5252
case NewAuth(username, password, scopes, note, client_id, client_secret) A.pureEval(Eval.later(Auth.newAuth(username, password, scopes, note, client_id, client_secret)))
53+
case AuthorizeUrl(client_id, redirect_uri, scopes) => A.pureEval(Eval.later(Auth.authorizeUrl(client_id, redirect_uri, scopes)))
5354
}
5455
}
5556

0 commit comments

Comments
 (0)