From d0b2131519a0bc296737db158730b0102539aefe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20V=C3=A1zquez?= Date: Sun, 15 Oct 2017 20:15:11 +0200 Subject: [PATCH] wip gitlab: get access token --- core/src/main/scala/Gitlab.scala | 46 +++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/core/src/main/scala/Gitlab.scala b/core/src/main/scala/Gitlab.scala index 8f82e38a..7a6f5e56 100644 --- a/core/src/main/scala/Gitlab.scala +++ b/core/src/main/scala/Gitlab.scala @@ -1,28 +1,39 @@ package nelson -import argonaut.Argonaut.casecodec4 +import argonaut.Argonaut.{ casecodec1, casecodec4 } import argonaut.{CodecJson, DecodeJson, EncodeJson} import nelson.Github._ import org.http4s +import org.http4s._ import org.http4s.argonaut._ -import org.http4s.{EntityDecoder, Header, Headers, Uri} import org.http4s.client.Client +import org.http4s.headers.Authorization import scalaz.concurrent.Task import scalaz.~> -import java.net.URI +import java.net.{ MalformedURLException, URI } object Gitlab { final class GitlabHttp(cfg: GitlabConfig, http4sClient: Client) extends (GithubOp ~> Task) { def apply[A](in: GithubOp[A]): Task[A] = in match { - case GetAccessToken(fromCode: String) => ??? - case GetUser(token: AccessToken) => - Uri.fromString(cfg.userEndpoint).map { uri => + case GetAccessToken(fromCode: String) => + fetch[AccessToken](cfg.tokenEndpoint) { uri => http4s.Request( - headers = Headers(Header(cfg.headers.PrivateToken, token.value)), - uri = uri + Method.POST, + uri + .withQueryParam("client_id", cfg.clientId) + .withQueryParam("client_secret", cfg.clientSecret) + .withQueryParam("code", fromCode) + .withQueryParam("grant_type", "authorization_code") + .withQueryParam("redirect_uri", cfg.redirectUri) ) - }.fold(t => Task.fail(new Exception(t.message)), http4sClient.expect[Github.User]) + } + case GetUser(token: AccessToken) => + fetch[Github.User](cfg.userEndpoint) { uri => + http4s.Request( + headers = Headers(Authorization(OAuth2BearerToken(token.value))), + uri = uri) + } case GetUserOrgKeys(token: AccessToken) => ??? case GetOrganizations(keys: List[Github.OrgKey], t: AccessToken) => ??? case GetReleaseAssetContent(asset: Github.Asset, t: AccessToken) => ??? @@ -33,14 +44,20 @@ object Gitlab { case PostRepoWebHook(slug: Slug, hook: Github.WebHook, t: AccessToken) => ??? case DeleteRepoWebHook(slug: Slug, id: Long, t: AccessToken) => ??? } + + private[this] def fetch[A: EntityDecoder](uri: String)(f: Uri => Request): Task[A] = + Uri.fromString(uri).map(f).fold(t => Task.fail(new MalformedURLException(t.message)), http4sClient.expect[A]) } - final case class GitlabConfig(domain: String) { + final case class GitlabConfig( + domain: String, + clientId: String, + clientSecret: String, + redirectUri: String) { val api = s"https://$domain/api/v4" + val oauth = s"https://$domain/oauth" + val tokenEndpoint = s"$oauth/token" val userEndpoint = s"$api/user" - object headers { - final val PrivateToken = "PRIVATE-TOKEN" - } } implicit def genericEntityDecoder[A: DecodeJson]: EntityDecoder[A] = jsonOf[A] @@ -49,6 +66,9 @@ object Gitlab { casecodec4(Github.User.apply, Github.User.unapply )("username", "avatar_url", "name", "email") + implicit lazy val AccessTokenCodec: CodecJson[AccessToken] = + casecodec1(AccessToken.apply, AccessToken.unapply)("access_token") + implicit lazy val UriToJson: EncodeJson[URI] = implicitly[EncodeJson[String]].contramap(_.toString)