You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by ct...@apache.org on 2013/12/05 00:58:03 UTC
[11/50] [abbrv] ACCUMULO-1479 implemented most of Table Namespace
Permissions, doesnt entirely work, not well tested
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/core/src/main/java/org/apache/accumulo/core/client/impl/thrift/SecurityErrorCode.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/client/impl/thrift/SecurityErrorCode.java b/core/src/main/java/org/apache/accumulo/core/client/impl/thrift/SecurityErrorCode.java
index b706ce8..9bf554f 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/impl/thrift/SecurityErrorCode.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/impl/thrift/SecurityErrorCode.java
@@ -45,7 +45,8 @@ import org.apache.thrift.TEnum;
PERMISSIONHANDLER_FAILED(14),
TOKEN_EXPIRED(15),
SERIALIZATION_ERROR(16),
- INSUFFICIENT_PROPERTIES(17);
+ INSUFFICIENT_PROPERTIES(17),
+ TABLE_NAMESPACE_DOESNT_EXIST(18);
private final int value;
@@ -102,6 +103,8 @@ import org.apache.thrift.TEnum;
return SERIALIZATION_ERROR;
case 17:
return INSUFFICIENT_PROPERTIES;
+ case 18:
+ return TABLE_NAMESPACE_DOESNT_EXIST;
default:
return null;
}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/core/src/main/java/org/apache/accumulo/core/client/mock/MockAccumulo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/client/mock/MockAccumulo.java b/core/src/main/java/org/apache/accumulo/core/client/mock/MockAccumulo.java
index 37e8379..f96abad 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/mock/MockAccumulo.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/mock/MockAccumulo.java
@@ -32,6 +32,7 @@ import org.apache.accumulo.core.metadata.MetadataTable;
import org.apache.accumulo.core.metadata.RootTable;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.security.TablePermission;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.io.Text;
@@ -100,7 +101,7 @@ public class MockAccumulo {
public void createNamespace(String username, String namespace) {
if (!namespaceExists(namespace)) {
MockTableNamespace n = new MockTableNamespace();
- n.userPermissions.put(username, EnumSet.allOf(TablePermission.class));
+ n.userPermissions.put(username, EnumSet.allOf(TableNamespacePermission.class));
namespaces.put(namespace, n);
}
}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/core/src/main/java/org/apache/accumulo/core/client/mock/MockSecurityOperations.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/client/mock/MockSecurityOperations.java b/core/src/main/java/org/apache/accumulo/core/client/mock/MockSecurityOperations.java
index 765cda9..dd48b52 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/mock/MockSecurityOperations.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/mock/MockSecurityOperations.java
@@ -27,6 +27,7 @@ import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.security.TablePermission;
public class MockSecurityOperations implements SecurityOperations {
@@ -128,6 +129,17 @@ public class MockSecurityOperations implements SecurityOperations {
}
@Override
+ public boolean hasTableNamespacePermission(String principal, String tableNamespace, TableNamespacePermission perm) throws AccumuloException, AccumuloSecurityException {
+ MockTableNamespace namespace = acu.namespaces.get(tableNamespace);
+ if (namespace == null)
+ throw new AccumuloSecurityException(tableNamespace, SecurityErrorCode.TABLE_DOESNT_EXIST);
+ EnumSet<TableNamespacePermission> perms = namespace.userPermissions.get(principal);
+ if (perms == null)
+ return false;
+ return perms.contains(perm);
+ }
+
+ @Override
public void grantSystemPermission(String principal, SystemPermission permission) throws AccumuloException, AccumuloSecurityException {
MockUser user = acu.users.get(principal);
if (user != null)
@@ -151,6 +163,20 @@ public class MockSecurityOperations implements SecurityOperations {
}
@Override
+ public void grantTableNamespacePermission(String principal, String tableNamespace, TableNamespacePermission permission) throws AccumuloException, AccumuloSecurityException {
+ if (acu.users.get(principal) == null)
+ throw new AccumuloSecurityException(principal, SecurityErrorCode.USER_DOESNT_EXIST);
+ MockTableNamespace namespace = acu.namespaces.get(tableNamespace);
+ if (namespace == null)
+ throw new AccumuloSecurityException(tableNamespace, SecurityErrorCode.TABLE_DOESNT_EXIST);
+ EnumSet<TableNamespacePermission> perms = namespace.userPermissions.get(principal);
+ if (perms == null)
+ namespace.userPermissions.put(principal, EnumSet.of(permission));
+ else
+ perms.add(permission);
+ }
+
+ @Override
public void revokeSystemPermission(String principal, SystemPermission permission) throws AccumuloException, AccumuloSecurityException {
MockUser user = acu.users.get(principal);
if (user != null)
@@ -172,6 +198,19 @@ public class MockSecurityOperations implements SecurityOperations {
}
+ @Override
+ public void revokeTableNamespacePermission(String principal, String tableNamespace, TableNamespacePermission permission) throws AccumuloException, AccumuloSecurityException {
+ if (acu.users.get(principal) == null)
+ throw new AccumuloSecurityException(principal, SecurityErrorCode.USER_DOESNT_EXIST);
+ MockTableNamespace namespace = acu.namespaces.get(tableNamespace);
+ if (namespace == null)
+ throw new AccumuloSecurityException(tableNamespace, SecurityErrorCode.TABLE_DOESNT_EXIST);
+ EnumSet<TableNamespacePermission> perms = namespace.userPermissions.get(principal);
+ if (perms != null)
+ perms.remove(permission);
+
+ }
+
@Deprecated
@Override
public Set<String> listUsers() throws AccumuloException, AccumuloSecurityException {
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/core/src/main/java/org/apache/accumulo/core/client/mock/MockTableNamespace.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/client/mock/MockTableNamespace.java b/core/src/main/java/org/apache/accumulo/core/client/mock/MockTableNamespace.java
index 2a32165..beec4db 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/mock/MockTableNamespace.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/mock/MockTableNamespace.java
@@ -25,13 +25,13 @@ import java.util.Map.Entry;
import org.apache.accumulo.core.conf.AccumuloConfiguration;
import org.apache.accumulo.core.conf.Property;
-import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
public class MockTableNamespace {
final Map<String,String> settings;
- Map<String,EnumSet<TablePermission>> userPermissions = new HashMap<String,EnumSet<TablePermission>>();
+ Map<String,EnumSet<TableNamespacePermission>> userPermissions = new HashMap<String,EnumSet<TableNamespacePermission>>();
public MockTableNamespace() {
settings = new HashMap<String,String>();
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/core/src/main/java/org/apache/accumulo/core/client/security/SecurityErrorCode.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/client/security/SecurityErrorCode.java b/core/src/main/java/org/apache/accumulo/core/client/security/SecurityErrorCode.java
index fb51387..f1ea539 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/security/SecurityErrorCode.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/security/SecurityErrorCode.java
@@ -37,5 +37,6 @@ public enum SecurityErrorCode {
PERMISSIONHANDLER_FAILED,
TOKEN_EXPIRED,
SERIALIZATION_ERROR,
- INSUFFICIENT_PROPERTIES;
+ INSUFFICIENT_PROPERTIES,
+ TABLE_NAMESPACE_DOESNT_EXIST;
}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java b/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java
index 699396e..6bdb8e6 100644
--- a/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java
+++ b/core/src/main/java/org/apache/accumulo/core/security/SystemPermission.java
@@ -29,7 +29,10 @@ public enum SystemPermission {
CREATE_USER((byte) 4),
DROP_USER((byte) 5),
ALTER_USER((byte) 6),
- SYSTEM((byte) 7);
+ SYSTEM((byte) 7),
+ CREATE_NAMESPACE((byte) 8),
+ DROP_NAMESPACE((byte) 9),
+ ALTER_NAMESPACE((byte) 10);
private byte permID;
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/core/src/main/java/org/apache/accumulo/core/security/TableNamespacePermission.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/security/TableNamespacePermission.java b/core/src/main/java/org/apache/accumulo/core/security/TableNamespacePermission.java
new file mode 100644
index 0000000..565a81a
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/security/TableNamespacePermission.java
@@ -0,0 +1,67 @@
+/*
+ * 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.accumulo.core.security;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public enum TableNamespacePermission {
+ // One can add new permissions, with new numbers, but please don't change or use numbers previously assigned
+ READ((byte) 0),
+ WRITE((byte) 1),
+ ALTER_TABLE_NAMESPACE((byte) 2),
+ GRANT((byte) 3),
+ ALTER_TABLE((byte) 4),
+ CREATE_TABLE((byte) 5),
+ DROP_TABLE((byte) 6),
+ BULK_IMPORT((byte) 7);
+
+ final private byte permID;
+
+ final private static TableNamespacePermission mapping[] = new TableNamespacePermission[8];
+ static {
+ for (TableNamespacePermission perm : TableNamespacePermission.values())
+ mapping[perm.permID] = perm;
+ }
+
+ private TableNamespacePermission(byte id) {
+ this.permID = id;
+ }
+
+ public byte getId() {
+ return this.permID;
+ }
+
+ public static List<String> printableValues() {
+ TableNamespacePermission[] a = TableNamespacePermission.values();
+
+ List<String> list = new ArrayList<String>(a.length);
+
+ for (TableNamespacePermission p : a)
+ list.add("Namespace." + p);
+
+ return list;
+ }
+
+ public static TableNamespacePermission getPermissionById(byte id) {
+ TableNamespacePermission result = mapping[id];
+ if (result != null)
+ return result;
+ throw new IndexOutOfBoundsException("No such permission");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
index f3e7200..9f6e7e4 100644
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/GrantCommand.java
@@ -21,6 +21,7 @@ import java.util.Set;
import org.apache.accumulo.core.security.SystemPermission;
import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.util.BadArgumentException;
import org.apache.accumulo.core.util.shell.Shell;
import org.apache.accumulo.core.util.shell.Shell.Command;
@@ -53,6 +54,17 @@ public class GrantCommand extends TableOperation {
}
} else if (permission[0].equalsIgnoreCase("Table")) {
super.execute(fullCommand, cl, shellState);
+ } else if (permission[0].equalsIgnoreCase("Namespace")) {
+ if (cl.hasOption(optTableNamespace.getOpt())) {
+ try {
+ shellState.getConnector().securityOperations()
+ .grantTableNamespacePermission(user, cl.getOptionValue(optTableNamespace.getOpt()), TableNamespacePermission.valueOf(permission[1]));
+ } catch (IllegalArgumentException e) {
+ throw new BadArgumentException("No such table namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+ }
+ } else {
+ throw new BadArgumentException("No Table Namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+ }
} else {
throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
}
@@ -71,7 +83,7 @@ public class GrantCommand extends TableOperation {
@Override
public String description() {
- return "grants system or table permissions for a user";
+ return "grants system, table, or table namespace permissions for a user";
}
@Override
@@ -84,6 +96,7 @@ public class GrantCommand extends TableOperation {
final Token cmd = new Token(getName());
cmd.addSubcommand(new Token(TablePermission.printableValues()));
cmd.addSubcommand(new Token(SystemPermission.printableValues()));
+ cmd.addSubcommand(new Token(TableNamespacePermission.printableValues()));
root.addSubcommand(cmd);
}
@@ -96,9 +109,13 @@ public class GrantCommand extends TableOperation {
systemOpt = new Option("s", "system", false, "grant a system permission");
+ optTableNamespace = new Option(Shell.tableNamespaceOption, "table-namespace", true, "name of a table namespace to operate on");
+ optTableNamespace.setArgName("tableNamespace");
+
group.addOption(systemOpt);
group.addOption(optTableName);
group.addOption(optTablePattern);
+ group.addOption(optTableNamespace);
o.addOptionGroup(group);
userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
index 676284a..cc9cd93 100644
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/RevokeCommand.java
@@ -20,6 +20,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.security.TablePermission;
import org.apache.accumulo.core.util.BadArgumentException;
import org.apache.accumulo.core.util.shell.Shell;
@@ -53,7 +54,18 @@ public class RevokeCommand extends TableOperation {
}
} else if (permission[0].equalsIgnoreCase("Table")) {
super.execute(fullCommand, cl, shellState);
- } else {
+ } else if (permission[0].equalsIgnoreCase("Namespace")) {
+ if (cl.hasOption(optTableNamespace.getOpt())) {
+ try {
+ shellState.getConnector().securityOperations()
+ .revokeTableNamespacePermission(user, cl.getOptionValue(optTableNamespace.getOpt()), TableNamespacePermission.valueOf(permission[1]));
+ } catch (IllegalArgumentException e) {
+ throw new BadArgumentException("No such table namespace permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+ }
+ } else {
+ throw new BadArgumentException("No Table Namespace specified to apply permission to", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
+ }
+ }else {
throw new BadArgumentException("Unrecognized permission", fullCommand, fullCommand.indexOf(cl.getArgs()[0]));
}
return 0;
@@ -84,6 +96,7 @@ public class RevokeCommand extends TableOperation {
final Token cmd = new Token(getName());
cmd.addSubcommand(new Token(TablePermission.printableValues()));
cmd.addSubcommand(new Token(SystemPermission.printableValues()));
+ cmd.addSubcommand(new Token(TableNamespacePermission.printableValues()));
root.addSubcommand(cmd);
}
@@ -96,9 +109,13 @@ public class RevokeCommand extends TableOperation {
systemOpt = new Option("s", "system", false, "revoke a system permission");
+ optTableNamespace = new Option(Shell.tableNamespaceOption, "table-namespace", true, "name of a table namespace to operate on");
+ optTableNamespace.setArgName("tableNamespace");
+
group.addOption(systemOpt);
group.addOption(optTableName);
group.addOption(optTablePattern);
+ group.addOption(optTableNamespace);
o.addOptionGroup(group);
userOpt = new Option(Shell.userOption, "user", true, "user to operate on");
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
index 79d78da..25d9d54 100644
--- a/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
+++ b/core/src/main/java/org/apache/accumulo/core/util/shell/commands/UserPermissionsCommand.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.security.TablePermission;
import org.apache.accumulo.core.util.shell.Shell;
import org.apache.accumulo.core.util.shell.Shell.Command;
@@ -62,12 +63,29 @@ public class UserPermissionsCommand extends Command {
runOnce = 0;
}
shellState.getReader().println();
+
+ for (String n : shellState.getConnector().tableNamespaceOperations().list()) {
+ delim = "";
+ for (TableNamespacePermission p : TableNamespacePermission.values()) {
+ if (p != null && shellState.getConnector().securityOperations().hasTableNamespacePermission(user, n, p)) {
+ if (runOnce == 0) {
+ shellState.getReader().print("\nTable Namespace permissions (" + n + "): ");
+ runOnce++;
+ }
+ shellState.getReader().print(delim + "Namespace." + p.name());
+ delim = ", ";
+ }
+ }
+ runOnce = 0;
+ }
+ shellState.getReader().println();
+
return 0;
}
@Override
public String description() {
- return "displays a user's system and table permissions";
+ return "displays a user's system, table, and table namespace permissions";
}
@Override
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/core/src/main/thrift/client.thrift
----------------------------------------------------------------------
diff --git a/core/src/main/thrift/client.thrift b/core/src/main/thrift/client.thrift
index 67f43d8..7c340d7 100644
--- a/core/src/main/thrift/client.thrift
+++ b/core/src/main/thrift/client.thrift
@@ -72,9 +72,10 @@ enum SecurityErrorCode {
AUTHENTICATOR_FAILED = 12,
AUTHORIZOR_FAILED = 13,
PERMISSIONHANDLER_FAILED = 14,
- TOKEN_EXPIRED = 15
- SERIALIZATION_ERROR = 16;
- INSUFFICIENT_PROPERTIES = 17;
+ TOKEN_EXPIRED = 15,
+ SERIALIZATION_ERROR = 16,
+ INSUFFICIENT_PROPERTIES = 17,
+ TABLE_NAMESPACE_DOESNT_EXIST = 18;
}
exception ThriftSecurityException {
@@ -127,15 +128,18 @@ service ClientService {
// permissions-related methods
bool hasSystemPermission(4:trace.TInfo tinfo, 5:security.TCredentials credentials, 2:string principal, 3:byte sysPerm) throws (1:ThriftSecurityException sec)
bool hasTablePermission(5:trace.TInfo tinfo, 6:security.TCredentials credentials, 2:string principal, 3:string tableName, 4:byte tblPerm) throws (1:ThriftSecurityException sec, 2:ThriftTableOperationException tope)
+ bool hasTableNamespacePermission(1:trace.TInfo tinfo, 2:security.TCredentials credentials, 3:string principal, 4:string tableNamespace, 5:byte tblNspcPerm) throws (1:ThriftSecurityException sec, 2:ThriftTableOperationException tope)
void grantSystemPermission(4:trace.TInfo tinfo, 5:security.TCredentials credentials, 2:string principal, 3:byte permission) throws (1:ThriftSecurityException sec)
void revokeSystemPermission(4:trace.TInfo tinfo, 5:security.TCredentials credentials, 2:string principal, 3:byte permission) throws (1:ThriftSecurityException sec)
void grantTablePermission(5:trace.TInfo tinfo, 6:security.TCredentials credentials, 2:string principal, 3:string tableName, 4:byte permission) throws (1:ThriftSecurityException sec, 2:ThriftTableOperationException tope)
void revokeTablePermission(5:trace.TInfo tinfo, 6:security.TCredentials credentials, 2:string principal, 3:string tableName, 4:byte permission) throws (1:ThriftSecurityException sec, 2:ThriftTableOperationException tope)
+ void grantTableNamespacePermission(1:trace.TInfo tinfo, 2:security.TCredentials credentials, 3:string principal, 4:string tableNamespace, 5:byte permission) throws (1:ThriftSecurityException sec, 2:ThriftTableOperationException tope)
+ void revokeTableNamespacePermission(1:trace.TInfo tinfo, 2:security.TCredentials credentials, 3:string principal, 4:string tableNamespace, 5:byte permission) throws (1:ThriftSecurityException sec, 2:ThriftTableOperationException tope)
// configuration methods
map<string, string> getConfiguration(2:trace.TInfo tinfo, 3:security.TCredentials credentials, 1:ConfigurationType type);
map<string, string> getTableConfiguration(1:trace.TInfo tinfo, 3:security.TCredentials credentials, 2:string tableName) throws (1:ThriftTableOperationException tope);
- map<string, string> getTableNamespaceConfiguration(1:trace.TInfo tinfo, 3:security.TCredentials credentials, 2:string ns) throws (1:ThriftTableOperationException tope);
+ map<string, string> getTableNamespaceConfiguration(1:trace.TInfo tinfo, 2:security.TCredentials credentials, 3:string ns) throws (1:ThriftTableOperationException tope);
bool checkClass(1:trace.TInfo tinfo, 4:security.TCredentials credentials, 2:string className, 3:string interfaceMatch);
bool checkTableClass(1:trace.TInfo tinfo, 5:security.TCredentials credentials, 2:string tableId, 3:string className, 4:string interfaceMatch) throws (1:ThriftSecurityException sec, 2:ThriftTableOperationException tope);
bool checkTableNamespaceClass(1:trace.TInfo tinfo, 2:security.TCredentials credentials, 3:string namespaceId, 4:string className, 5:string interfaceMatch) throws (1:ThriftSecurityException sec, 2:ThriftTableOperationException tope);
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/server/base/src/main/java/org/apache/accumulo/server/client/ClientServiceHandler.java
----------------------------------------------------------------------
diff --git a/server/base/src/main/java/org/apache/accumulo/server/client/ClientServiceHandler.java b/server/base/src/main/java/org/apache/accumulo/server/client/ClientServiceHandler.java
index 0421ec1..3148a3d 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/client/ClientServiceHandler.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/client/ClientServiceHandler.java
@@ -53,6 +53,7 @@ import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.security.Credentials;
import org.apache.accumulo.core.security.SystemPermission;
import org.apache.accumulo.core.security.TablePermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.security.thrift.TCredentials;
import org.apache.accumulo.server.conf.ServerConfiguration;
import org.apache.accumulo.server.fs.VolumeManager;
@@ -185,6 +186,13 @@ public class ClientServiceHandler implements ClientService.Iface {
}
@Override
+ public void grantTableNamespacePermission(TInfo tinfo, TCredentials credentials, String user, String tableNamespace, byte permission) throws ThriftSecurityException,
+ ThriftTableOperationException {
+ String namespaceId = checkTableNamespaceId(tableNamespace, TableOperation.PERMISSION);
+ security.grantTableNamespacePermission(credentials, user, namespaceId, TableNamespacePermission.getPermissionById(permission));
+ }
+
+ @Override
public void revokeSystemPermission(TInfo tinfo, TCredentials credentials, String user, byte permission) throws ThriftSecurityException {
security.revokeSystemPermission(credentials, user, SystemPermission.getPermissionById(permission));
}
@@ -209,6 +217,20 @@ public class ClientServiceHandler implements ClientService.Iface {
}
@Override
+ public boolean hasTableNamespacePermission(TInfo tinfo, TCredentials credentials, String user, String tableNamespace, byte perm) throws ThriftSecurityException,
+ ThriftTableOperationException {
+ String namespaceId = checkTableNamespaceId(tableNamespace, TableOperation.PERMISSION);
+ return security.hasTableNamespacePermission(credentials, user, namespaceId, TableNamespacePermission.getPermissionById(perm));
+ }
+
+ @Override
+ public void revokeTableNamespacePermission(TInfo tinfo, TCredentials credentials, String user, String tableNamespace, byte permission) throws ThriftSecurityException,
+ ThriftTableOperationException {
+ String namespaceId = checkTableNamespaceId(tableNamespace, TableOperation.PERMISSION);
+ security.revokeTableNamespacePermission(credentials, user, namespaceId, TableNamespacePermission.getPermissionById(permission));
+ }
+
+ @Override
public Set<String> listLocalUsers(TInfo tinfo, TCredentials credentials) throws ThriftSecurityException {
return security.listUsers(credentials);
}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
----------------------------------------------------------------------
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java b/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
index f00159c..cad84d0 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
@@ -23,8 +23,10 @@ import java.util.Set;
import org.apache.accumulo.core.Constants;
import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNamespaceNotFoundException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.admin.SecurityOperationsImpl;
+import org.apache.accumulo.core.client.impl.Tables;
import org.apache.accumulo.core.client.impl.thrift.SecurityErrorCode;
import org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException;
import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
@@ -40,6 +42,7 @@ import org.apache.accumulo.core.metadata.RootTable;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.security.Credentials;
import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.security.TablePermission;
import org.apache.accumulo.core.security.thrift.TCredentials;
import org.apache.accumulo.server.client.HdfsZooInstance;
@@ -304,6 +307,64 @@ public class SecurityOperation {
}
}
+ /**
+ * Checks if a user has a table namespace permission
+ *
+ * @return true if a user exists and has permission; false otherwise
+ */
+ protected boolean hasTableNamespacePermission(TCredentials credentials, String tableNamespace, TableNamespacePermission permission, boolean useCached)
+ throws ThriftSecurityException {
+ if (isSystemUser(credentials))
+ return true;
+ return _hasTableNamespacePermission(credentials.getPrincipal(), tableNamespace, permission, useCached);
+ }
+
+ /**
+ * Checks if a user has a table namespace permission given a tableId
+ *
+ * @return true if a user exists and has permission; false otherwise
+ */
+ protected boolean hasTableNamespacePermissionForTableId(TCredentials credentials, String tableId, TableNamespacePermission permission, boolean useCached)
+ throws ThriftSecurityException {
+ String tableNamespace = Tables.getNamespace(HdfsZooInstance.getInstance(), tableId);
+ return hasTableNamespacePermission(credentials, tableNamespace, permission, useCached);
+ }
+
+ /**
+ * Checks if a user has a table namespace permission given a tableName
+ *
+ * @return true if a user exists and has permission; false otherwise
+ */
+ protected boolean hasTableNamespacePermissionForTableName(TCredentials credentials, String tableName, TableNamespacePermission permission, boolean useCached)
+ throws ThriftSecurityException {
+ String tableNamespace = Tables.extractNamespace(tableName);
+ return hasTableNamespacePermission(credentials, tableNamespace, permission, useCached);
+ }
+
+ /**
+ * Checks if a user has a table namespace permission<br/>
+ * This cannot check if a system user has permission.
+ *
+ * @return true if a user exists and has permission; false otherwise
+ */
+ protected boolean _hasTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission, boolean useCached)
+ throws ThriftSecurityException {
+ targetUserExists(user);
+
+ if (tableNamespace.equals(Constants.SYSTEM_TABLE_NAMESPACE_ID) && permission.equals(TableNamespacePermission.READ))
+ return true;
+
+ try {
+ if (useCached)
+ return permHandle.hasCachedTableNamespacePermission(user, tableNamespace, permission);
+ return permHandle.hasTableNamespacePermission(user, tableNamespace, permission);
+ } catch (AccumuloSecurityException e) {
+ throw e.asThriftException();
+ } catch (TableNamespaceNotFoundException e) {
+ throw new ThriftSecurityException(user, SecurityErrorCode.TABLE_NAMESPACE_DOESNT_EXIST);
+ }
+ }
+
// some people just aren't allowed to ask about other users; here are those who can ask
private boolean canAskAboutOtherUsers(TCredentials credentials, String user) throws ThriftSecurityException {
authenticate(credentials);
@@ -325,7 +386,8 @@ public class SecurityOperation {
public boolean canScan(TCredentials credentials, String table) throws ThriftSecurityException {
authenticate(credentials);
- return hasTablePermission(credentials, table, TablePermission.READ, true);
+ return hasTablePermission(credentials, table, TablePermission.READ, true)
+ || hasTableNamespacePermissionForTableId(credentials, table, TableNamespacePermission.READ, true);
}
public boolean canScan(TCredentials credentials, String table, TRange range, List<TColumn> columns, List<IterInfo> ssiList,
@@ -340,20 +402,25 @@ public class SecurityOperation {
public boolean canWrite(TCredentials credentials, String table) throws ThriftSecurityException {
authenticate(credentials);
- return hasTablePermission(credentials, table, TablePermission.WRITE, true);
+ return hasTablePermission(credentials, table, TablePermission.WRITE, true)
+ || hasTableNamespacePermissionForTableId(credentials, table, TableNamespacePermission.WRITE, true);
}
public boolean canConditionallyUpdate(TCredentials credentials, String tableID, List<ByteBuffer> authorizations) throws ThriftSecurityException {
authenticate(credentials);
- return hasTablePermission(credentials, tableID, TablePermission.WRITE, true) && hasTablePermission(credentials, tableID, TablePermission.READ, true);
+ return (hasTablePermission(credentials, tableID, TablePermission.WRITE, true) || hasTableNamespacePermissionForTableId(credentials, tableID,
+ TableNamespacePermission.WRITE, true))
+ && (hasTablePermission(credentials, tableID, TablePermission.READ, true) || hasTableNamespacePermissionForTableId(credentials, tableID,
+ TableNamespacePermission.READ, true));
}
public boolean canSplitTablet(TCredentials credentials, String table) throws ThriftSecurityException {
authenticate(credentials);
return hasSystemPermission(credentials, SystemPermission.ALTER_TABLE, false) || hasSystemPermission(credentials, SystemPermission.SYSTEM, false)
- || hasTablePermission(credentials, table, TablePermission.ALTER_TABLE, false);
+ || hasTablePermission(credentials, table, TablePermission.ALTER_TABLE, false)
+ || hasTableNamespacePermissionForTableId(credentials, table, TableNamespacePermission.ALTER_TABLE, false);
}
/**
@@ -366,16 +433,19 @@ public class SecurityOperation {
public boolean canFlush(TCredentials c, String tableId) throws ThriftSecurityException {
authenticate(c);
- return hasTablePermission(c, tableId, TablePermission.WRITE, false) || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false);
+ return hasTablePermission(c, tableId, TablePermission.WRITE, false) || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false)
+ || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.ALTER_TABLE, false)
+ || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.WRITE, false);
}
public boolean canAlterTable(TCredentials c, String tableId) throws ThriftSecurityException {
authenticate(c);
- return hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false) || hasSystemPermission(c, SystemPermission.ALTER_TABLE, false);
+ return hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false) || hasSystemPermission(c, SystemPermission.ALTER_TABLE, false)
+ || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.ALTER_TABLE, false);
}
public boolean canCreateTable(TCredentials c, String tableName) throws ThriftSecurityException {
- return canCreateTable(c);
+ return canCreateTable(c) || hasTableNamespacePermissionForTableName(c, tableName, TableNamespacePermission.CREATE_TABLE, false);
}
public boolean canCreateTable(TCredentials c) throws ThriftSecurityException {
@@ -385,34 +455,41 @@ public class SecurityOperation {
public boolean canRenameTable(TCredentials c, String tableId, String oldTableName, String newTableName) throws ThriftSecurityException {
authenticate(c);
- return hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false);
+ return hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false)
+ || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.ALTER_TABLE, false);
}
public boolean canCloneTable(TCredentials c, String tableId, String tableName) throws ThriftSecurityException {
authenticate(c);
- return hasSystemPermission(c, SystemPermission.CREATE_TABLE, false) && hasTablePermission(c, tableId, TablePermission.READ, false);
+ return (hasSystemPermission(c, SystemPermission.CREATE_TABLE, false) || hasTableNamespacePermissionForTableName(c, tableName,
+ TableNamespacePermission.CREATE_TABLE, false))
+ && (hasTablePermission(c, tableId, TablePermission.READ, false) || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.READ, false));
}
public boolean canDeleteTable(TCredentials c, String tableId) throws ThriftSecurityException {
authenticate(c);
- return hasSystemPermission(c, SystemPermission.DROP_TABLE, false) || hasTablePermission(c, tableId, TablePermission.DROP_TABLE, false);
+ return hasSystemPermission(c, SystemPermission.DROP_TABLE, false) || hasTablePermission(c, tableId, TablePermission.DROP_TABLE, false)
+ || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.DROP_TABLE, false);
}
public boolean canOnlineOfflineTable(TCredentials c, String tableId, TableOperation op) throws ThriftSecurityException {
authenticate(c);
return hasSystemPermission(c, SystemPermission.SYSTEM, false) || hasSystemPermission(c, SystemPermission.ALTER_TABLE, false)
- || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false);
+ || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false)
+ || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.ALTER_TABLE, false);
}
public boolean canMerge(TCredentials c, String tableId) throws ThriftSecurityException {
authenticate(c);
return hasSystemPermission(c, SystemPermission.SYSTEM, false) || hasSystemPermission(c, SystemPermission.ALTER_TABLE, false)
- || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false);
+ || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false)
+ || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.ALTER_TABLE, false);
}
public boolean canDeleteRange(TCredentials c, String tableId, String tableName, Text startRow, Text endRow) throws ThriftSecurityException {
authenticate(c);
- return hasSystemPermission(c, SystemPermission.SYSTEM, false) || hasTablePermission(c, tableId, TablePermission.WRITE, false);
+ return hasSystemPermission(c, SystemPermission.SYSTEM, false) || hasTablePermission(c, tableId, TablePermission.WRITE, false)
+ || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.WRITE, false);
}
public boolean canBulkImport(TCredentials c, String tableId, String tableName, String dir, String failDir) throws ThriftSecurityException {
@@ -421,13 +498,16 @@ public class SecurityOperation {
public boolean canBulkImport(TCredentials c, String tableId) throws ThriftSecurityException {
authenticate(c);
- return hasTablePermission(c, tableId, TablePermission.BULK_IMPORT, false);
+ return hasTablePermission(c, tableId, TablePermission.BULK_IMPORT, false)
+ || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.BULK_IMPORT, false);
}
public boolean canCompact(TCredentials c, String tableId) throws ThriftSecurityException {
authenticate(c);
return hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, tableId, TablePermission.ALTER_TABLE, false)
- || hasTablePermission(c, tableId, TablePermission.WRITE, false);
+ || hasTablePermission(c, tableId, TablePermission.WRITE, false)
+ || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.ALTER_TABLE, false)
+ || hasTableNamespacePermissionForTableId(c, tableId, TableNamespacePermission.WRITE, false);
}
public boolean canChangeAuthorizations(TCredentials c, String user) throws ThriftSecurityException {
@@ -462,7 +542,14 @@ public class SecurityOperation {
public boolean canGrantTable(TCredentials c, String user, String table) throws ThriftSecurityException {
authenticate(c);
- return hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, table, TablePermission.GRANT, false);
+ return hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, table, TablePermission.GRANT, false)
+ || hasTableNamespacePermissionForTableId(c, table, TableNamespacePermission.ALTER_TABLE, false);
+ }
+
+ public boolean canGrantTableNamespace(TCredentials c, String user, String tableNamespace) throws ThriftSecurityException {
+ authenticate(c);
+ return hasSystemPermission(c, SystemPermission.ALTER_NAMESPACE, false)
+ || hasTableNamespacePermission(c, tableNamespace, TableNamespacePermission.GRANT, false);
}
public boolean canRevokeSystem(TCredentials c, String user, SystemPermission sysPerm) throws ThriftSecurityException {
@@ -480,7 +567,13 @@ public class SecurityOperation {
public boolean canRevokeTable(TCredentials c, String user, String table) throws ThriftSecurityException {
authenticate(c);
- return hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, table, TablePermission.GRANT, false);
+ return hasSystemPermission(c, SystemPermission.ALTER_TABLE, false) || hasTablePermission(c, table, TablePermission.GRANT, false)
+ || hasTableNamespacePermissionForTableId(c, table, TableNamespacePermission.ALTER_TABLE, false);
+ }
+
+ public boolean canRevokeTableNamespace(TCredentials c, String user, String tableNamespace) throws ThriftSecurityException {
+ authenticate(c);
+ return hasSystemPermission(c, SystemPermission.ALTER_NAMESPACE, false) || hasTablePermission(c, tableNamespace, TablePermission.GRANT, false);
}
public void changeAuthorizations(TCredentials credentials, String user, Authorizations authorizations) throws ThriftSecurityException {
@@ -568,6 +661,24 @@ public class SecurityOperation {
}
}
+ public void grantTableNamespacePermission(TCredentials c, String user, String tableNamespace, TableNamespacePermission permission)
+ throws ThriftSecurityException {
+ if (!canGrantTableNamespace(c, user, tableNamespace))
+ throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
+
+ targetUserExists(user);
+
+ try {
+ permHandle.grantTableNamespacePermission(user, tableNamespace, permission);
+ log.info("Granted table namespace permission " + permission + " for user " + user + " on the table namespace " + tableNamespace
+ + " at the request of user " + c.getPrincipal());
+ } catch (AccumuloSecurityException e) {
+ throw e.asThriftException();
+ } catch (TableNamespaceNotFoundException e) {
+ throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.TABLE_NAMESPACE_DOESNT_EXIST);
+ }
+ }
+
public void revokeSystemPermission(TCredentials credentials, String user, SystemPermission permission) throws ThriftSecurityException {
if (!canRevokeSystem(credentials, user, permission))
throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
@@ -600,6 +711,25 @@ public class SecurityOperation {
}
}
+ public void revokeTableNamespacePermission(TCredentials c, String user, String tableNamespace, TableNamespacePermission permission)
+ throws ThriftSecurityException {
+ if (!canRevokeTableNamespace(c, user, tableNamespace))
+ throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
+
+ targetUserExists(user);
+
+ try {
+ permHandle.revokeTableNamespacePermission(user, tableNamespace, permission);
+ log.info("Revoked table namespace permission " + permission + " for user " + user + " on the table namespace " + tableNamespace
+ + " at the request of user " + c.getPrincipal());
+
+ } catch (AccumuloSecurityException e) {
+ throw e.asThriftException();
+ } catch (TableNamespaceNotFoundException e) {
+ throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.TABLE_NAMESPACE_DOESNT_EXIST);
+ }
+ }
+
public boolean hasSystemPermission(TCredentials credentials, String user, SystemPermission permissionById) throws ThriftSecurityException {
if (!canAskAboutOtherUsers(credentials, user))
throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
@@ -612,6 +742,13 @@ public class SecurityOperation {
return _hasTablePermission(user, tableId, permissionById, false);
}
+ public boolean hasTableNamespacePermission(TCredentials credentials, String user, String tableNamespace, TableNamespacePermission permissionById)
+ throws ThriftSecurityException {
+ if (!canAskAboutOtherUsers(credentials, user))
+ throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
+ return _hasTableNamespacePermission(user, tableNamespace, permissionById, false);
+ }
+
public Set<String> listUsers(TCredentials credentials) throws ThriftSecurityException {
authenticate(credentials);
try {
@@ -634,13 +771,29 @@ public class SecurityOperation {
}
}
+ public void deleteTableNamespace(TCredentials credentials, String tableNamespace) throws ThriftSecurityException {
+ if (!canDeleteTable(credentials, tableNamespace))
+ throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
+ try {
+ permHandle.cleanTableNamespacePermissions(tableNamespace);
+ } catch (AccumuloSecurityException e) {
+ e.setUser(credentials.getPrincipal());
+ throw e.asThriftException();
+ } catch (TableNamespaceNotFoundException e) {
+ throw new ThriftSecurityException(credentials.getPrincipal(), SecurityErrorCode.TABLE_NAMESPACE_DOESNT_EXIST);
+ }
+ }
+
public boolean canExport(TCredentials credentials, String tableId, String tableName, String exportDir) throws ThriftSecurityException {
authenticate(credentials);
- return hasTablePermission(credentials, tableId, TablePermission.READ, false);
+ return hasTablePermission(credentials, tableId, TablePermission.READ, false)
+ || hasTableNamespacePermissionForTableId(credentials, tableId, TableNamespacePermission.READ, false);
}
public boolean canImport(TCredentials credentials, String tableName, String importDir) throws ThriftSecurityException {
authenticate(credentials);
- return hasSystemPermission(credentials, SystemPermission.CREATE_TABLE, false);
+ String tableId = Tables.getNamespace(HdfsZooInstance.getInstance(), tableName);
+ return hasSystemPermission(credentials, SystemPermission.CREATE_TABLE, false)
+ || hasTableNamespacePermissionForTableId(credentials, tableId, TableNamespacePermission.CREATE_TABLE, false);
}
}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/server/base/src/main/java/org/apache/accumulo/server/security/handler/InsecurePermHandler.java
----------------------------------------------------------------------
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/InsecurePermHandler.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/InsecurePermHandler.java
index b57abfe..f1d69e8 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/InsecurePermHandler.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/InsecurePermHandler.java
@@ -17,8 +17,10 @@
package org.apache.accumulo.server.security.handler;
import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNamespaceNotFoundException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.security.TablePermission;
import org.apache.accumulo.core.security.thrift.TCredentials;
@@ -99,5 +101,34 @@ public class InsecurePermHandler implements PermissionHandler {
@Override
public void initTable(String table) throws AccumuloSecurityException {}
+
+ @Override
+ public boolean hasTableNamespacePermission(String user, String namespace, TableNamespacePermission permission) throws AccumuloSecurityException,
+ TableNamespaceNotFoundException {
+ return true;
+ }
+
+ @Override
+ public boolean hasCachedTableNamespacePermission(String user, String namespace, TableNamespacePermission permission) throws AccumuloSecurityException,
+ TableNamespaceNotFoundException {
+ return true;
+ }
+
+ @Override
+ public void grantTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws AccumuloSecurityException,
+ TableNamespaceNotFoundException {
+ return;
+ }
+
+ @Override
+ public void revokeTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws AccumuloSecurityException,
+ TableNamespaceNotFoundException {
+ return;
+ }
+
+ @Override
+ public void cleanTableNamespacePermissions(String tableNamespace) throws AccumuloSecurityException, TableNamespaceNotFoundException {
+ return;
+ }
}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/server/base/src/main/java/org/apache/accumulo/server/security/handler/PermissionHandler.java
----------------------------------------------------------------------
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/PermissionHandler.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/PermissionHandler.java
index 72c64b5..63e7208 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/PermissionHandler.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/PermissionHandler.java
@@ -17,9 +17,11 @@
package org.apache.accumulo.server.security.handler;
import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNamespaceNotFoundException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException;
import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.security.TablePermission;
import org.apache.accumulo.core.security.thrift.TCredentials;
@@ -66,6 +68,16 @@ public interface PermissionHandler {
public boolean hasCachedTablePermission(String user, String table, TablePermission permission) throws AccumuloSecurityException, TableNotFoundException;
/**
+ * Used to get the table namespace permission of a user for a table namespace
+ */
+ public boolean hasTableNamespacePermission(String user, String namespace, TableNamespacePermission permission) throws AccumuloSecurityException, TableNamespaceNotFoundException;
+
+ /**
+ * Used to get the table namespace permission of a user for a table namespace, with caching. This method is for high frequency operations
+ */
+ public boolean hasCachedTableNamespacePermission(String user, String namespace, TableNamespacePermission permission) throws AccumuloSecurityException, TableNamespaceNotFoundException;
+
+ /**
* Gives the user the given system permission
*/
public void grantSystemPermission(String user, SystemPermission permission) throws AccumuloSecurityException;
@@ -86,11 +98,27 @@ public interface PermissionHandler {
public void revokeTablePermission(String user, String table, TablePermission permission) throws AccumuloSecurityException, TableNotFoundException;
/**
+ * Gives the user the given table namespace permission
+ */
+ public void grantTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws AccumuloSecurityException, TableNamespaceNotFoundException;
+
+ /**
+ * Denies the user the given table namespace permission.
+ */
+ public void revokeTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws AccumuloSecurityException, TableNamespaceNotFoundException;
+
+
+ /**
* Cleans up the permissions for a table. Used when a table gets deleted.
*/
public void cleanTablePermissions(String table) throws AccumuloSecurityException, TableNotFoundException;
/**
+ * Cleans up the permissions for a table namespace. Used when a table namespace gets deleted.
+ */
+ public void cleanTableNamespacePermissions(String tableNamespace) throws AccumuloSecurityException, TableNamespaceNotFoundException;
+
+ /**
* Initializes a new user
*/
public void initUser(String user) throws AccumuloSecurityException;
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java
----------------------------------------------------------------------
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java
index f219603..78b79a1 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java
@@ -24,11 +24,13 @@ import java.util.Set;
import java.util.TreeSet;
import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNamespaceNotFoundException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.impl.thrift.SecurityErrorCode;
import org.apache.accumulo.core.metadata.MetadataTable;
import org.apache.accumulo.core.metadata.RootTable;
import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.security.TablePermission;
import org.apache.accumulo.core.security.thrift.TCredentials;
import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
@@ -49,9 +51,11 @@ public class ZKPermHandler implements PermissionHandler {
private String ZKUserPath;
private String ZKTablePath;
+ private String ZKNamespacePath;
private final ZooCache zooCache;
private final String ZKUserSysPerms = "/System";
private final String ZKUserTablePerms = "/Tables";
+ private final String ZKUserNamespacePerms = "/Namespaces";
public static synchronized PermissionHandler getInstance() {
if (zkPermHandlerInstance == null)
@@ -63,6 +67,7 @@ public class ZKPermHandler implements PermissionHandler {
public void initialize(String instanceId, boolean initialize) {
ZKUserPath = ZKSecurityTool.getInstancePath(instanceId) + "/users";
ZKTablePath = ZKSecurityTool.getInstancePath(instanceId) + "/tables";
+ ZKNamespacePath = ZKSecurityTool.getInstancePath(instanceId) + "/namespaces";
}
public ZKPermHandler() {
@@ -118,6 +123,54 @@ public class ZKPermHandler implements PermissionHandler {
}
@Override
+ public boolean hasTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws TableNamespaceNotFoundException {
+ byte[] serializedPerms;
+ try {
+ String path = ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + tableNamespace;
+ ZooReaderWriter.getRetryingInstance().sync(path);
+ serializedPerms = ZooReaderWriter.getRetryingInstance().getData(path, null);
+ } catch (KeeperException e) {
+ if (e.code() == Code.NONODE) {
+ // maybe the table namespace was just deleted?
+ try {
+ // check for existence:
+ ZooReaderWriter.getRetryingInstance().getData(ZKNamespacePath + "/" + tableNamespace, null);
+ // it's there, you don't have permission
+ return false;
+ } catch (InterruptedException ex) {
+ log.warn("Unhandled InterruptedException, failing closed for table namespace permission check", e);
+ return false;
+ } catch (KeeperException ex) {
+ // not there, throw an informative exception
+ if (e.code() == Code.NONODE) {
+ throw new TableNamespaceNotFoundException(null, tableNamespace, "while checking permissions");
+ }
+ log.warn("Unhandled InterruptedException, failing closed for table permission check", e);
+ }
+ return false;
+ }
+ log.warn("Unhandled KeeperException, failing closed for table permission check", e);
+ return false;
+ } catch (InterruptedException e) {
+ log.warn("Unhandled InterruptedException, failing closed for table permission check", e);
+ return false;
+ }
+ if (serializedPerms != null) {
+ return ZKSecurityTool.convertTableNamespacePermissions(serializedPerms).contains(permission);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean hasCachedTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws AccumuloSecurityException, TableNamespaceNotFoundException {
+ byte[] serializedPerms = zooCache.get(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + tableNamespace);
+ if (serializedPerms != null) {
+ return ZKSecurityTool.convertTableNamespacePermissions(serializedPerms).contains(permission);
+ }
+ return false;
+ }
+
+ @Override
public void grantSystemPermission(String user, SystemPermission permission) throws AccumuloSecurityException {
try {
byte[] permBytes = zooCache.get(ZKUserPath + "/" + user + ZKUserSysPerms);
@@ -172,6 +225,33 @@ public class ZKPermHandler implements PermissionHandler {
}
@Override
+ public void grantTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws AccumuloSecurityException {
+ Set<TableNamespacePermission> tableNamespacePerms;
+ byte[] serializedPerms = zooCache.get(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + tableNamespace);
+ if (serializedPerms != null)
+ tableNamespacePerms = ZKSecurityTool.convertTableNamespacePermissions(serializedPerms);
+ else
+ tableNamespacePerms = new TreeSet<TableNamespacePermission>();
+
+ try {
+ if (tableNamespacePerms.add(permission)) {
+ synchronized (zooCache) {
+ zooCache.clear(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + tableNamespace);
+ IZooReaderWriter zoo = ZooReaderWriter.getRetryingInstance();
+ zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + tableNamespace, ZKSecurityTool.convertTableNamespacePermissions(tableNamespacePerms),
+ NodeExistsPolicy.OVERWRITE);
+ }
+ }
+ } catch (KeeperException e) {
+ log.error(e, e);
+ throw new AccumuloSecurityException(user, SecurityErrorCode.CONNECTION_ERROR, e);
+ } catch (InterruptedException e) {
+ log.error(e, e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
public void revokeSystemPermission(String user, SystemPermission permission) throws AccumuloSecurityException {
byte[] sysPermBytes = zooCache.get(ZKUserPath + "/" + user + ZKUserSysPerms);
@@ -227,6 +307,34 @@ public class ZKPermHandler implements PermissionHandler {
}
@Override
+ public void revokeTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws AccumuloSecurityException {
+ byte[] serializedPerms = zooCache.get(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + tableNamespace);
+
+ // User had no table namespace permission, nothing to revoke.
+ if (serializedPerms == null)
+ return;
+
+ Set<TableNamespacePermission> tableNamespacePerms = ZKSecurityTool.convertTableNamespacePermissions(serializedPerms);
+ try {
+ if (tableNamespacePerms.remove(permission)) {
+ zooCache.clear();
+ IZooReaderWriter zoo = ZooReaderWriter.getRetryingInstance();
+ if (tableNamespacePerms.size() == 0)
+ zoo.recursiveDelete(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + tableNamespace, NodeMissingPolicy.SKIP);
+ else
+ zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + tableNamespace, ZKSecurityTool.convertTableNamespacePermissions(tableNamespacePerms),
+ NodeExistsPolicy.OVERWRITE);
+ }
+ } catch (KeeperException e) {
+ log.error(e, e);
+ throw new AccumuloSecurityException(user, SecurityErrorCode.CONNECTION_ERROR, e);
+ } catch (InterruptedException e) {
+ log.error(e, e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
public void cleanTablePermissions(String table) throws AccumuloSecurityException {
try {
synchronized (zooCache) {
@@ -245,6 +353,24 @@ public class ZKPermHandler implements PermissionHandler {
}
@Override
+ public void cleanTableNamespacePermissions(String tableNamespace) throws AccumuloSecurityException {
+ try {
+ synchronized (zooCache) {
+ zooCache.clear();
+ IZooReaderWriter zoo = ZooReaderWriter.getRetryingInstance();
+ for (String user : zooCache.getChildren(ZKUserPath))
+ zoo.recursiveDelete(ZKUserPath + "/" + user + ZKUserNamespacePerms + "/" + tableNamespace, NodeMissingPolicy.SKIP);
+ }
+ } catch (KeeperException e) {
+ log.error(e, e);
+ throw new AccumuloSecurityException("unknownUser", SecurityErrorCode.CONNECTION_ERROR, e);
+ } catch (InterruptedException e) {
+ log.error(e, e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
public void initializeSecurity(TCredentials itw, String rootuser) throws AccumuloSecurityException {
IZooReaderWriter zoo = ZooReaderWriter.getRetryingInstance();
@@ -285,6 +411,7 @@ public class ZKPermHandler implements PermissionHandler {
try {
zoo.putPersistentData(ZKUserPath + "/" + user, new byte[0], NodeExistsPolicy.SKIP);
zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserTablePerms, new byte[0], NodeExistsPolicy.SKIP);
+ zoo.putPersistentData(ZKUserPath + "/" + user + ZKUserNamespacePerms, new byte[0], NodeExistsPolicy.SKIP);
} catch (KeeperException e) {
log.error(e, e);
throw new AccumuloSecurityException(user, SecurityErrorCode.CONNECTION_ERROR, e);
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKSecurityTool.java
----------------------------------------------------------------------
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKSecurityTool.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKSecurityTool.java
index 3b9d8b2..ce62b7e 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKSecurityTool.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKSecurityTool.java
@@ -31,6 +31,7 @@ import org.apache.accumulo.core.Constants;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.security.TablePermission;
import org.apache.log4j.Logger;
@@ -149,6 +150,26 @@ class ZKSecurityTool {
return toReturn;
}
+ public static byte[] convertTableNamespacePermissions(Set<TableNamespacePermission> namespacepermissions) {
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream(namespacepermissions.size());
+ DataOutputStream out = new DataOutputStream(bytes);
+ try {
+ for (TableNamespacePermission tnp : namespacepermissions)
+ out.writeByte(tnp.getId());
+ } catch (IOException e) {
+ log.error(e, e);
+ throw new RuntimeException(e); // this is impossible with ByteArrayOutputStream; crash hard if this happens
+ }
+ return bytes.toByteArray();
+ }
+
+ public static Set<TableNamespacePermission> convertTableNamespacePermissions(byte[] namespacepermissions) {
+ Set<TableNamespacePermission> toReturn = new HashSet<TableNamespacePermission>();
+ for (byte b : namespacepermissions)
+ toReturn.add(TableNamespacePermission.getPermissionById(b));
+ return toReturn;
+ }
+
public static String getInstancePath(String instanceId) {
return Constants.ZROOT + "/" + instanceId;
}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/test/src/main/java/org/apache/accumulo/test/randomwalk/security/WalkingSecurity.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/accumulo/test/randomwalk/security/WalkingSecurity.java b/test/src/main/java/org/apache/accumulo/test/randomwalk/security/WalkingSecurity.java
index 0ddb752..08fd395 100644
--- a/test/src/main/java/org/apache/accumulo/test/randomwalk/security/WalkingSecurity.java
+++ b/test/src/main/java/org/apache/accumulo/test/randomwalk/security/WalkingSecurity.java
@@ -27,6 +27,7 @@ import java.util.Set;
import java.util.TreeSet;
import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNamespaceNotFoundException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.impl.thrift.SecurityErrorCode;
import org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException;
@@ -35,6 +36,7 @@ import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.security.Credentials;
import org.apache.accumulo.core.security.SystemPermission;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.security.TablePermission;
import org.apache.accumulo.core.security.thrift.TCredentials;
import org.apache.accumulo.core.util.CachedConfiguration;
@@ -59,6 +61,7 @@ public class WalkingSecurity extends SecurityOperation implements Authorizor, Au
private static final String userPass = "UserPass";
private static final String userExists = "UserExists";
private static final String tableExists = "TableExists";
+ private static final String tableNamespaceExists = "TableNamespaceExists";
private static final String connector = "UserConnection";
@@ -205,6 +208,16 @@ public class WalkingSecurity extends SecurityOperation implements Authorizor, Au
}
@Override
+ public boolean hasTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws AccumuloSecurityException, TableNamespaceNotFoundException {
+ return Boolean.parseBoolean(state.getString("Nsp-" + user + '-' + permission.name()));
+ }
+
+ @Override
+ public boolean hasCachedTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws AccumuloSecurityException, TableNamespaceNotFoundException {
+ return hasTableNamespacePermission(user, tableNamespace, permission);
+ }
+
+ @Override
public void grantSystemPermission(String user, SystemPermission permission) throws AccumuloSecurityException {
setSysPerm(state, user, permission, true);
}
@@ -239,6 +252,25 @@ public class WalkingSecurity extends SecurityOperation implements Authorizor, Au
}
@Override
+ public void grantTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws AccumuloSecurityException, TableNamespaceNotFoundException {
+ setNspPerm(state, user, permission, tableNamespace, true);
+ }
+
+ private void setNspPerm(State state, String userName, TableNamespacePermission tnp, String tableNamespace, boolean value) {
+ if (tableNamespace.equals(userName))
+ throw new RuntimeException("I don't even know");
+ log.debug((value ? "Gave" : "Took") + " the table permission " + tnp.name() + (value ? " to" : " from") + " user " + userName);
+ state.set("Nsp-" + userName + '-' + tnp.name(), Boolean.toString(value));
+ if (tnp.equals(TableNamespacePermission.READ) || tnp.equals(TableNamespacePermission.WRITE))
+ state.set("Nsp-" + userName + '-' + tnp.name() + '-' + "time", System.currentTimeMillis());
+ }
+
+ @Override
+ public void revokeTableNamespacePermission(String user, String tableNamespace, TableNamespacePermission permission) throws AccumuloSecurityException, TableNamespaceNotFoundException {
+ setNspPerm(state, user, permission, tableNamespace, false);
+ }
+
+ @Override
public void cleanTablePermissions(String table) throws AccumuloSecurityException, TableNotFoundException {
for (String user : new String[] {getSysUserName(), getTabUserName()}) {
for (TablePermission tp : TablePermission.values()) {
@@ -249,6 +281,16 @@ public class WalkingSecurity extends SecurityOperation implements Authorizor, Au
}
@Override
+ public void cleanTableNamespacePermissions(String tableNamespace) throws AccumuloSecurityException, TableNamespaceNotFoundException {
+ for (String user : new String[] {getSysUserName(), getNspUserName()}) {
+ for (TableNamespacePermission tnp : TableNamespacePermission.values()) {
+ revokeTableNamespacePermission(user, tableNamespace, tnp);
+ }
+ }
+ state.set(tableNamespaceExists, Boolean.toString(false));
+ }
+
+ @Override
public void cleanUser(String user) throws AccumuloSecurityException {
if (getTableExists())
for (TablePermission tp : TablePermission.values())
@@ -267,11 +309,20 @@ public class WalkingSecurity extends SecurityOperation implements Authorizor, Au
return state.getString("system" + userName);
}
+ public String getNspUserName() {
+ return state.getString("namespace" + userName);
+ }
+
public void setTabUserName(String name) {
state.set("table" + userName, name);
state.set(name + userExists, Boolean.toString(false));
}
+ public void setNspUserName(String name) {
+ state.set("namespace" + userName, name);
+ state.set(name + userExists, Boolean.toString(false));
+ }
+
public void setSysUserName(String name) {
state.set("system" + userName, name);
}
http://git-wip-us.apache.org/repos/asf/accumulo/blob/dfdf5113/test/src/test/java/org/apache/accumulo/test/TableNamespacesIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/TableNamespacesIT.java b/test/src/test/java/org/apache/accumulo/test/TableNamespacesIT.java
index 584991e..b779152 100644
--- a/test/src/test/java/org/apache/accumulo/test/TableNamespacesIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/TableNamespacesIT.java
@@ -30,6 +30,7 @@ import java.util.Set;
import org.apache.accumulo.core.Constants;
import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.BatchWriter;
import org.apache.accumulo.core.client.BatchWriterConfig;
import org.apache.accumulo.core.client.Connector;
@@ -42,6 +43,7 @@ import org.apache.accumulo.core.client.TableNamespaceNotFoundException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.impl.TableNamespaces;
import org.apache.accumulo.core.client.impl.Tables;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.conf.Property;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Mutation;
@@ -49,6 +51,7 @@ import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.iterators.Filter;
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.core.security.TableNamespacePermission;
import org.apache.accumulo.core.util.UtilWaitThread;
import org.apache.accumulo.examples.simple.constraints.NumericValueConstraint;
import org.apache.accumulo.minicluster.MiniAccumuloCluster;
@@ -404,12 +407,12 @@ public class TableNamespacesIT {
} catch (MutationsRejectedException e) {
// supposed to be thrown
}
-
int num = c.tableNamespaceOperations().listConstraints(namespace).get(NumericValueConstraint.class.getName());
c.tableNamespaceOperations().removeConstraint(namespace, num);
}
/**
+<<<<<<< HEAD
* Tests that when a table moves to a new namespace that it's properties inherit from the new namespace and not the old one
*/
@Test
@@ -447,6 +450,38 @@ public class TableNamespacesIT {
}
assertTrue(!hasProp);
}
+ /**
+ * Tests new Namespace permissions as well as modifications to Table permissions because of namespaces
+ */
+ @Test
+ public void testPermissions() throws Exception {
+ Connector c = accumulo.getConnector("root", secret);
+
+ PasswordToken pass = new PasswordToken(secret);
+
+ String n1 = "namespace1";
+
+ String user1 = "dude";
+
+ c.tableNamespaceOperations().create(n1);
+ c.tableOperations().create(n1 + ".table1");
+
+ c.securityOperations().createLocalUser(user1, pass);
+
+ Connector user1Con = accumulo.getConnector(user1, secret);
+
+ try {
+ user1Con.tableOperations().create(n1 + ".table2");
+ fail();
+ } catch (AccumuloSecurityException e) {
+ // supposed to happen
+ }
+
+ c.securityOperations().grantTableNamespacePermission(user1, n1, TableNamespacePermission.CREATE_TABLE);
+
+ user1Con.tableOperations().create(n1 + ".table2");
+ assertTrue(c.tableOperations().list().contains(n1 + ".table2"));
+ }
private boolean checkTableHasProp(Connector c, String t, String propKey, String propVal) throws AccumuloException, TableNotFoundException {
for (Entry<String,String> e : c.tableOperations().getProperties(t)) {