diff --git a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/SecurityCommandHandlerPermissionsTest.java b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/SecurityCommandHandlerPermissionsTest.java index 25c4d2cd71f6f..59df6748ece5e 100644 --- a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/SecurityCommandHandlerPermissionsTest.java +++ b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/SecurityCommandHandlerPermissionsTest.java @@ -53,13 +53,13 @@ /** */ public class SecurityCommandHandlerPermissionsTest extends GridCommandHandlerAbstractTest { /** */ - private static final String TEST_NO_PERMISSIONS_LOGIN = "no-permissions-login"; + public static final String TEST_NO_PERMISSIONS_LOGIN = "no-permissions-login"; /** */ - private static final String TEST_LOGIN = "cli-admin-login"; + public static final String TEST_LOGIN = "cli-admin-login"; /** */ - private static final String DEFAULT_PWD = "pwd"; + public static final String DEFAULT_PWD = "pwd"; /** */ @Parameterized.Parameters(name = "cmdHnd={0}") @@ -164,7 +164,7 @@ private void checkCommandPermissions(Collection cmdArgs, SecurityPermiss } /** */ - List enrichWithConnectionArguments(Collection cmdArgs, String login) { + public static List enrichWithConnectionArguments(Collection cmdArgs, String login) { List args = new ArrayList<>(); args.add(CMD_USER); diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerConsistencyTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerConsistencyTest.java index 670b925bb2ca8..9e2556729db7f 100644 --- a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerConsistencyTest.java +++ b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerConsistencyTest.java @@ -17,7 +17,9 @@ package org.apache.ignite.util; +import java.security.Permissions; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.ThreadLocalRandom; @@ -39,6 +41,8 @@ import org.apache.ignite.internal.processors.cache.IgniteInternalCache; import org.apache.ignite.internal.processors.cache.version.GridCacheVersionManager; import org.apache.ignite.internal.processors.dr.GridDrType; +import org.apache.ignite.internal.processors.security.impl.TestSecurityData; +import org.apache.ignite.internal.processors.security.impl.TestSecurityPluginProvider; import org.apache.ignite.internal.util.typedef.G; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; @@ -48,11 +52,20 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import static java.util.Arrays.asList; import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC; import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL; import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK; import static org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_UNEXPECTED_ERROR; +import static org.apache.ignite.internal.commandline.SecurityCommandHandlerPermissionsTest.DEFAULT_PWD; +import static org.apache.ignite.internal.commandline.SecurityCommandHandlerPermissionsTest.TEST_LOGIN; +import static org.apache.ignite.internal.commandline.SecurityCommandHandlerPermissionsTest.TEST_NO_PERMISSIONS_LOGIN; +import static org.apache.ignite.internal.commandline.SecurityCommandHandlerPermissionsTest.enrichWithConnectionArguments; import static org.apache.ignite.internal.management.consistency.ConsistencyRepairTask.CONSISTENCY_VIOLATIONS_FOUND; +import static org.apache.ignite.plugin.security.SecurityPermission.ADMIN_OPS; +import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.ALL_PERMISSIONS; +import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.NO_PERMISSIONS; +import static org.apache.ignite.plugin.security.SecurityPermissionSetBuilder.systemPermissions; import static org.apache.ignite.testframework.GridTestUtils.assertContains; import static org.apache.ignite.testframework.LogListener.matches; @@ -92,19 +105,22 @@ public class GridCommandHandlerConsistencyTest extends GridCommandHandlerCluster protected final ListeningTestLogger listeningLog = new ListeningTestLogger(log); /** */ - @Parameterized.Parameters(name = "cmdHnd={0}, strategy={1}, explicitGrp={2}, callByGrp={3}") + @Parameterized.Parameters(name = "cmdHnd={0}, strategy={1}, explicitGrp={2}, callByGrp={3}, withSecurityEnabled={4}") public static Iterable data() { List res = new ArrayList<>(); - int cntr = 0; - List invokers = commandHandlers(); - - for (ReadRepairStrategy strategy : ReadRepairStrategy.values()) { - for (boolean explicitGrp : new boolean[]{false, true}) { - if (explicitGrp) - res.add(new Object[]{invokers.get(cntr++ % invokers.size()), strategy, explicitGrp, true}); - - res.add(new Object[]{invokers.get(cntr++ % invokers.size()), strategy, explicitGrp, false}); + for (String invoker : commandHandlers()) { + for (ReadRepairStrategy strategy : ReadRepairStrategy.values()) { + for (boolean explicitGrp : new boolean[] {false, true}) { + for (boolean callByGrp : new boolean[] {false, true}) { + for (boolean withSecurityEnabled : new boolean[] {false, true}) { + if (!explicitGrp && callByGrp || invoker.equals(JMX_CMD_HND) && withSecurityEnabled) + continue; + + res.add(new Object[] {invoker, strategy, explicitGrp, callByGrp, withSecurityEnabled}); + } + } + } } } @@ -129,6 +145,12 @@ public static Iterable data() { @Parameterized.Parameter(3) public boolean callByGrp; + /** + * True if security checks enabled. + */ + @Parameterized.Parameter(4) + public boolean withSecurityEnabled; + /** * */ @@ -154,6 +176,18 @@ protected CacheConfiguration cacheConfiguration(boolean tx) { cfg.setGridLogger(listeningLog); + if (withSecurityEnabled) { + cfg.setPluginProviders( + new TestSecurityPluginProvider( + igniteInstanceName, + DEFAULT_PWD, + ALL_PERMISSIONS, + false, + new TestSecurityData(TEST_NO_PERMISSIONS_LOGIN, DEFAULT_PWD, NO_PERMISSIONS, new Permissions()), + new TestSecurityData(TEST_LOGIN, DEFAULT_PWD, systemPermissions(ADMIN_OPS), new Permissions())) + ); + } + return cfg; } @@ -221,7 +255,8 @@ private void testAtomicAndTx(boolean incVal) throws Exception { } } - assertEquals(EXIT_CODE_OK, execute("--cache", "idle_verify")); + checkCommandExecution(EXIT_CODE_OK, asList("--cache", "idle_verify")); + assertContains(log, testOut.toString(), "conflict partitions has been found: [counterConflicts=0, hashConflicts=" + brokenParts.get()); @@ -285,7 +320,8 @@ public void testCacheFilter() throws Exception { AtomicInteger brokenParts = new AtomicInteger(PARTITIONS); - assertEquals(EXIT_CODE_OK, execute("--cache", "idle_verify")); + checkCommandExecution(EXIT_CODE_OK, asList("--cache", "idle_verify")); + assertContains(log, testOut.toString(), "conflict partitions has been found: [counterConflicts=0, hashConflicts=" + brokenParts.get()); @@ -306,11 +342,13 @@ public void testRepairNonExistentCache() throws Exception { injectTestSystemOut(); for (int i = 0; i < PARTITIONS; i++) { - assertEquals(EXIT_CODE_UNEXPECTED_ERROR, - execute("--consistency", "repair", + checkCommandExecution( + EXIT_CODE_UNEXPECTED_ERROR, + asList("--consistency", "repair", CACHE, "non-existent", PARTITIONS_ARG, String.valueOf(i), - STRATEGY, strategy.toString())); + STRATEGY, strategy.toString()) + ); assertTrue(ConsistencyStatusTask.MAP.isEmpty()); @@ -329,18 +367,20 @@ private void readRepair(AtomicInteger brokenParts, String cacheName, Integer rep i = Math.min(i + ThreadLocalRandom.current().nextInt(1, 10), PARTITIONS); - assertEquals(EXIT_CODE_OK, execute("--consistency", "repair", - CACHE, callByGrp ? cacheName + GRP_POSTFIX : cacheName, - PARTITIONS_ARG, - IntStream.range(from, i).mapToObj(Integer::toString).collect(Collectors.joining(",")), - STRATEGY, strategy.toString())); + checkCommandExecution( + EXIT_CODE_OK, + asList("--consistency", "repair", + CACHE, callByGrp ? cacheName + GRP_POSTFIX : cacheName, + PARTITIONS_ARG, IntStream.range(from, i).mapToObj(Integer::toString).collect(Collectors.joining(",")), + STRATEGY, strategy.toString()) + ); assertTrue(ConsistencyStatusTask.MAP.isEmpty()); assertContains(log, testOut.toString(), CONSISTENCY_VIOLATIONS_FOUND); assertContains(log, testOut.toString(), "[found=1, repaired=" + repairsPerEntry.toString()); - assertEquals(EXIT_CODE_OK, execute("--cache", "idle_verify")); + checkCommandExecution(EXIT_CODE_OK, asList("--cache", "idle_verify")); if (repairsPerEntry > 0) { brokenParts.addAndGet(-(i - from)); @@ -444,4 +484,20 @@ private void fillCache(String name, Ignite filtered, boolean incVal) throws Exce protected boolean binaryCache() { return false; } + + /** + * Wrapper for security check with {@link #assertEquals(int, int)}. The method checks 2 user logins + * for auth success/error. + * @param expExitCode Exp exit code. + * @param cmdArgs cmdArgs command arguments + */ + private void checkCommandExecution(int expExitCode, Collection cmdArgs) { + if (!withSecurityEnabled) + assertEquals(expExitCode, execute(new ArrayList<>(cmdArgs))); + else { + assertEquals(EXIT_CODE_UNEXPECTED_ERROR, execute(enrichWithConnectionArguments(cmdArgs, TEST_NO_PERMISSIONS_LOGIN))); + + assertEquals(expExitCode, execute(enrichWithConnectionArguments(cmdArgs, TEST_LOGIN))); + } + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/management/consistency/ConsistencyRepairTask.java b/modules/core/src/main/java/org/apache/ignite/internal/management/consistency/ConsistencyRepairTask.java index 7495ba4217c32..0a46c30d73bd7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/management/consistency/ConsistencyRepairTask.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/management/consistency/ConsistencyRepairTask.java @@ -40,6 +40,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtLocalPartition; import org.apache.ignite.internal.processors.cache.distributed.near.consistency.IgniteIrreparableConsistencyViolationException; import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow; +import org.apache.ignite.internal.processors.security.OperationSecurityContext; import org.apache.ignite.internal.util.GridConcurrentHashSet; import org.apache.ignite.internal.util.lang.GridCursor; import org.apache.ignite.internal.util.typedef.F; @@ -48,6 +49,7 @@ import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.resources.LoggerResource; + import static org.apache.ignite.events.EventType.EVT_CONSISTENCY_VIOLATION; /** @@ -271,7 +273,7 @@ private String processPartition(int p, ConsistencyRepairCommandArg arg) { * @param keys Keys. */ private void repair(IgniteCache cache, Set keys) { - try { + try (OperationSecurityContext ignored = ignite.context().security().withContext(ignite.localNode().id())) { cache.getAll(keys); // Repair. } catch (CacheException e) {