{-# LANGUAGE QuasiQuotes #-}

-- | [ZOHO oauth overview](https://www.zoho.com/crm/developer/docs/api/v2/oauth-overview.html)
module Network.OAuth2.Provider.ZOHO where

import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.Trans.Except (ExceptT (..))
import Data.Aeson
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

sampleZohoAuthorizationCodeApp :: AuthorizationCodeApplication
sampleZohoAuthorizationCodeApp :: AuthorizationCodeApplication
sampleZohoAuthorizationCodeApp =
  AuthorizationCodeApplication
    { acClientId :: ClientId
acClientId = ClientId
""
    , acClientSecret :: ClientSecret
acClientSecret = ClientSecret
""
    , acScope :: Set Scope
acScope = [Scope] -> Set Scope
forall a. Ord a => [a] -> Set a
Set.fromList [Scope
"ZohoCRM.users.READ"]
    , acAuthorizeRequestExtraParams :: Map Text Text
acAuthorizeRequestExtraParams = [(Text, Text)] -> Map Text Text
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Text
"access_type", Text
"offline"), (Text
"prompt", Text
"consent")]
    , acAuthorizeState :: AuthorizeState
acAuthorizeState = AuthorizeState
"CHANGE_ME"
    , acRedirectUri :: URI
acRedirectUri = [uri|http://localhost/oauth2/callback|]
    , acName :: Text
acName = Text
"sample-zoho-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 = IdpApplication i a
-> Manager -> AccessToken -> ExceptT ByteString m b
forall {k} (m :: * -> *) a b (i :: k).
(MonadIO m, HasUserInfoRequest a, FromJSON b) =>
IdpApplication i a
-> Manager -> AccessToken -> ExceptT ByteString m b
conduitUserInfoRequest

defaultZohoIdp :: Idp ZOHO
defaultZohoIdp :: Idp 'ZOHO
defaultZohoIdp =
  Idp
    { idpUserInfoEndpoint :: URI
idpUserInfoEndpoint = [uri|https://www.zohoapis.com/crm/v2/users|]
    , idpAuthorizeEndpoint :: URI
idpAuthorizeEndpoint = [uri|https://accounts.zoho.com/oauth/v2/auth|]
    , idpTokenEndpoint :: URI
idpTokenEndpoint = [uri|https://accounts.zoho.com/oauth/v2/token|]
    , idpDeviceAuthorizationEndpoint :: Maybe URI
idpDeviceAuthorizationEndpoint = Maybe URI
forall a. Maybe a
Nothing
    }

-- `oauth/user/info` url does not work and find answer from
-- https://help.zoho.com/portal/community/topic/oauth2-api-better-document-oauth-user-info
data ZOHOUser = ZOHOUser
  { ZOHOUser -> Text
email :: Text
  , ZOHOUser -> Text
fullName :: Text
  }
  deriving (Int -> ZOHOUser -> ShowS
[ZOHOUser] -> ShowS
ZOHOUser -> String
(Int -> ZOHOUser -> ShowS)
-> (ZOHOUser -> String) -> ([ZOHOUser] -> ShowS) -> Show ZOHOUser
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ZOHOUser -> ShowS
showsPrec :: Int -> ZOHOUser -> ShowS
$cshow :: ZOHOUser -> String
show :: ZOHOUser -> String
$cshowList :: [ZOHOUser] -> ShowS
showList :: [ZOHOUser] -> ShowS
Show, (forall x. ZOHOUser -> Rep ZOHOUser x)
-> (forall x. Rep ZOHOUser x -> ZOHOUser) -> Generic ZOHOUser
forall x. Rep ZOHOUser x -> ZOHOUser
forall x. ZOHOUser -> Rep ZOHOUser x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ZOHOUser -> Rep ZOHOUser x
from :: forall x. ZOHOUser -> Rep ZOHOUser x
$cto :: forall x. Rep ZOHOUser x -> ZOHOUser
to :: forall x. Rep ZOHOUser x -> ZOHOUser
Generic)

newtype ZOHOUserResp = ZOHOUserResp {ZOHOUserResp -> [ZOHOUser]
users :: [ZOHOUser]}
  deriving (Int -> ZOHOUserResp -> ShowS
[ZOHOUserResp] -> ShowS
ZOHOUserResp -> String
(Int -> ZOHOUserResp -> ShowS)
-> (ZOHOUserResp -> String)
-> ([ZOHOUserResp] -> ShowS)
-> Show ZOHOUserResp
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ZOHOUserResp -> ShowS
showsPrec :: Int -> ZOHOUserResp -> ShowS
$cshow :: ZOHOUserResp -> String
show :: ZOHOUserResp -> String
$cshowList :: [ZOHOUserResp] -> ShowS
showList :: [ZOHOUserResp] -> ShowS
Show, (forall x. ZOHOUserResp -> Rep ZOHOUserResp x)
-> (forall x. Rep ZOHOUserResp x -> ZOHOUserResp)
-> Generic ZOHOUserResp
forall x. Rep ZOHOUserResp x -> ZOHOUserResp
forall x. ZOHOUserResp -> Rep ZOHOUserResp x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ZOHOUserResp -> Rep ZOHOUserResp x
from :: forall x. ZOHOUserResp -> Rep ZOHOUserResp x
$cto :: forall x. Rep ZOHOUserResp x -> ZOHOUserResp
to :: forall x. Rep ZOHOUserResp x -> ZOHOUserResp
Generic)

instance FromJSON ZOHOUserResp

instance FromJSON ZOHOUser where
  parseJSON :: Value -> Parser ZOHOUser
parseJSON = Options -> Value -> Parser ZOHOUser
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions {fieldLabelModifier = camelTo2 '_'}