Configuration.hs (2932B)
1 module Core.Configuration ( adminEmail, appPort 2 , confLinkLength, dataPath, dbPath 3 , encKey, getRuntimeEnvironment 4 , keyFileInit, init) where 5 6 import qualified Data.ByteString as B 7 8 import Control.Monad (mapM) 9 import Configuration.Dotenv 10 import Core.Types 11 import Crypto.Saltine.Core.SecretBox (newKey) 12 import Crypto.Saltine.Class (encode) 13 import Prelude hiding (init) 14 import System.Directory (doesFileExist) 15 import System.Environment (getEnv, lookupEnv) 16 17 -- Load environment variables from dotenv file if required 18 init :: IO () 19 init = do 20 reqEnvLookup <- getRequiredEnv 21 if (Nothing `elem` reqEnvLookup) 22 then checkEnvFile requiredEnvVars 23 else pure () 24 where 25 getRequiredEnv :: IO [Maybe String] 26 getRequiredEnv = mapM (\s -> lookupEnv s) requiredEnvVars 27 28 checkEnvFile :: [String] -> IO () 29 checkEnvFile requiredEnv = do 30 dotEnvExists <- doesFileExist "./.env" 31 if dotEnvExists 32 then do 33 loadFile defaultConfig 34 fromEnvFile <- getRequiredEnv 35 if (Nothing `elem` fromEnvFile) 36 then error $ missingEnvMsg requiredEnv 37 else pure () 38 else error $ "Cannot find .env file in application directory.\n" 39 ++ missingEnvMsg requiredEnv 40 41 missingEnvMsg :: [String] -> String 42 missingEnvMsg required = 43 "Missing required environment variable(s).\n" 44 ++ "All required environment variables:\n" 45 ++ unlines required 46 47 -- Check if an encryption key exists on the filesystem and create one if not 48 keyFileInit :: IO () 49 keyFileInit = do 50 dataPathStr <- dataPath 51 keyExists <- doesFileExist $ dataPathStr ++ "data/encryptionKey" 52 case keyExists of 53 True -> putStrLn "Using existing key" 54 False -> do 55 key <- newKey 56 B.writeFile (dataPathStr ++ "data/encryptionKey") (encode key) 57 putStrLn "Creating new encryption key; any pre-existing DB entries will not decrypt" 58 59 -- Read and return the encryption key on the filesystem as a ByteString 60 encKey :: IO B.ByteString 61 encKey = do 62 dataPathStr <- dataPath 63 B.readFile (dataPathStr ++ "data/encryptionKey") 64 65 -- Helper functions for getting the value of environment variables 66 adminEmail :: IO String 67 adminEmail = getEnv "ADMINEMAIL" 68 69 getRuntimeEnvironment :: IO String 70 getRuntimeEnvironment = getEnv "ENVIRONMENT" 71 72 appPort :: IO String 73 appPort = getEnv "APPLICATIONPORT" 74 75 dataPath :: IO String 76 dataPath = getEnv "DATADIR" 77 78 dbPath :: String 79 dbPath = "data/Purr.sqlite" 80 81 confLinkLength :: IO String 82 confLinkLength = getEnv "LINKLENGTH" 83 84 requiredEnvVars :: [String] 85 requiredEnvVars = [ "ADMINEMAIL", "APPLICATIONHOST", "APPLICATIONPORT" 86 , "DATADIR", "ENVIRONMENT", "LINKLENGTH" 87 ]