module Env where import Control.Monad.IO.Class import Control.Monad.Trans.Except import Data.Aeson import Data.Aeson.Key qualified as Aeson import Data.Aeson.KeyMap qualified as Aeson import Data.Maybe import Data.Set qualified as Set import Data.Text.Lazy (Text) import Data.Text.Lazy qualified as TL import GHC.Generics import Network.OAuth2.Experiment import System.Directory newtype OAuthAppSettings = OAuthAppSettings (Aeson.KeyMap OAuthAppSetting) deriving (Generic) instance FromJSON OAuthAppSettings data OAuthAppSetting = OAuthAppSetting { clientId :: ClientId , clientSecret :: ClientSecret , scopes :: Set.Set Scope , user :: Maybe UserConfig } instance FromJSON OAuthAppSetting where parseJSON = withObject "parseJSON OAuthAppSetting" $ \t -> do clientId <- ClientId <$> t .: "client_id" clientSecret <- ClientSecret <$> t .: "client_secret" scopeTexts <- t .:? "scopes" user <- t .:? "user" let scopes = Set.map Scope (Set.fromList (fromMaybe [] scopeTexts)) pure OAuthAppSetting {..} data UserConfig = UserConfig { username :: Text , password :: Text } deriving (Generic) instance FromJSON UserConfig envFilePath :: String envFilePath = ".env.json" readEnvFile :: MonadIO m => ExceptT Text m OAuthAppSettings readEnvFile = do withExceptT wrapError $ ExceptT $ liftIO $ do pwd <- liftIO getCurrentDirectory eitherDecodeFileStrict (pwd <> "/" <> envFilePath) where wrapError :: String -> Text wrapError = TL.pack . ("Error when try to load .env.json\n" <>) lookup :: MonadIO m => Text -> ExceptT Text m OAuthAppSetting lookup idpAppName = do envs <- readEnvFile lookupWith envs idpAppName lookupWith :: MonadIO m => OAuthAppSettings -> Text -> ExceptT Text m OAuthAppSetting lookupWith (OAuthAppSettings val) idpAppName = do let key = TL.toLower idpAppName resp = Aeson.lookup (Aeson.fromString $ TL.unpack key) val except $ maybe (Left $ "[ Env.lookupWith ] Unable to load config for " <> key) Right resp