{-# LANGUAGE QuasiQuotes #-}

-- | [Github build oauth applications guide](https://docs.github.com/en/developers/apps/building-oauth-apps)
module Network.OAuth2.Provider.GitHub where

import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.Trans.Except (ExceptT (..))
import Data.Aeson (FromJSON)
import Data.ByteString.Lazy.Char8 qualified as BSL
import Data.Map.Strict qualified as Map
import Data.Set qualified as Set
import Data.Text.Lazy (Text)
import GHC.Generics
import Network.HTTP.Conduit (Manager)
import Network.OAuth.OAuth2
import Network.OAuth2.Experiment
import Network.OAuth2.Provider
import URI.ByteString.QQ

sampleGithubAuthorizationCodeApp :: AuthorizationCodeApplication
sampleGithubAuthorizationCodeApp :: AuthorizationCodeApplication
sampleGithubAuthorizationCodeApp =
  AuthorizationCodeApplication
    { acClientId :: ClientId
acClientId = ClientId
""
    , acClientSecret :: ClientSecret
acClientSecret = ClientSecret
""
    , acScope :: Set Scope
acScope = forall a. Set a
Set.empty
    , acAuthorizeState :: AuthorizeState
acAuthorizeState = AuthorizeState
"CHANGE_ME"
    , acAuthorizeRequestExtraParams :: Map Text Text
acAuthorizeRequestExtraParams = forall k a. Map k a
Map.empty
    , acRedirectUri :: URI
acRedirectUri = [uri|http://localhost|]
    , acName :: Text
acName = Text
"sample-github-authorization-code-app"
    , acTokenRequestAuthenticationMethod :: ClientAuthenticationMethod
acTokenRequestAuthenticationMethod = ClientAuthenticationMethod
ClientSecretBasic
    }

fetchUserInfo ::
  (MonadIO m, HasUserInfoRequest a, FromJSON b) =>
  IdpApplication i a ->
  Manager ->
  AccessToken ->
  ExceptT BSL.ByteString m b
fetchUserInfo :: forall {k} (m :: * -> *) a b (i :: k).
(MonadIO m, HasUserInfoRequest a, FromJSON b) =>
IdpApplication i a
-> Manager -> AccessToken -> ExceptT ByteString m b
fetchUserInfo = forall {k} (m :: * -> *) a b (i :: k).
(MonadIO m, HasUserInfoRequest a, FromJSON b) =>
IdpApplication i a
-> Manager -> AccessToken -> ExceptT ByteString m b
conduitUserInfoRequest

defaultGithubIdp :: Idp GitHub
defaultGithubIdp :: Idp 'GitHub
defaultGithubIdp =
  Idp
    { idpUserInfoEndpoint :: URI
idpUserInfoEndpoint = [uri|https://api.github.com/user|]
    , idpAuthorizeEndpoint :: URI
idpAuthorizeEndpoint = [uri|https://github.com/login/oauth/authorize|]
    , idpTokenEndpoint :: URI
idpTokenEndpoint = [uri|https://github.com/login/oauth/access_token|]
    , idpDeviceAuthorizationEndpoint :: Maybe URI
idpDeviceAuthorizationEndpoint = forall a. a -> Maybe a
Just [uri|https://github.com/login/device/code|]
    }

data GitHubUser = GitHubUser
  { GitHubUser -> Text
name :: Text
  , GitHubUser -> Integer
id :: Integer
  }
  deriving (Int -> GitHubUser -> ShowS
[GitHubUser] -> ShowS
GitHubUser -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GitHubUser] -> ShowS
$cshowList :: [GitHubUser] -> ShowS
show :: GitHubUser -> String
$cshow :: GitHubUser -> String
showsPrec :: Int -> GitHubUser -> ShowS
$cshowsPrec :: Int -> GitHubUser -> ShowS
Show, forall x. Rep GitHubUser x -> GitHubUser
forall x. GitHubUser -> Rep GitHubUser x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep GitHubUser x -> GitHubUser
$cfrom :: forall x. GitHubUser -> Rep GitHubUser x
Generic)

instance FromJSON GitHubUser