IGNITE-8135: SQL: authentication for CREATE TABLE and DROP TABLE commands. This 
closes #3801.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a57c9e1f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a57c9e1f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a57c9e1f

Branch: refs/heads/ignite-7708
Commit: a57c9e1f2a00fea310de5eabba92a642942b9796
Parents: 7a1d0ea
Author: devozerov <voze...@gridgain.com>
Authored: Thu Apr 12 15:02:57 2018 +0300
Committer: devozerov <voze...@gridgain.com>
Committed: Thu Apr 12 15:02:57 2018 +0300

----------------------------------------------------------------------
 .../apache/ignite/client/ClientException.java   |  3 +-
 .../internal/client/thin/ClientQueryCursor.java |  6 ++-
 .../platform/client/ClientRequestHandler.java   |  7 ++-
 .../cache/ClientCacheSqlFieldsQueryRequest.java | 19 +++++--
 .../security/SecurityContextHolder.java         | 53 ++++++++++++++++++++
 .../query/h2/ddl/DdlStatementsProcessor.java    |  9 ++++
 6 files changed, 91 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a57c9e1f/modules/core/src/main/java/org/apache/ignite/client/ClientException.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/client/ClientException.java 
b/modules/core/src/main/java/org/apache/ignite/client/ClientException.java
index 0555635..b0d9f6c 100644
--- a/modules/core/src/main/java/org/apache/ignite/client/ClientException.java
+++ b/modules/core/src/main/java/org/apache/ignite/client/ClientException.java
@@ -20,7 +20,7 @@ package org.apache.ignite.client;
 /**
  * Common thin client checked exception.
  */
-public class ClientException extends Exception {
+public class ClientException extends RuntimeException {
     /** Serial version uid. */
     private static final long serialVersionUID = 0L;
 
@@ -28,6 +28,7 @@ public class ClientException extends Exception {
      * Constructs a new exception with {@code null} as its detail message.
      */
     public ClientException() {
+        // No-op.
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/a57c9e1f/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientQueryCursor.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientQueryCursor.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientQueryCursor.java
index 9367cfd..086fab8 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientQueryCursor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/client/thin/ClientQueryCursor.java
@@ -54,6 +54,7 @@ class ClientQueryCursor<T> implements QueryCursor<T> {
             pager.close();
         }
         catch (Exception ignored) {
+            // No-op.
         }
     }
 
@@ -76,7 +77,10 @@ class ClientQueryCursor<T> implements QueryCursor<T> {
                         currPageIt = currPage.iterator();
                     }
                     catch (ClientException e) {
-                        throw new RuntimeException("Failed to retrieve query 
results", e);
+                        throw e;
+                    }
+                    catch (Exception e) {
+                        throw new ClientException("Failed to retrieve query 
results", e);
                     }
                 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/a57c9e1f/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java
index faa50bc..5ed0d38 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java
@@ -22,6 +22,7 @@ import 
org.apache.ignite.internal.processors.authentication.AuthorizationContext
 import org.apache.ignite.internal.processors.odbc.ClientListenerRequest;
 import org.apache.ignite.internal.processors.odbc.ClientListenerRequestHandler;
 import org.apache.ignite.internal.processors.odbc.ClientListenerResponse;
+import org.apache.ignite.internal.processors.security.SecurityContextHolder;
 
 /**
  * Thin client request handler.
@@ -47,8 +48,10 @@ public class ClientRequestHandler implements 
ClientListenerRequestHandler {
 
     /** {@inheritDoc} */
     @Override public ClientListenerResponse handle(ClientListenerRequest req) {
-        if (authCtx != null)
+        if (authCtx != null) {
             AuthorizationContext.context(authCtx);
+            SecurityContextHolder.set(ctx.securityContext());
+        }
 
         try {
             return ((ClientRequest)req).process(ctx);
@@ -56,6 +59,8 @@ public class ClientRequestHandler implements 
ClientListenerRequestHandler {
         finally {
             if (authCtx != null)
                 AuthorizationContext.clear();
+
+            SecurityContextHolder.clear();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/a57c9e1f/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java
index 3aa95bf..53f6353 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java
@@ -28,8 +28,11 @@ import 
org.apache.ignite.internal.processors.odbc.jdbc.JdbcStatementType;
 import org.apache.ignite.internal.processors.platform.cache.PlatformCache;
 import 
org.apache.ignite.internal.processors.platform.client.ClientConnectionContext;
 import org.apache.ignite.internal.processors.platform.client.ClientResponse;
+import org.apache.ignite.internal.processors.platform.client.ClientStatus;
+import 
org.apache.ignite.internal.processors.platform.client.IgniteClientException;
 import org.apache.ignite.internal.processors.query.QueryUtils;
-import org.apache.ignite.plugin.security.SecurityPermission;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.plugin.security.SecurityException;
 
 /**
  * Sql query request.
@@ -95,7 +98,7 @@ public class ClientCacheSqlFieldsQueryRequest extends 
ClientCacheRequest {
 
                 if (qry.getSchema() == null) {
                     String schema = 
QueryUtils.normalizeSchemaName(desc.cacheName(),
-                            desc.cacheConfiguration().getSqlSchema());
+                        desc.cacheConfiguration().getSqlSchema());
 
                     qry.setSchema(schema);
                 }
@@ -108,7 +111,7 @@ public class ClientCacheSqlFieldsQueryRequest extends 
ClientCacheRequest {
             FieldsQueryCursor cur = curs.get(0);
 
             ClientCacheFieldsQueryCursor cliCur = new 
ClientCacheFieldsQueryCursor(
-                    cur, qry.getPageSize(), ctx);
+                cur, qry.getPageSize(), ctx);
 
             long cursorId = ctx.resources().put(cliCur);
 
@@ -119,6 +122,16 @@ public class ClientCacheSqlFieldsQueryRequest extends 
ClientCacheRequest {
         catch (Exception e) {
             ctx.decrementCursors();
 
+            SecurityException securityEx = X.cause(e, SecurityException.class);
+
+            if (securityEx != null) {
+                throw new IgniteClientException(
+                    ClientStatus.SECURITY_VIOLATION,
+                    "Client is not authorized to perform this operation",
+                    securityEx
+                );
+            }
+
             throw e;
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/a57c9e1f/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextHolder.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextHolder.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextHolder.java
new file mode 100644
index 0000000..14d70c9
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/security/SecurityContextHolder.java
@@ -0,0 +1,53 @@
+/*
+ * 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.security;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Thread-local security context.
+ */
+public class SecurityContextHolder {
+    /** Context. */
+    private static final ThreadLocal<SecurityContext> CTX = new 
ThreadLocal<>();
+
+    /**
+     * Get security context.
+     *
+     * @return Security context.
+     */
+    @Nullable public static SecurityContext get() {
+        return CTX.get();
+    }
+
+    /**
+     * Set security context.
+     *
+     * @param ctx Context.
+     */
+    public static void set(@Nullable SecurityContext ctx) {
+        CTX.set(ctx);
+    }
+
+    /**
+     * Clear security context.
+     */
+    public static void clear() {
+        set(null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/a57c9e1f/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 b148969..bc5c1e0 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
@@ -34,6 +34,8 @@ import org.apache.ignite.cache.query.FieldsQueryCursor;
 import org.apache.ignite.configuration.CacheConfiguration;
 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.UserManagementOperation;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.QueryCursorImpl;
 import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
@@ -56,6 +58,8 @@ import 
org.apache.ignite.internal.processors.query.h2.sql.GridSqlDropTable;
 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.processors.security.SecurityContext;
+import org.apache.ignite.internal.processors.security.SecurityContextHolder;
 import org.apache.ignite.internal.sql.command.SqlAlterTableCommand;
 import org.apache.ignite.internal.sql.command.SqlAlterUserCommand;
 import org.apache.ignite.internal.sql.command.SqlCommand;
@@ -67,6 +71,7 @@ import org.apache.ignite.internal.sql.command.SqlIndexColumn;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.plugin.security.SecurityPermission;
 import org.h2.command.Prepared;
 import org.h2.command.ddl.AlterTableAlterColumn;
 import org.h2.command.ddl.CreateIndex;
@@ -316,6 +321,8 @@ public class DdlStatementsProcessor {
                 }
             }
             else if (stmt0 instanceof GridSqlCreateTable) {
+                ctx.security().authorize(null, 
SecurityPermission.CACHE_CREATE, SecurityContextHolder.get());
+
                 GridSqlCreateTable cmd = (GridSqlCreateTable)stmt0;
 
                 if (!F.eq(QueryUtils.DFLT_SCHEMA, cmd.schemaName()))
@@ -349,6 +356,8 @@ public class DdlStatementsProcessor {
                 }
             }
             else if (stmt0 instanceof GridSqlDropTable) {
+                ctx.security().authorize(null, 
SecurityPermission.CACHE_DESTROY, SecurityContextHolder.get());
+
                 GridSqlDropTable cmd = (GridSqlDropTable)stmt0;
 
                 if (!F.eq(QueryUtils.DFLT_SCHEMA, cmd.schemaName()))

Reply via email to