{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
module GoPro.Plus.Auth (
authenticate, refreshAuth,
AuthInfo(..), access_token, expires_in, refresh_token, resource_owner_id,
HasGoProAuth(..), withAuth, AuthReader, Token
) where
import Control.Lens
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.Reader (ReaderT (..), ask, runReaderT)
import Data.Aeson (FromJSON (..), genericParseJSON)
import Data.Text (Text)
import Generics.Deriving.Base (Generic)
import Network.Wreq (FormParam (..))
import GoPro.Plus.Internal.HTTP
apiClientID, apiClientSecret :: String
apiClientID = "71611e67ea968cfacf45e2b6936c81156fcf5dbe553a2bf2d342da1562d05f46"
apiClientSecret = "3863c9b438c07b82f39ab3eeeef9c24fefa50c6856253e3f1d37e0e3b1ead68d"
authURL :: String
authURL = "https://api.gopro.com/v1/oauth2/token"
type Token = Text
data AuthInfo = AuthInfo {
_access_token :: Token
, _expires_in :: Int
, _refresh_token :: Text
, _resource_owner_id :: Text
} deriving(Generic, Show)
class Monad m => HasGoProAuth m where
goproAuth :: m AuthInfo
instance FromJSON AuthInfo where
parseJSON = genericParseJSON jsonOpts
makeLenses ''AuthInfo
authenticate :: MonadIO m
=> String
-> String
-> m AuthInfo
authenticate username password =
jpostWith defOpts authURL ["grant_type" := ("password" :: String),
"client_id" := apiClientID,
"client_secret" := apiClientSecret,
"scope" := ("root root:channels public me upload media_library_beta live" :: String),
"username" := username,
"password" := password]
refreshAuth :: MonadIO m => AuthInfo -> m AuthInfo
refreshAuth AuthInfo{..} =
jpostWith defOpts authURL ["grant_type" := ("refresh_token" :: String),
"client_id" := apiClientID,
"client_secret" := apiClientSecret,
"refresh_token" := _refresh_token]
type AuthReader = ReaderT AuthInfo
instance Monad m => HasGoProAuth (AuthReader m) where
goproAuth = ask
withAuth :: AuthInfo -> AuthReader m a -> m a
withAuth = flip runReaderT