From 15d4b4af479c4997c8006f8f1aa83eed78bc2244 Mon Sep 17 00:00:00 2001 From: Darun Seethammagari Date: Wed, 17 Apr 2024 17:33:45 -0700 Subject: [PATCH] Refactor getting tables without permissions --- runner/src/provisioner/provisioner.test.ts | 58 ++++++++++------------ runner/src/provisioner/provisioner.ts | 38 +++++++------- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/runner/src/provisioner/provisioner.test.ts b/runner/src/provisioner/provisioner.test.ts index 15f8ea82b..10fa30e72 100644 --- a/runner/src/provisioner/provisioner.test.ts +++ b/runner/src/provisioner/provisioner.test.ts @@ -3,7 +3,7 @@ import pgFormat from 'pg-format'; import Provisioner from './provisioner'; import IndexerConfig from '../indexer-config/indexer-config'; import { LogLevel } from '../indexer-meta/log-entry'; -import { type HasuraTableMetadata } from '../hasura-client'; +import { type HasuraPermission, type HasuraTableMetadata } from '../hasura-client'; describe('Provisioner', () => { let adminPgClient: any; @@ -251,44 +251,35 @@ describe('Provisioner', () => { }); it('ensuring consistent state tracks logs and metadata table once, adds permissions twice', async () => { - hasuraClient.getTrackedTablePermissions = jest.fn().mockReturnValueOnce([]).mockReturnValueOnce([ - { - table: { - name: 'blocks', - schema: 'morgs_near_test_function', - }, - }, - { - table: { - name: '__logs', - schema: 'morgs_near_test_function', - }, - }, - { - table: { - name: '__metadata', - schema: 'morgs_near_test_function', - }, - } - ]); - hasuraClient.getTableNames = jest.fn().mockReturnValueOnce(['blocks']).mockReturnValueOnce(['blocks', '__logs', '__metadata']); + hasuraClient.getTableNames = jest.fn().mockReturnValue(['blocks', '__logs', '__metadata']); + hasuraClient.getTrackedTablePermissions = jest.fn() + .mockReturnValueOnce([ + generateTableConfig('morgs_near_test_function', 'blocks', 'morgs_near', ['select', 'insert', 'update', 'delete']), + ]) + .mockReturnValueOnce([ + generateTableConfig('morgs_near_test_function', 'blocks', 'morgs_near', ['select', 'insert', 'update', 'delete']), + generateTableConfig('morgs_near_test_function', '__logs', 'morgs_near', []), + generateTableConfig('morgs_near_test_function', '__metadata', 'morgs_near', []), + ]); await provisioner.ensureConsistentHasuraState(indexerConfig); await provisioner.ensureConsistentHasuraState(indexerConfig); + expect(hasuraClient.getTableNames).toBeCalledTimes(2); expect(hasuraClient.trackTables).toBeCalledTimes(1); expect(hasuraClient.addPermissionsToTables).toBeCalledTimes(2); }); it('ensuring consistent state caches result', async () => { + hasuraClient.getTableNames = jest.fn().mockReturnValue(['blocks', '__logs', '__metadata']); hasuraClient.getTrackedTablePermissions = jest.fn().mockReturnValue([ - generateTableConfig('morgs_near_test_function', 'blocks', 'morgs_near'), - generateTableConfig('morgs_near_test_function', '__logs', 'morgs_near'), - generateTableConfig('morgs_near_test_function', '__metadata', 'morgs_near'), + generateTableConfig('morgs_near_test_function', 'blocks', 'morgs_near', ['select', 'insert', 'update', 'delete']), + generateTableConfig('morgs_near_test_function', '__logs', 'morgs_near', ['select', 'insert', 'update', 'delete']), + generateTableConfig('morgs_near_test_function', '__metadata', 'morgs_near', ['select', 'insert', 'update', 'delete']), ]); - hasuraClient.getTableNames = jest.fn().mockReturnValue(['blocks', '__logs', '__metadata']); await provisioner.ensureConsistentHasuraState(indexerConfig); await provisioner.ensureConsistentHasuraState(indexerConfig); + expect(hasuraClient.getTableNames).toBeCalledTimes(1); expect(hasuraClient.trackTables).not.toBeCalled(); expect(hasuraClient.addPermissionsToTables).not.toBeCalled(); expect(userPgClientQuery).not.toBeCalled(); @@ -352,15 +343,18 @@ describe('Provisioner', () => { }); }); -function generateTableConfig (schemaName: string, tableName: string, role: string): HasuraTableMetadata { - return { +function generateTableConfig (schemaName: string, tableName: string, role: string, permissionsToAdd: HasuraPermission[]): HasuraTableMetadata { + const config: HasuraTableMetadata = { table: { name: tableName, schema: schemaName, }, - insert_permissions: [{ role, permission: {} }], - select_permissions: [{ role, permission: {} }], - update_permissions: [{ role, permission: {} }], - delete_permissions: [{ role, permission: {} }], }; + + permissionsToAdd.forEach((permission) => { + const permissionKey: keyof Omit = `${permission}_permissions`; + config[permissionKey] = [{ role, permission: {} }]; + }); + + return config; } diff --git a/runner/src/provisioner/provisioner.ts b/runner/src/provisioner/provisioner.ts index 1e5ec5213..36afc8dc3 100644 --- a/runner/src/provisioner/provisioner.ts +++ b/runner/src/provisioner/provisioner.ts @@ -3,7 +3,12 @@ import pgFormatLib from 'pg-format'; import { wrapError } from '../utility'; import cryptoModule from 'crypto'; -import HasuraClient, { HasuraPermissionMetadata, type HasuraDatabaseConnectionParameters, type HasuraPermission, type HasuraTableMetadata } from '../hasura-client'; +import HasuraClient, { + type HasuraDatabaseConnectionParameters, + type HasuraPermission, + type HasuraTableMetadata, + type HasuraRolePermission +} from '../hasura-client'; import { logsTableDDL } from './schemas/logs-table'; import { metadataTableDDL } from './schemas/metadata-table'; import PgClientClass, { type PostgresConnectionParams } from '../pg-client'; @@ -289,22 +294,25 @@ export default class Provisioner { const hasuraTablesMetadata = await this.getTrackedTablesWithPermissions(indexerConfig); const untrackedTables = this.getUntrackedTables(tableNamesToCheck, hasuraTablesMetadata); - const tablesWithoutPermissions = this.getTablesWithoutPermissions( + const tablesWithoutPermissions = this.getTablesWithoutRole( indexerConfig.hasuraRoleName(), tableNamesToCheck, hasuraTablesMetadata, permissionsToAdd ); + console.log('untrackedTables', untrackedTables); + console.log('tablesWithoutPermissions', tablesWithoutPermissions); if (untrackedTables.length === 0 && tablesWithoutPermissions.length === 0) { + console.log('Consistent state achieved'); this.setConsistentState(indexerConfig.accountId, indexerConfig.functionName); - } else { - if (untrackedTables.length > 0) { - await this.trackTables(indexerConfig.schemaName(), untrackedTables, indexerConfig.databaseName()); - } - if (tablesWithoutPermissions.length > 0) { - await this.addPermissionsToTables(indexerConfig, tablesWithoutPermissions, permissionsToAdd); - } + return; + } + if (untrackedTables.length > 0) { + await this.trackTables(indexerConfig.schemaName(), untrackedTables, indexerConfig.databaseName()); + } + if (tablesWithoutPermissions.length > 0) { + await this.addPermissionsToTables(indexerConfig, tablesWithoutPermissions, permissionsToAdd); } }, 'Failed to ensure consistent Hasura state'); } @@ -333,25 +341,21 @@ export default class Provisioner { return allTables.filter((tableName: string) => { const tablePermissionsMetadata = tableMetadata.get(tableName); if (!tablePermissionsMetadata) { - return false; + return true; } - return permissionsToCheck.some((permission: string) => { - const permissionAttribute = `${permission}_permissions` as keyof Omit; - return this.roleLacksPermissionInTable(roleName, tablePermissionsMetadata[permissionAttribute]); - }); + return this.roleLacksPermissionsForTable(roleName, tablePermissionsMetadata, permissionsToCheck); }); } - private roleLacksPermissionsInTable (roleName: string, tablePermissionsMetadata: HasuraTableMetadata, permissionsToCheck: HasuraPermission[]): boolean { + private roleLacksPermissionsForTable (roleName: string, tablePermissionsMetadata: HasuraTableMetadata, permissionsToCheck: HasuraPermission[]): boolean { return permissionsToCheck.some((permission: string) => { const permissionAttribute = `${permission}_permissions` as keyof Omit; return this.roleLacksPermission(roleName, tablePermissionsMetadata[permissionAttribute]); }); } - private roleLacksPermission (roleName: string, tablePermission: HasuraPermissionMetadata | undefined): boolean { - // Returns true if the table does not have the permission or the specified role lacks the permission + private roleLacksPermission (roleName: string, tablePermission: HasuraRolePermission[] | undefined): boolean { return !tablePermission?.some((roleWithPermission: { role: string }) => roleWithPermission.role === roleName); }