2021-11-04 19:08:33 +03:00
|
|
|
module Hasura.RQL.DDL.Headers
|
|
|
|
( HeaderConf (..),
|
|
|
|
HeaderValue (HVEnv, HVValue),
|
|
|
|
makeHeadersFromConf,
|
|
|
|
toHeadersConf,
|
|
|
|
)
|
|
|
|
where
|
2018-11-23 16:02:46 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
import Data.Aeson
|
|
|
|
import Data.CaseInsensitive qualified as CI
|
|
|
|
import Data.Environment qualified as Env
|
|
|
|
import Data.Text qualified as T
|
|
|
|
import Hasura.Base.Error
|
|
|
|
import Hasura.Base.Instances ()
|
|
|
|
import Hasura.Incremental (Cacheable)
|
|
|
|
import Hasura.Prelude
|
|
|
|
import Network.HTTP.Types qualified as HTTP
|
2018-11-23 16:02:46 +03:00
|
|
|
|
|
|
|
data HeaderConf = HeaderConf HeaderName HeaderValue
|
2021-09-24 01:56:37 +03:00
|
|
|
deriving (Show, Eq, Generic)
|
|
|
|
|
2019-11-27 01:49:42 +03:00
|
|
|
instance NFData HeaderConf
|
2021-09-24 01:56:37 +03:00
|
|
|
|
2018-11-23 16:02:46 +03:00
|
|
|
instance Hashable HeaderConf
|
2021-09-24 01:56:37 +03:00
|
|
|
|
2019-12-15 16:28:23 +03:00
|
|
|
instance Cacheable HeaderConf
|
2018-11-23 16:02:46 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
type HeaderName = Text
|
2018-11-23 16:02:46 +03:00
|
|
|
|
2020-10-27 16:53:49 +03:00
|
|
|
data HeaderValue = HVValue Text | HVEnv Text
|
2021-09-24 01:56:37 +03:00
|
|
|
deriving (Show, Eq, Generic)
|
|
|
|
|
2019-11-27 01:49:42 +03:00
|
|
|
instance NFData HeaderValue
|
2021-09-24 01:56:37 +03:00
|
|
|
|
2018-11-23 16:02:46 +03:00
|
|
|
instance Hashable HeaderValue
|
2021-09-24 01:56:37 +03:00
|
|
|
|
2019-12-15 16:28:23 +03:00
|
|
|
instance Cacheable HeaderValue
|
2018-11-23 16:02:46 +03:00
|
|
|
|
|
|
|
instance FromJSON HeaderConf where
|
|
|
|
parseJSON (Object o) = do
|
|
|
|
name <- o .: "name"
|
|
|
|
value <- o .:? "value"
|
|
|
|
valueFromEnv <- o .:? "value_from_env"
|
2021-09-24 01:56:37 +03:00
|
|
|
case (value, valueFromEnv) of
|
|
|
|
(Nothing, Nothing) -> fail "expecting value or value_from_env keys"
|
2018-11-23 16:02:46 +03:00
|
|
|
(Just val, Nothing) -> return $ HeaderConf name (HVValue val)
|
2020-08-05 16:14:53 +03:00
|
|
|
(Nothing, Just val) -> do
|
|
|
|
when (T.isPrefixOf "HASURA_GRAPHQL_" val) $
|
2022-11-02 23:53:23 +03:00
|
|
|
fail $
|
|
|
|
"env variables starting with \"HASURA_GRAPHQL_\" are not allowed in value_from_env: " <> T.unpack val
|
2020-08-05 16:14:53 +03:00
|
|
|
return $ HeaderConf name (HVEnv val)
|
2021-09-24 01:56:37 +03:00
|
|
|
(Just _, Just _) -> fail "expecting only one of value or value_from_env keys"
|
2018-11-23 16:02:46 +03:00
|
|
|
parseJSON _ = fail "expecting object for headers"
|
|
|
|
|
|
|
|
instance ToJSON HeaderConf where
|
|
|
|
toJSON (HeaderConf name (HVValue val)) = object ["name" .= name, "value" .= val]
|
2021-09-24 01:56:37 +03:00
|
|
|
toJSON (HeaderConf name (HVEnv val)) = object ["name" .= name, "value_from_env" .= val]
|
2018-11-23 16:02:46 +03:00
|
|
|
|
2020-02-13 20:38:23 +03:00
|
|
|
-- | Resolve configuration headers
|
2021-09-24 01:56:37 +03:00
|
|
|
makeHeadersFromConf ::
|
|
|
|
MonadError QErr m => Env.Environment -> [HeaderConf] -> m [HTTP.Header]
|
2020-07-14 22:00:58 +03:00
|
|
|
makeHeadersFromConf env = mapM getHeader
|
2018-11-23 16:02:46 +03:00
|
|
|
where
|
2020-04-24 10:55:51 +03:00
|
|
|
getHeader hconf =
|
2021-09-24 01:56:37 +03:00
|
|
|
((CI.mk . txtToBs) *** txtToBs)
|
|
|
|
<$> case hconf of
|
2020-02-13 20:38:23 +03:00
|
|
|
(HeaderConf name (HVValue val)) -> return (name, val)
|
2021-09-24 01:56:37 +03:00
|
|
|
(HeaderConf name (HVEnv val)) -> do
|
2020-07-14 22:00:58 +03:00
|
|
|
let mEnv = Env.lookupEnv env (T.unpack val)
|
2020-02-13 20:38:23 +03:00
|
|
|
case mEnv of
|
2021-09-24 01:56:37 +03:00
|
|
|
Nothing -> throw400 NotFound $ "environment variable '" <> val <> "' not set"
|
2020-02-13 20:38:23 +03:00
|
|
|
Just envval -> pure (name, T.pack envval)
|
2020-04-24 10:55:51 +03:00
|
|
|
|
|
|
|
-- | Encode headers to HeaderConf
|
|
|
|
toHeadersConf :: [HTTP.Header] -> [HeaderConf]
|
|
|
|
toHeadersConf =
|
|
|
|
map (uncurry HeaderConf . ((bsToTxt . CI.original) *** (HVValue . bsToTxt)))
|