{-# LANGUAGE DataKinds                  #-}
{-# LANGUAGE DeriveAnyClass             #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE KindSignatures             #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE ScopedTypeVariables        #-}

module Auth.Types
  ( addUserAgent
  , OAuthCode(OAuthCode)
  , OAuthToken(..)
  , TokenProvider(..)
  , Token(..)
  , OAuthClientId(..)
  , OAuthClientSecret(..)
  ) where

import Control.Newtype.Generics (Newtype)
import Data.Aeson (FromJSON, ToJSON, genericParseJSON, parseJSON)
import Data.Aeson.Casing (aesonDrop, snakeCase)
import Data.Text (Text)
import GHC.Generics (Generic)
import Network.HTTP.Conduit (Request)
import Network.HTTP.Simple (addRequestHeader)
import Network.HTTP.Types (hUserAgent)
import Servant (FromHttpApiData, ToHttpApiData, parseQueryParam, toUrlPiece)

------------------------------------------------------------
newtype OAuthCode =
  OAuthCode Text
  deriving stock (Int -> OAuthCode -> ShowS
[OAuthCode] -> ShowS
OAuthCode -> String
(Int -> OAuthCode -> ShowS)
-> (OAuthCode -> String)
-> ([OAuthCode] -> ShowS)
-> Show OAuthCode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OAuthCode] -> ShowS
$cshowList :: [OAuthCode] -> ShowS
show :: OAuthCode -> String
$cshow :: OAuthCode -> String
showsPrec :: Int -> OAuthCode -> ShowS
$cshowsPrec :: Int -> OAuthCode -> ShowS
Show, OAuthCode -> OAuthCode -> Bool
(OAuthCode -> OAuthCode -> Bool)
-> (OAuthCode -> OAuthCode -> Bool) -> Eq OAuthCode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OAuthCode -> OAuthCode -> Bool
$c/= :: OAuthCode -> OAuthCode -> Bool
== :: OAuthCode -> OAuthCode -> Bool
$c== :: OAuthCode -> OAuthCode -> Bool
Eq, (forall x. OAuthCode -> Rep OAuthCode x)
-> (forall x. Rep OAuthCode x -> OAuthCode) -> Generic OAuthCode
forall x. Rep OAuthCode x -> OAuthCode
forall x. OAuthCode -> Rep OAuthCode x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep OAuthCode x -> OAuthCode
$cfrom :: forall x. OAuthCode -> Rep OAuthCode x
Generic)
  deriving anyclass (O OAuthCode -> OAuthCode
OAuthCode -> O OAuthCode
(O OAuthCode -> OAuthCode)
-> (OAuthCode -> O OAuthCode) -> Newtype OAuthCode
forall n. (O n -> n) -> (n -> O n) -> Newtype n
unpack :: OAuthCode -> O OAuthCode
$cunpack :: OAuthCode -> O OAuthCode
pack :: O OAuthCode -> OAuthCode
$cpack :: O OAuthCode -> OAuthCode
Newtype)

instance FromHttpApiData OAuthCode where
  parseQueryParam :: Text -> Either Text OAuthCode
parseQueryParam = OAuthCode -> Either Text OAuthCode
forall a b. b -> Either a b
Right (OAuthCode -> Either Text OAuthCode)
-> (Text -> OAuthCode) -> Text -> Either Text OAuthCode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> OAuthCode
OAuthCode

data OAuthToken a = OAuthToken
  { OAuthToken a -> Token a
oAuthTokenAccessToken :: !(Token a)
  , OAuthToken a -> Text
oAuthTokenScope       :: !Text
  , OAuthToken a -> Text
oAuthTokenTokenType   :: !Text
  } deriving (Int -> OAuthToken a -> ShowS
[OAuthToken a] -> ShowS
OAuthToken a -> String
(Int -> OAuthToken a -> ShowS)
-> (OAuthToken a -> String)
-> ([OAuthToken a] -> ShowS)
-> Show (OAuthToken a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (a :: TokenProvider). Int -> OAuthToken a -> ShowS
forall (a :: TokenProvider). [OAuthToken a] -> ShowS
forall (a :: TokenProvider). OAuthToken a -> String
showList :: [OAuthToken a] -> ShowS
$cshowList :: forall (a :: TokenProvider). [OAuthToken a] -> ShowS
show :: OAuthToken a -> String
$cshow :: forall (a :: TokenProvider). OAuthToken a -> String
showsPrec :: Int -> OAuthToken a -> ShowS
$cshowsPrec :: forall (a :: TokenProvider). Int -> OAuthToken a -> ShowS
Show, OAuthToken a -> OAuthToken a -> Bool
(OAuthToken a -> OAuthToken a -> Bool)
-> (OAuthToken a -> OAuthToken a -> Bool) -> Eq (OAuthToken a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (a :: TokenProvider). OAuthToken a -> OAuthToken a -> Bool
/= :: OAuthToken a -> OAuthToken a -> Bool
$c/= :: forall (a :: TokenProvider). OAuthToken a -> OAuthToken a -> Bool
== :: OAuthToken a -> OAuthToken a -> Bool
$c== :: forall (a :: TokenProvider). OAuthToken a -> OAuthToken a -> Bool
Eq, (forall x. OAuthToken a -> Rep (OAuthToken a) x)
-> (forall x. Rep (OAuthToken a) x -> OAuthToken a)
-> Generic (OAuthToken a)
forall x. Rep (OAuthToken a) x -> OAuthToken a
forall x. OAuthToken a -> Rep (OAuthToken a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (a :: TokenProvider) x. Rep (OAuthToken a) x -> OAuthToken a
forall (a :: TokenProvider) x. OAuthToken a -> Rep (OAuthToken a) x
$cto :: forall (a :: TokenProvider) x. Rep (OAuthToken a) x -> OAuthToken a
$cfrom :: forall (a :: TokenProvider) x. OAuthToken a -> Rep (OAuthToken a) x
Generic)

-- | We use the default JSON encoding for sending-to-PureScript's
-- sake, but a custom one for receiving-from-Github.
instance ToJSON (OAuthToken a)

instance FromJSON (OAuthToken a) where
  parseJSON :: Value -> Parser (OAuthToken a)
parseJSON = Options -> Value -> Parser (OAuthToken a)
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON (Options -> Value -> Parser (OAuthToken a))
-> Options -> Value -> Parser (OAuthToken a)
forall a b. (a -> b) -> a -> b
$ Int -> ShowS -> Options
aesonDrop Int
10 ShowS
snakeCase

------------------------------------------------------------
data TokenProvider =
  Github

newtype Token (a :: TokenProvider) =
  Token Text
  deriving stock (Int -> Token a -> ShowS
[Token a] -> ShowS
Token a -> String
(Int -> Token a -> ShowS)
-> (Token a -> String) -> ([Token a] -> ShowS) -> Show (Token a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (a :: TokenProvider). Int -> Token a -> ShowS
forall (a :: TokenProvider). [Token a] -> ShowS
forall (a :: TokenProvider). Token a -> String
showList :: [Token a] -> ShowS
$cshowList :: forall (a :: TokenProvider). [Token a] -> ShowS
show :: Token a -> String
$cshow :: forall (a :: TokenProvider). Token a -> String
showsPrec :: Int -> Token a -> ShowS
$cshowsPrec :: forall (a :: TokenProvider). Int -> Token a -> ShowS
Show, Token a -> Token a -> Bool
(Token a -> Token a -> Bool)
-> (Token a -> Token a -> Bool) -> Eq (Token a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (a :: TokenProvider). Token a -> Token a -> Bool
/= :: Token a -> Token a -> Bool
$c/= :: forall (a :: TokenProvider). Token a -> Token a -> Bool
== :: Token a -> Token a -> Bool
$c== :: forall (a :: TokenProvider). Token a -> Token a -> Bool
Eq, (forall x. Token a -> Rep (Token a) x)
-> (forall x. Rep (Token a) x -> Token a) -> Generic (Token a)
forall x. Rep (Token a) x -> Token a
forall x. Token a -> Rep (Token a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (a :: TokenProvider) x. Rep (Token a) x -> Token a
forall (a :: TokenProvider) x. Token a -> Rep (Token a) x
$cto :: forall (a :: TokenProvider) x. Rep (Token a) x -> Token a
$cfrom :: forall (a :: TokenProvider) x. Token a -> Rep (Token a) x
Generic)
  deriving newtype (Value -> Parser [Token a]
Value -> Parser (Token a)
(Value -> Parser (Token a))
-> (Value -> Parser [Token a]) -> FromJSON (Token a)
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
forall (a :: TokenProvider). Value -> Parser [Token a]
forall (a :: TokenProvider). Value -> Parser (Token a)
parseJSONList :: Value -> Parser [Token a]
$cparseJSONList :: forall (a :: TokenProvider). Value -> Parser [Token a]
parseJSON :: Value -> Parser (Token a)
$cparseJSON :: forall (a :: TokenProvider). Value -> Parser (Token a)
FromJSON,[Token a] -> Encoding
[Token a] -> Value
Token a -> Encoding
Token a -> Value
(Token a -> Value)
-> (Token a -> Encoding)
-> ([Token a] -> Value)
-> ([Token a] -> Encoding)
-> ToJSON (Token a)
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
forall (a :: TokenProvider). [Token a] -> Encoding
forall (a :: TokenProvider). [Token a] -> Value
forall (a :: TokenProvider). Token a -> Encoding
forall (a :: TokenProvider). Token a -> Value
toEncodingList :: [Token a] -> Encoding
$ctoEncodingList :: forall (a :: TokenProvider). [Token a] -> Encoding
toJSONList :: [Token a] -> Value
$ctoJSONList :: forall (a :: TokenProvider). [Token a] -> Value
toEncoding :: Token a -> Encoding
$ctoEncoding :: forall (a :: TokenProvider). Token a -> Encoding
toJSON :: Token a -> Value
$ctoJSON :: forall (a :: TokenProvider). Token a -> Value
ToJSON)
  deriving anyclass (O (Token a) -> Token a
Token a -> O (Token a)
(O (Token a) -> Token a)
-> (Token a -> O (Token a)) -> Newtype (Token a)
forall n. (O n -> n) -> (n -> O n) -> Newtype n
forall (a :: TokenProvider). O (Token a) -> Token a
forall (a :: TokenProvider). Token a -> O (Token a)
unpack :: Token a -> O (Token a)
$cunpack :: forall (a :: TokenProvider). Token a -> O (Token a)
pack :: O (Token a) -> Token a
$cpack :: forall (a :: TokenProvider). O (Token a) -> Token a
Newtype)

instance ToHttpApiData (Token a) where
  toUrlPiece :: Token a -> Text
toUrlPiece (Token Text
token) = Text
"token " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
token

addUserAgent :: Request -> Request
addUserAgent :: Request -> Request
addUserAgent = HeaderName -> ByteString -> Request -> Request
addRequestHeader HeaderName
hUserAgent ByteString
"haskell-conduit"

newtype OAuthClientId = OAuthClientId Text
  deriving stock (Int -> OAuthClientId -> ShowS
[OAuthClientId] -> ShowS
OAuthClientId -> String
(Int -> OAuthClientId -> ShowS)
-> (OAuthClientId -> String)
-> ([OAuthClientId] -> ShowS)
-> Show OAuthClientId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OAuthClientId] -> ShowS
$cshowList :: [OAuthClientId] -> ShowS
show :: OAuthClientId -> String
$cshow :: OAuthClientId -> String
showsPrec :: Int -> OAuthClientId -> ShowS
$cshowsPrec :: Int -> OAuthClientId -> ShowS
Show, OAuthClientId -> OAuthClientId -> Bool
(OAuthClientId -> OAuthClientId -> Bool)
-> (OAuthClientId -> OAuthClientId -> Bool) -> Eq OAuthClientId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OAuthClientId -> OAuthClientId -> Bool
$c/= :: OAuthClientId -> OAuthClientId -> Bool
== :: OAuthClientId -> OAuthClientId -> Bool
$c== :: OAuthClientId -> OAuthClientId -> Bool
Eq, (forall x. OAuthClientId -> Rep OAuthClientId x)
-> (forall x. Rep OAuthClientId x -> OAuthClientId)
-> Generic OAuthClientId
forall x. Rep OAuthClientId x -> OAuthClientId
forall x. OAuthClientId -> Rep OAuthClientId x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep OAuthClientId x -> OAuthClientId
$cfrom :: forall x. OAuthClientId -> Rep OAuthClientId x
Generic)
  deriving newtype (Value -> Parser [OAuthClientId]
Value -> Parser OAuthClientId
(Value -> Parser OAuthClientId)
-> (Value -> Parser [OAuthClientId]) -> FromJSON OAuthClientId
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [OAuthClientId]
$cparseJSONList :: Value -> Parser [OAuthClientId]
parseJSON :: Value -> Parser OAuthClientId
$cparseJSON :: Value -> Parser OAuthClientId
FromJSON,[OAuthClientId] -> Encoding
[OAuthClientId] -> Value
OAuthClientId -> Encoding
OAuthClientId -> Value
(OAuthClientId -> Value)
-> (OAuthClientId -> Encoding)
-> ([OAuthClientId] -> Value)
-> ([OAuthClientId] -> Encoding)
-> ToJSON OAuthClientId
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [OAuthClientId] -> Encoding
$ctoEncodingList :: [OAuthClientId] -> Encoding
toJSONList :: [OAuthClientId] -> Value
$ctoJSONList :: [OAuthClientId] -> Value
toEncoding :: OAuthClientId -> Encoding
$ctoEncoding :: OAuthClientId -> Encoding
toJSON :: OAuthClientId -> Value
$ctoJSON :: OAuthClientId -> Value
ToJSON)
  deriving anyclass (O OAuthClientId -> OAuthClientId
OAuthClientId -> O OAuthClientId
(O OAuthClientId -> OAuthClientId)
-> (OAuthClientId -> O OAuthClientId) -> Newtype OAuthClientId
forall n. (O n -> n) -> (n -> O n) -> Newtype n
unpack :: OAuthClientId -> O OAuthClientId
$cunpack :: OAuthClientId -> O OAuthClientId
pack :: O OAuthClientId -> OAuthClientId
$cpack :: O OAuthClientId -> OAuthClientId
Newtype)

newtype OAuthClientSecret = OAuthClientSecret Text
  deriving stock (Int -> OAuthClientSecret -> ShowS
[OAuthClientSecret] -> ShowS
OAuthClientSecret -> String
(Int -> OAuthClientSecret -> ShowS)
-> (OAuthClientSecret -> String)
-> ([OAuthClientSecret] -> ShowS)
-> Show OAuthClientSecret
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OAuthClientSecret] -> ShowS
$cshowList :: [OAuthClientSecret] -> ShowS
show :: OAuthClientSecret -> String
$cshow :: OAuthClientSecret -> String
showsPrec :: Int -> OAuthClientSecret -> ShowS
$cshowsPrec :: Int -> OAuthClientSecret -> ShowS
Show, OAuthClientSecret -> OAuthClientSecret -> Bool
(OAuthClientSecret -> OAuthClientSecret -> Bool)
-> (OAuthClientSecret -> OAuthClientSecret -> Bool)
-> Eq OAuthClientSecret
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OAuthClientSecret -> OAuthClientSecret -> Bool
$c/= :: OAuthClientSecret -> OAuthClientSecret -> Bool
== :: OAuthClientSecret -> OAuthClientSecret -> Bool
$c== :: OAuthClientSecret -> OAuthClientSecret -> Bool
Eq, (forall x. OAuthClientSecret -> Rep OAuthClientSecret x)
-> (forall x. Rep OAuthClientSecret x -> OAuthClientSecret)
-> Generic OAuthClientSecret
forall x. Rep OAuthClientSecret x -> OAuthClientSecret
forall x. OAuthClientSecret -> Rep OAuthClientSecret x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep OAuthClientSecret x -> OAuthClientSecret
$cfrom :: forall x. OAuthClientSecret -> Rep OAuthClientSecret x
Generic)
  deriving newtype (Value -> Parser [OAuthClientSecret]
Value -> Parser OAuthClientSecret
(Value -> Parser OAuthClientSecret)
-> (Value -> Parser [OAuthClientSecret])
-> FromJSON OAuthClientSecret
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [OAuthClientSecret]
$cparseJSONList :: Value -> Parser [OAuthClientSecret]
parseJSON :: Value -> Parser OAuthClientSecret
$cparseJSON :: Value -> Parser OAuthClientSecret
FromJSON,[OAuthClientSecret] -> Encoding
[OAuthClientSecret] -> Value
OAuthClientSecret -> Encoding
OAuthClientSecret -> Value
(OAuthClientSecret -> Value)
-> (OAuthClientSecret -> Encoding)
-> ([OAuthClientSecret] -> Value)
-> ([OAuthClientSecret] -> Encoding)
-> ToJSON OAuthClientSecret
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [OAuthClientSecret] -> Encoding
$ctoEncodingList :: [OAuthClientSecret] -> Encoding
toJSONList :: [OAuthClientSecret] -> Value
$ctoJSONList :: [OAuthClientSecret] -> Value
toEncoding :: OAuthClientSecret -> Encoding
$ctoEncoding :: OAuthClientSecret -> Encoding
toJSON :: OAuthClientSecret -> Value
$ctoJSON :: OAuthClientSecret -> Value
ToJSON)
  deriving anyclass (O OAuthClientSecret -> OAuthClientSecret
OAuthClientSecret -> O OAuthClientSecret
(O OAuthClientSecret -> OAuthClientSecret)
-> (OAuthClientSecret -> O OAuthClientSecret)
-> Newtype OAuthClientSecret
forall n. (O n -> n) -> (n -> O n) -> Newtype n
unpack :: OAuthClientSecret -> O OAuthClientSecret
$cunpack :: OAuthClientSecret -> O OAuthClientSecret
pack :: O OAuthClientSecret -> OAuthClientSecret
$cpack :: O OAuthClientSecret -> OAuthClientSecret
Newtype)