This is an automated email from the ASF dual-hosted git repository.

alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new db4ac5f5881 IGNITE-21587 SQL Calcite: Add operations authorization 
(#11278)
db4ac5f5881 is described below

commit db4ac5f5881dc2997372b18a2b22ed097b0f1966
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Fri Mar 22 10:59:52 2024 +0300

    IGNITE-21587 SQL Calcite: Add operations authorization (#11278)
---
 .../query/calcite/exec/ExecutionServiceImpl.java   |  48 ++++
 .../query/calcite/exec/QueryTaskExecutorImpl.java  |   9 +-
 .../query/calcite/schema/CacheTableImpl.java       |  22 ++
 .../query/calcite/schema/IgniteTable.java          |  17 ++
 .../query/calcite/schema/SystemViewTableImpl.java  |   5 +
 .../calcite/exec/rel/AbstractExecutionTest.java    |   2 +
 .../integration/AuthorizationIntegrationTest.java  | 254 +++++++++++++++++++++
 .../query/calcite/planner/PlannerTest.java         |   2 +
 .../query/calcite/planner/TestTable.java           |   5 +
 .../ignite/testsuites/IntegrationTestSuite.java    |   2 +
 10 files changed, 365 insertions(+), 1 deletion(-)

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 835c13ede19..56ac14c372f 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
@@ -28,6 +28,7 @@ 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 +89,20 @@ import 
org.apache.ignite.internal.processors.query.calcite.prepare.ExplainPlan;
 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;
@@ -568,6 +577,11 @@ public class ExecutionServiceImpl<Row> extends 
AbstractService implements Execut
 
         List<Fragment> fragments = execPlan.fragments();
 
+        if (ctx.security().enabled()) {
+            for (Fragment fragment : fragments)
+                checkPermissions(fragment.root());
+        }
+
         // Local execution
         Fragment fragment = F.first(fragments);
 
@@ -741,6 +755,40 @@ public class ExecutionServiceImpl<Row> extends 
AbstractService implements Execut
         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<List<?>> executeExplain(RootQuery<Row> qry, 
ExplainPlan plan) {
         QueryCursorImpl<List<?>> cur = new 
QueryCursorImpl<>(singletonList(singletonList(plan.plan())));
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 c22714783d7..b489d05192c 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 @@ package 
org.apache.ignite.internal.processors.query.calcite.exec;
 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 class QueryTaskExecutorImpl extends AbstractService 
implements QueryTaskE
 
     /** {@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 f53d1d1fed9..bc74437c3d4 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.calcite.type.IgniteTypeFactor
 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 class CacheTableImpl extends AbstractTable 
implements IgniteCacheTable {
         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> C unwrap(Class<C> 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 ca1afb2d221..df52e419997 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 interface IgniteTable extends TranslatableTable {
      * @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 2ac2a70bab3..4333a9832ad 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 class SystemViewTableImpl extends AbstractTable 
implements IgniteTable {
         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/rel/AbstractExecutionTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/AbstractExecutionTest.java
index 3bad2abfc7f..1df721c03ae 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.MessageServic
 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 class AbstractExecutionTest extends 
GridCommonAbstractTest {
             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/integration/AuthorizationIntegrationTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java
new file mode 100644
index 00000000000..56edba4475c
--- /dev/null
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/AuthorizationIntegrationTest.java
@@ -0,0 +1,254 @@
+/*
+ * 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;
+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;
+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 ALLOWED_READ_CACHE = "allowed_read_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(ALLOWED_READ_CACHE, CACHE_READ)
+        .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<>(ALLOWED_READ_CACHE).setIndexedTypes(Integer.class, 
Integer.class));
+        grid0.getOrCreateCache(new 
CacheConfiguration<>(FORBIDDEN_CACHE).setIndexedTypes(Integer.class, 
Integer.class));
+
+        IgnitePredicate<CacheEvent> lsnrPut = evt -> {
+            // Ensure event is triggered with the correct security context.
+            ensureSubjId(grid0, evt.subjectId());
+
+            putCnt.incrementAndGet();
+
+            return true;
+        };
+
+        IgnitePredicate<CacheEvent> lsnrRemove = evt -> {
+            // Ensure event is triggered with the correct security context.
+            ensureSubjId(grid0, evt.subjectId());
+
+            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(ALLOWED_READ_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<? extends Exception> 
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);
+
+        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);
+    }
+
+    /** 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<? 
extends Exception> 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 fcd8731a19c..2bc2761a03b 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.trait.IgniteDistribut
 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 @@ public class PlannerTest extends AbstractPlannerTest {
         UUID nodeId
     ) throws IgniteCheckedException {
         GridTestKernalContext kernal = newContext();
+        kernal.add(new NoOpIgniteSecurityProcessor(kernal));
 
         QueryTaskExecutorImpl taskExecutor = new QueryTaskExecutorImpl(kernal);
         taskExecutor.stripedThreadPoolExecutor(new 
IgniteStripedThreadPoolExecutor(
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 d8b9617b5ca..f6632a35284 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 class TestTable implements IgniteCacheTable {
     @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 f61fbc1b19c..5ab4bd46e01 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.IndexWithSameNameCalc
 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 @@ import org.junit.runners.Suite;
     PartitionPruneTest.class,
     JoinRehashIntegrationTest.class,
     IndexWithSameNameCalciteTest.class,
+    AuthorizationIntegrationTest.class,
 })
 public class IntegrationTestSuite {
 }

Reply via email to