Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 29 additions & 9 deletions test/spec/Feature/Auth/AsymmetricJwtSpec.hs
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
module Feature.Auth.AsymmetricJwtSpec where

import Network.Wai (Application)

import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai
import Text.Heredoc

import PostgREST.Config (AppConfig (..), parseSecret)

import Protolude
import SpecHelper

spec :: SpecWith ((), Application)
spec = describe "server started with asymmetric JWK" $
-- these tests will stop working 9999999999s after the UNIX EPOCH
spec :: SpecWithConfig
spec withConfig =
let
auth = authHeaderJWT "eyJhbGciOiJSUzI1NiJ9.eyJyb2xlIjogInBvc3RncmVzdF90ZXN0X2F1dGhvciJ9Cg.CBOYWDvqgAR0YYnZnyDGTQi6AJLc2Pds6_eV3YuBG6I36mj_h05eLhkEKNEDA5ZteMzCiY83P60rC_xtxVd7B6vo3BeF5uoanPS3rrbuHzKPwzsrgrD_CqvEuJ4n7Q9epkQiLsNkcexneENZDRqFjbwZx3DrXiCWwlK3Ytr5NAIGxmy0od-0xNpb2U1nXQyO_Q3mumWFViRt4tmFn_3goDHNKG3Ha_AzImfUNvHnWL78kAc4rbn15vLtWXD8PwtSnZaB4lY4V6RfsaW937srQsmRetvytM1i_bHBnjkjQLAqGbXPyItjtlXPs0uGNBadE8-wgkLtfmSCC4v2DjUthw"
jwk = encodeUtf8 [str|{"alg":"RS256","e":"AQAB","key_ops":["verify"],"kty":"RSA","n":"0etQ2Tg187jb04MWfpuogYGV75IFrQQBxQaGH75eq_FpbkyoLcEpRUEWSbECP2eeFya2yZ9vIO5ScD-lPmovePk4Aa4SzZ8jdjhmAbNykleRPCxMg0481kz6PQhnHRUv3nF5WP479CnObJKqTVdEagVL66oxnX9VhZG9IZA7k0Th5PfKQwrKGyUeTGczpOjaPqbxlunP73j9AfnAt4XCS8epa-n3WGz1j-wfpr_ys57Aq-zBCfqP67UYzNpeI1AoXsJhD9xSDOzvJgFRvc3vm2wjAW4LEMwi48rCplamOpZToIHEPIaPzpveYQwDnB1HFTR1ove9bpKJsHmi-e2uzQ","use":"sig"}|]
jwks = encodeUtf8 [str|{"keys": [{"alg":"RS256","e":"AQAB","key_ops":["verify"],"kty":"RSA","n":"0etQ2Tg187jb04MWfpuogYGV75IFrQQBxQaGH75eq_FpbkyoLcEpRUEWSbECP2eeFya2yZ9vIO5ScD-lPmovePk4Aa4SzZ8jdjhmAbNykleRPCxMg0481kz6PQhnHRUv3nF5WP479CnObJKqTVdEagVL66oxnX9VhZG9IZA7k0Th5PfKQwrKGyUeTGczpOjaPqbxlunP73j9AfnAt4XCS8epa-n3WGz1j-wfpr_ys57Aq-zBCfqP67UYzNpeI1AoXsJhD9xSDOzvJgFRvc3vm2wjAW4LEMwi48rCplamOpZToIHEPIaPzpveYQwDnB1HFTR1ove9bpKJsHmi-e2uzQ","use":"sig"}]}|]
in
describe "server started with asymmetric JWK" $ do

context "secret provided as JWK" $ withConfig (
baseCfg {
configJwtSecret = Just jwk
, configJWKS = rightToMaybe $ parseSecret jwk
}
) $ it "succeeds with jwt token signed with an asymmetric key" $
request methodGet "/authors_only" [auth] ""
`shouldRespondWith` 200

-- this test will stop working 9999999999s after the UNIX EPOCH
it "succeeds with jwt token signed with an asymmetric key" $ do
let auth = authHeaderJWT "eyJhbGciOiJSUzI1NiJ9.eyJyb2xlIjogInBvc3RncmVzdF90ZXN0X2F1dGhvciJ9Cg.CBOYWDvqgAR0YYnZnyDGTQi6AJLc2Pds6_eV3YuBG6I36mj_h05eLhkEKNEDA5ZteMzCiY83P60rC_xtxVd7B6vo3BeF5uoanPS3rrbuHzKPwzsrgrD_CqvEuJ4n7Q9epkQiLsNkcexneENZDRqFjbwZx3DrXiCWwlK3Ytr5NAIGxmy0od-0xNpb2U1nXQyO_Q3mumWFViRt4tmFn_3goDHNKG3Ha_AzImfUNvHnWL78kAc4rbn15vLtWXD8PwtSnZaB4lY4V6RfsaW937srQsmRetvytM1i_bHBnjkjQLAqGbXPyItjtlXPs0uGNBadE8-wgkLtfmSCC4v2DjUthw"
request methodGet "/authors_only" [auth] ""
`shouldRespondWith` 200
context "secret provided as JWKSet" $ withConfig (
baseCfg {
configJwtSecret = Just jwks
, configJWKS = rightToMaybe $ parseSecret jwks
}
) $ it "succeeds with jwt token signed with an asymmetric key" $
request methodGet "/authors_only" [auth] ""
`shouldRespondWith` 200
18 changes: 12 additions & 6 deletions test/spec/Feature/Auth/AudienceJwtSecretSpec.hs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
module Feature.Auth.AudienceJwtSecretSpec where

import Network.Wai (Application)

import Network.HTTP.Types
import Protolude hiding (get)
import SpecHelper
import Test.Hspec
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON

spec :: SpecWith ((), Application)
spec = describe "test handling of aud claims in JWT when the jwt-aud config is set" $ do
import PostgREST.Config (AppConfig (..), parseSecret)

spec :: SpecWithConfig
spec withConfig = withConfig (
baseCfg {
configJwtSecret = Just generateSecret
, configJwtAudience = Just "youraudience"
, configJWKS = rightToMaybe $ parseSecret generateSecret
}
) $ describe "test handling of aud claims in JWT when the jwt-aud config is set" $ do

context "when the audience claim is a string" $ do
-- this test will stop working 9999999999s after the UNIX EPOCH
Expand Down Expand Up @@ -147,8 +153,8 @@ spec = describe "test handling of aud claims in JWT when the jwt-aud config is s
it "succeeds without a JWT" $
get "/has_count_column" `shouldRespondWith` 200

disabledSpec :: SpecWith ((), Application)
disabledSpec = describe "test handling of aud claims in JWT when the jwt-aud config is not set" $ do
disabledSpec :: SpecWithConfig
disabledSpec withConfig = withConfig baseCfg $ describe "test handling of aud claims in JWT when the jwt-aud config is not set" $ do

context "when the audience claim is a string" $ do
it "ignores the audience claim and suceeds" $ do
Expand Down
6 changes: 2 additions & 4 deletions test/spec/Feature/Auth/AuthSpec.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
module Feature.Auth.AuthSpec where

import Network.Wai (Application)

import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai
Expand All @@ -10,8 +8,8 @@ import Test.Hspec.Wai.JSON
import Protolude hiding (get)
import SpecHelper

spec :: SpecWith ((), Application)
spec = describe "authorization" $ do
spec :: SpecWithConfig
spec withConfig = withConfig baseCfg $ describe "authorization" $ do
let single = ("Accept","application/vnd.pgrst.object+json")

it "denies access to tables that anonymous does not own" $
Expand Down
13 changes: 9 additions & 4 deletions test/spec/Feature/Auth/BinaryJwtSecretSpec.hs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
module Feature.Auth.BinaryJwtSecretSpec where

import Network.Wai (Application)

import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai

import PostgREST.Config (AppConfig (..), parseSecret)

import Protolude
import SpecHelper

spec :: SpecWith ((), Application)
spec = describe "server started with binary JWT secret" $
spec :: SpecWithConfig
spec withConfig = withConfig (
baseCfg {
configJwtSecret = Just generateSecret
, configJWKS = rightToMaybe $ parseSecret generateSecret
}
) $ describe "server started with binary JWT secret" $

-- this test will stop working 9999999999s after the UNIX EPOCH
it "succeeds with jwt token encoded with a binary secret" $ do
Expand Down
8 changes: 4 additions & 4 deletions test/spec/Feature/Auth/NoAnonSpec.hs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
module Feature.Auth.NoAnonSpec where

import Network.Wai (Application)

import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON

import PostgREST.Config (AppConfig (..))

import Protolude hiding (get)
import SpecHelper

spec :: SpecWith ((), Application)
spec = describe "server started without anonymous role" $ do
spec :: SpecWithConfig
spec withConfig = withConfig (baseCfg { configDbAnonRole = Nothing }) $ describe "server started without anonymous role" $ do
Comment thread
wolfgangwalther marked this conversation as resolved.
it "behaves normally on attempted auth" $ do
-- token body: { "role": "postgrest_test_author" }
let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIn0.Xod-F15qsGL0WhdOCr2j3DdKuTw9QJERVgoFD3vGaWA"
Expand Down
13 changes: 9 additions & 4 deletions test/spec/Feature/Auth/NoJwtSecretSpec.hs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
module Feature.Auth.NoJwtSecretSpec where

import Network.Wai (Application)

import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON

import PostgREST.Config (AppConfig (..))

import Protolude hiding (get)
import SpecHelper

spec :: SpecWith ((), Application)
spec = describe "server started without JWT secret" $ do
spec :: SpecWithConfig
spec withConfig = withConfig (
baseCfg {
configJwtSecret = Nothing
, configJWKS = Nothing
}
) $ describe "server started without JWT secret" $ do

it "responds with error on attempted auth" $ do
-- token body: { "role": "postgrest_test_author" }
Expand Down
8 changes: 4 additions & 4 deletions test/spec/Feature/ConcurrentSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
module Feature.ConcurrentSpec where

import Control.Concurrent.Async (mapConcurrently)
import Network.Wai (Application)

import Control.Monad.Base
import Control.Monad.Trans.Control
Expand All @@ -16,10 +15,11 @@ import Test.Hspec.Wai
import Test.Hspec.Wai.Internal
import Test.Hspec.Wai.JSON

import Protolude hiding (get)
import Protolude hiding (get)
import SpecHelper

spec :: SpecWith ((), Application)
spec =
spec :: SpecWithConfig
spec withConfig = withConfig baseCfg $
describe "Querying in parallel" $
it "should not raise 'transaction in progress' error" $
raceTest 10 $
Expand Down
7 changes: 3 additions & 4 deletions test/spec/Feature/CorsSpec.hs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
module Feature.CorsSpec where

import Network.Wai (Application)

import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai

import Protolude
import SpecHelper

spec :: SpecWith ((), Application)
spec =
spec :: SpecWithConfig
spec withConfig = withConfig baseCfg $
describe "CORS" $ do
it "replies naively and permissively to preflight request" $
request methodOptions "/"
Expand Down
7 changes: 4 additions & 3 deletions test/spec/Feature/ExtraSearchPathSpec.hs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
module Feature.ExtraSearchPathSpec where

import Network.HTTP.Types
import Network.Wai (Application)
import Test.Hspec
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON

import PostgREST.Config (AppConfig (..))

import Protolude hiding (get)
import SpecHelper

spec :: SpecWith ((), Application)
spec = describe "extra search path" $ do
spec :: SpecWithConfig
spec withConfig = withConfig (baseCfg { configDbExtraSearchPath = ["public", "extensions", "EXTRA \"@/\\#~_-"] }) $ describe "extra search path" $ do

it "finds the ltree <@ operator on the public schema" $
request methodGet "/ltree_sample?path=cd.Top.Science.Astronomy" [] ""
Expand Down
7 changes: 3 additions & 4 deletions test/spec/Feature/NoSuperuserSpec.hs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
module Feature.NoSuperuserSpec where

import Network.Wai (Application)

import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai

import Protolude
import SpecHelper

spec :: SpecWith ((), Application)
spec =
spec :: SpecWithConfig
spec withConfig = withConfig baseCfg $
describe "No Superuser" $ do
it "proves that the authenticator role is not a superuser" $ do
request methodGet "/rpc/is_superuser"
Expand Down
9 changes: 6 additions & 3 deletions test/spec/Feature/ObservabilitySpec.hs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
module Feature.ObservabilitySpec where

import Network.Wai (Application)
import Data.CaseInsensitive (mk)

import Network.HTTP.Types
import Test.Hspec
import Test.Hspec.Wai

import PostgREST.Config (AppConfig (..))

import Protolude
import SpecHelper

spec :: SpecWith ((), Application)
spec =
spec :: SpecWithConfig
spec withConfig = withConfig (baseCfg { configServerTraceHeader = Just $ mk "X-Request-Id" }) $
describe "Observability" $ do
it "includes the server trace header on the response" $ do
request methodHead "/"
Expand Down
8 changes: 5 additions & 3 deletions test/spec/Feature/OpenApi/DisabledOpenApiSpec.hs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
module Feature.OpenApi.DisabledOpenApiSpec where

import Network.HTTP.Types
import Network.Wai (Application)

import Test.Hspec
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON

import PostgREST.Config (AppConfig (..), OpenAPIMode (..))

import Protolude
import SpecHelper

spec :: SpecWith ((), Application)
spec =
spec :: SpecWithConfig
spec withConfig = withConfig (baseCfg { configOpenApiMode = OADisabled }) $
describe "Disabled OpenApi" $ do
it "responds with 404" $
request methodGet "/"
Expand Down
13 changes: 10 additions & 3 deletions test/spec/Feature/OpenApi/IgnorePrivOpenApiSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,26 @@ import Control.Lens ((^?))

import Data.Aeson.Lens
import Data.Aeson.QQ
import Data.List.NonEmpty (fromList)

import Network.HTTP.Types
import Network.Wai (Application)
import Network.Wai.Test (SResponse (..))

import Test.Hspec hiding (pendingWith)
import Test.Hspec.Wai

import PostgREST.Config (AppConfig (..), OpenAPIMode (..))

import Protolude hiding (get)
import SpecHelper

spec :: SpecWith ((), Application)
spec = describe "OpenAPI Ignore Privileges" $ do
spec :: SpecWithConfig
spec withConfig = withConfig (
baseCfg {
configOpenApiMode = OAIgnorePriv
, configDbSchemas = fromList ["test", "v1"]
}
) $ describe "OpenAPI Ignore Privileges" $ do
it "root path returns a valid openapi spec" $ do
validateOpenApiResponse [("Accept", "application/openapi+json")]
request methodHead "/"
Expand Down
5 changes: 2 additions & 3 deletions test/spec/Feature/OpenApi/OpenApiSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ module Feature.OpenApi.OpenApiSpec where

import Control.Lens ((^?))
import Data.Aeson.Types (Value (..))
import Network.Wai (Application)
import Network.Wai.Test (SResponse (..))

import Data.Aeson.Lens
Expand All @@ -15,8 +14,8 @@ import PostgREST.Version (docsVersion)
import Protolude hiding (get)
import SpecHelper

spec :: SpecWith ((), Application)
spec = describe "OpenAPI" $ do
spec :: SpecWithConfig
spec withConfig = withConfig baseCfg $ describe "OpenAPI" $ do
it "root path returns a valid openapi spec" $ do
validateOpenApiResponse [("Accept", "application/openapi+json")]
request methodHead "/"
Expand Down
9 changes: 5 additions & 4 deletions test/spec/Feature/OpenApi/ProxySpec.hs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
module Feature.OpenApi.ProxySpec where

import Network.Wai (Application)
import Test.Hspec hiding (pendingWith)
import Test.Hspec hiding (pendingWith)

import PostgREST.Config (AppConfig (..))

import Protolude
import SpecHelper

spec :: SpecWith ((), Application)
spec =
spec :: SpecWithConfig
spec withConfig = withConfig (baseCfg { configOpenApiServerProxyUri = Just "https://postgrest.com/openapi.json" }) $
describe "GET / with proxy" $
it "returns a valid openapi spec with proxy" $
validateOpenApiResponse [("Accept", "application/openapi+json")]
11 changes: 7 additions & 4 deletions test/spec/Feature/OpenApi/RootSpec.hs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
module Feature.OpenApi.RootSpec where

import Network.HTTP.Types
import Network.Wai (Application)

import Test.Hspec hiding (pendingWith)
import Test.Hspec.Wai
import Test.Hspec.Wai.JSON

import Protolude hiding (get)
import PostgREST.Config (AppConfig (..))
import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..))

spec :: SpecWith ((), Application)
spec =
import Protolude hiding (get)
import SpecHelper

spec :: SpecWithConfig
spec withConfig = withConfig (baseCfg { configDbRootSpec = Just $ QualifiedIdentifier mempty "root" }) $
describe "root spec function" $ do
it "accepts application/openapi+json" $ do
request methodGet "/"
Expand Down
Loading
Loading