ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject [1/4] ignite git commit: IGNITE-7436: Simple username/password authentication. This closes #3483.
Date Thu, 22 Mar 2018 11:47:14 GMT
Repository: ignite
Updated Branches:
  refs/heads/master 664f1aa1a -> edef7add0


http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationOnNotActiveClusterTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationOnNotActiveClusterTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationOnNotActiveClusterTest.java
new file mode 100644
index 0000000..7405d7a
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationOnNotActiveClusterTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.authentication;
+
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Test for {@link IgniteAuthenticationProcessor}.
+ */
+public class AuthenticationOnNotActiveClusterTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Nodes count. */
+    protected static final int NODES_COUNT = 4;
+
+    /** Client node. */
+    protected static final int CLI_NODE = NODES_COUNT - 1;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        if (getTestIgniteInstanceIndex(igniteInstanceName) == CLI_NODE)
+            cfg.setClientMode(true);
+
+        TcpDiscoverySpi spi = new TcpDiscoverySpi();
+
+        spi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(spi);
+
+        cfg.setAuthenticationEnabled(true);
+
+        cfg.setDataStorageConfiguration(new DataStorageConfiguration()
+            .setDefaultDataRegionConfiguration(new DataRegionConfiguration()
+                .setPersistenceEnabled(true)));
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", true);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        super.afterTest();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDefaultUser() throws Exception {
+        startGrids(NODES_COUNT);
+
+        for (int i = 0; i < NODES_COUNT; ++i) {
+            AuthorizationContext actx = grid(i).context().authentication().authenticate("ignite", "ignite");
+
+            assertNotNull(actx);
+            assertEquals("ignite", actx.userName());
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNotDefaultUser() throws Exception {
+        startGrids(NODES_COUNT + 1);
+
+        grid(0).cluster().active(true);
+
+        AuthorizationContext actxDflt = grid(0).context().authentication().authenticate(User.DFAULT_USER_NAME, "ignite");
+
+        AuthorizationContext.context(actxDflt);
+
+        for (int i = 0; i < 10; ++i)
+            grid(0).context().authentication().addUser("test" + i, "passwd");
+
+        stopAllGrids();
+
+        U.sleep(500);
+
+        startGrids(NODES_COUNT);
+
+        for (int i = 0; i < NODES_COUNT; ++i) {
+            for (int usrCnt = 0; usrCnt < 10; ++usrCnt) {
+                AuthorizationContext actx = grid(i).context().authentication().authenticate("test" + usrCnt, "passwd");
+
+                assertNotNull(actx);
+                assertEquals("test" + usrCnt, actx.userName());
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationProcessorNodeRestartTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationProcessorNodeRestartTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationProcessorNodeRestartTest.java
new file mode 100644
index 0000000..632a8b9
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationProcessorNodeRestartTest.java
@@ -0,0 +1,425 @@
+/*
+ * 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.authentication;
+
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Test for {@link IgniteAuthenticationProcessor} on unstable topology.
+ */
+public class AuthenticationProcessorNodeRestartTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Nodes count. */
+    private static final int NODES_COUNT = 4;
+
+    /** Nodes restarts count. */
+    private static final int RESTARTS = 10;
+
+    /** Client node. */
+    protected static final int CLI_NODE = NODES_COUNT - 1;
+
+    /** Authorization context for default user. */
+    protected AuthorizationContext actxDflt;
+
+    /** Random. */
+    private static final Random RND = new Random(System.currentTimeMillis());
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        if (getTestIgniteInstanceIndex(igniteInstanceName) == CLI_NODE)
+            cfg.setClientMode(true);
+
+        TcpDiscoverySpi spi = new TcpDiscoverySpi();
+
+        spi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(spi);
+
+        cfg.setAuthenticationEnabled(true);
+
+        cfg.setDataStorageConfiguration(new DataStorageConfiguration()
+            .setDefaultDataRegionConfiguration(new DataRegionConfiguration()
+                .setPersistenceEnabled(true)));
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", true);
+
+        startGrids(NODES_COUNT);
+
+        grid(0).cluster().active(true);
+
+        actxDflt = grid(0).context().authentication().authenticate(User.DFAULT_USER_NAME, "ignite");
+
+        assertNotNull(actxDflt);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        super.afterTest();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testConcurrentAddUpdateRemoveNodeRestartCoordinator() throws Exception {
+        fail("https://issues.apache.org/jira/browse/IGNITE-7472");
+
+        final IgniteInternalFuture restartFut = restartCoordinator();
+
+        AuthorizationContext.context(actxDflt);
+
+        final AtomicInteger usrCnt = new AtomicInteger();
+
+        GridTestUtils.runMultiThreaded(new Runnable() {
+            @Override public void run() {
+                AuthorizationContext.context(actxDflt);
+
+                String user = "test" + usrCnt.getAndIncrement();
+
+                try {
+                    int state = 0;
+                    while (!restartFut.isDone()) {
+                        try {
+                            switch (state) {
+                                case 0:
+                                    grid(CLI_NODE).context().authentication().addUser(user, "passwd_" + user);
+
+                                    break;
+
+                                case 1:
+                                    grid(CLI_NODE).context().authentication().updateUser(user, "new_passwd_" + user);
+
+                                    break;
+
+                                case 2:
+                                    grid(CLI_NODE).context().authentication().removeUser(user);
+
+                                    break;
+
+                                default:
+                                    fail("Invalid state: " + state);
+                            }
+
+                            state = ++state > 2 ? 0 : state;
+                        }
+                        catch (UserManagementException e) {
+                            U.error(log, e);
+                            fail("Unexpected exception on user operation");
+                        }
+                        catch (IgniteCheckedException e) {
+                            // Reconnect
+                            U.error(log, e);
+                        }
+                    }
+                }
+                catch (Exception e) {
+                    U.error(log, "Unexpected exception on concurrent add/remove: " + user, e);
+                    fail();
+                }
+            }
+        }, 10, "user-op");
+
+        restartFut.get();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testConcurrentAuthorize() throws Exception {
+        final int testUsersCnt = 10;
+
+        AuthorizationContext.context(actxDflt);
+
+        for (int i = 0; i < testUsersCnt; ++i)
+            grid(CLI_NODE).context().authentication().addUser("test" + i, "passwd_test" + i);
+
+        final IgniteInternalFuture restartFut = GridTestUtils.runAsync(new Runnable() {
+            @Override public void run() {
+                try {
+                    for (int i = 0; i < RESTARTS; ++i) {
+                        int nodeIdx = RND.nextInt(NODES_COUNT - 1);
+
+                        stopGrid(nodeIdx);
+
+                        U.sleep(500);
+
+                        startGrid(nodeIdx);
+
+                        U.sleep(500);
+                    }
+                }
+                catch (Exception e) {
+                    e.printStackTrace(System.err);
+                    fail("Unexpected exception on server restart: " + e.getMessage());
+                }
+            }
+        });
+
+        final AtomicInteger usrCnt = new AtomicInteger();
+
+        GridTestUtils.runMultiThreaded(new Runnable() {
+            @Override public void run() {
+                String user = "test" + usrCnt.getAndIncrement();
+
+                try {
+                    while (!restartFut.isDone()) {
+                        AuthorizationContext actx = grid(CLI_NODE).context().authentication()
+                            .authenticate(user, "passwd_" + user);
+
+                        assertNotNull(actx);
+                    }
+                }
+                catch (IgniteCheckedException e) {
+                    // Skip exception if server down.
+                    if (!e.getMessage().contains("Failed to send message (node may have left the grid or "
+                        + "TCP connection cannot be established due to firewall issues)")) {
+                        e.printStackTrace();
+                        fail("Unexpected exception: " + e.getMessage());
+                    }
+                }
+                catch (Exception e) {
+                    e.printStackTrace();
+                    fail("Unexpected exception: " + e.getMessage());
+                }
+            }
+        }, testUsersCnt, "user-op");
+
+        restartFut.get();
+    }
+
+    /**
+     * @return Future.
+     */
+    protected IgniteInternalFuture restartCoordinator() {
+        return GridTestUtils.runAsync(new Runnable() {
+            @Override public void run() {
+                try {
+                    int restarts = 0;
+
+                    while (restarts < RESTARTS) {
+                        for (int i = 0; i < CLI_NODE; ++i, ++restarts) {
+                            if (restarts >= RESTARTS)
+                                break;
+
+                            stopGrid(i);
+
+                            U.sleep(500);
+
+                            startGrid(i);
+
+                            U.sleep(500);
+                        }
+                    }
+                }
+                catch (Exception e) {
+                    U.error(log, "Unexpected exception on coordinator restart", e);
+                    fail();
+                }
+            }
+        });
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void test1kUsersNodeRestartServer() throws Exception {
+        final AtomicInteger usrCnt = new AtomicInteger();
+
+        GridTestUtils.runMultiThreaded(new Runnable() {
+            @Override public void run() {
+                AuthorizationContext.context(actxDflt);
+
+                try {
+                    while (usrCnt.get() < 200) {
+                        String user = "test" + usrCnt.getAndIncrement();
+
+                        System.out.println("+++ CREATE  " + user);
+                        grid(0).context().authentication().addUser(user, "init");
+                    }
+                }
+                catch (Exception e) {
+                    e.printStackTrace();
+                    fail("Unexpected exception on add / remove");
+                }
+            }
+        }, 3, "user-op");
+
+        usrCnt.set(0);
+
+        GridTestUtils.runMultiThreaded(new Runnable() {
+            @Override public void run() {
+                AuthorizationContext.context(actxDflt);
+
+                try {
+                    while (usrCnt.get() < 200) {
+                        String user = "test" + usrCnt.getAndIncrement();
+
+                        System.out.println("+++ ALTER " + user);
+
+                        grid(0).context().authentication().updateUser(user, "passwd_" + user);
+                    }
+                }
+                catch (Exception e) {
+                    e.printStackTrace();
+                    fail("Unexpected exception on add / remove");
+                }
+            }
+        }, 3, "user-op");
+
+        System.out.println("+++ STOP");
+        stopGrid(0, true);
+
+        U.sleep(1000);
+
+        System.out.println("+++ START");
+        startGrid(0);
+
+        AuthorizationContext actx = grid(0).context().authentication().authenticate("ignite", "ignite");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testConcurrentAddUpdateRemoveNodeRestartServer() throws Exception {
+        final IgniteInternalFuture restartFut = GridTestUtils.runAsync(new Runnable() {
+            @Override public void run() {
+                try {
+                    for (int i = 0; i < RESTARTS; ++i) {
+                        stopGrid(1);
+
+                        U.sleep(500);
+
+                        startGrid(1);
+
+                        U.sleep(500);
+                    }
+                }
+                catch (Exception e) {
+                    e.printStackTrace(System.err);
+                    fail("Unexpected exception on server restart: " + e.getMessage());
+                }
+            }
+        });
+
+        AuthorizationContext.context(actxDflt);
+
+        final AtomicInteger usrCnt = new AtomicInteger();
+
+        GridTestUtils.runMultiThreaded(new Runnable() {
+            @Override public void run() {
+                AuthorizationContext.context(actxDflt);
+
+                String user = "test" + usrCnt.getAndIncrement();
+
+                try {
+                    while (!restartFut.isDone()) {
+                        grid(CLI_NODE).context().authentication().addUser(user, "init");
+
+                        grid(CLI_NODE).context().authentication().updateUser(user, "passwd_" + user);
+
+                        grid(CLI_NODE).context().authentication().removeUser(user);
+                    }
+                }
+                catch (Exception e) {
+                    e.printStackTrace();
+                    fail("Unexpected exception on add / remove");
+                }
+            }
+        }, 10, "user-op");
+
+        restartFut.get();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testConcurrentFailedOperationNodeRestartServer() throws Exception {
+        final IgniteInternalFuture restartFut = GridTestUtils.runAsync(new Runnable() {
+            @Override public void run() {
+                try {
+                    for (int i = 0; i < RESTARTS; ++i) {
+                        stopGrid(1);
+
+                        U.sleep(500);
+
+                        startGrid(1);
+
+                        U.sleep(500);
+                    }
+                }
+                catch (Exception e) {
+                    e.printStackTrace(System.err);
+                    fail("Unexpected exception on server restart: " + e.getMessage());
+                }
+            }
+        });
+
+        AuthorizationContext.context(actxDflt);
+
+        grid(CLI_NODE).context().authentication().addUser("test", "test");
+
+        GridTestUtils.runMultiThreaded(new Runnable() {
+            @Override public void run() {
+                AuthorizationContext.context(actxDflt);
+
+                try {
+                    while (!restartFut.isDone()) {
+                        GridTestUtils.assertThrows(log, new Callable<Object>() {
+                            @Override public Object call() throws Exception {
+                                grid(CLI_NODE).context().authentication().addUser("test", "test");
+
+                                return null;
+                            }
+                        }, UserManagementException.class, "User already exists");
+                    }
+                }
+                catch (Exception e) {
+                    e.printStackTrace();
+                    fail("Unexpected error on failed operation");
+                }
+            }
+        }, 10, "user-op");
+
+        restartFut.get();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationProcessorSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationProcessorSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationProcessorSelfTest.java
new file mode 100644
index 0000000..71d86f2
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/authentication/AuthenticationProcessorSelfTest.java
@@ -0,0 +1,637 @@
+/*
+ * 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.authentication;
+
+import java.util.Base64;
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Test for {@link IgniteAuthenticationProcessor}.
+ */
+public class AuthenticationProcessorSelfTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Nodes count. */
+    protected static final int NODES_COUNT = 4;
+
+    /** Iterations count. */
+    private static final int ITERATIONS = 10;
+
+    /** Client node. */
+    protected static final int CLI_NODE = NODES_COUNT - 1;
+
+    /** Random. */
+    private static final Random RND = new Random(System.currentTimeMillis());
+
+    /** Authorization context for default user. */
+    protected AuthorizationContext actxDflt;
+
+    /**
+     * @param len String length.
+     * @return Random string (Base64 on random bytes).
+     */
+    private static String randomString(int len) {
+        byte[] rndBytes = new byte[len / 2];
+
+        RND.nextBytes(rndBytes);
+
+        return Base64.getEncoder().encodeToString(rndBytes);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        if (getTestIgniteInstanceIndex(igniteInstanceName) == CLI_NODE)
+            cfg.setClientMode(true);
+
+        TcpDiscoverySpi spi = new TcpDiscoverySpi();
+
+        spi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(spi);
+
+        cfg.setAuthenticationEnabled(true);
+
+        cfg.setDataStorageConfiguration(new DataStorageConfiguration()
+            .setDefaultDataRegionConfiguration(new DataRegionConfiguration()
+                .setPersistenceEnabled(true)));
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", true);
+
+        startGrids(NODES_COUNT);
+
+        grid(0).cluster().active(true);
+
+        actxDflt = grid(0).context().authentication().authenticate(User.DFAULT_USER_NAME, "ignite");
+
+        assertNotNull(actxDflt);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        super.afterTest();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDefaultUser() throws Exception {
+        for (int i = 0; i < NODES_COUNT; ++i) {
+            AuthorizationContext actx = grid(i).context().authentication().authenticate("ignite", "ignite");
+
+            assertNotNull(actx);
+            assertEquals("ignite", actx.userName());
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDefaultUserUpdate() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        try {
+            // Change from all nodes
+            for (int nodeIdx = 0; nodeIdx < NODES_COUNT; ++nodeIdx) {
+                grid(nodeIdx).context().authentication().updateUser("ignite", "ignite" + nodeIdx);
+
+                // Check each change from all nodes
+                for (int i = 0; i < NODES_COUNT; ++i) {
+                    AuthorizationContext actx = grid(i).context().authentication().authenticate("ignite", "ignite" + nodeIdx);
+
+                    assertNotNull(actx);
+                    assertEquals("ignite", actx.userName());
+                }
+            }
+        }
+        finally {
+            AuthorizationContext.clear();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRemoveDefault() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        try {
+            for (int i = 0; i < NODES_COUNT; ++i) {
+                final int nodeIdx = i;
+
+                GridTestUtils.assertThrows(log, new Callable<Object>() {
+                    @Override public Object call() throws Exception {
+                        grid(nodeIdx).context().authentication().removeUser("ignite");
+
+                        return null;
+                    }
+                }, IgniteAccessControlException.class, "Default user cannot be removed");
+
+                assertNotNull(grid(nodeIdx).context().authentication().authenticate("ignite", "ignite"));
+            }
+        }
+        finally {
+            AuthorizationContext.context(null);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testUserManagementPermission() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        try {
+            grid(0).context().authentication().addUser("test", "test");
+
+            final AuthorizationContext actx = grid(0).context().authentication().authenticate("test", "test");
+
+            for (int i = 0; i < NODES_COUNT; ++i) {
+                final int nodeIdx = i;
+
+                AuthorizationContext.context(actx);
+
+                GridTestUtils.assertThrows(log, new Callable<Object>() {
+                    @Override public Object call() throws Exception {
+                        grid(nodeIdx).context().authentication().addUser("test1", "test1");
+
+                        return null;
+                    }
+                }, IgniteAccessControlException.class, "User management operations are not allowed for user");
+
+                GridTestUtils.assertThrows(log, new Callable<Object>() {
+                    @Override public Object call() throws Exception {
+                        grid(nodeIdx).context().authentication().removeUser("test");
+
+                        return null;
+                    }
+                }, IgniteAccessControlException.class, "User management operations are not allowed for user");
+
+                grid(nodeIdx).context().authentication().updateUser("test", "new_password");
+
+                grid(nodeIdx).context().authentication().updateUser("test", "test");
+
+                // Check error on empty auth context:
+                AuthorizationContext.context(null);
+
+                GridTestUtils.assertThrows(log, new Callable<Object>() {
+                    @Override public Object call() throws Exception {
+                        grid(nodeIdx).context().authentication().removeUser("test");
+
+                        return null;
+                    }
+                }, IgniteAccessControlException.class, "Operation not allowed: authorized context is empty");
+            }
+        }
+        finally {
+            AuthorizationContext.context(null);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testProceedUsersOnJoinNode() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        try {
+            grid(0).context().authentication().addUser("test0", "test");
+            grid(0).context().authentication().addUser("test1", "test");
+
+            int nodeIdx = NODES_COUNT;
+
+            startGrid(nodeIdx);
+
+            AuthorizationContext actx0 = grid(nodeIdx).context().authentication().authenticate("test0", "test");
+            AuthorizationContext actx1 = grid(nodeIdx).context().authentication().authenticate("test1", "test");
+
+            assertNotNull(actx0);
+            assertEquals("test0", actx0.userName());
+            assertNotNull(actx1);
+            assertEquals("test1", actx1.userName());
+        }
+        finally {
+            AuthorizationContext.context(null);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAuthenticationInvalidUser() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        try {
+            for (int i = 0; i < NODES_COUNT; ++i) {
+                final int nodeIdx = i;
+
+                GridTestUtils.assertThrows(log, new Callable<Object>() {
+                    @Override public Object call() throws Exception {
+                        grid(nodeIdx).context().authentication().authenticate("invalid_name", "test");
+
+                        return null;
+                    }
+                }, IgniteAccessControlException.class, "The user name or password is incorrect");
+
+                GridTestUtils.assertThrows(log, new Callable<Object>() {
+                    @Override public Object call() throws Exception {
+                        grid(nodeIdx).context().authentication().authenticate("test", "invalid_password");
+
+                        return null;
+                    }
+                }, IgniteAccessControlException.class, "The user name or password is incorrect");
+            }
+        }
+        finally {
+            AuthorizationContext.context(null);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAddUpdateRemoveUser() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        try {
+            for (int i = 0; i < NODES_COUNT; ++i) {
+                for (int j = 0; j < NODES_COUNT; ++j)
+                    checkAddUpdateRemoveUser(grid(i), grid(j));
+            }
+        }
+        finally {
+            AuthorizationContext.context(null);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testUpdateUser() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        try {
+            grid(0).context().authentication().addUser("test", "test");
+
+            AuthorizationContext actx = grid(0).context().authentication().authenticate("test", "test");
+
+            for (int i = 0; i < NODES_COUNT; ++i) {
+                for (int j = 0; j < NODES_COUNT; ++j)
+                    checkUpdateUser(actx, grid(i), grid(j));
+            }
+        }
+        finally {
+            AuthorizationContext.context(null);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testUpdateRemoveDoesNotExistsUser() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        try {
+            for (int i = 0; i < NODES_COUNT; ++i) {
+                final int nodeIdx = i;
+
+                GridTestUtils.assertThrows(log, new Callable<Object>() {
+                    @Override public Object call() throws Exception {
+                        grid(nodeIdx).context().authentication().updateUser("invalid_name", "test");
+
+                        return null;
+                    }
+                }, UserManagementException.class, "User doesn't exist");
+
+                GridTestUtils.assertThrows(log, new Callable<Object>() {
+                    @Override public Object call() throws Exception {
+                        grid(nodeIdx).context().authentication().removeUser("invalid_name");
+
+                        return null;
+                    }
+                }, UserManagementException.class, "User doesn't exist");
+            }
+        }
+        finally {
+            AuthorizationContext.context(null);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAddAlreadyExistsUser() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        try {
+            grid(0).context().authentication().addUser("test", "test");
+
+            for (int i = 0; i < NODES_COUNT; ++i) {
+                final int nodeIdx = i;
+
+                GridTestUtils.assertThrows(log, new Callable<Object>() {
+                    @Override public Object call() throws Exception {
+                        grid(nodeIdx).context().authentication().addUser("test", "new_passwd");
+
+                        return null;
+                    }
+                }, UserManagementException.class, "User already exists");
+            }
+        }
+        finally {
+            AuthorizationContext.context(null);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAuthorizeOnClientDisconnect() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        grid(CLI_NODE).context().authentication().addUser("test", "test");
+
+        AuthorizationContext.context(null);
+
+        final IgniteInternalFuture stopServersFut = GridTestUtils.runAsync(new Runnable() {
+            @Override public void run() {
+                try {
+                    for (int i = 0; i < CLI_NODE; ++i) {
+                        Thread.sleep(500);
+
+                        stopGrid(i);
+                    }
+                }
+                catch (Exception e) {
+                    e.printStackTrace();
+                    fail("Unexpected exception");
+                }
+            }
+        });
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+                @Override public Object call() throws Exception {
+                    while (!stopServersFut.isDone()) {
+                        AuthorizationContext actx = grid(CLI_NODE).context().authentication()
+                            .authenticate("test", "test");
+
+                        assertNotNull(actx);
+                    }
+
+                    return null;
+                }
+            },
+            IgniteCheckedException.class,
+            "Client node was disconnected from topology (operation result is unknown)");
+
+        stopServersFut.get();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testConcurrentAddRemove() throws Exception {
+        final AtomicInteger usrCnt = new AtomicInteger();
+
+        GridTestUtils.runMultiThreaded(new Runnable() {
+            @Override public void run() {
+                AuthorizationContext.context(actxDflt);
+                String user = "test" + usrCnt.getAndIncrement();
+
+                try {
+                    for (int i = 0; i < ITERATIONS; ++i) {
+                        grid(CLI_NODE).context().authentication().addUser(user, "passwd_" + user);
+
+                        grid(CLI_NODE).context().authentication().removeUser(user);
+                    }
+                }
+                catch (Exception e) {
+                    e.printStackTrace();
+                    fail("Unexpected exception");
+                }
+            }
+        }, 10, "user-op");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testUserPersistence() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        try {
+            for (int i = 0; i < NODES_COUNT; ++i)
+                grid(i).context().authentication().addUser("test" + i , "passwd" + i);
+
+            grid(CLI_NODE).context().authentication().updateUser("ignite", "new_passwd");
+
+            stopAllGrids();
+
+            startGrids(NODES_COUNT);
+
+            for (int i = 0; i < NODES_COUNT; ++i) {
+                for (int usrIdx = 0; usrIdx < NODES_COUNT; ++usrIdx) {
+                    AuthorizationContext actx0 = grid(i).context().authentication()
+                        .authenticate("test" + usrIdx, "passwd" + usrIdx);
+
+                    assertNotNull(actx0);
+                    assertEquals("test" + usrIdx, actx0.userName());
+                }
+
+                AuthorizationContext actx = grid(i).context().authentication()
+                    .authenticate("ignite", "new_passwd");
+
+                assertNotNull(actx);
+                assertEquals("ignite", actx.userName());
+            }
+        }
+        finally {
+            AuthorizationContext.clear();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDefaultUserPersistence() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        try {
+            grid(CLI_NODE).context().authentication().addUser("test", "passwd");
+
+            stopAllGrids();
+
+            U.sleep(500);
+
+            startGrids(NODES_COUNT);
+
+            for (int i = 0; i < NODES_COUNT; ++i) {
+                AuthorizationContext  actx = grid(i).context().authentication()
+                    .authenticate("ignite", "ignite");
+
+                assertNotNull(actx);
+                assertEquals("ignite", actx.userName());
+
+                actx = grid(i).context().authentication()
+                    .authenticate("test", "passwd");
+
+                assertNotNull(actx);
+                assertEquals("test", actx.userName());
+
+            }
+        }
+        finally {
+            AuthorizationContext.clear();
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testInvalidUserNamePassword() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                grid(CLI_NODE).context().authentication().addUser(null, "test");
+
+                return null;
+            }
+        }, UserManagementException.class, "User name is empty");
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                grid(CLI_NODE).context().authentication().addUser("", "test");
+
+                return null;
+            }
+        }, UserManagementException.class, "User name is empty");
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                grid(CLI_NODE).context().authentication().addUser("test", null);
+
+                return null;
+            }
+        }, UserManagementException.class, "Password is empty");
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                grid(CLI_NODE).context().authentication().addUser("test", "");
+
+                return null;
+            }
+        }, UserManagementException.class, "Password is empty");
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                grid(CLI_NODE).context().authentication().addUser(
+                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+                    "a");
+
+                return null;
+            }
+        }, UserManagementException.class, "User name is too long");
+    }
+
+    /**
+     * @param name User name to check.
+     */
+    private void checkInvalidUsername(final String name) {
+
+    }
+
+    /**
+     * @param passwd User's password to check.
+     */
+    private void checkInvalidPassword(final String passwd) {
+        AuthorizationContext.context(actxDflt);
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                grid(CLI_NODE).context().authentication().addUser("test", passwd);
+
+                return null;
+            }
+        }, UserManagementException.class, "Invalid user name");
+    }
+    /**
+     * @param createNode Node to execute create operation.
+     * @param authNode Node to execute authentication.
+     * @throws Exception On error.
+     */
+    private void checkAddUpdateRemoveUser(IgniteEx createNode, IgniteEx authNode) throws Exception {
+        createNode.context().authentication().addUser("test", "test");
+
+        AuthorizationContext newActx = authNode.context().authentication().authenticate("test", "test");
+
+        assertNotNull(newActx);
+        assertEquals("test", newActx.userName());
+
+        createNode.context().authentication().updateUser("test", "newpasswd");
+
+        newActx = authNode.context().authentication().authenticate("test", "newpasswd");
+
+        assertNotNull(newActx);
+        assertEquals("test", newActx.userName());
+
+        createNode.context().authentication().removeUser("test");
+    }
+
+    /**
+     * @param actx Authorization context.
+     * @param updNode Node to execute update operation.
+     * @param authNode Node to execute authentication.
+     * @throws Exception On error.
+     */
+    private void checkUpdateUser(AuthorizationContext actx, IgniteEx updNode, IgniteEx authNode) throws Exception {
+        String newPasswd = randomString(16);
+
+        updNode.context().authentication().updateUser("test", newPasswd);
+
+        AuthorizationContext actxNew = authNode.context().authentication().authenticate("test", newPasswd);
+
+        assertNotNull(actxNew);
+        assertEquals("test", actxNew.userName());
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/WalModeChangeCommonAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/WalModeChangeCommonAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/WalModeChangeCommonAbstractSelfTest.java
index 1c41386..e2ae4fa 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/WalModeChangeCommonAbstractSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/WalModeChangeCommonAbstractSelfTest.java
@@ -31,6 +31,7 @@ import org.apache.ignite.internal.IgniteClientReconnectAbstractTest;
 import org.apache.ignite.internal.util.lang.GridAbsPredicate;
 import org.apache.ignite.internal.util.lang.IgniteInClosureX;
 import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
 import org.apache.ignite.testframework.GridTestUtils;
@@ -104,6 +105,19 @@ public abstract class WalModeChangeCommonAbstractSelfTest extends GridCommonAbst
             for (String cacheName : cacheNames)
                 destroyCache(node0, cacheName);
         }
+
+        awaitPartitionMapExchange();
+
+        assertTrue(GridTestUtils.waitForCondition(new GridAbsPredicate() {
+            @Override public boolean apply() {
+                for (Ignite node0 : Ignition.allGrids()) {
+                    if (!node0.cacheNames().isEmpty())
+                        return false;
+                }
+
+                return true;
+            }
+        }, 2000));
     }
 
     /**
@@ -114,7 +128,7 @@ public abstract class WalModeChangeCommonAbstractSelfTest extends GridCommonAbst
      */
     @SuppressWarnings("unchecked")
     protected void createCache(Ignite node, CacheConfiguration ccfg) {
-        node.createCache(ccfg);
+        node.getOrCreateCache(ccfg);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/core/src/test/java/org/apache/ignite/internal/sql/SqlParserUserSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/sql/SqlParserUserSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/sql/SqlParserUserSelfTest.java
new file mode 100644
index 0000000..d3296f7
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/sql/SqlParserUserSelfTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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.sql;
+
+import org.apache.ignite.internal.sql.command.SqlAlterUserCommand;
+import org.apache.ignite.internal.sql.command.SqlCreateUserCommand;
+import org.apache.ignite.internal.sql.command.SqlDropUserCommand;
+
+/**
+ * Tests for SQL parser: CREATE INDEX.
+ */
+@SuppressWarnings({"UnusedReturnValue", "ThrowableNotThrown"})
+public class SqlParserUserSelfTest extends SqlParserAbstractSelfTest {
+    /**
+     * Tests for CREATE USER command.
+     *
+     * @throws Exception If failed.
+     */
+    public void testCreateUser() throws Exception {
+        // Base.
+        parseValidateCreate("CREATE USER test WITH PASSWORD 'test'", "TEST", "test");
+        parseValidateCreate("CREATE USER \"test\" WITH PASSWORD 'test'", "test", "test");
+        parseValidateCreate("CREATE USER \"Test Name\" WITH PASSWORD 'PaSSword'",
+            "Test Name", "PaSSword");
+        parseValidateCreate("CREATE USER test WITH PASSWORD '~!''@#$%^&*()_+=-`:\"|?.,/'",
+            "TEST", "~!'@#$%^&*()_+=-`:\"|?.,/");
+
+        assertParseError(null, "CREATE USER 'test' WITH PASSWORD 'test'",
+            "Unexpected token: \"test\" (expected: \"[username identifier]\")");
+        assertParseError(null, "CREATE USER \"PUBLIC\".\"test\" WITH PASSWORD 'test'",
+            "Unexpected token: \".\" (expected: \"WITH\")");
+    }
+
+    /**
+     * Tests for ALTER USER command.
+     *
+     * @throws Exception If failed.
+     */
+    public void testAlterUser() throws Exception {
+        // Base.
+        parseValidateAlter("ALTER USER test WITH PASSWORD 'test'", "TEST", "test");
+        parseValidateAlter("ALTER USER \"test\" WITH PASSWORD 'test'", "test", "test");
+        parseValidateAlter("ALTER USER \"Test Name\" WITH PASSWORD 'PaSSword'",
+            "Test Name", "PaSSword");
+        parseValidateAlter("ALTER USER test WITH PASSWORD '~!''@#$%^&*()_+=-`:\"|?.,/'",
+            "TEST", "~!'@#$%^&*()_+=-`:\"|?.,/");
+
+        assertParseError(null, "ALTER USER 'test' WITH PASSWORD 'test'",
+            "Unexpected token: \"test\" (expected: \"[username identifier]\")");
+        assertParseError(null, "ALTER USER \"PUBLIC\".\"test\" WITH PASSWORD 'test'",
+            "Unexpected token: \".\" (expected: \"WITH\")");
+    }
+
+    /**
+     * Tests for ALTER USER command.
+     *
+     * @throws Exception If failed.
+     */
+    public void testDropUser() throws Exception {
+        // Base.
+        parseValidateDrop("DROP USER test", "TEST");
+        parseValidateDrop("DROP USER \"test\"", "test");
+        parseValidateDrop("DROP USER \"Test Name\"", "Test Name");
+
+        assertParseError(null, "DROP USER 'test'",
+            "Unexpected token: \"test\" (expected: \"[username identifier]\")");
+        assertParseError(null, "DROP USER \"PUBLIC\".\"test\"",
+            "Unexpected token: \".\"");
+    }
+
+    /**
+     * Parse and validate SQL script.
+     *
+     * @param sql SQL.
+     * @param expUserName Expected user name.
+     * @param expPasswd Expected user password.
+     * @return Command.
+     */
+    private static SqlCreateUserCommand parseValidateCreate(String sql, String expUserName, String expPasswd) {
+        SqlCreateUserCommand cmd = (SqlCreateUserCommand)new SqlParser(null, sql).nextCommand();
+
+        assertEquals(expUserName, cmd.userName());
+        assertEquals(expPasswd, cmd.password());
+
+        return cmd;
+    }
+
+    /**
+     * Parse and validate SQL script.
+     *
+     * @param sql SQL.
+     * @param expUserName Expected user name.
+     * @param expPasswd Expected user password.
+     * @return Command.
+     */
+    private static SqlAlterUserCommand parseValidateAlter(String sql, String expUserName, String expPasswd) {
+        SqlAlterUserCommand cmd = (SqlAlterUserCommand)new SqlParser(null, sql).nextCommand();
+
+        assertEquals(expUserName, cmd.userName());
+        assertEquals(expPasswd, cmd.password());
+
+        return cmd;
+    }
+
+    /**
+     * Parse and validate SQL script.
+     *
+     * @param sql SQL.
+     * @param expUserName Expected user name.
+     * @return Command.
+     */
+    private static SqlDropUserCommand parseValidateDrop(String sql, String expUserName) {
+        SqlDropUserCommand cmd = (SqlDropUserCommand)new SqlParser(null, sql).nextCommand();
+
+        assertEquals(expUserName, cmd.userName());
+
+        return cmd;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/core/src/test/java/org/apache/ignite/spi/discovery/FilterDataForClientNodeDiscoveryTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/FilterDataForClientNodeDiscoveryTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/FilterDataForClientNodeDiscoveryTest.java
new file mode 100644
index 0000000..54b48e5
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/FilterDataForClientNodeDiscoveryTest.java
@@ -0,0 +1,214 @@
+/*
+ * 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.spi.discovery;
+
+import java.util.Arrays;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.managers.discovery.CustomEventListener;
+import org.apache.ignite.internal.managers.discovery.DiscoCache;
+import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
+import org.apache.ignite.internal.managers.discovery.DiscoveryServerOnlyCustomMessage;
+import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class FilterDataForClientNodeDiscoveryTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Join servers count. */
+    private int joinSrvCnt;
+
+    /** Join clients count. */
+    private int joinCliCnt;
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        super.afterTest();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDataBag() throws Exception {
+        startGrid(configuration(0, false));
+        startGrid(configuration(1, false));
+
+        assertEquals(3, joinSrvCnt);
+        assertEquals(0, joinCliCnt);
+
+        startGrid(configuration(2, true));
+        startGrid(configuration(3, true));
+
+        assertEquals(5, joinSrvCnt);
+        assertEquals(4, joinCliCnt);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDiscoveryServerOnlyCustomMessage() throws Exception {
+        startGrid(configuration(0, false));
+        startGrid(configuration(1, false));
+        startGrid(configuration(2, true));
+        startGrid(configuration(3, true));
+
+        final boolean [] recvMsg = new boolean[4];
+
+        for (int i = 0; i < 4; ++i) {
+            final int idx0 = i;
+
+            grid(i).context().discovery().setCustomEventListener(
+                MessageForServer.class, new CustomEventListener<MessageForServer>() {
+                @Override public void onCustomEvent(AffinityTopologyVersion topVer, ClusterNode snd,
+                    MessageForServer msg) {
+
+                    recvMsg[idx0] = true;
+                }
+            });
+        }
+
+        for (int i = 0; i < 4; ++i) {
+            Arrays.fill(recvMsg, false);
+
+            grid(i).context().discovery().sendCustomEvent(new MessageForServer());
+
+            Thread.sleep(500);
+
+            assertEquals(true, recvMsg[0]);
+            assertEquals(true, recvMsg[1]);
+            assertEquals(false, recvMsg[2]);
+            assertEquals(false, recvMsg[3]);
+        }
+    }
+
+
+    /**
+     * @param nodeIdx Node index.
+     * @param client Client flag.
+     * @return Ignite configuration.
+     * @throws Exception On error.
+     */
+    private IgniteConfiguration configuration(int nodeIdx, boolean client) throws Exception {
+        IgniteConfiguration cfg = getConfiguration(getTestIgniteInstanceName(nodeIdx));
+
+        TcpDiscoverySpi testSpi = new TestDiscoverySpi();
+
+        testSpi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(testSpi);
+
+        cfg.setClientMode(client);
+
+        return cfg;
+    }
+
+    /**
+     *
+     */
+    private class TestDiscoverySpi extends TcpDiscoverySpi {
+        /** Test exchange. */
+        private TestDiscoveryDataExchange testEx = new TestDiscoveryDataExchange();
+
+        /**
+         *
+         */
+        public TestDiscoverySpi() {
+            exchange = testEx;
+        }
+
+
+        /** {@inheritDoc} */
+        @Override public void setDataExchange(DiscoverySpiDataExchange exchange) {
+            testEx.setExchange(exchange);
+        }
+    }
+
+    /**
+     *
+     */
+    private class TestDiscoveryDataExchange implements DiscoverySpiDataExchange {
+        /** Real exchange. */
+        private DiscoverySpiDataExchange ex;
+
+        /** {@inheritDoc} */
+        @Override public DiscoveryDataBag collect(DiscoveryDataBag dataBag) {
+            if (dataBag.isJoiningNodeClient())
+                joinCliCnt++;
+            else
+                joinSrvCnt++;
+
+            return ex.collect(dataBag);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void onExchange(DiscoveryDataBag dataBag) {
+            ex.onExchange(dataBag);
+        }
+
+        /**
+         * @param ex Exchange.
+         */
+        public void setExchange(DiscoverySpiDataExchange ex) {
+            this.ex = ex;
+        }
+    }
+
+    /**
+     *
+     */
+    private static class MessageForServer implements DiscoveryServerOnlyCustomMessage {
+        /** */
+        private static final long serialVersionUID = 0L;
+
+        /** */
+        private final IgniteUuid id = IgniteUuid.randomUuid();
+
+        /** {@inheritDoc} */
+        @Override public IgniteUuid id() {
+            return id;
+        }
+
+        /** {@inheritDoc} */
+        @Nullable @Override public DiscoveryCustomMessage ackMessage() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean isMutable() {
+            return false;
+        }
+
+        /** {@inheritDoc} */
+        @Override public DiscoCache createDiscoCache(GridDiscoveryManager mgr, AffinityTopologyVersion topVer,
+            DiscoCache discoCache) {
+            return null;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
index 43a49fa..da01208 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
@@ -18,6 +18,10 @@
 package org.apache.ignite.testsuites;
 
 import junit.framework.TestSuite;
+import org.apache.ignite.internal.processors.authentication.AuthenticationConfigurationClusterTest;
+import org.apache.ignite.internal.processors.authentication.AuthenticationOnNotActiveClusterTest;
+import org.apache.ignite.internal.processors.authentication.AuthenticationProcessorNodeRestartTest;
+import org.apache.ignite.internal.processors.authentication.AuthenticationProcessorSelfTest;
 import org.apache.ignite.internal.processors.cache.WalModeChangeAdvancedSelfTest;
 import org.apache.ignite.internal.processors.cache.WalModeChangeCoordinatorNotAffinityNodeSelfTest;
 import org.apache.ignite.internal.processors.cache.WalModeChangeSelfTest;
@@ -67,6 +71,11 @@ public class IgniteCacheTestSuite6 extends TestSuite {
 //        TODO enable this test after IGNITE-6753, now it takes too long
 //        suite.addTestSuite(IgniteOutOfMemoryPropagationTest.class);
 
+        suite.addTestSuite(AuthenticationConfigurationClusterTest.class);
+        suite.addTestSuite(AuthenticationProcessorSelfTest.class);
+        suite.addTestSuite(AuthenticationOnNotActiveClusterTest.class);
+        suite.addTestSuite(AuthenticationProcessorNodeRestartTest.class);
+
         return suite;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
index 0681d10..1f82316 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteSpiDiscoverySelfTestSuite.java
@@ -20,6 +20,7 @@ package org.apache.ignite.testsuites;
 import junit.framework.TestSuite;
 import org.apache.ignite.spi.GridTcpSpiForwardingSelfTest;
 import org.apache.ignite.spi.discovery.AuthenticationRestartTest;
+import org.apache.ignite.spi.discovery.FilterDataForClientNodeDiscoveryTest;
 import org.apache.ignite.spi.discovery.IgniteDiscoveryCacheReuseSelfTest;
 import org.apache.ignite.spi.discovery.tcp.DiscoveryUnmarshalVulnerabilityTest;
 import org.apache.ignite.spi.discovery.tcp.IgniteClientConnectTest;
@@ -117,6 +118,8 @@ public class IgniteSpiDiscoverySelfTestSuite extends TestSuite {
 
         suite.addTest(new TestSuite(DiscoveryUnmarshalVulnerabilityTest.class));
 
+        suite.addTest(new TestSuite(FilterDataForClientNodeDiscoveryTest.class));
+
         return suite;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index 65f08b2..7a42d80 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -124,10 +124,14 @@ import org.apache.ignite.internal.sql.SqlParseException;
 import org.apache.ignite.internal.sql.SqlParser;
 import org.apache.ignite.internal.sql.command.SqlAlterTableCommand;
 import org.apache.ignite.internal.sql.command.SqlBulkLoadCommand;
+import org.apache.ignite.internal.sql.command.SqlAlterUserCommand;
+import org.apache.ignite.internal.sql.command.SqlBulkLoadCommand;
 import org.apache.ignite.internal.sql.command.SqlCommand;
 import org.apache.ignite.internal.sql.command.SqlCreateIndexCommand;
+import org.apache.ignite.internal.sql.command.SqlCreateUserCommand;
 import org.apache.ignite.internal.sql.command.SqlDropIndexCommand;
 import org.apache.ignite.internal.sql.command.SqlSetStreamingCommand;
+import org.apache.ignite.internal.sql.command.SqlDropUserCommand;
 import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap;
 import org.apache.ignite.internal.util.GridEmptyCloseableIterator;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
@@ -193,7 +197,7 @@ import static org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryType
 @SuppressWarnings({"UnnecessaryFullyQualifiedName", "NonFinalStaticVariableUsedInClassInitialization"})
 public class IgniteH2Indexing implements GridQueryIndexing {
     public static final Pattern INTERNAL_CMD_RE = Pattern.compile(
-        "^(create|drop)\\s+index|^alter\\s+table|^copy|^set", Pattern.CASE_INSENSITIVE);
+        "^(create|drop)\\s+index|^alter\\s+table|^copy|^set|^(create|alter|drop)\\s+user", Pattern.CASE_INSENSITIVE);
 
     /*
      * Register IO for indexes.
@@ -1512,9 +1516,12 @@ public class IgniteH2Indexing implements GridQueryIndexing {
             // COPY
             // ALTER TABLE
             // SET STREAMING
-            if (!(cmd instanceof SqlCreateIndexCommand || cmd instanceof SqlDropIndexCommand ||
-                cmd instanceof SqlAlterTableCommand || cmd instanceof SqlBulkLoadCommand ||
-                cmd instanceof SqlSetStreamingCommand))
+            // CREATE/ALTER/DROP USER
+            if (!(cmd instanceof SqlCreateIndexCommand || cmd instanceof SqlDropIndexCommand
+                || cmd instanceof SqlAlterTableCommand || cmd instanceof SqlBulkLoadCommand
+                || cmd instanceof SqlSetStreamingCommand
+                || cmd instanceof SqlCreateUserCommand || cmd instanceof SqlAlterUserCommand
+                || cmd instanceof SqlDropUserCommand))
                 return null;
         }
         catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
index d4f2b0e..b148969 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ddl/DdlStatementsProcessor.java
@@ -57,9 +57,12 @@ import org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser;
 import org.apache.ignite.internal.processors.query.h2.sql.GridSqlStatement;
 import org.apache.ignite.internal.processors.query.schema.SchemaOperationException;
 import org.apache.ignite.internal.sql.command.SqlAlterTableCommand;
+import org.apache.ignite.internal.sql.command.SqlAlterUserCommand;
 import org.apache.ignite.internal.sql.command.SqlCommand;
 import org.apache.ignite.internal.sql.command.SqlCreateIndexCommand;
+import org.apache.ignite.internal.sql.command.SqlCreateUserCommand;
 import org.apache.ignite.internal.sql.command.SqlDropIndexCommand;
+import org.apache.ignite.internal.sql.command.SqlDropUserCommand;
 import org.apache.ignite.internal.sql.command.SqlIndexColumn;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.typedef.F;
@@ -108,7 +111,7 @@ public class DdlStatementsProcessor {
      */
     @SuppressWarnings("unchecked")
     public FieldsQueryCursor<List<?>> runDdlStatement(String sql, SqlCommand cmd) throws IgniteCheckedException {
-        IgniteInternalFuture fut;
+        IgniteInternalFuture fut = null;
 
         try {
             if (cmd instanceof SqlCreateIndexCommand) {
@@ -205,6 +208,21 @@ public class DdlStatementsProcessor {
 
                 fut = new GridFinishedFuture();
             }
+            else if (cmd instanceof SqlCreateUserCommand) {
+                SqlCreateUserCommand addCmd = (SqlCreateUserCommand)cmd;
+
+                ctx.authentication().addUser(addCmd.userName(), addCmd.password());
+            }
+            else if (cmd instanceof SqlAlterUserCommand) {
+                SqlAlterUserCommand altCmd = (SqlAlterUserCommand)cmd;
+
+                ctx.authentication().updateUser(altCmd.userName(), altCmd.password());
+            }
+            else if (cmd instanceof SqlDropUserCommand) {
+                SqlDropUserCommand dropCmd = (SqlDropUserCommand)cmd;
+
+                ctx.authentication().removeUser(dropCmd.userName());
+            }
             else
                 throw new IgniteSQLException("Unsupported DDL operation: " + sql,
                     IgniteQueryErrorCode.UNSUPPORTED_OPERATION);

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/authentication/SqlUserCommandSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/authentication/SqlUserCommandSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/authentication/SqlUserCommandSelfTest.java
new file mode 100644
index 0000000..7d0a579
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/authentication/SqlUserCommandSelfTest.java
@@ -0,0 +1,294 @@
+/*
+ * 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.cache.authentication;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.processors.authentication.AuthorizationContext;
+import org.apache.ignite.internal.processors.authentication.IgniteAccessControlException;
+import org.apache.ignite.internal.processors.authentication.User;
+import org.apache.ignite.internal.processors.authentication.UserManagementException;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Test for leaks JdbcConnection on SqlFieldsQuery execute.
+ */
+public class SqlUserCommandSelfTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Nodes count. */
+    private static final int NODES_COUNT = 3;
+
+    /** Client node. */
+    private static final int CLI_NODE = NODES_COUNT - 1;
+
+    /** Authorization context for default user. */
+    private AuthorizationContext actxDflt;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        if (getTestIgniteInstanceIndex(igniteInstanceName) == CLI_NODE)
+            cfg.setClientMode(true);
+
+        TcpDiscoverySpi spi = new TcpDiscoverySpi();
+
+        spi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(spi);
+
+        cfg.setAuthenticationEnabled(true);
+
+        cfg.setDataStorageConfiguration(new DataStorageConfiguration()
+            .setDefaultDataRegionConfiguration(new DataRegionConfiguration()
+                .setPersistenceEnabled(true)));
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", true);
+
+        startGrids(NODES_COUNT);
+
+        grid(0).cluster().active(true);
+
+        actxDflt = grid(0).context().authentication().authenticate(User.DFAULT_USER_NAME, "ignite");
+
+        assertNotNull(actxDflt);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        super.afterTest();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testCreateUpdateDropUser() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        for (int i = 0; i < NODES_COUNT; ++i) {
+            userSql(i, "CREATE USER test WITH PASSWORD 'test'");
+
+            AuthorizationContext actx = grid(i).context().authentication()
+                .authenticate("TEST", "test");
+
+            assertNotNull(actx);
+            assertEquals("TEST", actx.userName());
+
+            userSql(i, "ALTER USER test WITH PASSWORD 'newpasswd'");
+
+            actx = grid(i).context().authentication()
+                .authenticate("TEST", "newpasswd");
+
+            assertNotNull(actx);
+            assertEquals("TEST", actx.userName());
+
+            userSql(i, "DROP USER test");
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testCreateWithAlreadyExistUser() throws Exception {
+        AuthorizationContext.context(actxDflt);
+        userSql(0, "CREATE USER test WITH PASSWORD 'test'");
+
+        for (int i = 0; i < NODES_COUNT; ++i) {
+            final int idx = i;
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    userSql(idx, "CREATE USER test WITH PASSWORD 'test'");
+
+                    return null;
+                }
+            }, UserManagementException.class, "User already exists [login=TEST]");
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAlterDropNotExistUser() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        for (int i = 0; i < NODES_COUNT; ++i) {
+            final int idx = i;
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    userSql(idx, "ALTER USER test WITH PASSWORD 'test'");
+
+                    return null;
+                }
+            }, UserManagementException.class, "User doesn't exist [userName=TEST]");
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    userSql(idx, "DROP USER test");
+
+                    return null;
+                }
+            }, UserManagementException.class, "User doesn't exist [userName=TEST]");
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNotAuthenticateOperation() throws Exception {
+        for (int i = 0; i < NODES_COUNT; ++i) {
+            final int idx = i;
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    userSql(idx, "CREATE USER test WITH PASSWORD 'test'");
+
+                    return null;
+                }
+            }, IgniteAccessControlException.class, "Operation not allowed: authorized context is empty");
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    userSql(idx, "ALTER USER test WITH PASSWORD 'test'");
+
+                    return null;
+                }
+            }, IgniteAccessControlException.class, "Operation not allowed: authorized context is empty");
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    userSql(idx, "DROP USER test");
+
+                    return null;
+                }
+            }, IgniteAccessControlException.class, "Operation not allowed: authorized context is empty");
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNotAuthorizedOperation() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        userSql(0, "CREATE USER user0 WITH PASSWORD 'user0'");
+
+        AuthorizationContext actx = grid(0).context().authentication()
+            .authenticate("USER0", "user0");
+
+        AuthorizationContext.context(actx);
+
+        for (int i = 0; i < NODES_COUNT; ++i) {
+            final int idx = i;
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    userSql(idx, "CREATE USER test WITH PASSWORD 'test'");
+
+                    return null;
+                }
+            }, IgniteAccessControlException.class, "User management operations are not allowed for user");
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    userSql(idx, "ALTER USER test WITH PASSWORD 'test'");
+
+                    return null;
+                }
+            }, IgniteAccessControlException.class, "User management operations are not allowed for user");
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    userSql(idx, "DROP USER test");
+
+                    return null;
+                }
+            }, IgniteAccessControlException.class, "User management operations are not allowed for user");
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDropDefaultUser() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        for (int i = 0; i < NODES_COUNT; ++i) {
+            final int idx = i;
+
+            GridTestUtils.assertThrowsAnyCause(log, new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    userSql(idx, "DROP USER \"ignite\"");
+
+                    return null;
+                }
+            }, IgniteAccessControlException.class, "Default user cannot be removed");
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testQuotedUsername() throws Exception {
+        AuthorizationContext.context(actxDflt);
+
+        userSql(0, "CREATE USER \"test\" with password 'test'");
+
+        userSql(0, "CREATE USER \" test\" with password 'test'");
+
+        userSql(0, "CREATE USER \" test \" with password 'test'");
+
+        userSql(0, "CREATE USER \"test \" with password 'test'");
+
+        userSql(0, "CREATE USER \"111\" with password 'test'");
+    }
+
+    /**
+     * @param nodeIdx Node index.
+     * @param sql Sql query.
+     */
+    private void userSql(int nodeIdx, String sql) {
+        List<List<?>> res = grid(nodeIdx).context().query().querySqlFields(
+            new SqlFieldsQuery(sql), false).getAll();
+
+        assertEquals(1, res.size());
+        assertEquals(1, res.get(0).size());
+        assertEquals(0L, res.get(0).get(0));
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index 35d1be2..e10fff1 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -77,6 +77,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCrossCachesJoinsQueryTe
 import org.apache.ignite.internal.processors.cache.IncorrectQueryEntityTest;
 import org.apache.ignite.internal.processors.cache.QueryEntityCaseMismatchTest;
 import org.apache.ignite.internal.processors.cache.SqlFieldsQuerySelfTest;
+import org.apache.ignite.internal.processors.cache.authentication.SqlUserCommandSelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheAtomicFieldsQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheAtomicNearEnabledFieldsQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.distributed.near.IgniteCacheAtomicNearEnabledQuerySelfTest;
@@ -172,6 +173,7 @@ import org.apache.ignite.internal.sql.SqlParserBulkLoadSelfTest;
 import org.apache.ignite.internal.sql.SqlParserCreateIndexSelfTest;
 import org.apache.ignite.internal.sql.SqlParserDropIndexSelfTest;
 import org.apache.ignite.internal.sql.SqlParserSetStreamingSelfTest;
+import org.apache.ignite.internal.sql.SqlParserUserSelfTest;
 import org.apache.ignite.spi.communication.tcp.GridOrderedMessageCancelSelfTest;
 import org.apache.ignite.testframework.IgniteTestSuite;
 
@@ -400,6 +402,10 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
         suite.addTestSuite(H2RowCacheSelfTest.class);
         suite.addTestSuite(H2RowCachePageEvictionTest.class);
 
+        // User operation SQL
+        suite.addTestSuite(SqlParserUserSelfTest.class);
+        suite.addTestSuite(SqlUserCommandSelfTest.class);
+
         return suite;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/edef7add/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index d60f6c2..0e591f8 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -835,6 +835,7 @@
                                         <exclude>src/main/java/org/apache/ignite/internal/util/nio/SelectedSelectionKeySet.java</exclude><!-- Apache 2.0 license -->
                                         <exclude>src/main/java/org/apache/ignite/internal/util/snaptree/*.java</exclude><!--BSD license-->
                                         <exclude>src/main/java/org/jsr166/*.java</exclude>
+                                        <exclude>src/main/java/org/mindrot/*.java</exclude>
                                         <exclude>src/test/java/org/apache/ignite/p2p/p2p.properties</exclude><!--test depends on file content-->
                                         <exclude>src/test/resources/log/ignite.log.tst</exclude><!--test resource-->
                                         <exclude>src/test/java/org/apache/ignite/spi/deployment/uri/META-INF/ignite.incorrefs</exclude><!--test resource-->


Mime
View raw message