private boolean shouldDenyPrivilege(String userName, String entityName, TestingPrivilegeType type) { TestingPrivilege testPrivilege = privilege(userName, entityName, type); for (TestingPrivilege denyPrivilege : denyPrivileges) { if (denyPrivilege.matches(testPrivilege)) { return true; } } return false; }
@Inject public TestingAccessControlManager(TransactionManager transactionManager) { super(transactionManager); setSystemAccessControl(AllowAllSystemAccessControl.NAME, ImmutableMap.of()); }
@Override public void checkCanSetUser(Optional<Principal> principal, String userName) { if (shouldDenyPrivilege(userName, userName, SET_USER)) { denySetUser(principal, userName); } if (denyPrivileges.isEmpty()) { super.checkCanSetUser(principal, userName); } }
protected void assertAccessAllowed(Session session, @Language("SQL") String sql, TestingPrivilege... deniedPrivileges) { executeExclusively(() -> { try { queryRunner.getAccessControl().deny(deniedPrivileges); queryRunner.execute(session, sql); } finally { queryRunner.getAccessControl().reset(); } }); }
this.costCalculator = new CostCalculatorUsingExchanges(taskCountEstimator); this.estimatedExchangesCostCalculator = new CostCalculatorWithEstimatedExchanges(costCalculator, taskCountEstimator); this.accessControl = new TestingAccessControlManager(transactionManager); this.pageSourceManager = new PageSourceManager();
protected void assertAccessDenied( Session session, @Language("SQL") String sql, @Language("RegExp") String exceptionsMessageRegExp, TestingPrivilege... deniedPrivileges) { executeExclusively(() -> { try { queryRunner.getAccessControl().deny(deniedPrivileges); queryRunner.execute(session, sql); fail("Expected " + AccessDeniedException.class.getSimpleName()); } catch (RuntimeException e) { assertExceptionMessage(sql, e, ".*Access Denied: " + exceptionsMessageRegExp); } finally { queryRunner.getAccessControl().reset(); } }); }
new TablePropertyManager(), transactionManager); this.accessControl = new TestingAccessControlManager(transactionManager); this.pageSourceManager = new PageSourceManager();
@Override public void checkCanSetSystemSessionProperty(Identity identity, String propertyName) { if (shouldDenyPrivilege(identity.getUser(), propertyName, SET_SESSION)) { denySetSystemSessionProperty(propertyName); } if (denyPrivileges.isEmpty()) { super.checkCanSetSystemSessionProperty(identity, propertyName); } }
@Test public void testAccessControl() { assertAccessDenied("INSERT INTO orders SELECT * FROM orders", "Cannot insert into table .*.orders.*", privilege("orders", INSERT_TABLE)); assertAccessDenied("DELETE FROM orders", "Cannot delete from table .*.orders.*", privilege("orders", DELETE_TABLE)); assertAccessDenied("CREATE TABLE foo AS SELECT * FROM orders", "Cannot create table .*.foo.*", privilege("foo", CREATE_TABLE)); assertAccessDenied("SELECT * FROM nation", "Cannot select from columns \\[nationkey, regionkey, name, comment\\] in table .*.nation.*", privilege("nationkey", SELECT_COLUMN)); assertAccessDenied("SELECT * FROM (SELECT * FROM nation)", "Cannot select from columns \\[nationkey, regionkey, name, comment\\] in table .*.nation.*", privilege("nationkey", SELECT_COLUMN)); assertAccessDenied("SELECT name FROM (SELECT * FROM nation)", "Cannot select from columns \\[nationkey, regionkey, name, comment\\] in table .*.nation.*", privilege("nationkey", SELECT_COLUMN)); assertAccessAllowed("SELECT name FROM nation", privilege("nationkey", SELECT_COLUMN)); assertAccessDenied("SELECT n1.nationkey, n2.regionkey FROM nation n1, nation n2", "Cannot select from columns \\[nationkey, regionkey\\] in table .*.nation.*", privilege("nationkey", SELECT_COLUMN)); assertAccessDenied("SELECT count(name) as c FROM nation where comment > 'abc' GROUP BY regionkey having max(nationkey) > 10", "Cannot select from columns \\[nationkey, regionkey, name, comment\\] in table .*.nation.*", privilege("nationkey", SELECT_COLUMN)); assertAccessDenied("SELECT 1 FROM region, nation where region.regionkey = nation.nationkey", "Cannot select from columns \\[nationkey\\] in table .*.nation.*", privilege("nationkey", SELECT_COLUMN)); assertAccessDenied("SELECT count(*) FROM nation", "Cannot select from columns \\[\\] in table .*.nation.*", privilege("nation", SELECT_COLUMN)); assertAccessDenied("WITH t1 AS (SELECT * FROM nation) SELECT * FROM t1", "Cannot select from columns \\[nationkey, regionkey, name, comment\\] in table .*.nation.*", privilege("nationkey", SELECT_COLUMN)); assertAccessAllowed("SELECT name AS my_alias FROM nation", privilege("my_alias", SELECT_COLUMN)); assertAccessAllowed("SELECT my_alias from (SELECT name AS my_alias FROM nation)", privilege("my_alias", SELECT_COLUMN)); assertAccessDenied("SELECT name AS my_alias FROM nation", "Cannot select from columns \\[name\\] in table .*.nation.*", privilege("name", SELECT_COLUMN)); }
protected void assertAccessAllowed(Session session, @Language("SQL") String sql, TestingPrivilege... deniedPrivileges) { executeExclusively(() -> { try { queryRunner.getAccessControl().deny(deniedPrivileges); queryRunner.execute(session, sql); } finally { queryRunner.getAccessControl().reset(); } }); }
@Inject public TestingAccessControlManager(TransactionManager transactionManager) { super(transactionManager); setSystemAccessControl(ALLOW_ALL_ACCESS_CONTROL, ImmutableMap.of()); }
@Override public void checkCanSetCatalogSessionProperty(TransactionId transactionId, Identity identity, String catalogName, String propertyName) { if (shouldDenyPrivilege(identity.getUser(), catalogName + "." + propertyName, SET_SESSION)) { denySetCatalogSessionProperty(catalogName, propertyName); } if (denyPrivileges.isEmpty()) { super.checkCanSetCatalogSessionProperty(transactionId, identity, catalogName, propertyName); } }
@Test public void testNonQueryAccessControl() { skipTestUnless(supportsViews()); assertAccessDenied("SET SESSION " + QUERY_MAX_MEMORY + " = '10MB'", "Cannot set system session property " + QUERY_MAX_MEMORY, privilege(QUERY_MAX_MEMORY, SET_SESSION)); assertAccessDenied("CREATE TABLE foo (pk bigint)", "Cannot create table .*.foo.*", privilege("foo", CREATE_TABLE)); assertAccessDenied("DROP TABLE orders", "Cannot drop table .*.orders.*", privilege("orders", DROP_TABLE)); assertAccessDenied("ALTER TABLE orders RENAME TO foo", "Cannot rename table .*.orders.* to .*.foo.*", privilege("orders", RENAME_TABLE)); assertAccessDenied("ALTER TABLE orders ADD COLUMN foo bigint", "Cannot add a column to table .*.orders.*", privilege("orders", ADD_COLUMN)); assertAccessDenied("ALTER TABLE orders DROP COLUMN foo", "Cannot drop a column from table .*.orders.*", privilege("orders", DROP_COLUMN)); assertAccessDenied("ALTER TABLE orders RENAME COLUMN orderkey TO foo", "Cannot rename a column in table .*.orders.*", privilege("orders", RENAME_COLUMN)); assertAccessDenied("CREATE VIEW foo as SELECT * FROM orders", "Cannot create view .*.foo.*", privilege("foo", CREATE_VIEW)); // todo add DROP VIEW test... not all connectors have view support try { assertAccessDenied("SELECT 1", "Principal .* cannot become user " + getSession().getUser() + ".*", privilege(getSession().getUser(), SET_USER)); } catch (AssertionError e) { // There is no clean exception message for authorization failure. We simply get a 403 Assertions.assertContains(e.getMessage(), "statusCode=403"); } }
protected void assertAccessDenied( Session session, @Language("SQL") String sql, @Language("RegExp") String exceptionsMessageRegExp, TestingPrivilege... deniedPrivileges) { executeExclusively(() -> { try { queryRunner.getAccessControl().deny(deniedPrivileges); queryRunner.execute(session, sql); fail("Expected " + AccessDeniedException.class.getSimpleName()); } catch (RuntimeException e) { assertExceptionMessage(sql, e, ".*Access Denied: " + exceptionsMessageRegExp); } finally { queryRunner.getAccessControl().reset(); } }); }
@Override public void checkCanCreateView(TransactionId transactionId, Identity identity, QualifiedObjectName viewName) { if (shouldDenyPrivilege(identity.getUser(), viewName.getObjectName(), CREATE_VIEW)) { denyCreateView(viewName.toString()); } if (denyPrivileges.isEmpty()) { super.checkCanCreateView(transactionId, identity, viewName); } }
viewOwnerSession, "CREATE VIEW test_view_access AS SELECT * FROM orders", privilege("orders", CREATE_VIEW_WITH_SELECT_COLUMNS)); "SELECT * FROM test_view_access", "View owner 'test_view_access_owner' cannot create view that selects from .*.orders.*", privilege(viewOwnerSession.getUser(), "orders", CREATE_VIEW_WITH_SELECT_COLUMNS)); viewOwnerSession, "SELECT * FROM test_view_access", privilege(viewOwnerSession.getUser(), "orders", CREATE_VIEW_WITH_SELECT_COLUMNS)); privilege(getSession().getUser(), "orders", CREATE_VIEW_WITH_SELECT_COLUMNS)); assertAccessAllowed( "SELECT * FROM test_view_access", privilege(getSession().getUser(), "orders", SELECT_COLUMN)); nestedViewOwnerSession, "CREATE VIEW test_nested_view_access AS SELECT * FROM test_view_access", privilege("test_view_access", CREATE_VIEW_WITH_SELECT_COLUMNS)); "SELECT * FROM test_nested_view_access", "View owner 'test_nested_view_access_owner' cannot create view that selects from .*.test_view_access.*", privilege(nestedViewOwnerSession.getUser(), "test_view_access", CREATE_VIEW_WITH_SELECT_COLUMNS)); privilege(getSession().getUser(), "test_view_access", CREATE_VIEW_WITH_SELECT_COLUMNS)); assertAccessAllowed( "SELECT * FROM test_nested_view_access", privilege(getSession().getUser(), "test_view_access", SELECT_COLUMN));
@Override public void checkCanCreateSchema(TransactionId transactionId, Identity identity, CatalogSchemaName schemaName) { if (shouldDenyPrivilege(identity.getUser(), schemaName.getSchemaName(), CREATE_SCHEMA)) { denyCreateSchema(schemaName.toString()); } if (denyPrivileges.isEmpty()) { super.checkCanCreateSchema(transactionId, identity, schemaName); } }
assertAccessDenied("DELETE FROM test_delete where orderkey < 12", "Cannot select from columns \\[orderkey\\] in table or view .*.test_delete.*", privilege("orderkey", SELECT_COLUMN)); assertAccessAllowed("DELETE FROM test_delete where orderkey < 12", privilege("orderdate", SELECT_COLUMN)); assertAccessAllowed("DELETE FROM test_delete", privilege("orders", SELECT_COLUMN));
@Override public void checkCanDropTable(TransactionId transactionId, Identity identity, QualifiedObjectName tableName) { if (shouldDenyPrivilege(identity.getUser(), tableName.getObjectName(), DROP_TABLE)) { denyDropTable(tableName.toString()); } if (denyPrivileges.isEmpty()) { super.checkCanDropTable(transactionId, identity, tableName); } }
private boolean shouldDenyPrivilege(String userName, String entityName, TestingPrivilegeType type) { TestingPrivilege testPrivilege = privilege(userName, entityName, type); for (TestingPrivilege denyPrivilege : denyPrivileges) { if (denyPrivilege.matches(testPrivilege)) { return true; } } return false; }