-- | <http://strava.github.io/api/v3/oauth/>
module Strive.Actions.Authentication
  ( buildAuthorizeUrl,
    exchangeToken,
    deauthorize,
  )
where

import Data.ByteString.Char8 (unpack)
import Network.HTTP.Types (Query, renderQuery, toQuery)
import Strive.Aliases
  ( ApplicationId,
    ApplicationSecret,
    AuthorizationCode,
    RedirectUri,
    Result,
  )
import Strive.Client (Client, buildClient)
import Strive.Internal.HTTP (post)
import Strive.Options (BuildAuthorizeUrlOptions)
import Strive.Types (DeauthorizationResponse, TokenExchangeResponse)

-- | <http://strava.github.io/api/v3/oauth/#get-authorize>
buildAuthorizeUrl ::
  ApplicationId -> RedirectUri -> BuildAuthorizeUrlOptions -> String
buildAuthorizeUrl :: ApplicationId -> String -> BuildAuthorizeUrlOptions -> String
buildAuthorizeUrl ApplicationId
clientId String
redirectUri BuildAuthorizeUrlOptions
options =
  String
"https://www.strava.com/oauth/authorize" forall a. Semigroup a => a -> a -> a
<> ByteString -> String
unpack (Bool -> Query -> ByteString
renderQuery Bool
True Query
query)
  where
    query :: Query
query =
      forall a. QueryLike a => a -> Query
toQuery
        [ (String
"client_id", forall a. Show a => a -> String
show ApplicationId
clientId),
          (String
"redirect_uri", String
redirectUri),
          (String
"response_type", String
"code")
        ]
        forall a. Semigroup a => a -> a -> a
<> forall a. QueryLike a => a -> Query
toQuery BuildAuthorizeUrlOptions
options

-- | <http://strava.github.io/api/v3/oauth/#post-token>
exchangeToken ::
  ApplicationId ->
  ApplicationSecret ->
  AuthorizationCode ->
  IO (Result TokenExchangeResponse)
exchangeToken :: ApplicationId
-> String -> String -> IO (Result TokenExchangeResponse)
exchangeToken ApplicationId
clientId String
clientSecret String
code = do
  Client
client <- Maybe Text -> IO Client
buildClient forall a. Maybe a
Nothing
  forall q j.
(QueryLike q, FromJSON j) =>
Client -> String -> q -> IO (Result j)
post Client
client String
resource [(String, String)]
query
  where
    resource :: String
resource = String
"oauth/token"
    query :: [(String, String)]
query =
      [ (String
"client_id", forall a. Show a => a -> String
show ApplicationId
clientId),
        (String
"client_secret", String
clientSecret),
        (String
"code", String
code)
      ]

-- | <http://strava.github.io/api/v3/oauth/#deauthorize>
deauthorize :: Client -> IO (Result DeauthorizationResponse)
deauthorize :: Client -> IO (Result DeauthorizationResponse)
deauthorize Client
client = forall q j.
(QueryLike q, FromJSON j) =>
Client -> String -> q -> IO (Result j)
post Client
client String
resource Query
query
  where
    resource :: String
resource = String
"oauth/deauthorize"
    query :: Query
query = [] :: Query