refactor: move logStdout/corsPolicy to Middleware

* remove configQuiet from Config

configQuiet was not an end user setting.
The logging setup is now an internal parameter.

* move proxy uri validation to Private dir
This commit is contained in:
steve-chavez
2020-07-13 11:30:16 -05:00
committed by Steve Chavez
parent 0ff05edd16
commit e272ea47be
10 changed files with 197 additions and 177 deletions
+49 -16
View File
@@ -1,6 +1,6 @@
{-|
Module : PostgREST.Middleware
Description : Sets the PostgreSQL GUCs, role, search_path and pre-request function. Validates JWT.
Description : Sets CORS policy. Also the PostgreSQL GUCs, role, search_path and pre-request function.
-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE FlexibleContexts #-}
@@ -8,20 +8,29 @@ Description : Sets the PostgreSQL GUCs, role, search_path and pre-request functi
module PostgREST.Middleware where
import qualified Data.Aeson as JSON
import qualified Data.HashMap.Strict as M
import Data.Scientific (FPFormat (..), formatScientific,
isInteger)
import qualified Hasql.Transaction as H
import qualified Data.Aeson as JSON
import qualified Data.ByteString.Char8 as BS
import qualified Data.CaseInsensitive as CI
import Data.Function (id)
import qualified Data.HashMap.Strict as M
import Data.List (lookup)
import Data.Scientific (FPFormat (..),
formatScientific, isInteger)
import Data.Text (strip)
import qualified Hasql.Transaction as H
import Network.Wai (Application, Response)
import Network.Wai.Middleware.Cors (cors)
import Network.Wai.Middleware.Gzip (def, gzip)
import Network.Wai.Middleware.Static (only, staticPolicy)
import Network.Wai (Application, Request,
Response, requestHeaders)
import Network.Wai.Middleware.Cors (CorsResourcePolicy (..),
cors)
import Network.Wai.Middleware.Gzip (def, gzip)
import Network.Wai.Middleware.RequestLogger (logStdout)
import Network.Wai.Middleware.Static (only, staticPolicy)
import PostgREST.ApiRequest (ApiRequest (..))
import PostgREST.Config (AppConfig (..), corsPolicy)
import PostgREST.Config (AppConfig (..))
import PostgREST.QueryBuilder (setLocalQuery, setLocalSearchPathQuery)
import PostgREST.Types (LogSetup (..))
import Protolude hiding (head, toS)
import Protolude.Conv (toS)
@@ -31,7 +40,7 @@ runPgLocals :: AppConfig -> M.HashMap Text JSON.Value ->
ApiRequest -> H.Transaction Response
runPgLocals conf claims app req = do
H.sql $ toS . mconcat $ setSearchPathSql : setRoleSql ++ claimsSql ++ [methodSql, pathSql] ++ headersSql ++ cookiesSql ++ appSettingsSql
traverse_ H.sql customReqCheck
traverse_ H.sql preReq
app req
where
methodSql = setLocalQuery mempty ("request.method", toS $ iMethod req)
@@ -46,14 +55,38 @@ runPgLocals conf claims app req = do
-- role claim defaults to anon if not specified in jwt
claimsWithRole = M.union claims (M.singleton "role" anon)
anon = JSON.String . toS $ configAnonRole conf
customReqCheck = (\f -> "select " <> toS f <> "();") <$> configReqCheck conf
preReq = (\f -> "select " <> toS f <> "();") <$> configPreReq conf
defaultMiddle :: Application -> Application
defaultMiddle =
gzip def
pgrstMiddleware :: LogSetup -> Application -> Application
pgrstMiddleware logs =
(if logs == LogQuiet then id else logStdout)
. gzip def
. cors corsPolicy
. staticPolicy (only [("favicon.ico", "static/favicon.ico")])
defaultCorsPolicy :: CorsResourcePolicy
defaultCorsPolicy = CorsResourcePolicy Nothing
["GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS"] ["Authorization"] Nothing
(Just $ 60*60*24) False False True
-- | CORS policy to be used in by Wai Cors middleware
corsPolicy :: Request -> Maybe CorsResourcePolicy
corsPolicy req = case lookup "origin" headers of
Just origin -> Just defaultCorsPolicy {
corsOrigins = Just ([origin], True)
, corsRequestHeaders = "Authentication":accHeaders
, corsExposedHeaders = Just [
"Content-Encoding", "Content-Location", "Content-Range", "Content-Type"
, "Date", "Location", "Server", "Transfer-Encoding", "Range-Unit"
]
}
Nothing -> Nothing
where
headers = requestHeaders req
accHeaders = case lookup "access-control-request-headers" headers of
Just hdrs -> map (CI.mk . toS . strip . toS) $ BS.split ',' hdrs
Nothing -> []
unquoted :: JSON.Value -> Text
unquoted (JSON.String t) = t
unquoted (JSON.Number n) =