2 Module : Gargantext.API.Settings
3 Description : Settings of the API (Server and Client)
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
12 {-# OPTIONS_GHC -fno-warn-name-shadowing #-}
14 {-# LANGUAGE NoImplicitPrelude #-}
15 {-# LANGUAGE DataKinds #-}
16 {-# LANGUAGE DeriveGeneric #-}
17 {-# LANGUAGE ScopedTypeVariables #-}
18 {-# LANGUAGE TemplateHaskell #-}
19 {-# LANGUAGE OverloadedStrings #-}
20 {-# LANGUAGE FlexibleInstances #-}
22 module Gargantext.API.Settings
25 import System.Log.FastLogger
27 import GHC.Generics (Generic)
28 import Prelude (Bounded())
29 import System.Environment (lookupEnv)
30 import System.IO (FilePath)
31 import Database.PostgreSQL.Simple (Connection, connect)
32 import Network.HTTP.Client (Manager)
33 import Network.HTTP.Client.TLS (newTlsManager)
35 import Data.Maybe (fromMaybe)
36 import Data.Either (either)
38 import Data.Text.Encoding (encodeUtf8)
39 import Data.ByteString.Lazy.Internal
42 import Servant.Client (BaseUrl, parseBaseUrl)
43 import Servant.Job.Async (newJobEnv, defaultSettings)
44 import Web.HttpApiData (parseUrlPiece)
45 import qualified Jose.Jwk as Jose
46 import qualified Jose.Jwa as Jose
48 import Control.Monad.Logger
50 import Gargantext.Prelude
51 import Gargantext.Database.Utils (databaseParameters)
52 import Gargantext.API.Orchestrator.Types
56 data SendEmailType = SendEmailViaAws
59 deriving (Show, Read, Enum, Bounded, Generic)
62 data Settings = Settings
63 { _allowedOrigin :: ByteString -- ^ allowed origin for CORS
64 , _allowedHost :: ByteString -- ^ allowed host for CORS
65 , _appPort :: PortNumber
66 , _logLevelLimit :: LogLevel -- ^ log level from the monad-logger package
67 -- , _dbServer :: Text
68 -- ^ this is not used yet
69 , _jwtSecret :: Jose.Jwk -- ^ key from the jose-jwt package
70 , _sendLoginEmails :: SendEmailType
71 , _scrapydUrl :: BaseUrl
77 parseJwk :: Text -> Jose.Jwk
78 parseJwk secretStr = jwk
80 secretBs = encodeUtf8 secretStr
81 jwk = Jose.SymmetricJwk secretBs
84 (Just $ Jose.Signed Jose.HS256)
86 devSettings :: Settings
87 devSettings = Settings
88 { _allowedOrigin = "http://localhost:8008"
89 , _allowedHost = "localhost:3000"
91 , _logLevelLimit = LevelDebug
92 -- , _dbServer = "localhost"
93 -- generate with dd if=/dev/urandom bs=1 count=32 | base64
94 -- make sure jwtSecret differs between development and production, because you do not want
95 -- your production key inside source control.
96 , _jwtSecret = parseJwk "MVg0YAPVSPiYQc/qIs/rV/X32EFR0zOJWfHFgMbszMw="
97 , _sendLoginEmails = LogEmailToConsole
98 , _scrapydUrl = fromMaybe (panic "Invalid scrapy URL") $ parseBaseUrl "http://localhost:6800"
103 reqSetting :: FromHttpApiData a => Text -> IO a
105 e <- fromMaybe (panic $ "Missing " <> name) <$> lookupEnv (unpack name)
106 pure $ either (panic $ "Unable to parse " <> name) identity $ parseUrlPiece $ pack e
108 optSetting :: FromHttpApiData a => Text -> a -> IO a
109 optSetting name d = do
110 me <- lookupEnv (unpack name)
113 Just e -> pure $ either (panic $ "Unable to parse " <> name) identity $ parseUrlPiece $ pack e
115 --settingsFromEnvironment :: IO Settings
116 --settingsFromEnvironment =
117 -- Settings <$> (encodeUtf8 <$> reqSetting "ALLOWED_ORIGIN")
118 -- <*> (encodeUtf8 <$> reqSetting "ALLOWED_HOST")
119 -- <*> optSetting "PORT" 3000
120 -- <*> (parseLogLevel <$> optSetting "LOG_LEVEL" "warn")
121 -- <*> reqSetting "DB_SERVER"
122 -- <*> (parseJwk <$> reqSetting "JWT_SECRET")
123 -- <*> optSetting "SEND_EMAIL" SendEmailViaAws
125 data FireWall = FireWall { unFireWall :: Bool }
128 { _env_settings :: !Settings
129 , _env_logger :: !LoggerSet
130 , _env_conn :: !Connection
131 , _env_manager :: !Manager
132 , _env_self_url :: !BaseUrl
133 , _env_scrapers :: !ScrapersEnv
139 data MockEnv = MockEnv
140 { _menv_firewall :: !FireWall
146 newEnv :: PortNumber -> FilePath -> IO Env
147 newEnv port file = do
148 manager <- newTlsManager
149 settings <- pure (devSettings & appPort .~ port) -- TODO read from 'file'
150 when (port /= settings ^. appPort) $
151 panic "TODO: conflicting settings of port"
152 self_url <- parseBaseUrl $ "http://0.0.0.0:" <> show port
153 param <- databaseParameters file
154 conn <- connect param
155 scrapers_env <- newJobEnv defaultSettings manager
156 logger <- newStderrLoggerSet defaultBufSize
158 { _env_settings = settings
159 , _env_logger = logger
161 , _env_manager = manager
162 , _env_scrapers = scrapers_env
163 , _env_self_url = self_url