server: fix bug which allowed metadata to be inconsistent in the replace_metadata API call

https://github.com/hasura/graphql-engine-mono/pull/2288

GitOrigin-RevId: 93b181c957a5c38748c419a5146f0590605957ce
This commit is contained in:
Karthikeyan Chinnakonda 2021-09-14 17:32:13 +05:30 committed by hasura-bot
parent 2d8daf20dd
commit a268a3dc2f
4 changed files with 101 additions and 2 deletions

View File

@ -8,6 +8,8 @@
- server: update `create_scheduled_event` API to return `event_id` in response
- server: fix bug which allowed inconsistent metadata to exist after the `replace_metadata` API even though `allow_inconsistent_object` is set to `false`.
## v2.0.9
- server: disable mutation for materialised views (#6688)

View File

@ -393,7 +393,14 @@ runDropInconsistentMetadata _ = do
metadataModifier <- execWriterT $ mapM_ (tell . purgeMetadataObj) (reverse inconsSchObjs)
metadata <- getMetadata
putMetadata $ unMetadataModifier metadataModifier metadata
buildSchemaCacheStrict
buildSchemaCache noMetadataModify
-- after building the schema cache, we need to check the inconsistent metadata, if any
-- are only those which are not droppable
newInconsistentObjects <- scInconsistentObjs <$> askSchemaCache
let droppableInconsistentObjects = filter droppableInconsistentMetadata newInconsistentObjects
unless (null droppableInconsistentObjects) $
throwError (err400 Unexpected "cannot continue due to new inconsistent metadata")
{ qeInternal = Just $ toJSON newInconsistentObjects }
return successMsg
purgeMetadataObj :: MetadataObjId -> MetadataModifier

View File

@ -246,7 +246,7 @@ buildSchemaCacheStrict = do
buildSchemaCache noMetadataModify
sc <- askSchemaCache
let inconsObjs = scInconsistentObjs sc
when (any droppableInconsistentMetadata inconsObjs) $ do
unless (null inconsObjs) $ do
let err = err400 Unexpected "cannot continue due to inconsistent metadata"
throwError err{ qeInternal = Just $ toJSON inconsObjs }

View File

@ -43,6 +43,96 @@ class TestMetadata:
check_query_f(hge_ctx, self.dir() +
'/replace_metadata_allow_inconsistent.yaml')
def test_replace_metadata_disallow_inconsistent_metadata(self, hge_ctx):
st_code, resp = hge_ctx.v1metadataq({"type": "export_metadata", "args": {}})
assert st_code == 200, resp
default_source_config = {}
default_source = list(filter(lambda source: (source["name"] == "default"), resp["sources"]))
if default_source:
default_source_config = default_source[0]["configuration"]
else:
assert False, "default source config not found"
return
st_code, resp = hge_ctx.v1metadataq({
"type": "replace_metadata",
"version": 2,
"args": {
"metadata": {
"version": 3,
"sources": [
{
"name": "default",
"kind": "postgres",
"tables": [
{
"table": {
"schema": "public",
"name": "author"
},
"insert_permissions": [
{
"role": "user1",
"permission": {
"check": {},
"columns": [
"id",
"name"
],
"backend_only": False
}
},
{
"role": "user2",
"permission": {
"check": {
"id": {
"_eq": "X-Hasura-User-Id"
}
},
"columns": [
"id",
"name"
],
"backend_only": False
}
}
]
}
],
"configuration": default_source_config
}
],
"inherited_roles": [
{
"role_name": "users",
"role_set": [
"user2",
"user1"
]
}
]
}
}
})
assert st_code == 400, resp
assert resp == {
"internal": [
{
"reason": "Could not inherit permission for the role 'users' for the entity: 'insert permission, table: author, source: 'default''",
"name": "users",
"type": "inherited role permission inconsistency",
"entity": {
"permission_type": "insert",
"source": "default",
"table": "author"
}
}
],
"path": "$.args",
"error": "cannot continue due to inconsistent metadata",
"code": "unexpected"
}
def test_dump_internal_state(self, hge_ctx):
check_query_f(hge_ctx, self.dir() + '/dump_internal_state.yaml')