You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2018/03/23 02:55:17 UTC
ignite git commit: IGNITE-8002 REST: Added support of new
authentication via new API.
Repository: ignite
Updated Branches:
refs/heads/master 14f7bcea5 -> 921f0cf9b
IGNITE-8002 REST: Added support of new authentication via new API.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/921f0cf9
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/921f0cf9
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/921f0cf9
Branch: refs/heads/master
Commit: 921f0cf9b3ab6454339fa57b929093f56372c61e
Parents: 14f7bce
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Mar 23 09:55:13 2018 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Mar 23 09:55:13 2018 +0700
----------------------------------------------------------------------
.../client/suite/IgniteClientTestSuite.java | 2 +
.../JettyRestProcessorAbstractSelfTest.java | 4 +-
...ettyRestProcessorAuthenticationSelfTest.java | 172 +++++++++++++++++++
.../processors/rest/GridRestCommand.java | 15 +-
.../processors/rest/GridRestProcessor.java | 132 +++++++++-----
.../handlers/user/UserActionCommandHandler.java | 97 +++++++++++
.../rest/handlers/user/package-info.java | 22 +++
.../protocols/tcp/GridTcpRestNioListener.java | 7 +-
.../rest/request/GridRestRequest.java | 21 ++-
.../rest/request/RestUserActionRequest.java | 64 +++++++
.../http/jetty/GridJettyRestHandler.java | 24 ++-
11 files changed, 507 insertions(+), 53 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/921f0cf9/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
index 223268c..79fcf38 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
@@ -49,6 +49,7 @@ import org.apache.ignite.internal.client.util.ClientByteUtilsTest;
import org.apache.ignite.internal.client.util.ClientConsistentHashSelfTest;
import org.apache.ignite.internal.client.util.ClientJavaHasherSelfTest;
import org.apache.ignite.internal.processors.rest.ClientMemcachedProtocolSelfTest;
+import org.apache.ignite.internal.processors.rest.JettyRestProcessorAuthenticationSelfTest;
import org.apache.ignite.internal.processors.rest.JettyRestProcessorSignedSelfTest;
import org.apache.ignite.internal.processors.rest.JettyRestProcessorUnsignedSelfTest;
import org.apache.ignite.internal.processors.rest.RestBinaryProtocolSelfTest;
@@ -86,6 +87,7 @@ public class IgniteClientTestSuite extends TestSuite {
// Test jetty rest processor
suite.addTestSuite(JettyRestProcessorSignedSelfTest.class);
suite.addTestSuite(JettyRestProcessorUnsignedSelfTest.class);
+ suite.addTestSuite(JettyRestProcessorAuthenticationSelfTest.class);
// Test TCP rest processor with original memcache client.
suite.addTestSuite(ClientMemcachedProtocolSelfTest.class);
http://git-wip-us.apache.org/repos/asf/ignite/blob/921f0cf9/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
index ece467a..5dc44c4 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
@@ -281,13 +281,13 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
* @param content Content to check.
* @param err Error message.
*/
- private void assertResponseContainsError(String content, String err) throws IOException {
+ protected void assertResponseContainsError(String content, String err) throws IOException {
assertFalse(F.isEmpty(content));
assertNotNull(err);
JsonNode node = JSON_MAPPER.readTree(content);
- assertEquals(STATUS_FAILED, node.get("successStatus").asInt());
+ assertTrue(node.get("successStatus").asInt() != STATUS_SUCCESS);
assertTrue(node.get("response").isNull());
assertTrue(node.get("error").asText().contains(err));
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/921f0cf9/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationSelfTest.java
new file mode 100644
index 0000000..ca62091
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAuthenticationSelfTest.java
@@ -0,0 +1,172 @@
+/*
+ * 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.rest;
+
+import java.util.concurrent.Callable;
+import com.fasterxml.jackson.databind.JsonNode;
+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.IgniteAccessControlException;
+import org.apache.ignite.internal.processors.authentication.IgniteAuthenticationProcessor;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.testframework.GridTestUtils;
+
+import static org.apache.ignite.configuration.WALMode.NONE;
+
+/**
+ * Test REST with enabled authentication.
+ */
+public class JettyRestProcessorAuthenticationSelfTest extends JettyRestProcessorUnsignedSelfTest {
+ /** */
+ private static final String DFLT_LOGIN = "ignite";
+
+ /** */
+ private static final String DFLT_PWD = "ignite";
+
+ /** */
+ private String login = DFLT_LOGIN;
+
+ /** */
+ private String pwd = DFLT_PWD;
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", true);
+
+ super.beforeTestsStarted();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ login = DFLT_LOGIN;
+ pwd = DFLT_PWD;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void initCache() {
+ // We need to activate cluster.
+ grid(0).cluster().active(true);
+
+ super.initCache();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ cfg.setAuthenticationEnabled(true);
+
+ // For now persistence is needed because of current authentication implementation.
+ DataStorageConfiguration dsCfg = new DataStorageConfiguration()
+ .setDefaultDataRegionConfiguration(new DataRegionConfiguration()
+ .setMaxSize(100 * 1024 * 1024))
+ .setWalMode(NONE);
+
+ DataRegionConfiguration testDataRegionCfg = new DataRegionConfiguration();
+ testDataRegionCfg.setName("testDataRegion");
+ testDataRegionCfg.setMaxSize(10 * 1024 * 1024);
+
+ DataRegionConfiguration authDataRegionCfg = new DataRegionConfiguration();
+ authDataRegionCfg.setName("authDataRegion")
+ .setMaxSize(10 * 1024 * 1024)
+ .setPersistenceEnabled(true);
+
+ dsCfg.setDataRegionConfigurations(testDataRegionCfg, authDataRegionCfg);
+
+ cfg.setDataStorageConfiguration(dsCfg);
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected String restUrl() {
+ String url = super.restUrl();
+
+ if (!F.isEmpty(login)) {
+ url += "ignite.login=" + login;
+
+ if (!F.isEmpty(pwd))
+ url += "&ignite.password=" + pwd;
+
+ url += '&';
+ }
+
+ return url;
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testMissingCredentials() throws Exception {
+ login = null;
+ pwd = null;
+
+ String ret = content(null, GridRestCommand.VERSION);
+
+ assertResponseContainsError(ret, "The user name or password is incorrect");
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testAddUpdateRemoveUser() throws Exception {
+ // Add user.
+ String ret = content(null, GridRestCommand.ADD_USER,
+ "user", "user1",
+ "password", "password1");
+
+ JsonNode res = jsonResponse(ret);
+
+ assertTrue(res.asBoolean());
+
+ IgniteAuthenticationProcessor auth = grid(0).context().authentication();
+
+ assertNotNull(auth.authenticate("user1", "password1"));
+
+ // Update user password.
+ ret = content(null, GridRestCommand.UPDATE_USER,
+ "user", "user1",
+ "password", "password2");
+
+ res = jsonResponse(ret);
+
+ assertTrue(res.asBoolean());
+
+ assertNotNull(auth.authenticate("user1", "password2"));
+
+ // Remove user.
+ ret = content(null, GridRestCommand.REMOVE_USER,
+ "user", "user1");
+
+ res = jsonResponse(ret);
+
+ assertTrue(res.asBoolean());
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ grid(0).context().authentication().authenticate("user1", "password1");
+
+ return null;
+ }
+ }, IgniteAccessControlException.class, "The user name or password is incorrect");
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/921f0cf9/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
index 2b53b54..0b9a662 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
@@ -166,7 +166,16 @@ public enum GridRestCommand {
CLUSTER_INACTIVE("inactive"),
/** */
- CLUSTER_CURRENT_STATE("currentstate");
+ CLUSTER_CURRENT_STATE("currentstate"),
+
+ /** */
+ ADD_USER("adduser"),
+
+ /** */
+ REMOVE_USER("removeuser"),
+
+ /** */
+ UPDATE_USER("updateuser");
/** Enum values. */
private static final GridRestCommand[] VALS = values();
@@ -174,9 +183,7 @@ public enum GridRestCommand {
/** Key to enum map. */
private static final Map<String, GridRestCommand> cmds = new HashMap<>();
- /**
- * Map keys to commands.
- */
+ // Map keys to commands.
static {
for (GridRestCommand cmd : values())
cmds.put(cmd.key(), cmd);
http://git-wip-us.apache.org/repos/asf/ignite/blob/921f0cf9/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
index de9e63b..4b8497e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
@@ -34,6 +34,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
+import org.apache.ignite.IgniteAuthenticationException;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteSystemProperties;
import org.apache.ignite.configuration.ConnectorConfiguration;
@@ -41,6 +42,7 @@ import org.apache.ignite.configuration.ConnectorMessageInterceptor;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.processors.GridProcessorAdapter;
+import org.apache.ignite.internal.processors.authentication.AuthorizationContext;
import org.apache.ignite.internal.processors.rest.client.message.GridClientTaskResultBean;
import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandler;
import org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheCommandHandler;
@@ -50,6 +52,7 @@ import org.apache.ignite.internal.processors.rest.handlers.log.GridLogCommandHan
import org.apache.ignite.internal.processors.rest.handlers.query.QueryCommandHandler;
import org.apache.ignite.internal.processors.rest.handlers.task.GridTaskCommandHandler;
import org.apache.ignite.internal.processors.rest.handlers.top.GridTopologyCommandHandler;
+import org.apache.ignite.internal.processors.rest.handlers.user.UserActionCommandHandler;
import org.apache.ignite.internal.processors.rest.handlers.version.GridVersionCommandHandler;
import org.apache.ignite.internal.processors.rest.protocols.tcp.GridTcpRestProtocol;
import org.apache.ignite.internal.processors.rest.request.GridRestCacheRequest;
@@ -218,7 +221,10 @@ public class GridRestProcessor extends GridProcessorAdapter {
if (log.isDebugEnabled())
log.debug("Received request from client: " + req);
- if (ctx.security().enabled()) {
+ boolean authenticationEnabled = ctx.authentication().enabled();
+ boolean securityEnabled = ctx.security().enabled();
+
+ if (authenticationEnabled || securityEnabled) {
Session ses;
try {
@@ -237,25 +243,54 @@ public class GridRestProcessor extends GridProcessorAdapter {
if (log.isDebugEnabled())
log.debug("Next clientId and sessionToken were extracted according to request: " +
- "[clientId="+req.clientId()+", sesTok="+Arrays.toString(req.sessionToken())+"]");
+ "[clientId=" + req.clientId() + ", sesTok=" + Arrays.toString(req.sessionToken()) + "]");
- SecurityContext secCtx0 = ses.secCtx;
+ if (securityEnabled) {
+ SecurityContext secCtx0 = ses.secCtx;
- try {
- if (secCtx0 == null)
- ses.secCtx = secCtx0 = authenticate(req);
+ try {
+ if (secCtx0 == null)
+ ses.secCtx = secCtx0 = authenticate(req);
- authorize(req, secCtx0);
+ authorize(req, secCtx0);
+ }
+ catch (SecurityException e) {
+ assert secCtx0 != null;
+
+ return new GridFinishedFuture<>(new GridRestResponse(STATUS_SECURITY_CHECK_FAILED, e.getMessage()));
+ }
+ catch (IgniteCheckedException e) {
+ return new GridFinishedFuture<>(new GridRestResponse(STATUS_AUTH_FAILED, e.getMessage()));
+ }
}
- catch (SecurityException e) {
- assert secCtx0 != null;
+ else {
+ AuthorizationContext authCtx0 = ses.authCtx;
- GridRestResponse res = new GridRestResponse(STATUS_SECURITY_CHECK_FAILED, e.getMessage());
+ try {
+ if (authCtx0 == null) {
+ SecurityCredentials creds = credentials(req);
- return new GridFinishedFuture<>(res);
- }
- catch (IgniteCheckedException e) {
- return new GridFinishedFuture<>(new GridRestResponse(STATUS_AUTH_FAILED, e.getMessage()));
+ String login = null;
+
+ if (creds.getLogin() instanceof String)
+ login = (String)creds.getLogin();
+
+ String pwd = null;
+
+ if (creds.getPassword() instanceof String)
+ pwd = (String)creds.getPassword();
+
+ if (F.isEmpty(login) || F.isEmpty(pwd))
+ throw new IgniteAuthenticationException("The user name or password is incorrect");
+
+ ses.authCtx = ctx.authentication().authenticate(login, pwd);
+
+ req.authorizationContext(ses.authCtx);
+ }
+ }
+ catch (IgniteCheckedException e) {
+ return new GridFinishedFuture<>(new GridRestResponse(STATUS_AUTH_FAILED, e.getMessage()));
+ }
}
}
@@ -469,6 +504,7 @@ public class GridRestProcessor extends GridProcessorAdapter {
addHandler(new QueryCommandHandler(ctx));
addHandler(new GridLogCommandHandler(ctx));
addHandler(new GridChangeStateCommandHandler(ctx));
+ addHandler(new UserActionCommandHandler(ctx));
// Start protocols.
startTcpProtocol();
@@ -645,7 +681,9 @@ public class GridRestProcessor extends GridProcessorAdapter {
break;
}
}
- } /**
+ }
+
+ /**
* Applies interceptor to a response object.
* Specially handler {@link Map} and {@link Collection} responses.
*
@@ -679,6 +717,35 @@ public class GridRestProcessor extends GridProcessorAdapter {
}
/**
+ * Extract credentials from request.
+ *
+ * @param req Request.
+ * @return Security credentials.
+ */
+ private SecurityCredentials credentials(GridRestRequest req) {
+ Object creds = req.credentials();
+
+ if (creds instanceof SecurityCredentials)
+ return (SecurityCredentials)creds;
+
+ if (creds instanceof String) {
+ String credStr = (String)creds;
+
+ int idx = credStr.indexOf(':');
+
+ return idx >= 0 && idx < credStr.length() ?
+ new SecurityCredentials(credStr.substring(0, idx), credStr.substring(idx + 1)) :
+ new SecurityCredentials(credStr, null);
+ }
+
+ SecurityCredentials cred = new SecurityCredentials();
+
+ cred.setUserObject(creds);
+
+ return cred;
+ }
+
+ /**
* Authenticates remote client.
*
* @param req Request to authenticate.
@@ -693,37 +760,16 @@ public class GridRestProcessor extends GridProcessorAdapter {
authCtx.subjectType(REMOTE_CLIENT);
authCtx.subjectId(req.clientId());
authCtx.nodeAttributes(Collections.<String, Object>emptyMap());
-
- SecurityCredentials cred;
-
- if (req.credentials() instanceof SecurityCredentials)
- cred = (SecurityCredentials)req.credentials();
- else if (req.credentials() instanceof String) {
- String credStr = (String)req.credentials();
-
- int idx = credStr.indexOf(':');
-
- cred = idx >= 0 && idx < credStr.length() ?
- new SecurityCredentials(credStr.substring(0, idx), credStr.substring(idx + 1)) :
- new SecurityCredentials(credStr, null);
- }
- else {
- cred = new SecurityCredentials();
-
- cred.setUserObject(req.credentials());
- }
-
authCtx.address(req.address());
-
- authCtx.credentials(cred);
+ authCtx.credentials(credentials(req));
SecurityContext subjCtx = ctx.security().authenticate(authCtx);
if (subjCtx == null) {
if (req.credentials() == null)
throw new IgniteCheckedException("Failed to authenticate remote client (secure session SPI not set?): " + req);
- else
- throw new IgniteCheckedException("Failed to authenticate remote client (invalid credentials?): " + req);
+
+ throw new IgniteCheckedException("Failed to authenticate remote client (invalid credentials?): " + req);
}
return subjCtx;
@@ -814,6 +860,9 @@ public class GridRestProcessor extends GridProcessorAdapter {
case CLUSTER_CURRENT_STATE:
case CLUSTER_ACTIVE:
case CLUSTER_INACTIVE:
+ case ADD_USER:
+ case REMOVE_USER:
+ case UPDATE_USER:
break;
default:
@@ -935,6 +984,9 @@ public class GridRestProcessor extends GridProcessorAdapter {
/** Security context. */
private volatile SecurityContext secCtx;
+ /** Authorization context. */
+ private volatile AuthorizationContext authCtx;
+
/**
* @param clientId Client ID.
* @param sesId session ID.
@@ -977,7 +1029,7 @@ public class GridRestProcessor extends GridProcessorAdapter {
* Checks expiration of session and if expired then sets TIMEDOUT_FLAG.
*
* @param sesTimeout Session timeout.
- * @return <code>True</code> if expired.
+ * @return {@code True} if expired.
* @see #touch()
*/
boolean isTimedOut(long sesTimeout) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/921f0cf9/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/user/UserActionCommandHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/user/UserActionCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/user/UserActionCommandHandler.java
new file mode 100644
index 0000000..40870a3
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/user/UserActionCommandHandler.java
@@ -0,0 +1,97 @@
+/*
+ * 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.rest.handlers.user;
+
+import java.util.Collection;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.processors.authentication.AuthorizationContext;
+import org.apache.ignite.internal.processors.authentication.IgniteAuthenticationProcessor;
+import org.apache.ignite.internal.processors.rest.GridRestCommand;
+import org.apache.ignite.internal.processors.rest.GridRestResponse;
+import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandlerAdapter;
+import org.apache.ignite.internal.processors.rest.request.GridRestRequest;
+import org.apache.ignite.internal.processors.rest.request.RestUserActionRequest;
+import org.apache.ignite.internal.util.future.GridFinishedFuture;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+import static org.apache.ignite.internal.processors.rest.GridRestCommand.ADD_USER;
+import static org.apache.ignite.internal.processors.rest.GridRestCommand.REMOVE_USER;
+import static org.apache.ignite.internal.processors.rest.GridRestCommand.UPDATE_USER;
+
+/**
+ * User actions handler.
+ */
+public class UserActionCommandHandler extends GridRestCommandHandlerAdapter {
+ /** Commands. */
+ private static final Collection<GridRestCommand> SUPPORTED_COMMANDS = U.sealList(ADD_USER, REMOVE_USER, UPDATE_USER);
+
+ /**
+ * @param ctx Context.
+ */
+ public UserActionCommandHandler(GridKernalContext ctx) {
+ super(ctx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<GridRestCommand> supportedCommands() {
+ return SUPPORTED_COMMANDS;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteInternalFuture<GridRestResponse> handleAsync(GridRestRequest req) {
+ assert req != null;
+
+ if (log.isDebugEnabled())
+ log.debug("Handling topology REST request: " + req);
+
+ RestUserActionRequest req0 = (RestUserActionRequest)req;
+
+ try {
+ GridRestCommand cmd = req.command();
+
+ IgniteAuthenticationProcessor authentication = ctx.authentication();
+
+ AuthorizationContext.context(req.authorizationContext());
+
+ switch (cmd) {
+ case ADD_USER:
+ authentication.addUser(req0.user(), req0.password());
+ break;
+
+ case REMOVE_USER:
+ authentication.removeUser(req0.user());
+ break;
+
+ case UPDATE_USER:
+ authentication.updateUser(req0.user(), req0.password());
+ break;
+ }
+
+ if (log.isDebugEnabled())
+ log.debug("Handled topology REST request [req=" + req + ']');
+
+ return new GridFinishedFuture<>(new GridRestResponse(true));
+ }
+ catch (Throwable e) {
+ log.error("Failed to handle REST request [req=" + req + ']', e);
+
+ return new GridFinishedFuture<>(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/921f0cf9/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/user/package-info.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/user/package-info.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/user/package-info.java
new file mode 100644
index 0000000..79cfd99
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/user/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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 description. -->
+ * REST user commands.
+ */
+package org.apache.ignite.internal.processors.rest.handlers.user;
http://git-wip-us.apache.org/repos/asf/ignite/blob/921f0cf9/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestNioListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestNioListener.java
index a44cc7c..23c25c7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestNioListener.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/GridTcpRestNioListener.java
@@ -99,9 +99,7 @@ public class GridTcpRestNioListener extends GridNioServerListenerAdapter<GridCli
/** Supported protocol versions. */
private static final Collection<Short> SUPP_VERS = new HashSet<>();
- /**
- * Fills {@code cacheCmdMap}.
- */
+ // Fills {@code cacheCmdMap}.
static {
cacheCmdMap.put(PUT, CACHE_PUT);
cacheCmdMap.put(PUT_ALL, CACHE_PUT_ALL);
@@ -356,7 +354,8 @@ public class GridTcpRestNioListener extends GridNioServerListenerAdapter<GridCli
restTopReq.command(TOPOLOGY);
restReq = restTopReq;
- }else if (msg instanceof GridClientStateRequest) {
+ }
+ else if (msg instanceof GridClientStateRequest) {
GridClientStateRequest req = (GridClientStateRequest)msg;
GridRestChangeStateRequest restChangeReq = new GridRestChangeStateRequest();
http://git-wip-us.apache.org/repos/asf/ignite/blob/921f0cf9/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestRequest.java
index 57cb91b..2d90733 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/GridRestRequest.java
@@ -19,9 +19,11 @@ package org.apache.ignite.internal.processors.rest.request;
import java.net.InetSocketAddress;
import java.util.UUID;
+import org.apache.ignite.internal.processors.authentication.AuthorizationContext;
import org.apache.ignite.internal.processors.rest.GridRestCommand;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
/**
* Grid command request.
@@ -46,6 +48,9 @@ public class GridRestRequest {
/** Command. */
private GridRestCommand cmd;
+ /** */
+ private AuthorizationContext authCtx;
+
/**
* @return Destination ID.
*/
@@ -142,8 +147,22 @@ public class GridRestRequest {
this.addr = addr;
}
+ /**
+ * @return Authorization context.
+ */
+ @Nullable public AuthorizationContext authorizationContext() {
+ return authCtx;
+ }
+
+ /**
+ * @param authCtx Authorization context.
+ */
+ public void authorizationContext(AuthorizationContext authCtx) {
+ this.authCtx = authCtx;
+ }
+
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(GridRestRequest.class, this);
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/921f0cf9/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestUserActionRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestUserActionRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestUserActionRequest.java
new file mode 100644
index 0000000..bf569df
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestUserActionRequest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.rest.request;
+
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * User request.
+ */
+public class RestUserActionRequest extends GridRestRequest {
+ /** User name. */
+ private String user;
+
+ /** Password. */
+ private String pwd;
+
+ /**
+ * @param user User name.
+ */
+ public void user(String user) {
+ this.user = user;
+ }
+
+ /**
+ * @return User name.
+ */
+ public String user() {
+ return user;
+ }
+
+ /**
+ * @param pwd User password.
+ */
+ public void password(String pwd) {
+ this.pwd = pwd;
+ }
+
+ /**
+ * @return User password.
+ */
+ public String password() {
+ return pwd;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(RestUserActionRequest.class, this, super.toString());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/921f0cf9/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
----------------------------------------------------------------------
diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
index 85398cc..b3fbddd 100644
--- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
+++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
@@ -55,6 +55,7 @@ import org.apache.ignite.internal.processors.rest.request.GridRestRequest;
import org.apache.ignite.internal.processors.rest.request.GridRestTaskRequest;
import org.apache.ignite.internal.processors.rest.request.GridRestTopologyRequest;
import org.apache.ignite.internal.processors.rest.request.RestQueryRequest;
+import org.apache.ignite.internal.processors.rest.request.RestUserActionRequest;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteClosure;
@@ -100,6 +101,12 @@ public class GridJettyRestHandler extends AbstractHandler {
private static final String WRITE_SYNCHRONIZATION_MODE_PARAM = "writeSynchronizationMode";
/** */
+ private static final String IGNITE_LOGIN = "ignite.login";
+
+ /** */
+ private static final String IGNITE_PASSWORD = "ignite.password";
+
+ /** */
private static final String TEMPLATE_NAME_PARAM = "templateName";
/** */
@@ -724,6 +731,19 @@ public class GridJettyRestHandler extends AbstractHandler {
break;
}
+ case ADD_USER:
+ case REMOVE_USER:
+ case UPDATE_USER: {
+ RestUserActionRequest restReq0 = new RestUserActionRequest();
+
+ restReq0.user((String)params.get("user"));
+ restReq0.password((String)params.get("password"));
+
+ restReq = restReq0;
+
+ break;
+ }
+
case EXECUTE_SQL_QUERY:
case EXECUTE_SQL_FIELDS_QUERY: {
RestQueryRequest restReq0 = new RestQueryRequest();
@@ -820,9 +840,9 @@ public class GridJettyRestHandler extends AbstractHandler {
restReq.command(cmd);
- if (params.containsKey("ignite.login") || params.containsKey("ignite.password")) {
+ if (params.containsKey(IGNITE_LOGIN) || params.containsKey(IGNITE_PASSWORD)) {
SecurityCredentials cred = new SecurityCredentials(
- (String)params.get("ignite.login"), (String)params.get("ignite.password"));
+ (String)params.get(IGNITE_LOGIN), (String)params.get(IGNITE_PASSWORD));
restReq.credentials(cred);
}