Move BackendOnlyPermissionsSpec

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5539
GitOrigin-RevId: 96851c840ea945af250c8eb876ea183b8384f5d9
This commit is contained in:
Tom Harding 2022-08-19 13:57:45 +01:00 committed by hasura-bot
parent 8600d78456
commit 283d51668f
3 changed files with 355 additions and 347 deletions

View File

@ -1232,7 +1232,6 @@ test-suite tests-hspec
-- Test
Test.ArrayParamPermissionSpec
Test.BackendOnlyPermissionsSpec
Test.BigQuery.ComputedFieldSpec
Test.BigQuery.Metadata.ComputedFieldSpec
Test.BigQuery.Queries.SpatialTypesSpec
@ -1261,6 +1260,7 @@ test-suite tests-hspec
Test.HelloWorldSpec
Test.LongIdentifiersSpec
Test.Mutations.MultiplePerRequest.UpdateManySpec
Test.Postgres.BackendOnlyPermissionsSpec
Test.Postgres.DefaultValuesSpec
Test.Postgres.TimestampSpec
Test.Postgres.UniqueConstraintsSpec

View File

@ -1,346 +0,0 @@
{-# LANGUAGE QuasiQuotes #-}
-- | Test backend only permissions
module Test.BackendOnlyPermissionsSpec (spec) where
import Data.List.NonEmpty qualified as NE
import Harness.Backend.Postgres qualified as Postgres
import Harness.GraphqlEngine qualified as GraphqlEngine
import Harness.Quoter.Graphql (graphql)
import Harness.Quoter.Yaml (yaml)
import Harness.Test.Fixture qualified as Fixture
import Harness.Test.Schema (Table (..), table)
import Harness.Test.Schema qualified as Schema
import Harness.TestEnvironment (TestEnvironment)
import Harness.Yaml (shouldReturnYaml)
import Hasura.Prelude
import Test.Hspec (SpecWith, describe, it)
--------------------------------------------------------------------------------
-- ** Preamble
spec :: SpecWith TestEnvironment
spec =
-- Postgres
Fixture.run
( NE.fromList
[ (Fixture.fixture $ Fixture.Backend Fixture.Postgres)
{ Fixture.setupTeardown = \(testEnv, _) ->
[ Postgres.setupTablesAction schema testEnv
]
<> postgresPermissionsSetup testEnv
}
]
)
tests
--------------------------------------------------------------------------------
-- ** Schema
schema :: [Schema.Table]
schema = [author, article]
author :: Schema.Table
author =
(table "author")
{ tableColumns =
[ Schema.column "id" Schema.TInt,
Schema.column "name" Schema.TStr
],
tablePrimaryKey = ["id"],
tableData =
[ [Schema.VInt 1, Schema.VStr "Author 1"],
[Schema.VInt 2, Schema.VStr "Author 2"]
]
}
article :: Schema.Table
article =
(table "article")
{ tableColumns =
[ Schema.column "id" Schema.TInt,
Schema.column "title" Schema.TStr,
Schema.columnNull "content" Schema.TStr,
Schema.column "author_id" Schema.TInt
],
tablePrimaryKey = ["id"],
tableReferences = [Schema.Reference "author_id" "author" "id"]
}
--------------------------------------------------------------------------------
-- ** Postgres Setup and teardown
postgresPermissionsSetup :: TestEnvironment -> [Fixture.SetupAction]
postgresPermissionsSetup testEnvironment =
[ Fixture.SetupAction
{ setupAction =
GraphqlEngine.postMetadata_
testEnvironment
[yaml|
type: pg_create_update_permission
args:
table:
schema: hasura
name: author
source: postgres
role: backend_only_role
permission:
columns:
- name
filter:
id: x-hasura-user-id
check:
name:
_ne: ""
backend_only: true
|],
teardownAction = \_ ->
GraphqlEngine.postMetadata_
testEnvironment
[yaml|
type: pg_drop_update_permission
args:
table:
schema: hasura
name: author
source: postgres
role: backend_only_role
|]
},
Fixture.SetupAction
{ setupAction =
GraphqlEngine.postMetadata_
testEnvironment
[yaml|
type: pg_create_update_permission
args:
table:
schema: hasura
name: author
source: postgres
role: frontend_only_role
permission:
columns:
- name
filter:
id: x-hasura-user-id
check:
name:
_ne: ""
|],
teardownAction = \_ ->
GraphqlEngine.postMetadata_
testEnvironment
[yaml|
type: pg_drop_update_permission
args:
table:
schema: hasura
name: author
source: postgres
role: frontend_only_role
|]
},
Fixture.SetupAction
{ setupAction =
GraphqlEngine.postMetadata_
testEnvironment
[yaml|
type: pg_create_delete_permission
args:
table:
schema: hasura
name: author
source: postgres
role: backend_only_role
permission:
filter:
id: x-hasura-user-id
backend_only: true
|],
teardownAction = \_ ->
GraphqlEngine.postMetadata_
testEnvironment
[yaml|
type: pg_drop_delete_permission
args:
table:
schema: hasura
name: author
source: postgres
role: backend_only_role
|]
},
Fixture.SetupAction
{ setupAction =
GraphqlEngine.postMetadata_
testEnvironment
[yaml|
type: pg_create_delete_permission
args:
table:
schema: hasura
name: author
source: postgres
role: frontend_only_role
permission:
filter:
id: x-hasura-user-id
|],
teardownAction = \_ ->
GraphqlEngine.postMetadata_
testEnvironment
[yaml|
type: pg_drop_delete_permission
args:
table:
schema: hasura
name: author
source: postgres
role: frontend_only_role
|]
}
]
-------------------------------------------------------------------------------
tests :: Fixture.Options -> SpecWith TestEnvironment
tests opts = do
describe "backend-only fields should be exposed to a role with `backend_only` set to `true`" $ do
let userHeaders = [("X-Hasura-Role", "backend_only_role"), ("X-Hasura-User-Id", "1"), ("X-Hasura-use-backend-only-permissions", "true")]
it "update root field should be accesible" $ \testEnvironment -> do
let query =
[graphql|
mutation {
update_hasura_author (_set: {name: "Author 1 modified"}, where: {}) {
affected_rows
}
}
|]
expectedResponse =
[yaml|
data:
update_hasura_author:
affected_rows: 1
|]
shouldReturnYaml
opts
(GraphqlEngine.postGraphqlWithHeaders testEnvironment userHeaders query)
expectedResponse
it "delete root field should be accesible" $ \testEnvironment -> do
let query =
[graphql|
mutation {
delete_hasura_author (where: {}) {
affected_rows
}
}
|]
expectedResponse =
[yaml|
data:
delete_hasura_author:
affected_rows: 1
|]
shouldReturnYaml
opts
(GraphqlEngine.postGraphqlWithHeaders testEnvironment userHeaders query)
expectedResponse
describe "backend-only fields should not be exposed to a role with `backend_only` set to `true` but `X-Hasura-use-backend-only-permissions` set to `false`" $ do
let userHeaders = [("X-Hasura-Role", "backend_only_role"), ("X-Hasura-User-Id", ""), ("X-Hasura-use-backend-only-permissions", "false")]
it "update root field should not be accesible" $ \testEnvironment -> do
let query =
[graphql|
mutation {
update_hasura_author (_set: {name: "Author 1 modified"}, where: {}) {
affected_rows
}
}
|]
expectedResponse =
[yaml|
errors:
- extensions:
path: $
code: validation-failed
message: no mutations exist
|]
shouldReturnYaml
opts
(GraphqlEngine.postGraphqlWithHeaders testEnvironment userHeaders query)
expectedResponse
it "delete root field should not be accesible" $ \testEnvironment -> do
let query =
[graphql|
mutation {
delete_hasura_author (where: {}) {
affected_rows
}
}
|]
expectedResponse =
[yaml|
errors:
- extensions:
path: $
code: validation-failed
message: no mutations exist
|]
shouldReturnYaml
opts
(GraphqlEngine.postGraphqlWithHeaders testEnvironment userHeaders query)
expectedResponse
describe "backend-only fields should be exposed to a role with `backend_only` set to `false`" $ do
let userHeaders = [("X-Hasura-Role", "frontend_only_role"), ("X-Hasura-User-Id", "2"), ("X-Hasura-use-backend-only-permissions", "true")]
it "update root field should be accesible" $ \testEnvironment -> do
let query =
[graphql|
mutation {
update_hasura_author (_set: {name: "Author 2 modified"}, where: {}) {
affected_rows
}
}
|]
expectedResponse =
[yaml|
data:
update_hasura_author:
affected_rows: 1
|]
shouldReturnYaml
opts
(GraphqlEngine.postGraphqlWithHeaders testEnvironment userHeaders query)
expectedResponse
it "delete root field should be accesible" $ \testEnvironment -> do
let query =
[graphql|
mutation {
delete_hasura_author (where: {}) {
affected_rows
}
}
|]
expectedResponse =
[yaml|
data:
delete_hasura_author:
affected_rows: 1
|]
shouldReturnYaml
opts
(GraphqlEngine.postGraphqlWithHeaders testEnvironment userHeaders query)
expectedResponse

View File

@ -0,0 +1,354 @@
{-# LANGUAGE QuasiQuotes #-}
-- |
-- Tests for backend-only permissions.
--
-- https://hasura.io/docs/latest/schema/postgres/data-validations/#using-hasura-permissions
module Test.Postgres.BackendOnlyPermissionsSpec (spec) where
import Data.Aeson (Value)
import Data.ByteString (ByteString)
import Data.List.NonEmpty qualified as NE
import Harness.Backend.Postgres qualified as Postgres
import Harness.GraphqlEngine (postGraphqlWithHeaders, postMetadata_)
import Harness.Quoter.Graphql (graphql)
import Harness.Quoter.Yaml (yaml)
import Harness.Test.Fixture qualified as Fixture
import Harness.Test.Schema (Table (..), table)
import Harness.Test.Schema qualified as Schema
import Harness.TestEnvironment (TestEnvironment)
import Harness.Yaml (shouldReturnYaml)
import Hasura.Prelude
import Network.HTTP.Types.Header (HeaderName)
import Test.Hspec (SpecWith, describe, it)
spec :: SpecWith TestEnvironment
spec =
Fixture.run
( NE.fromList
[ (Fixture.fixture $ Fixture.Backend Fixture.Postgres)
{ Fixture.setupTeardown = \(testEnvironment, _) ->
[ Postgres.setupTablesAction schema testEnvironment,
setupMetadata testEnvironment
]
}
]
)
tests
--------------------------------------------------------------------------------
-- Schema
schema :: [Schema.Table]
schema =
[ (table "author")
{ tableColumns =
[ Schema.column "id" Schema.TInt,
Schema.column "name" Schema.TStr
],
tablePrimaryKey = ["id"],
tableData =
[ [Schema.VInt 1, Schema.VStr "Author 1"],
[Schema.VInt 2, Schema.VStr "Author 2"]
]
},
(table "article")
{ tableColumns =
[ Schema.column "id" Schema.TInt,
Schema.column "title" Schema.TStr,
Schema.columnNull "content" Schema.TStr,
Schema.column "author_id" Schema.TInt
],
tablePrimaryKey = ["id"],
tableReferences = [Schema.Reference "author_id" "author" "id"]
}
]
-------------------------------------------------------------------------------
-- Tests
tests :: Fixture.Options -> SpecWith TestEnvironment
tests opts = do
let shouldBe :: IO Value -> Value -> IO ()
shouldBe = shouldReturnYaml opts
describe "Backend-only fields should be exposed to a role with `backend_only` set to `true`" do
let headers =
[ ("X-Hasura-Role", "backend_only_role"),
("X-Hasura-User-Id", "1"),
("X-Hasura-use-backend-only-permissions", "true")
]
it "Update root field should be accesible" \testEnvironment -> do
let expected :: Value
expected =
[yaml|
data:
update_hasura_author:
affected_rows: 1
|]
actual :: IO Value
actual =
postGraphqlWithHeaders
testEnvironment
headers
[graphql|
mutation {
update_hasura_author (_set: { name: "Author 1 modified" }, where: {}) {
affected_rows
}
}
|]
actual `shouldBe` expected
it "Delete root field should be accesible" \testEnvironment -> do
let expected :: Value
expected =
[yaml|
data:
delete_hasura_author:
affected_rows: 1
|]
actual :: IO Value
actual =
postGraphqlWithHeaders
testEnvironment
headers
[graphql|
mutation {
delete_hasura_author (where: {}) {
affected_rows
}
}
|]
actual `shouldBe` expected
describe "Backend-only fields should not be exposed to a role with `backend_only` set to `true` but `X-Hasura-use-backend-only-permissions` set to `false`" do
let headers :: [(HeaderName, ByteString)]
headers =
[ ("X-Hasura-Role", "backend_only_role"),
("X-Hasura-User-Id", ""),
("X-Hasura-use-backend-only-permissions", "false")
]
it "Update root field should not be accesible" \testEnvironment -> do
let expected :: Value
expected =
[yaml|
errors:
- extensions:
path: $
code: validation-failed
message: no mutations exist
|]
actual :: IO Value
actual =
postGraphqlWithHeaders
testEnvironment
headers
[graphql|
mutation {
update_hasura_author (
_set: { name: "Author 1 modified" },
where: {}
) {
affected_rows
}
}
|]
actual `shouldBe` expected
it "Delete root field should not be accesible" \testEnvironment -> do
let expected :: Value
expected =
[yaml|
errors:
- extensions:
path: $
code: validation-failed
message: no mutations exist
|]
actual :: IO Value
actual =
postGraphqlWithHeaders
testEnvironment
headers
[graphql|
mutation {
delete_hasura_author (where: {}) {
affected_rows
}
}
|]
actual `shouldBe` expected
describe "Backend-only fields should be exposed to a role with `backend_only` set to `false`" do
let headers =
[ ("X-Hasura-Role", "frontend_only_role"),
("X-Hasura-User-Id", "2"),
("X-Hasura-use-backend-only-permissions", "true")
]
it "Update root field should be accesible" \testEnvironment -> do
let expected :: Value
expected =
[yaml|
data:
update_hasura_author:
affected_rows: 1
|]
actual :: IO Value
actual =
postGraphqlWithHeaders
testEnvironment
headers
[graphql|
mutation {
update_hasura_author (
_set: { name: "Author 2 modified" },
where: {}
) {
affected_rows
}
}
|]
actual `shouldBe` expected
it "Delete root field should be accesible" \testEnvironment -> do
let expected :: Value
expected =
[yaml|
data:
delete_hasura_author:
affected_rows: 1
|]
actual :: IO Value
actual =
postGraphqlWithHeaders
testEnvironment
headers
[graphql|
mutation {
delete_hasura_author (where: {}) {
affected_rows
}
}
|]
actual `shouldBe` expected
--------------------------------------------------------------------------------
-- Metadata
setupMetadata :: TestEnvironment -> Fixture.SetupAction
setupMetadata testEnvironment = do
let setup :: IO ()
setup =
postMetadata_
testEnvironment
[yaml|
type: bulk
args:
- type: pg_create_update_permission
args:
table:
schema: hasura
name: author
source: postgres
role: backend_only_role
permission:
columns:
- name
filter:
id: x-hasura-user-id
check:
name:
_ne: ""
backend_only: true
- type: pg_create_update_permission
args:
table:
schema: hasura
name: author
source: postgres
role: frontend_only_role
permission:
columns:
- name
filter:
id: x-hasura-user-id
check:
name:
_ne: ""
- type: pg_create_delete_permission
args:
table:
schema: hasura
name: author
source: postgres
role: backend_only_role
permission:
filter:
id: x-hasura-user-id
backend_only: true
- type: pg_create_delete_permission
args:
table:
schema: hasura
name: author
source: postgres
role: frontend_only_role
permission:
filter:
id: x-hasura-user-id
|]
teardown :: IO ()
teardown =
postMetadata_
testEnvironment
[yaml|
type: bulk
args:
- type: pg_drop_delete_permission
args:
table:
schema: hasura
name: author
source: postgres
role: frontend_only_role
- type: pg_drop_delete_permission
args:
table:
schema: hasura
name: author
source: postgres
role: backend_only_role
- type: pg_drop_update_permission
args:
table:
schema: hasura
name: author
source: postgres
role: frontend_only_role
- type: pg_drop_update_permission
args:
table:
schema: hasura
name: author
source: postgres
role: backend_only_role
|]
Fixture.SetupAction setup \_ -> teardown