@@ -24,8 +24,9 @@ import Share.Utils.Servant.Cookies qualified as Cookies
2424import Share.Web.Authentication (cookieSessionTTL )
2525import Hasql.Pool qualified as Pool
2626import Hasql.Pool.Config qualified as Pool
27- import Network.URI (parseURI )
27+ import Network.URI (parseURI , uriScheme )
2828import Servant.API qualified as Servant
29+ import Servant.Client qualified as ServantClient
2930import System.Environment (lookupEnv )
3031import System.Exit
3132import System.Log.FastLogger qualified as FL
@@ -34,6 +35,10 @@ import System.Log.Raven.Transport.HttpConduit qualified as Sentry
3435import System.Log.Raven.Types qualified as Sentry
3536import Unison.Runtime.Interface as RT
3637import Data.Time.Clock qualified as Time
38+ import Network.HTTP.Client.TLS qualified as TLS
39+ import Network.HTTP.Client qualified as HTTPClient
40+ import Vault qualified
41+ import Data.ByteString.Char8 qualified as BSC
3742
3843withEnv :: (Env () -> IO a ) -> IO a
3944withEnv action = do
@@ -114,6 +119,35 @@ withEnv action = do
114119 pgConnectionPool <- Pool. acquire pgSettings
115120 timeCache <- FL. newTimeCache FL. simpleTimeFormat -- E.g. 05/Sep/2023:13:23:56 -0700
116121 sandboxedRuntime <- RT. startRuntime True RT. Persistent " share"
122+
123+ -- Vault setup
124+ unproxiedHttpClient <- TLS. newTlsManager
125+ vaultHost <- fromEnv " VAULT_HOST" parseBaseUrl
126+ userSecretsVaultMount <- fromEnv " USER_SECRETS_VAULT_MOUNT" ((fmap . fmap ) Vault. SecretMount . nonEmptyTextParser " USER_SECRETS_VAULT_MOUNT" )
127+ shareVaultToken <- fromEnv " VAULT_TOKEN" ((fmap . fmap ) Vault. VaultToken . nonEmptyTextParser " VAULT_TOKEN" )
128+ let vaultClientEnv = ServantClient. mkClientEnv unproxiedHttpClient vaultHost
129+
130+
131+
132+ proxiedHttpClient <- do
133+ if Deployment. onLocal
134+ then TLS. newTlsManager
135+ else do
136+ httpProxyHost <- fromEnv " SHARE_PROXY_HOST" (\ proxyHost -> case parseURI proxyHost of
137+ Nothing -> pure $ Left " Invalid SHARE_PROXY_ADDRESS"
138+ Just uri -> if uriScheme uri == " http:" || uriScheme uri == " https:"
139+ then pure $ Right (BSC. pack proxyHost)
140+ else pure $ Left " SHARE_PROXY_ADDRESS must be http or https" )
141+ httpProxyPort <- fromEnv " SHARE_PROXY_PORT" (pure . maybeToEither " Invalid SHARE_PROXY_PORT" . readMaybe)
142+
143+ -- http proxy setup
144+ let proxyOverride = HTTPClient. useProxy (HTTPClient. Proxy {HTTPClient. proxyHost = httpProxyHost, HTTPClient. proxyPort = httpProxyPort})
145+ let proxiedManagerSettings =
146+ TLS. tlsManagerSettings
147+ & HTTPClient. managerSetProxy proxyOverride
148+ TLS. newTlsManagerWith proxiedManagerSettings
149+
150+ -- Logging setup
117151 let ctx = ()
118152 -- We use a zero-width-space to separate log-lines on ingestion, this allows us to use newlines for
119153 -- formatting, but without affecting log-grouping.
@@ -122,6 +156,15 @@ withEnv action = do
122156 action $ Env {logger = (logger . (\ msg -> zeroWidthSpace <> msg <> " \n " )), .. }
123157 where
124158 readPort p = pure $ maybeToRight " SHARE_PORT was not a number" (readMaybe p)
159+ nonEmptyTextParser :: Text -> String -> IO (Either String Text )
160+ nonEmptyTextParser varName = \ case
161+ " " -> pure . Left . Text. unpack $ " Expected a value for env var " <> varName <> " , but got an empty string"
162+ str -> pure . Right $ Text. pack str
163+
164+ parseBaseUrl :: String -> IO (Either String ServantClient. BaseUrl )
165+ parseBaseUrl str = do
166+ u <- ServantClient. parseBaseUrl str
167+ pure $ Right u
125168
126169fromEnv :: String -> (String -> IO (Either String a )) -> IO a
127170fromEnv var from = do
0 commit comments