about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2020-07-30T12·58+0100
committerWilliam Carroll <wpcarro@gmail.com>2020-07-30T12·58+0100
commitb6e8389edd486d407025383825a1beaf6b7f63b7 (patch)
treeb38c6fd1231bce0548be7557f2e509cea84b66c1
parent385164c6afea7995b797cf8ddddefa187c26f646 (diff)
Read env variables using envy library
Using my dear friend's, dmjio's, excellent library, envy -- to read and parse
variables from the system environment.

I added and git-ignored the .envrc file that contains API secrets. I'm using
Envy to read these values, so that I don't hard-code these values into the
source code.
-rw-r--r--.gitignore1
-rw-r--r--shell.nix1
-rw-r--r--src/App.hs24
-rw-r--r--src/Main.hs8
-rw-r--r--src/Types.hs12
5 files changed, 33 insertions, 13 deletions
diff --git a/.gitignore b/.gitignore
index ebea556fe5b6..d4d62d436b26 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.envrc
 *.db
 *.sqlite3
 !populate.sqlite3
diff --git a/shell.nix b/shell.nix
index 8c948e9cb55d..bd31438b1957 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 708dd896fab2..7536e3c771e1 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 de40b3225e4a..9df4232066bb 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 eed9bf8c1696..135c50f17f4a 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 =