module Tonatona.Google
( run
, Dsl
, DslBackend
, Config
, ServantError
, JWT
, JWT.Scope(..)
) where
import Tonalude
import qualified Google.Client as Client
import qualified Google.Form as Form
import Google.JWT (JWT)
import qualified Google.JWT as JWT
import Google.Response (Token)
import qualified Google.Response as Response
import Servant.Client (ServantError)
import Tonatona (HasConfig(..), HasParser(..))
import TonaParser (Parser, (.||), argLong, envVar, liftWith, requiredVal)
import Tonatona.Google.Internal
run ::
(HasConfig env Config)
=> (ServantError -> RIO env a)
-> [JWT.Scope]
-> Dsl env a
-> RIO env a
run errorHandler scopes query = do
Config {..} <- asks config
eToken <- liftIO $ Client.getToken (Just delegationEmail) jwt scopes
case eToken of
Left err -> errorHandler err
Right token ->
runReaderT query (DslBackend token) `catch` errorHandler
data Config = Config
{ serviceKeyFile :: ServiceKeyFile
, jwt :: JWT
, delegationEmail :: JWT.Email
}
newtype ServiceKeyFile = ServiceKeyFile { unServiceKeyFile :: FilePath }
deriving (Eq, Read, Show)
instance HasParser ServiceKeyFile where
parser = ServiceKeyFile <$>
requiredVal
"File path to service key file (Example: \"gmail-3abc452de.json\")"
( argLong "service-key-file" .|| envVar "SERVICE_KEY_FILE")
parseJwt :: ServiceKeyFile -> Parser JWT
parseJwt (ServiceKeyFile fp) = do
mjwt <- liftIO $ JWT.readServiceKeyFile fp
case mjwt of
Nothing ->
error $ "Failed to parse service key file: " <> fp
Just jwt ->
pure jwt
parseEmail :: Parser JWT.Email
parseEmail = JWT.Email <$>
requiredVal
"Email account to use for delegation."
( argLong "delegation-email" .|| envVar "DELEGATION_EMAIL")
instance HasParser Config where
parser = do
keyFile <- parser
Config
<$> pure keyFile
<*> parseJwt keyFile
<*> parseEmail