From 08831c6870152a9b89c1beab87d421564a9e9487 Mon Sep 17 00:00:00 2001 From: Aleksey Plekhanov Date: Thu, 14 Mar 2024 17:05:51 +0300 Subject: [PATCH 1/5] IGNITE-21630 SQL Calcite: Add operations authorization --- .../calcite/exec/ExchangeServiceImpl.java | 1 + .../query/calcite/exec/ExecutionContext.java | 11 +- .../calcite/exec/ExecutionServiceImpl.java | 62 +++++ .../calcite/exec/QueryTaskExecutorImpl.java | 9 +- .../query/calcite/schema/CacheTableImpl.java | 22 ++ .../query/calcite/schema/IgniteTable.java | 17 ++ .../calcite/schema/SystemViewTableImpl.java | 5 + .../exec/LogicalRelImplementorTest.java | 1 + .../calcite/exec/RuntimeSortedIndexTest.java | 1 + .../exec/rel/AbstractExecutionTest.java | 1 + .../AuthorizationIntegrationTest.java | 221 ++++++++++++++++++ .../query/calcite/planner/PlannerTest.java | 1 + .../query/calcite/planner/TestTable.java | 5 + .../testsuites/IntegrationTestSuite.java | 2 + 14 files changed, 357 insertions(+), 2 deletions(-) create mode 100644 modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java index b10b69f221305..b3ba8b52485d6 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java @@ -360,6 +360,7 @@ private ExecutionContext baseInboxContext(UUID nodeId, UUID qryId, long fragm null, NoOpMemoryTracker.INSTANCE, NoOpIoTracker.INSTANCE, + ExecutionContext.NO_OP_SECURITY_CONTEXT_PROVIDER, 0, ImmutableMap.of()); } diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionContext.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionContext.java index 1ed10914db56a..e902a4a63d176 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionContext.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionContext.java @@ -24,6 +24,7 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; +import java.util.function.Supplier; import org.apache.calcite.DataContext; import org.apache.calcite.linq4j.QueryProvider; import org.apache.calcite.schema.SchemaPlus; @@ -57,6 +58,9 @@ * Runtime context allowing access to the tables in a database. */ public class ExecutionContext extends AbstractQueryContext implements DataContext { + /** */ + public static final Supplier NO_OP_SECURITY_CONTEXT_PROVIDER = () -> null; + /** Placeholder for values, which expressions is not specified. */ private static final Object UNSPECIFIED_VALUE = new Object(); @@ -102,6 +106,9 @@ public class ExecutionContext extends AbstractQueryContext implements DataC /** */ private final IoTracker ioTracker; + /** */ + private final Supplier secCtxProvider; + /** */ private final long timeout; @@ -129,6 +136,7 @@ public ExecutionContext( RowHandler handler, MemoryTracker qryMemoryTracker, IoTracker ioTracker, + Supplier secCtxProvider, long timeout, Map params ) { @@ -145,6 +153,7 @@ public ExecutionContext( this.ioTracker = ioTracker; this.params = params; this.timeout = timeout; + this.secCtxProvider = secCtxProvider; startTs = U.currentTimeMillis(); @@ -309,7 +318,7 @@ public void execute(RunnableX task, Consumer onError) { return; executor.execute(qryId, fragmentId(), () -> { - try { + try (AutoCloseable ignore = secCtxProvider.get()) { if (!isCancelled()) task.run(); } diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java index 835c13ede19bc..86bd1e6ad27e9 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java @@ -24,10 +24,12 @@ import java.util.Objects; import java.util.UUID; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import org.apache.calcite.plan.Context; import org.apache.calcite.plan.Contexts; import org.apache.calcite.plan.RelOptUtil; +import org.apache.calcite.rel.core.TableModify; import org.apache.calcite.sql.SqlInsert; import org.apache.calcite.sql.SqlKind; import org.apache.calcite.tools.Frameworks; @@ -88,12 +90,20 @@ import org.apache.ignite.internal.processors.query.calcite.prepare.FieldsMetadataImpl; import org.apache.ignite.internal.processors.query.calcite.prepare.Fragment; import org.apache.ignite.internal.processors.query.calcite.prepare.FragmentPlan; +import org.apache.ignite.internal.processors.query.calcite.prepare.IgniteRelShuttle; import org.apache.ignite.internal.processors.query.calcite.prepare.MappingQueryContext; import org.apache.ignite.internal.processors.query.calcite.prepare.MultiStepPlan; import org.apache.ignite.internal.processors.query.calcite.prepare.PrepareServiceImpl; import org.apache.ignite.internal.processors.query.calcite.prepare.QueryPlan; import org.apache.ignite.internal.processors.query.calcite.prepare.QueryPlanCache; import org.apache.ignite.internal.processors.query.calcite.prepare.ddl.CreateTableCommand; +import org.apache.ignite.internal.processors.query.calcite.rel.IgniteIndexBound; +import org.apache.ignite.internal.processors.query.calcite.rel.IgniteIndexCount; +import org.apache.ignite.internal.processors.query.calcite.rel.IgniteIndexScan; +import org.apache.ignite.internal.processors.query.calcite.rel.IgniteRel; +import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableModify; +import org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableScan; +import org.apache.ignite.internal.processors.query.calcite.schema.IgniteTable; import org.apache.ignite.internal.processors.query.calcite.schema.SchemaHolder; import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory; import org.apache.ignite.internal.processors.query.calcite.util.AbstractService; @@ -101,6 +111,7 @@ import org.apache.ignite.internal.processors.query.calcite.util.ConvertingClosableIterator; import org.apache.ignite.internal.processors.query.calcite.util.ListFieldsQueryCursor; import org.apache.ignite.internal.processors.query.running.HeavyQueriesTracker; +import org.apache.ignite.internal.processors.security.SecurityContext; import org.apache.ignite.internal.processors.security.SecurityUtils; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.X; @@ -568,6 +579,11 @@ private ListFieldsQueryCursor mapAndExecutePlan( List fragments = execPlan.fragments(); + if (ctx.security().enabled()) { + for (Fragment fragment : fragments) + checkPermissions(fragment.root()); + } + // Local execution Fragment fragment = F.first(fragments); @@ -608,6 +624,7 @@ private ListFieldsQueryCursor mapAndExecutePlan( handler, qry.createMemoryTracker(memoryTracker, cfg.getQueryMemoryQuota()), createIoTracker(locNodeId, qry.localQueryId()), + securityContextProvider(), timeout, qryParams); @@ -741,6 +758,40 @@ private ListFieldsQueryCursor mapAndExecutePlan( return new ListFieldsQueryCursor<>(plan, it, ectx); } + /** */ + private void checkPermissions(IgniteRel root) { + IgniteRelShuttle shuttle = new IgniteRelShuttle() { + @Override public IgniteRel visit(IgniteTableModify rel) { + return authorize(rel, rel.getOperation() == TableModify.Operation.DELETE ? + IgniteTable.Operation.REMOVE : IgniteTable.Operation.PUT); + } + + @Override public IgniteRel visit(IgniteTableScan rel) { + return authorize(rel, IgniteTable.Operation.READ); + } + + @Override public IgniteRel visit(IgniteIndexScan rel) { + return authorize(rel, IgniteTable.Operation.READ); + } + + @Override public IgniteRel visit(IgniteIndexCount rel) { + return authorize(rel, IgniteTable.Operation.READ); + } + + @Override public IgniteRel visit(IgniteIndexBound rel) { + return authorize(rel, IgniteTable.Operation.READ); + } + + private IgniteRel authorize(IgniteRel rel, IgniteTable.Operation op) { + rel.getTable().unwrap(IgniteTable.class).authorize(op); + + return rel; + } + }; + + shuttle.visit(root); + } + /** */ private FieldsQueryCursor> executeExplain(RootQuery qry, ExplainPlan plan) { QueryCursorImpl> cur = new QueryCursorImpl<>(singletonList(singletonList(plan.plan()))); @@ -815,6 +866,7 @@ private void onMessage(UUID nodeId, final QueryStartRequest msg) { handler, qry.createMemoryTracker(memoryTracker, cfg.getQueryMemoryQuota()), createIoTracker(nodeId, msg.originatingQryId()), + securityContextProvider(), msg.timeout(), Commons.parametersMap(msg.parameters()) ); @@ -889,4 +941,14 @@ private IoTracker createIoTracker(UUID originatingNodeId, long originatingQryId) new PerformanceStatisticsIoTracker(perfStatProc, originatingNodeId, originatingQryId) : NoOpIoTracker.INSTANCE; } + + /** */ + private Supplier securityContextProvider() { + SecurityContext secCtx = ctx.security().securityContext(); + + if (secCtx == null) + return ExecutionContext.NO_OP_SECURITY_CONTEXT_PROVIDER; + + return () -> ctx.security().withContext(secCtx); + } } diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/QueryTaskExecutorImpl.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/QueryTaskExecutorImpl.java index c22714783d722..b489d05192cd1 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/QueryTaskExecutorImpl.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/QueryTaskExecutorImpl.java @@ -20,6 +20,7 @@ import java.util.UUID; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.processors.query.calcite.util.AbstractService; +import org.apache.ignite.internal.processors.security.SecurityContext; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.thread.IgniteStripedThreadPoolExecutor; @@ -33,6 +34,9 @@ public class QueryTaskExecutorImpl extends AbstractService implements QueryTaskE /** */ public static final String THREAD_POOL_NAME = "CalciteQueryExecutor"; + /** */ + private final GridKernalContext ctx; + /** */ private IgniteStripedThreadPoolExecutor stripedThreadPoolExecutor; @@ -42,6 +46,7 @@ public class QueryTaskExecutorImpl extends AbstractService implements QueryTaskE /** */ public QueryTaskExecutorImpl(GridKernalContext ctx) { super(ctx); + this.ctx = ctx; } /** @@ -60,9 +65,11 @@ public void exceptionHandler(Thread.UncaughtExceptionHandler eHnd) { /** {@inheritDoc} */ @Override public void execute(UUID qryId, long fragmentId, Runnable qryTask) { + SecurityContext secCtx = ctx.security().securityContext(); + stripedThreadPoolExecutor.execute( () -> { - try { + try (AutoCloseable ignored = ctx.security().withContext(secCtx)) { qryTask.run(); } catch (Throwable e) { diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableImpl.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableImpl.java index f53d1d1fed9cd..bc74437c3d492 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableImpl.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/CacheTableImpl.java @@ -43,6 +43,7 @@ import org.apache.ignite.internal.processors.query.stat.ObjectStatisticsImpl; import org.apache.ignite.internal.processors.query.stat.StatisticsKey; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.security.SecurityPermission; import org.jetbrains.annotations.Nullable; /** @@ -165,6 +166,27 @@ public CacheTableImpl(GridKernalContext ctx, CacheTableDescriptor desc) { return desc.typeDescription().tableName(); } + /** {@inheritDoc} */ + @Override public void authorize(Operation op) { + SecurityPermission perm; + + switch (op) { + case READ: + perm = SecurityPermission.CACHE_READ; + break; + case PUT: + perm = SecurityPermission.CACHE_PUT; + break; + case REMOVE: + perm = SecurityPermission.CACHE_REMOVE; + break; + default: + throw new AssertionError("Unexpected operation type: " + op); + } + + ctx.security().authorize(desc.cacheInfo().name(), perm); + } + /** {@inheritDoc} */ @Override public C unwrap(Class aCls) { if (aCls.isInstance(desc)) diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteTable.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteTable.java index ca1afb2d2216a..df52e419997d8 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteTable.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/IgniteTable.java @@ -157,4 +157,21 @@ public Iterable scan( * @return Table name. */ String name(); + + /** + * Authorizes operation on table. + */ + void authorize(Operation op); + + /** */ + enum Operation { + /** */ + READ, + + /** */ + PUT, + + /** */ + REMOVE + } } diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewTableImpl.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewTableImpl.java index 2ac2a70bab3ba..4333a9832ad8d 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewTableImpl.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SystemViewTableImpl.java @@ -166,6 +166,11 @@ public SystemViewTableImpl(SystemViewTableDescriptorImpl desc) { return desc.name(); } + /** {@inheritDoc} */ + @Override public void authorize(Operation op) { + // No-op. + } + /** */ private static class StatisticsImpl implements Statistic { /** {@inheritDoc} */ diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java index 8105a9da3fd50..022523d58bf36 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java @@ -131,6 +131,7 @@ public class LogicalRelImplementorTest extends GridCommonAbstractTest { ArrayRowHandler.INSTANCE, NoOpMemoryTracker.INSTANCE, NoOpIoTracker.INSTANCE, + ExecutionContext.NO_OP_SECURITY_CONTEXT_PROVIDER, 0, null ) { diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/RuntimeSortedIndexTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/RuntimeSortedIndexTest.java index 818b1074fba8c..8e6f60271c749 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/RuntimeSortedIndexTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/RuntimeSortedIndexTest.java @@ -118,6 +118,7 @@ private RuntimeSortedIndex generate(RelDataType rowType, final List executionContext(UUID nodeId, UUID qryId, l ArrayRowHandler.INSTANCE, NoOpMemoryTracker.INSTANCE, NoOpIoTracker.INSTANCE, + ExecutionContext.NO_OP_SECURITY_CONTEXT_PROVIDER, 0, ImmutableMap.of() ); diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java new file mode 100644 index 0000000000000..d146ec4a07674 --- /dev/null +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java @@ -0,0 +1,221 @@ +package org.apache.ignite.internal.processors.query.calcite.integration; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.Ignition; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.calcite.CalciteQueryEngineConfiguration; +import org.apache.ignite.client.ClientAuthorizationException; +import org.apache.ignite.client.Config; +import org.apache.ignite.client.IgniteClient; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.ClientConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.configuration.SqlConfiguration; +import org.apache.ignite.events.CacheEvent; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.processors.security.AbstractSecurityTest; +import org.apache.ignite.internal.processors.security.impl.TestSecurityData; +import org.apache.ignite.internal.processors.security.impl.TestSecurityPluginProvider; +import org.apache.ignite.lang.IgnitePredicate; +import org.apache.ignite.plugin.security.SecurityException; +import org.apache.ignite.plugin.security.SecurityPermissionSet; +import org.apache.ignite.plugin.security.SecurityPermissionSetBuilder; +import org.apache.ignite.testframework.GridTestUtils; +import org.junit.Test; + +import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT; +import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_REMOVED; +import static org.apache.ignite.plugin.security.SecurityPermission.CACHE_PUT; +import static org.apache.ignite.plugin.security.SecurityPermission.CACHE_READ; +import static org.apache.ignite.plugin.security.SecurityPermission.CACHE_REMOVE; + +/** + * Test authorization of different operations. + */ +public class AuthorizationIntegrationTest extends AbstractSecurityTest { + /** */ + private static final String LOGIN = "client"; + + /** */ + private static final String PWD = "pwd"; + + /** */ + private static final String ALLOWED_CACHE = "allowed_cache"; + + /** */ + private static final String FORBIDDEN_CACHE = "forbidden_cache"; + + /** */ + private static final AtomicInteger putCnt = new AtomicInteger(); + + /** */ + private static final AtomicInteger removeCnt = new AtomicInteger(); + + /** */ + private final SecurityPermissionSet clientPermissions = SecurityPermissionSetBuilder.create() + .defaultAllowAll(false) + .appendCachePermissions(ALLOWED_CACHE, CACHE_PUT, CACHE_READ, CACHE_REMOVE) + .appendCachePermissions(FORBIDDEN_CACHE, EMPTY_PERMS).build(); + + /** */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + return super.getConfiguration(igniteInstanceName) + .setIncludeEventTypes(EVT_CACHE_OBJECT_PUT, EVT_CACHE_OBJECT_REMOVED) + .setSqlConfiguration(new SqlConfiguration() + .setQueryEnginesConfiguration(new CalciteQueryEngineConfiguration())); + } + + /** {@inheritDoc} */ + @Override protected TestSecurityData[] securityData() { + return new TestSecurityData[] { + new TestSecurityData(LOGIN, PWD, clientPermissions, null) + }; + } + + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + IgniteEx grid0 = startGridAllowAll("srv1"); + IgniteEx grid1 = startGridAllowAll("srv2"); + + grid0.getOrCreateCache(new CacheConfiguration<>(ALLOWED_CACHE).setIndexedTypes(Integer.class, Integer.class)); + grid0.getOrCreateCache(new CacheConfiguration<>(FORBIDDEN_CACHE).setIndexedTypes(Integer.class, Integer.class)); + + IgnitePredicate lsnrPut = evt -> { + try { + assertEquals(LOGIN, grid0.context().security().authenticatedSubject(evt.subjectId()).login()); + } + catch (IgniteCheckedException e) { + throw new AssertionError("Unexpected exception", e); + } + + putCnt.incrementAndGet(); + + return true; + }; + + IgnitePredicate lsnrRemove = evt -> { + try { + assertEquals(LOGIN, grid0.context().security().authenticatedSubject(evt.subjectId()).login()); + } + catch (IgniteCheckedException e) { + throw new AssertionError("Unexpected exception", e); + } + + removeCnt.incrementAndGet(); + + return true; + }; + + grid0.events().localListen(lsnrPut, EVT_CACHE_OBJECT_PUT); + grid1.events().localListen(lsnrPut, EVT_CACHE_OBJECT_PUT); + grid0.events().localListen(lsnrRemove, EVT_CACHE_OBJECT_REMOVED); + grid1.events().localListen(lsnrRemove, EVT_CACHE_OBJECT_REMOVED); + } + + /** */ + @Override protected void beforeTest() throws Exception { + super.beforeTest(); + + grid("srv1").cache(ALLOWED_CACHE).clear(); + grid("srv1").cache(FORBIDDEN_CACHE).clear(); + } + + /** */ + @Test + public void testClientNode() throws Exception { + try (IgniteEx clientNode = startGrid(getConfiguration("client", + new TestSecurityPluginProvider(LOGIN, PWD, clientPermissions, null, + globalAuth, securityData())).setClientMode(true)) + ) { + check( + sql -> clientNode.cache(ALLOWED_CACHE).query(new SqlFieldsQuery(sql)).getAll(), + SecurityException.class, + "Authorization failed" + ); + } + } + + /** */ + @Test + public void testThinClient() throws Exception { + try (IgniteClient client = Ignition.startClient( + new ClientConfiguration().setAddresses(Config.SERVER).setUserName(LOGIN).setUserPassword(PWD)) + ) { + check( + sql -> client.cache(ALLOWED_CACHE).query(new SqlFieldsQuery(sql)).getAll(), + ClientAuthorizationException.class, + "User is not authorized" + ); + } + } + + /** */ + @Test + public void testJdbc() throws Exception { + try (Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1/?user=" + LOGIN + + "&password=" + PWD) + ) { + try (Statement stmt = conn.createStatement()) { + check(stmt::execute, SQLException.class, "Authorization failed"); + } + } + } + + /** */ + private void check(SqlExecutor sqlExecutor, Class errCls, String errMsg) throws Exception { + putCnt.set(0); + removeCnt.set(0); + int cnt = 10; + + for (int i = 0; i < cnt; i++) + sqlExecutor.execute(insertSql(ALLOWED_CACHE, i)); + + sqlExecutor.execute(selectSql(ALLOWED_CACHE)); + sqlExecutor.execute(deleteSql(ALLOWED_CACHE)); + + assertEquals(cnt, putCnt.get()); + assertEquals(cnt, removeCnt.get()); + + for (int i = 0; i < cnt; i++) + assertThrows(sqlExecutor, insertSql(FORBIDDEN_CACHE, i), errCls, errMsg); + + assertThrows(sqlExecutor, selectSql(FORBIDDEN_CACHE), errCls, errMsg); + assertThrows(sqlExecutor, deleteSql(FORBIDDEN_CACHE), errCls, errMsg); + assertThrows(sqlExecutor, "CREATE TABLE test(id INT, val VARCHAR)", errCls, errMsg); + } + + /** */ + private void assertThrows(SqlExecutor sqlExecutor, String sql, Class errCls, String errMsg) { + GridTestUtils.assertThrowsAnyCause(log, () -> { + sqlExecutor.execute(sql); + + return null; + }, errCls, errMsg); + } + + /** */ + private String insertSql(String cacheName, int key) { + return "INSERT INTO \"" + cacheName + "\".Integer (_KEY, _VAL) VALUES (" + key + ", " + key + ')'; + } + + /** */ + private String selectSql(String cacheName) { + return "SELECT _KEY, _VAL FROM \"" + cacheName + "\".Integer"; + } + + /** */ + private String deleteSql(String cacheName) { + return "DELETE FROM \"" + cacheName + "\".Integer"; + } + + /** Functional interface (throwable consumer) for SQL execution by different clients. */ + private interface SqlExecutor { + /** */ + void execute(String sql) throws Exception; + } +} diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java index fcd8731a19c55..fa0b17c8f18ce 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java @@ -428,6 +428,7 @@ private Node implementFragment( ArrayRowHandler.INSTANCE, NoOpMemoryTracker.INSTANCE, NoOpIoTracker.INSTANCE, + ExecutionContext.NO_OP_SECURITY_CONTEXT_PROVIDER, 0, Commons.parametersMap(ctx.parameters())); diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TestTable.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TestTable.java index d8b9617b5ca81..f6632a35284ec 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TestTable.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/TestTable.java @@ -297,4 +297,9 @@ public TestTable addIndex(String name, int... keys) { @Override public String name() { return name; } + + /** {@inheritDoc} */ + @Override public void authorize(Operation op) { + // No-op. + } } diff --git a/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java b/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java index f61fbc1b19c4e..5ab4bd46e01b2 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java +++ b/modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java @@ -24,6 +24,7 @@ import org.apache.ignite.internal.processors.query.calcite.SqlFieldsQueryUsageTest; import org.apache.ignite.internal.processors.query.calcite.UnstableTopologyTest; import org.apache.ignite.internal.processors.query.calcite.integration.AggregatesIntegrationTest; +import org.apache.ignite.internal.processors.query.calcite.integration.AuthorizationIntegrationTest; import org.apache.ignite.internal.processors.query.calcite.integration.CalciteBasicSecondaryIndexIntegrationTest; import org.apache.ignite.internal.processors.query.calcite.integration.CalciteErrorHandlilngIntegrationTest; import org.apache.ignite.internal.processors.query.calcite.integration.CorrelatesIntegrationTest; @@ -131,6 +132,7 @@ PartitionPruneTest.class, JoinRehashIntegrationTest.class, IndexWithSameNameCalciteTest.class, + AuthorizationIntegrationTest.class, }) public class IntegrationTestSuite { } From 81614e87e5688e44d46801050116912385e9d083 Mon Sep 17 00:00:00 2001 From: Aleksey Plekhanov Date: Thu, 14 Mar 2024 17:20:47 +0300 Subject: [PATCH 2/5] IGNITE-21630 Cleanup --- .../calcite/exec/ExchangeServiceImpl.java | 1 - .../query/calcite/exec/ExecutionContext.java | 11 +------- .../calcite/exec/ExecutionServiceImpl.java | 14 ---------- .../exec/LogicalRelImplementorTest.java | 1 - .../calcite/exec/RuntimeSortedIndexTest.java | 1 - .../exec/rel/AbstractExecutionTest.java | 1 - .../AuthorizationIntegrationTest.java | 27 ++++++++++--------- .../query/calcite/planner/PlannerTest.java | 1 - 8 files changed, 16 insertions(+), 41 deletions(-) diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java index b3ba8b52485d6..b10b69f221305 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExchangeServiceImpl.java @@ -360,7 +360,6 @@ private ExecutionContext baseInboxContext(UUID nodeId, UUID qryId, long fragm null, NoOpMemoryTracker.INSTANCE, NoOpIoTracker.INSTANCE, - ExecutionContext.NO_OP_SECURITY_CONTEXT_PROVIDER, 0, ImmutableMap.of()); } diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionContext.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionContext.java index e902a4a63d176..1ed10914db56a 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionContext.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionContext.java @@ -24,7 +24,6 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; -import java.util.function.Supplier; import org.apache.calcite.DataContext; import org.apache.calcite.linq4j.QueryProvider; import org.apache.calcite.schema.SchemaPlus; @@ -58,9 +57,6 @@ * Runtime context allowing access to the tables in a database. */ public class ExecutionContext extends AbstractQueryContext implements DataContext { - /** */ - public static final Supplier NO_OP_SECURITY_CONTEXT_PROVIDER = () -> null; - /** Placeholder for values, which expressions is not specified. */ private static final Object UNSPECIFIED_VALUE = new Object(); @@ -106,9 +102,6 @@ public class ExecutionContext extends AbstractQueryContext implements DataC /** */ private final IoTracker ioTracker; - /** */ - private final Supplier secCtxProvider; - /** */ private final long timeout; @@ -136,7 +129,6 @@ public ExecutionContext( RowHandler handler, MemoryTracker qryMemoryTracker, IoTracker ioTracker, - Supplier secCtxProvider, long timeout, Map params ) { @@ -153,7 +145,6 @@ public ExecutionContext( this.ioTracker = ioTracker; this.params = params; this.timeout = timeout; - this.secCtxProvider = secCtxProvider; startTs = U.currentTimeMillis(); @@ -318,7 +309,7 @@ public void execute(RunnableX task, Consumer onError) { return; executor.execute(qryId, fragmentId(), () -> { - try (AutoCloseable ignore = secCtxProvider.get()) { + try { if (!isCancelled()) task.run(); } diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java index 86bd1e6ad27e9..56ac14c372fc1 100644 --- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java +++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/ExecutionServiceImpl.java @@ -24,7 +24,6 @@ import java.util.Objects; import java.util.UUID; import java.util.function.Function; -import java.util.function.Supplier; import java.util.stream.Collectors; import org.apache.calcite.plan.Context; import org.apache.calcite.plan.Contexts; @@ -111,7 +110,6 @@ import org.apache.ignite.internal.processors.query.calcite.util.ConvertingClosableIterator; import org.apache.ignite.internal.processors.query.calcite.util.ListFieldsQueryCursor; import org.apache.ignite.internal.processors.query.running.HeavyQueriesTracker; -import org.apache.ignite.internal.processors.security.SecurityContext; import org.apache.ignite.internal.processors.security.SecurityUtils; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.X; @@ -624,7 +622,6 @@ private ListFieldsQueryCursor mapAndExecutePlan( handler, qry.createMemoryTracker(memoryTracker, cfg.getQueryMemoryQuota()), createIoTracker(locNodeId, qry.localQueryId()), - securityContextProvider(), timeout, qryParams); @@ -866,7 +863,6 @@ private void onMessage(UUID nodeId, final QueryStartRequest msg) { handler, qry.createMemoryTracker(memoryTracker, cfg.getQueryMemoryQuota()), createIoTracker(nodeId, msg.originatingQryId()), - securityContextProvider(), msg.timeout(), Commons.parametersMap(msg.parameters()) ); @@ -941,14 +937,4 @@ private IoTracker createIoTracker(UUID originatingNodeId, long originatingQryId) new PerformanceStatisticsIoTracker(perfStatProc, originatingNodeId, originatingQryId) : NoOpIoTracker.INSTANCE; } - - /** */ - private Supplier securityContextProvider() { - SecurityContext secCtx = ctx.security().securityContext(); - - if (secCtx == null) - return ExecutionContext.NO_OP_SECURITY_CONTEXT_PROVIDER; - - return () -> ctx.security().withContext(secCtx); - } } diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java index 022523d58bf36..8105a9da3fd50 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementorTest.java @@ -131,7 +131,6 @@ public class LogicalRelImplementorTest extends GridCommonAbstractTest { ArrayRowHandler.INSTANCE, NoOpMemoryTracker.INSTANCE, NoOpIoTracker.INSTANCE, - ExecutionContext.NO_OP_SECURITY_CONTEXT_PROVIDER, 0, null ) { diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/RuntimeSortedIndexTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/RuntimeSortedIndexTest.java index 8e6f60271c749..818b1074fba8c 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/RuntimeSortedIndexTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/RuntimeSortedIndexTest.java @@ -118,7 +118,6 @@ private RuntimeSortedIndex generate(RelDataType rowType, final List executionContext(UUID nodeId, UUID qryId, l ArrayRowHandler.INSTANCE, NoOpMemoryTracker.INSTANCE, NoOpIoTracker.INSTANCE, - ExecutionContext.NO_OP_SECURITY_CONTEXT_PROVIDER, 0, ImmutableMap.of() ); diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java index d146ec4a07674..7be3ca6c0ed1b 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java @@ -4,6 +4,7 @@ import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; +import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.Ignition; @@ -86,12 +87,8 @@ public class AuthorizationIntegrationTest extends AbstractSecurityTest { grid0.getOrCreateCache(new CacheConfiguration<>(FORBIDDEN_CACHE).setIndexedTypes(Integer.class, Integer.class)); IgnitePredicate lsnrPut = evt -> { - try { - assertEquals(LOGIN, grid0.context().security().authenticatedSubject(evt.subjectId()).login()); - } - catch (IgniteCheckedException e) { - throw new AssertionError("Unexpected exception", e); - } + // Ensure event is triggered with the correct security context. + ensureSubjId(grid0, evt.subjectId()); putCnt.incrementAndGet(); @@ -99,12 +96,8 @@ public class AuthorizationIntegrationTest extends AbstractSecurityTest { }; IgnitePredicate lsnrRemove = evt -> { - try { - assertEquals(LOGIN, grid0.context().security().authenticatedSubject(evt.subjectId()).login()); - } - catch (IgniteCheckedException e) { - throw new AssertionError("Unexpected exception", e); - } + // Ensure event is triggered with the correct security context. + ensureSubjId(grid0, evt.subjectId()); removeCnt.incrementAndGet(); @@ -189,6 +182,16 @@ private void check(SqlExecutor sqlExecutor, Class errCls, S assertThrows(sqlExecutor, "CREATE TABLE test(id INT, val VARCHAR)", errCls, errMsg); } + /** Ensure security context subject relates to client. */ + private void ensureSubjId(IgniteEx ignite, UUID subjId) { + try { + assertEquals(LOGIN, ignite.context().security().authenticatedSubject(subjId).login()); + } + catch (IgniteCheckedException e) { + throw new AssertionError("Unexpected exception", e); + } + } + /** */ private void assertThrows(SqlExecutor sqlExecutor, String sql, Class errCls, String errMsg) { GridTestUtils.assertThrowsAnyCause(log, () -> { diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java index fa0b17c8f18ce..fcd8731a19c55 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java @@ -428,7 +428,6 @@ private Node implementFragment( ArrayRowHandler.INSTANCE, NoOpMemoryTracker.INSTANCE, NoOpIoTracker.INSTANCE, - ExecutionContext.NO_OP_SECURITY_CONTEXT_PROVIDER, 0, Commons.parametersMap(ctx.parameters())); From fa9ed95d45d607383d8a21a24583f0d81fc8cb40 Mon Sep 17 00:00:00 2001 From: Aleksey Plekhanov Date: Thu, 14 Mar 2024 17:37:18 +0300 Subject: [PATCH 3/5] IGNITE-21630 License --- .../AuthorizationIntegrationTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java index 7be3ca6c0ed1b..5ab6da79b50d3 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java @@ -1,3 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.apache.ignite.internal.processors.query.calcite.integration; import java.sql.Connection; From a69ce3c34a9f6ecbe76a97538cb5982f2d836633 Mon Sep 17 00:00:00 2001 From: Aleksey Plekhanov Date: Fri, 15 Mar 2024 11:16:14 +0300 Subject: [PATCH 4/5] IGNITE-21587 Fix tests --- .../query/calcite/exec/rel/AbstractExecutionTest.java | 2 ++ .../internal/processors/query/calcite/planner/PlannerTest.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AbstractExecutionTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AbstractExecutionTest.java index 3bad2abfc7ff3..1df721c03ae77 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AbstractExecutionTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AbstractExecutionTest.java @@ -56,6 +56,7 @@ import org.apache.ignite.internal.processors.query.calcite.message.TestIoManager; import org.apache.ignite.internal.processors.query.calcite.metadata.FragmentDescription; import org.apache.ignite.internal.processors.query.calcite.prepare.BaseQueryContext; +import org.apache.ignite.internal.processors.security.NoOpIgniteSecurityProcessor; import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor; import org.apache.ignite.internal.util.typedef.T2; import org.apache.ignite.plugin.extensions.communication.Message; @@ -162,6 +163,7 @@ public void setup() throws Exception { GridTestKernalContext kernal = newContext(); kernal.add(new GridTimeoutProcessor(kernal)); + kernal.add(new NoOpIgniteSecurityProcessor(kernal)); QueryTaskExecutorImpl taskExecutor = new QueryTaskExecutorImpl(kernal); taskExecutor.stripedThreadPoolExecutor(new IgniteTestStripedThreadPoolExecutor( diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java index fcd8731a19c55..2bc2761a03b21 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlannerTest.java @@ -72,6 +72,7 @@ import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory; import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeSystem; import org.apache.ignite.internal.processors.query.calcite.util.Commons; +import org.apache.ignite.internal.processors.security.NoOpIgniteSecurityProcessor; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.testframework.junits.GridTestKernalContext; import org.apache.ignite.thread.IgniteStripedThreadPoolExecutor; @@ -383,6 +384,7 @@ private Node implementFragment( UUID nodeId ) throws IgniteCheckedException { GridTestKernalContext kernal = newContext(); + kernal.add(new NoOpIgniteSecurityProcessor(kernal)); QueryTaskExecutorImpl taskExecutor = new QueryTaskExecutorImpl(kernal); taskExecutor.stripedThreadPoolExecutor(new IgniteStripedThreadPoolExecutor( From 889dd4676318fd4d85bb6684d97b0226d2c3e4df Mon Sep 17 00:00:00 2001 From: Aleksey Plekhanov Date: Fri, 22 Mar 2024 09:46:46 +0300 Subject: [PATCH 5/5] IGNITE-21587 SQL Calcite: Add operations authorization (test case added) --- .../integration/AuthorizationIntegrationTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java index 5ab6da79b50d3..56edba4475c7d 100644 --- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java +++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java @@ -65,6 +65,9 @@ public class AuthorizationIntegrationTest extends AbstractSecurityTest { /** */ private static final String ALLOWED_CACHE = "allowed_cache"; + /** */ + private static final String ALLOWED_READ_CACHE = "allowed_read_cache"; + /** */ private static final String FORBIDDEN_CACHE = "forbidden_cache"; @@ -78,6 +81,7 @@ public class AuthorizationIntegrationTest extends AbstractSecurityTest { private final SecurityPermissionSet clientPermissions = SecurityPermissionSetBuilder.create() .defaultAllowAll(false) .appendCachePermissions(ALLOWED_CACHE, CACHE_PUT, CACHE_READ, CACHE_REMOVE) + .appendCachePermissions(ALLOWED_READ_CACHE, CACHE_READ) .appendCachePermissions(FORBIDDEN_CACHE, EMPTY_PERMS).build(); /** */ @@ -101,6 +105,7 @@ public class AuthorizationIntegrationTest extends AbstractSecurityTest { IgniteEx grid1 = startGridAllowAll("srv2"); grid0.getOrCreateCache(new CacheConfiguration<>(ALLOWED_CACHE).setIndexedTypes(Integer.class, Integer.class)); + grid0.getOrCreateCache(new CacheConfiguration<>(ALLOWED_READ_CACHE).setIndexedTypes(Integer.class, Integer.class)); grid0.getOrCreateCache(new CacheConfiguration<>(FORBIDDEN_CACHE).setIndexedTypes(Integer.class, Integer.class)); IgnitePredicate lsnrPut = evt -> { @@ -132,6 +137,7 @@ public class AuthorizationIntegrationTest extends AbstractSecurityTest { super.beforeTest(); grid("srv1").cache(ALLOWED_CACHE).clear(); + grid("srv1").cache(ALLOWED_READ_CACHE).clear(); grid("srv1").cache(FORBIDDEN_CACHE).clear(); } @@ -196,6 +202,13 @@ private void check(SqlExecutor sqlExecutor, Class errCls, S assertThrows(sqlExecutor, selectSql(FORBIDDEN_CACHE), errCls, errMsg); assertThrows(sqlExecutor, deleteSql(FORBIDDEN_CACHE), errCls, errMsg); + + for (int i = 0; i < cnt; i++) + assertThrows(sqlExecutor, insertSql(ALLOWED_READ_CACHE, i), errCls, errMsg); + + sqlExecutor.execute(selectSql(ALLOWED_READ_CACHE)); + assertThrows(sqlExecutor, deleteSql(ALLOWED_READ_CACHE), errCls, errMsg); + assertThrows(sqlExecutor, "CREATE TABLE test(id INT, val VARCHAR)", errCls, errMsg); }