diff --git a/.gitignore b/.gitignore index ebea556fe..d4d62d436 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.envrc *.db *.sqlite3 !populate.sqlite3 diff --git a/shell.nix b/shell.nix index 8c948e9cb..bd31438b1 100644 --- a/shell.nix +++ b/shell.nix @@ -10,6 +10,7 @@ in pkgs.mkShell { hpkgs.warp hpkgs.cryptonite hpkgs.uuid + hpkgs.envy ])) ]; } diff --git a/src/App.hs b/src/App.hs index 708dd896f..7536e3c77 100644 --- a/src/App.hs +++ b/src/App.hs @@ -37,15 +37,15 @@ err429 = ServerError , errHeaders = [] } -server :: FilePath -> Server API -server dbFile = createAccount - :<|> deleteAccount - :<|> listAccounts - :<|> createTrip - :<|> deleteTrip - :<|> listTrips - :<|> login - :<|> logout +server :: T.Config -> Server API +server T.Config{..} = createAccount + :<|> deleteAccount + :<|> listAccounts + :<|> createTrip + :<|> deleteTrip + :<|> listTrips + :<|> login + :<|> logout where -- Admit Admins + whatever the predicate `p` passes. adminsAnd cookie p = Auth.assert dbFile cookie (\acct@T.Account{..} -> accountRole == T.Admin || p acct) @@ -124,6 +124,6 @@ server dbFile = createAccount liftIO $ Sessions.delete dbFile uuid pure $ addHeader Auth.emptyCookie NoContent -run :: FilePath -> IO () -run dbFile = - Warp.run 3000 (serve (Proxy @ API) $ server dbFile) +run :: T.Config -> IO () +run config = + Warp.run 3000 (serve (Proxy @ API) $ server config) diff --git a/src/Main.hs b/src/Main.hs index de40b3225..9df423206 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,7 +1,13 @@ +-------------------------------------------------------------------------------- module Main where -------------------------------------------------------------------------------- import qualified App +import qualified System.Envy as Envy -------------------------------------------------------------------------------- main :: IO () -main = App.run "../db.sqlite3" +main = do + mEnv <- Envy.decodeEnv + case mEnv of + Left err -> putStrLn err + Right env -> App.run env diff --git a/src/Types.hs b/src/Types.hs index eed9bf8c1..135c50f17 100644 --- a/src/Types.hs +++ b/src/Types.hs @@ -16,6 +16,7 @@ import Database.SQLite.Simple.ToField import GHC.Generics import Web.Cookie import Servant.API +import System.Envy (FromEnv, fromEnv, env) import Crypto.Random.Types (MonadRandom) import qualified Crypto.KDF.BCrypt as BC @@ -26,6 +27,17 @@ import qualified Data.Text.Encoding as TE import qualified Data.UUID as UUID -------------------------------------------------------------------------------- +-- | Top-level application configuration. +data Config = Config + { mailgunAPIKey :: Text + , dbFile :: FilePath + } deriving (Eq, Show) + +instance FromEnv Config where + fromEnv _ = + Config <$> env "MAILGUN_API_KEY" + <*> env "DB_FILE" + -- TODO(wpcarro): Properly handle NULL for columns like profilePicture. forNewtype :: (Typeable b) => (Text -> b) -> FieldParser b forNewtype wrapper field =