From a192cadcedf93c5f7c61b0865591c33a31249190 Mon Sep 17 00:00:00 2001 From: Diogo Biazus Date: Tue, 20 Oct 2015 19:20:53 -0400 Subject: [PATCH] All green :D --- src/PostgREST/PgStructure.hs | 4 ++-- test/Feature/AuthSpec.hs | 45 +++-------------------------------- test/Feature/InsertSpec.hs | 3 ++- test/Feature/StructureSpec.hs | 3 +-- test/fixtures/schema.sql | 35 +++++++++++++++++++-------- 5 files changed, 33 insertions(+), 57 deletions(-) diff --git a/src/PostgREST/PgStructure.hs b/src/PostgREST/PgStructure.hs index a33d7829d..df736cf3a 100644 --- a/src/PostgREST/PgStructure.hs +++ b/src/PostgREST/PgStructure.hs @@ -44,7 +44,7 @@ doesProcReturnJWT = doesProc [H.stmt| ON pronamespace = n.oid WHERE nspname = ? AND proname = ? - AND pg_catalog.pg_get_function_result(p.oid) = 'jwt' + AND pg_catalog.pg_get_function_result(p.oid) = 'jwt_claims' |] tableFromRow :: (Text, Text, Bool, Maybe Text) -> Table @@ -167,7 +167,7 @@ allRelations = do allColumns :: [Relation] -> H.Tx P.Postgres s [Column] allColumns rels = do cols <- H.listEx $ [H.stmt| - SELECT + SELECT DISTINCT info.table_schema AS schema, info.table_name AS table_name, info.column_name AS name, diff --git a/test/Feature/AuthSpec.hs b/test/Feature/AuthSpec.hs index 7362e7a15..c12bcdee0 100644 --- a/test/Feature/AuthSpec.hs +++ b/test/Feature/AuthSpec.hs @@ -18,50 +18,11 @@ spec = beforeAll it "hides tables that anonymous does not own" $ get "/authors_only" `shouldRespondWith` 404 - it "indicates login failure (BasicAuth)" $ do - let auth = authHeaderBasic "postgrest_test_author" "fakefake" - request methodGet "/authors_only" [auth] "" - `shouldRespondWith` 401 - - it "allows users with permissions to see their tables (BasicAuth)" $ do - _ <- post "/postgrest/users" [json| { "id": "jdoe", "pass": "1234", "role": "postgrest_test_author" } |] - let auth = authHeaderBasic "jdoe" "1234" - request methodGet "/authors_only" [auth] "" - `shouldRespondWith` 200 - - it "respects database constraints for role" $ - post "/postgrest/users" [json| { "id": "ssmith", "pass": "1234", "role": "SUPER_ADMIN_TRUNCATE_POWERS" } |] - `shouldRespondWith` 400 - - it "does not send a value when no role is provided" $ do - post "/postgrest/users" [json| { "id": "bdeey", "pass": "1234" } |] - `shouldRespondWith` 201 - let auth = authHeaderBasic "jdoe" "1234" - request methodGet "/authors_only" [auth] "" - `shouldRespondWith` 200 - - it "recovers after 400 error with logged in user" $ do - _ <- post "/postgrest/users" [json| { "id": "jdoe", "pass": "1234", "role": "postgrest_test_author" } |] - let auth = authHeaderBasic "jdoe" "1234" - _ <- request methodPost "/rpc/problem" [auth] "" - request methodGet "/authors_only" [auth] "" - `shouldRespondWith` 200 - - it "allows users to login (JWT)" $ do - _ <- post "/postgrest/users" [json| { "id": "jdoe", "pass": "1234", "role": "postgrest_test_author" } |] - post "/postgrest/tokens" [json| { "id": "jdoe", "pass": "1234" } |] + it "returns jwt functions as jwt tokens" $ do + post "/rpc/login" [json| { "id": "jdoe", "pass": "1234" } |] `shouldRespondWith` ResponseMatcher { matchBody = Just [json| {"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIiwiaWQiOiJqZG9lIn0.y4vZuu1dDdwAl0-S00MCRWRYMlJ5YAMSir6Es6WtWx0"} |] - , matchStatus = 201 - , matchHeaders = ["Content-Type" <:> "application/json"] - } - - it "indicates login failure (JWT)" $ do - _ <- post "/postgrest/users" [json| { "id": "jdoe", "pass": "1234", "role": "postgrest_test_author" } |] - post "/postgrest/tokens" [json| { "id": "jdoe", "pass": "NOPE" } |] - `shouldRespondWith` ResponseMatcher { - matchBody = Just [json| {"message":"Failed authentication."} |] - , matchStatus = 401 + , matchStatus = 200 , matchHeaders = ["Content-Type" <:> "application/json"] } diff --git a/test/Feature/InsertSpec.hs b/test/Feature/InsertSpec.hs index 7d19e5683..91c5c0b04 100644 --- a/test/Feature/InsertSpec.hs +++ b/test/Feature/InsertSpec.hs @@ -284,11 +284,12 @@ spec = afterAll_ resetDb $ around withApp $ do describe "Row level permission" $ it "set user_id when inserting rows" $ do + let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIiwiaWQiOiJqZG9lIn0.y4vZuu1dDdwAl0-S00MCRWRYMlJ5YAMSir6Es6WtWx0" _ <- post "/postgrest/users" [json| { "id":"jdoe", "pass": "1234", "role": "postgrest_test_author" } |] _ <- post "/postgrest/users" [json| { "id":"jroe", "pass": "1234", "role": "postgrest_test_author" } |] p1 <- request methodPost "/authors_only" - [ authHeaderBasic "jdoe" "1234", ("Prefer", "return=representation") ] + [ auth, ("Prefer", "return=representation") ] [json| { "secret": "nyancat" } |] liftIO $ do simpleBody p1 `shouldBe` [json| { "owner":"jdoe", "secret":"nyancat" } |] diff --git a/test/Feature/StructureSpec.hs b/test/Feature/StructureSpec.hs index 187584f28..2a28f43db 100644 --- a/test/Feature/StructureSpec.hs +++ b/test/Feature/StructureSpec.hs @@ -40,8 +40,7 @@ spec = around withApp $ do {matchStatus = 200} it "lists only views user has permission to see" $ do - _ <- post "/postgrest/users" [json| { "id":"jdoe", "pass": "1234", "role": "postgrest_test_author" } |] - let auth = authHeaderBasic "jdoe" "1234" + let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXN0X3Rlc3RfYXV0aG9yIiwiaWQiOiJqZG9lIn0.y4vZuu1dDdwAl0-S00MCRWRYMlJ5YAMSir6Es6WtWx0" request methodGet "/" [auth] "" `shouldRespondWith` [json| [ diff --git a/test/fixtures/schema.sql b/test/fixtures/schema.sql index 2066c4f68..61ab265c6 100755 --- a/test/fixtures/schema.sql +++ b/test/fixtures/schema.sql @@ -76,7 +76,7 @@ CREATE FUNCTION set_authors_only_owner() RETURNS trigger LANGUAGE plpgsql AS $$ begin - NEW.owner = current_setting('user_vars.user_id'); + NEW.owner = current_setting('postgrest.claims.id'); RETURN NEW; end $$; @@ -268,15 +268,6 @@ CREATE VIEW test.projects_view AS projects.client_id FROM projects; ALTER TABLE test.projects_view OWNER TO postgrest_test; -------- SAMPLE DATA ----- -INSERT INTO clients VALUES (1, 'Microsoft'),(2, 'Apple'); -INSERT INTO projects VALUES (1,'Windows 7', 1),(2,'Windows 10', 1),(3,'IOS', 2),(4,'OSX', 2); -INSERT INTO tasks VALUES (1,'Design w7',1),(2,'Code w7',1),(3,'Design w10',2),(4,'Code w10',2),(5,'Design IOS',3),(6,'Code IOS',3),(7,'Design OSX',4),(8,'Code OSX',4); -INSERT INTO users VALUES (1, 'Angela Martin'),(2, 'Michael Scott'),(3, 'Dwight Schrute'); -INSERT INTO users_projects VALUES(1,1),(1,2),(2,3),(2,4),(3,1),(3,3); -INSERT INTO users_tasks VALUES(1,1),(1,2),(1,3),(1,4),(2,5),(2,6),(2,7),(3,1),(3,5); -INSERT INTO comments VALUES (1, 1, 2, 6, 'Needs to be delivered ASAP'); ----------------- CREATE SEQUENCE items_id_seq START WITH 1 @@ -298,6 +289,13 @@ CREATE FUNCTION test.getitemrange(min bigint, max bigint) RETURNS SETOF test.ite $$ LANGUAGE SQL; +CREATE TYPE public.jwt_claims AS (role text, id text); +CREATE FUNCTION test.login(id text, pass text) +RETURNS public.jwt_claims +SECURITY DEFINER +AS $$ +SELECT rolname::text, id::text FROM postgrest.auth WHERE id = id AND pass = pass; +$$ LANGUAGE SQL; CREATE FUNCTION test.sayhello(name text) RETURNS text AS $$ SELECT 'Hello, ' || $1; @@ -663,6 +661,10 @@ REVOKE ALL ON FUNCTION getitemrange(bigint, bigint) FROM postgrest_test; GRANT EXECUTE ON FUNCTION getitemrange(bigint, bigint) TO postgrest_test; GRANT EXECUTE ON FUNCTION getitemrange(bigint, bigint) TO postgrest_anonymous; +REVOKE ALL ON FUNCTION login(text, text) FROM PUBLIC; +REVOKE ALL ON FUNCTION login(text, text) FROM postgrest_test; +GRANT EXECUTE ON FUNCTION login(text, text) TO postgrest_test; +GRANT EXECUTE ON FUNCTION login(text, text) TO postgrest_anonymous; REVOKE ALL ON FUNCTION sayhello(text) FROM PUBLIC; REVOKE ALL ON FUNCTION sayhello(text) FROM postgrest_test; @@ -758,3 +760,16 @@ SET search_path = private, pg_catalog; REVOKE ALL ON TABLE articles FROM PUBLIC; REVOKE ALL ON TABLE articles FROM postgrest_test; GRANT ALL ON TABLE articles TO postgrest_test; + +SET search_path = test, private, postgrest, public, pg_catalog; + +------- SAMPLE DATA ----- +INSERT INTO clients VALUES (1, 'Microsoft'),(2, 'Apple'); +INSERT INTO projects VALUES (1,'Windows 7', 1),(2,'Windows 10', 1),(3,'IOS', 2),(4,'OSX', 2); +INSERT INTO tasks VALUES (1,'Design w7',1),(2,'Code w7',1),(3,'Design w10',2),(4,'Code w10',2),(5,'Design IOS',3),(6,'Code IOS',3),(7,'Design OSX',4),(8,'Code OSX',4); +INSERT INTO users VALUES (1, 'Angela Martin'),(2, 'Michael Scott'),(3, 'Dwight Schrute'); +INSERT INTO users_projects VALUES(1,1),(1,2),(2,3),(2,4),(3,1),(3,3); +INSERT INTO users_tasks VALUES(1,1),(1,2),(1,3),(1,4),(2,5),(2,6),(2,7),(3,1),(3,5); +INSERT INTO comments VALUES (1, 1, 2, 6, 'Needs to be delivered ASAP'); +INSERT INTO postgrest.auth (id, pass, rolname) VALUES ('jdoe', '1234', 'postgrest_test_author'); +----------------