From 85d9feeeabb7ee3ede9515d7f6a9fba1c0a3124a Mon Sep 17 00:00:00 2001 From: steve-chavez Date: Thu, 12 Oct 2017 19:08:12 -0500 Subject: [PATCH] Add `set schema` to middleware Fix #828, breaking change: computed columns now only work if they are on the config schema. Fix #835, tests now not depend on the search_path of the postgrest_test_authenticator. --- CHANGELOG.md | 6 ++++++ src/PostgREST/Middleware.hs | 3 ++- test/Feature/QuerySpec.hs | 3 +++ test/Feature/StructureSpec.hs | 2 +- test/fixtures/jwt.sql | 3 +-- test/fixtures/privileges.sql | 2 ++ test/fixtures/schema.sql | 25 +++++++++---------------- 7 files changed, 24 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51a7d7aae..cd23774ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +- #828, Fix computed column only working in public schema - @steve-chavez + +### Changed + +- Computed columns now only work if they belong to the db-schema - @steve-chavez + ## [0.4.4.0] - 2018-01-08 ### Added diff --git a/src/PostgREST/Middleware.hs b/src/PostgREST/Middleware.hs index 04043572b..868443000 100644 --- a/src/PostgREST/Middleware.hs +++ b/src/PostgREST/Middleware.hs @@ -32,7 +32,7 @@ runWithClaims conf eClaims app req = JWTInvalid e -> return $ unauthed $ show e JWTMissingSecret -> return $ simpleError status500 [] "Server lacks JWT secret" JWTClaims claims -> do - H.sql $ toS.mconcat $ setRoleSql ++ claimsSql ++ headersSql ++ cookiesSql + H.sql $ toS.mconcat $ setSchemaSql ++ setRoleSql ++ claimsSql ++ headersSql ++ cookiesSql mapM_ H.sql customReqCheck app req where @@ -41,6 +41,7 @@ runWithClaims conf eClaims app req = claimsSql = map (pgFmtEnvVar "request.jwt.claim.") [(c,unquoted v) | (c,v) <- M.toList claimsWithRole] setRoleSql = maybeToList $ (\r -> "set local role " <> r <> ";") . toS . pgFmtLit . unquoted <$> M.lookup "role" claimsWithRole + setSchemaSql = ["set schema " <> pgFmtLit (configSchema conf) <> ";"] :: [Text] -- role claim defaults to anon if not specified in jwt claimsWithRole = M.union claims (M.singleton "role" anon) anon = String . toS $ configAnonRole conf diff --git a/test/Feature/QuerySpec.hs b/test/Feature/QuerySpec.hs index eff82e7bc..9ef607d48 100644 --- a/test/Feature/QuerySpec.hs +++ b/test/Feature/QuerySpec.hs @@ -171,6 +171,9 @@ spec = do [json| [{"id":1},{"id":2},{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9},{"id":10},{"id":11},{"id":12},{"id":13},{"id":14},{"id":15}] |] { matchHeaders = [matchContentTypeJson] } + it "cannot access a computed column that is outside of the config schema" $ + get "/items?always_false=is.false" `shouldRespondWith` 400 + it "matches filtering nested items 2" $ get "/clients?select=id,projects{id,tasks2{id,name}}&projects.tasks.name=like.Design*" `shouldRespondWith` [json| {"message":"Could not find foreign keys between these entities, No relation found between projects and tasks2"}|] diff --git a/test/Feature/StructureSpec.hs b/test/Feature/StructureSpec.hs index 26ab0ef9f..89081e4d3 100644 --- a/test/Feature/StructureSpec.hs +++ b/test/Feature/StructureSpec.hs @@ -173,7 +173,7 @@ spec = do "type": "string" }, "enum": { - "format": "test.enum_menagerie_type", + "format": "enum_menagerie_type", "type": "string" }, "integer": { diff --git a/test/fixtures/jwt.sql b/test/fixtures/jwt.sql index 359184e33..554034e1e 100644 --- a/test/fixtures/jwt.sql +++ b/test/fixtures/jwt.sql @@ -4,7 +4,6 @@ set client_min_messages to warning; DROP SCHEMA IF EXISTS jwt CASCADE; CREATE SCHEMA jwt; - CREATE OR REPLACE FUNCTION jwt.url_encode(data bytea) RETURNS text LANGUAGE sql AS $$ SELECT translate(encode(data, 'base64'), E'+/=\n', '-_'); $$; @@ -31,7 +30,7 @@ WITH WHEN algorithm = 'HS384' THEN 'sha384' WHEN algorithm = 'HS512' THEN 'sha512' ELSE '' END) -- hmac throws error -SELECT jwt.url_encode(hmac(signables, secret, (select * FROM alg))); +SELECT jwt.url_encode(public.hmac(signables, secret, (select * FROM alg))); $$; diff --git a/test/fixtures/privileges.sql b/test/fixtures/privileges.sql index 025852b6e..7670bc5ea 100644 --- a/test/fixtures/privileges.sql +++ b/test/fixtures/privileges.sql @@ -81,3 +81,5 @@ GRANT UPDATE (article_id, user_id) ON TABLE limited_article_stars TO postgrest_t REVOKE EXECUTE ON FUNCTION privileged_hello(text) FROM PUBLIC; -- All functions are available to every role(PUBLIC) by default GRANT EXECUTE ON FUNCTION privileged_hello(text) TO postgrest_test_author; + +GRANT USAGE ON SCHEMA test TO postgrest_test_default_role; diff --git a/test/fixtures/schema.sql b/test/fixtures/schema.sql index f85db180f..a8206d027 100755 --- a/test/fixtures/schema.sql +++ b/test/fixtures/schema.sql @@ -112,16 +112,19 @@ CREATE TABLE items ( ); -SET search_path = public, pg_catalog; - --- --- Name: always_true(test.items); Type: FUNCTION; Schema: public; Owner: - --- - CREATE FUNCTION always_true(test.items) RETURNS boolean LANGUAGE sql STABLE AS $$ SELECT true $$; +CREATE FUNCTION anti_id(test.items) RETURNS bigint + LANGUAGE sql STABLE + AS $_$ SELECT $1.id * -1 $_$; + +SET search_path = public, pg_catalog; + +CREATE FUNCTION always_false(test.items) RETURNS boolean + LANGUAGE sql STABLE + AS $$ SELECT false $$; create table public_consumers ( id serial not null unique, @@ -136,16 +139,6 @@ create table public_orders ( primary key (id) ); --- --- Name: anti_id(test.items); Type: FUNCTION; Schema: public; Owner: - --- - -CREATE FUNCTION anti_id(test.items) RETURNS bigint - LANGUAGE sql STABLE - AS $_$ SELECT $1.id * -1 $_$; - - - SET search_path = تست, pg_catalog; CREATE TABLE موارد (