fix: Fix wrong CORS header Authentication -> Authorization
Also refactors defaultCorsPolicy and corsPolicy and cleans up CORS tests
This commit is contained in:
committed by
Steve Chavez
parent
7db4a75146
commit
130dcc4f66
@@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
- #2058, Return 204 No Content without Content-Type for PUT - @wolfgangwalther
|
- #2058, Return 204 No Content without Content-Type for PUT - @wolfgangwalther
|
||||||
- #2077, Fix `is` not working with upper or mixed case values like `NULL, TrUe, FaLsE` - @steve-chavez
|
- #2077, Fix `is` not working with upper or mixed case values like `NULL, TrUe, FaLsE` - @steve-chavez
|
||||||
- #2024, Fix schema cache loading when views with XMLTABLE and DEFAULT are present - @wolfgangwalther
|
- #2024, Fix schema cache loading when views with XMLTABLE and DEFAULT are present - @wolfgangwalther
|
||||||
|
- #1724, Fix wrong CORS header Authentication -> Authorization - @wolfgangwalther
|
||||||
|
|
||||||
## [9.0.0] - 2021-11-25
|
## [9.0.0] - 2021-11-25
|
||||||
|
|
||||||
|
|||||||
+12
-14
@@ -8,8 +8,6 @@ module PostgREST.Middleware
|
|||||||
( runPgLocals
|
( runPgLocals
|
||||||
, pgrstFormat
|
, pgrstFormat
|
||||||
, pgrstMiddleware
|
, pgrstMiddleware
|
||||||
, defaultCorsPolicy
|
|
||||||
, corsPolicy
|
|
||||||
, optionalRollback
|
, optionalRollback
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@@ -132,21 +130,21 @@ pgrstMiddleware logLevel =
|
|||||||
LogWarn -> unsafePerformIO $ Wai.mkRequestLogger Wai.def { Wai.outputFormat = Wai.CustomOutputFormat $ pgrstFormat status400}
|
LogWarn -> unsafePerformIO $ Wai.mkRequestLogger Wai.def { Wai.outputFormat = Wai.CustomOutputFormat $ pgrstFormat status400}
|
||||||
LogInfo -> Wai.logStdout
|
LogInfo -> Wai.logStdout
|
||||||
|
|
||||||
defaultCorsPolicy :: Wai.CorsResourcePolicy
|
|
||||||
defaultCorsPolicy = Wai.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
|
-- | CORS policy to be used in by Wai Cors middleware
|
||||||
corsPolicy :: Wai.Request -> Maybe Wai.CorsResourcePolicy
|
corsPolicy :: Wai.Request -> Maybe Wai.CorsResourcePolicy
|
||||||
corsPolicy req = case lookup "origin" headers of
|
corsPolicy req = case lookup "origin" headers of
|
||||||
Just origin -> Just defaultCorsPolicy {
|
Just origin ->
|
||||||
Wai.corsOrigins = Just ([origin], True)
|
Just Wai.CorsResourcePolicy
|
||||||
, Wai.corsRequestHeaders = "Authentication" : accHeaders
|
{ Wai.corsOrigins = Just ([origin], True)
|
||||||
, Wai.corsExposedHeaders = Just [
|
, Wai.corsMethods = ["GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS"]
|
||||||
"Content-Encoding", "Content-Location", "Content-Range", "Content-Type"
|
, Wai.corsRequestHeaders = "Authorization" : accHeaders
|
||||||
, "Date", "Location", "Server", "Transfer-Encoding", "Range-Unit"
|
, Wai.corsExposedHeaders = Just
|
||||||
]
|
[ "Content-Encoding", "Content-Location", "Content-Range", "Content-Type"
|
||||||
|
, "Date", "Location", "Server", "Transfer-Encoding", "Range-Unit"]
|
||||||
|
, Wai.corsMaxAge = Just $ 60*60*24
|
||||||
|
, Wai.corsVaryOrigin = False
|
||||||
|
, Wai.corsRequireOrigin = False
|
||||||
|
, Wai.corsIgnoreFailures = True
|
||||||
}
|
}
|
||||||
Nothing -> Nothing
|
Nothing -> Nothing
|
||||||
where
|
where
|
||||||
|
|||||||
+42
-60
@@ -1,74 +1,56 @@
|
|||||||
module Feature.CorsSpec where
|
module Feature.CorsSpec where
|
||||||
|
|
||||||
-- {{{ Imports
|
import Network.Wai (Application)
|
||||||
import qualified Data.ByteString.Lazy as BL
|
|
||||||
|
|
||||||
import Network.Wai (Application)
|
|
||||||
import Network.Wai.Test (SResponse (simpleBody, simpleHeaders))
|
|
||||||
|
|
||||||
import Network.HTTP.Types
|
import Network.HTTP.Types
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
import Test.Hspec.Wai
|
import Test.Hspec.Wai
|
||||||
|
|
||||||
import Protolude
|
import Protolude
|
||||||
import SpecHelper
|
|
||||||
-- }}}
|
|
||||||
|
|
||||||
spec :: SpecWith ((), Application)
|
spec :: SpecWith ((), Application)
|
||||||
spec =
|
spec =
|
||||||
describe "CORS" $ do
|
describe "CORS" $ do
|
||||||
let preflightHeaders = [
|
it "replies naively and permissively to preflight request" $
|
||||||
("Accept", "*/*"),
|
request methodOptions "/"
|
||||||
("Origin", "http://example.com"),
|
[ ("Accept", "*/*")
|
||||||
("Access-Control-Request-Method", "POST"),
|
, ("Origin", "http://example.com")
|
||||||
("Access-Control-Request-Headers", "Foo,Bar") ]
|
, ("Access-Control-Request-Method", "POST")
|
||||||
let normalCors = [
|
, ("Access-Control-Request-Headers", "Foo,Bar") ]
|
||||||
("Host", "localhost:3000"),
|
""
|
||||||
("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:32.0) Gecko/20100101 Firefox/32.0"),
|
`shouldRespondWith`
|
||||||
("Origin", "http://localhost:8000"),
|
""
|
||||||
("Accept", "text/csv, */*; q=0.01"),
|
{ matchHeaders = [ "Access-Control-Allow-Origin" <:> "http://example.com"
|
||||||
("Accept-Language", "en-US,en;q=0.5"),
|
, "Access-Control-Allow-Credentials" <:> "true"
|
||||||
("Accept-Encoding", "gzip, deflate"),
|
, "Access-Control-Allow-Methods" <:> "GET, POST, PATCH, PUT, DELETE, OPTIONS, HEAD"
|
||||||
("Referer", "http://localhost:8000/"),
|
, "Access-Control-Allow-Headers" <:> "Authorization, Foo, Bar, Accept, Accept-Language, Content-Language"
|
||||||
("Connection", "keep-alive") ]
|
, "Access-Control-Max-Age" <:> "86400" ]
|
||||||
|
}
|
||||||
|
|
||||||
describe "preflight request" $ do
|
it "exposes necesssary response headers to regular request" $
|
||||||
it "replies naively and permissively to preflight request" $ do
|
request methodGet "/items"
|
||||||
r <- request methodOptions "/items" preflightHeaders ""
|
[("Origin", "http://example.com")]
|
||||||
liftIO $ do
|
""
|
||||||
let respHeaders = simpleHeaders r
|
`shouldRespondWith`
|
||||||
respHeaders `shouldSatisfy` matchHeader
|
ResponseMatcher
|
||||||
"Access-Control-Allow-Origin"
|
{ matchStatus = 200
|
||||||
"http://example.com"
|
, matchBody = MatchBody (\_ _ -> Nothing) -- match any body
|
||||||
respHeaders `shouldSatisfy` matchHeader
|
, matchHeaders = [ "Access-Control-Expose-Headers" <:>
|
||||||
"Access-Control-Allow-Credentials"
|
"Content-Encoding, Content-Location, Content-Range, Content-Type, \
|
||||||
"true"
|
\Date, Location, Server, Transfer-Encoding, Range-Unit"]
|
||||||
respHeaders `shouldSatisfy` matchHeader
|
}
|
||||||
"Access-Control-Allow-Methods"
|
|
||||||
"GET, POST, PATCH, PUT, DELETE, OPTIONS, HEAD"
|
|
||||||
respHeaders `shouldSatisfy` matchHeader
|
|
||||||
"Access-Control-Allow-Headers"
|
|
||||||
"Authentication, Foo, Bar, Accept, Accept-Language, Content-Language"
|
|
||||||
respHeaders `shouldSatisfy` matchHeader
|
|
||||||
"Access-Control-Max-Age"
|
|
||||||
"86400"
|
|
||||||
|
|
||||||
it "suppresses body in response" $ do
|
it "allows INFO body through even with CORS request headers present to postflight request" $
|
||||||
r <- request methodOptions "/" preflightHeaders ""
|
request methodOptions "/items"
|
||||||
liftIO $ simpleBody r `shouldBe` ""
|
[ ("Host", "localhost:3000")
|
||||||
|
, ("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:32.0) Gecko/20100101 Firefox/32.0")
|
||||||
describe "regular request" $
|
, ("Origin", "http://localhost:8000")
|
||||||
it "exposes necesssary response headers" $ do
|
, ("Accept", "text/csv, */*; q=0.01")
|
||||||
r <- request methodGet "/items" [("Origin", "http://example.com")] ""
|
, ("Accept-Language", "en-US,en;q=0.5")
|
||||||
liftIO $ simpleHeaders r `shouldSatisfy` matchHeader
|
, ("Accept-Encoding", "gzip, deflate")
|
||||||
"Access-Control-Expose-Headers"
|
, ("Referer", "http://localhost:8000/")
|
||||||
"Content-Encoding, Content-Location, Content-Range, Content-Type, \
|
, ("Connection", "keep-alive") ]
|
||||||
\Date, Location, Server, Transfer-Encoding, Range-Unit"
|
""
|
||||||
|
`shouldRespondWith`
|
||||||
describe "postflight request" $
|
""
|
||||||
it "allows INFO body through even with CORS request headers present" $ do
|
{ matchHeaders = [ "Access-Control-Allow-Origin" <:> "*" ] }
|
||||||
r <- request methodOptions "/items" normalCors ""
|
|
||||||
liftIO $ do
|
|
||||||
simpleHeaders r `shouldSatisfy` matchHeader
|
|
||||||
"Access-Control-Allow-Origin" "\\*"
|
|
||||||
simpleBody r `shouldSatisfy` BL.null
|
|
||||||
|
|||||||
Reference in New Issue
Block a user