2022-05-31 17:41:09 +03:00
{- # LANGUAGE QuasiQuotes # -}
-- | Test backend only permissions
module Test.BackendOnlyPermissionsSpec ( spec ) where
2022-08-11 18:03:04 +03:00
import Data.List.NonEmpty qualified as NE
2022-05-31 17:41:09 +03:00
import Harness.Backend.Postgres qualified as Postgres
import Harness.GraphqlEngine qualified as GraphqlEngine
import Harness.Quoter.Graphql ( graphql )
2022-08-05 12:34:25 +03:00
import Harness.Quoter.Yaml ( yaml )
2022-08-10 16:07:58 +03:00
import Harness.Test.Fixture qualified as Fixture
2022-06-17 11:44:04 +03:00
import Harness.Test.Schema ( Table ( .. ) , table )
2022-05-31 17:41:09 +03:00
import Harness.Test.Schema qualified as Schema
import Harness.TestEnvironment ( TestEnvironment )
2022-08-05 12:34:25 +03:00
import Harness.Yaml ( shouldReturnYaml )
2022-08-03 17:18:43 +03:00
import Hasura.Prelude
2022-05-31 17:41:09 +03:00
import Test.Hspec ( SpecWith , describe , it )
--------------------------------------------------------------------------------
-- ** Preamble
spec :: SpecWith TestEnvironment
spec =
2022-08-10 16:07:58 +03:00
-- Postgres
Fixture . run
2022-08-11 18:03:04 +03:00
( NE . fromList
[ ( Fixture . fixture $ Fixture . Backend Fixture . Postgres )
{ Fixture . setupTeardown = \ ( testEnv , _ ) ->
[ Postgres . setupTablesAction schema testEnv
]
<> postgresPermissionsSetup testEnv
}
]
)
2022-05-31 17:41:09 +03:00
tests
--------------------------------------------------------------------------------
-- ** Schema
schema :: [ Schema . Table ]
schema = [ author , article ]
author :: Schema . Table
author =
2022-06-17 11:44:04 +03:00
( 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 " ]
]
}
2022-05-31 17:41:09 +03:00
article :: Schema . Table
article =
2022-06-17 11:44:04 +03:00
( 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 " ]
}
2022-05-31 17:41:09 +03:00
--------------------------------------------------------------------------------
-- ** Postgres Setup and teardown
2022-08-10 16:07:58 +03:00
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
| ]
}
]
2022-05-31 17:41:09 +03:00
-------------------------------------------------------------------------------
2022-08-10 16:07:58 +03:00
tests :: Fixture . Options -> SpecWith TestEnvironment
2022-05-31 17:41:09 +03:00
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