From d8dc57152b7184db9906887e3ce6e43ea5983812 Mon Sep 17 00:00:00 2001 From: Guanghao Zhang Date: Thu, 23 Nov 2017 14:51:45 +0800 Subject: [PATCH] HBASE-19334 User.runAsLoginUser not work in AccessController because it use a short circuited connection --- .../hbase/security/access/AccessControlLists.java | 204 +++++++-------------- .../hbase/security/access/AccessController.java | 40 +--- .../security/access/TestTablePermissions.java | 89 ++++----- 3 files changed, 105 insertions(+), 228 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlLists.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlLists.java index 4e67f6e..74c8a91 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlLists.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlLists.java @@ -18,9 +18,7 @@ package org.apache.hadoop.hbase.security.access; -import org.apache.hadoop.hbase.CompareOperator; import org.apache.hadoop.hbase.PrivateCellUtil; -import org.apache.hadoop.hbase.client.Admin; import org.apache.hadoop.hbase.shaded.com.google.common.collect.ArrayListMultimap; import org.apache.hadoop.hbase.shaded.com.google.common.collect.ListMultimap; import org.apache.hadoop.hbase.shaded.com.google.common.collect.Lists; @@ -31,7 +29,6 @@ import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -62,8 +59,6 @@ import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.client.TableDescriptor; import org.apache.hadoop.hbase.exceptions.DeserializationException; -import org.apache.hadoop.hbase.filter.QualifierFilter; -import org.apache.hadoop.hbase.filter.RegexStringComparator; import org.apache.hadoop.hbase.protobuf.ProtobufUtil; import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos; import org.apache.hadoop.hbase.regionserver.InternalScanner; @@ -121,15 +116,15 @@ public class AccessControlLists { private static final Log LOG = LogFactory.getLog(AccessControlLists.class); - /** - * Stores a new user permission grant in the access control lists table. - * @param conf the configuration - * @param userPerm the details of the permission to be granted - * @param t acl table instance. It is closed upon method return. - * @throws IOException in the case of an error accessing the metadata table - */ - static void addUserPermission(Configuration conf, UserPermission userPerm, Table t, - boolean mergeExistingPermissions) throws IOException { + static void addUserPermission(Configuration conf, UserPermission userPerm, + boolean mergeExistingPermissions) throws IOException { + try (Connection conn = ConnectionFactory.createConnection(conf)) { + addUserPermission(conn, userPerm, mergeExistingPermissions); + } + } + + static void addUserPermission(Connection conn, UserPermission userPerm, + boolean mergeExistingPermissions) throws IOException { Permission.Action[] actions = userPerm.getActions(); byte[] rowKey = userPermissionRowKey(userPerm); Put p = new Put(rowKey); @@ -142,19 +137,19 @@ public class AccessControlLists { } Set actionSet = new TreeSet(); - if(mergeExistingPermissions){ - List perms = getUserPermissions(conf, rowKey); + if (mergeExistingPermissions) { + List perms = getUserPermissions(conn.getConfiguration(), rowKey); UserPermission currentPerm = null; for (UserPermission perm : perms) { if (Bytes.equals(perm.getUser(), userPerm.getUser()) - && ((userPerm.isGlobal() && ACL_TABLE_NAME.equals(perm.getTableName())) + && ((userPerm.isGlobal() && ACL_TABLE_NAME.equals(perm.getTableName())) || perm.tableFieldsEqual(userPerm))) { currentPerm = perm; break; } } - if(currentPerm != null && currentPerm.getActions() != null){ + if (currentPerm != null && currentPerm.getActions() != null) { actionSet.addAll(Arrays.asList(currentPerm.getActions())); } } @@ -171,57 +166,39 @@ public class AccessControlLists { p.addImmutable(ACL_LIST_FAMILY, key, value); if (LOG.isDebugEnabled()) { - LOG.debug("Writing permission with rowKey "+ - Bytes.toString(rowKey)+" "+ - Bytes.toString(key)+": "+Bytes.toStringBinary(value) - ); + LOG.debug("Writing permission with rowKey " + Bytes.toString(rowKey) + " " + + Bytes.toString(key) + ": " + Bytes.toStringBinary(value)); } - try { - /** - * TODO: Use Table.put(Put) instead. This Table.put() happens within the RS. We are already in - * AccessController. Means already there was an RPC happened to server (Actual grant call from - * client side). At RpcServer we have a ThreadLocal where we keep the CallContext and inside - * that the current RPC called user info is set. The table on which put was called is created - * via the RegionCP env and that uses a special Connection. The normal RPC channel will be by - * passed here means there would have no further contact on to the RpcServer. So the - * ThreadLocal is never getting reset. We ran the new put as a super user (User.runAsLoginUser - * where the login user is the user who started RS process) but still as per the RPC context - * it is the old user. When AsyncProcess was used, the execute happen via another thread from - * pool and so old ThreadLocal variable is not accessible and so it looks as if no Rpc context - * and we were relying on the super user who starts the RS process. - */ - t.put(Collections.singletonList(p)); - } finally { - t.close(); + try (Table table = conn.getTable(ACL_TABLE_NAME)) { + table.put(p); } } - static void addUserPermission(Configuration conf, UserPermission userPerm, Table t) - throws IOException{ - addUserPermission(conf, userPerm, t, false); + static void addUserPermission(Configuration conf, UserPermission userPerm) throws IOException { + addUserPermission(conf, userPerm, false); } - /** - * Removes a previously granted permission from the stored access control - * lists. The {@link TablePermission} being removed must exactly match what - * is stored -- no wildcard matching is attempted. Ie, if user "bob" has - * been granted "READ" access to the "data" table, but only to column family - * plus qualifier "info:colA", then trying to call this method with only - * user "bob" and the table name "data" (but without specifying the - * column qualifier "info:colA") will have no effect. - * - * @param conf the configuration - * @param userPerm the details of the permission to be revoked - * @param t acl table - * @throws IOException if there is an error accessing the metadata table - */ - static void removeUserPermission(Configuration conf, UserPermission userPerm, Table t) - throws IOException { + static void addUserPermission(Connection conn, UserPermission userPerm) throws IOException { + addUserPermission(conn, userPerm, false); + } + + static void removeUserPermission(Configuration conf, UserPermission userPerm) throws IOException { + try (Connection conn = ConnectionFactory.createConnection(conf)) { + removeUserPermission(conn, userPerm); + } + } + + static void removeUserPermission(Connection conn, UserPermission userPerm) throws IOException { if (null == userPerm.getActions()) { - removePermissionRecord(conf, userPerm, t); + Delete d = new Delete(userPermissionRowKey(userPerm)); + d.addColumns(ACL_LIST_FAMILY, userPermissionKey(userPerm)); + try (Table table = conn.getTable(ACL_TABLE_NAME)) { + table.delete(d); + } } else { // Get all the global user permissions from the acl table - List permsList = getUserPermissions(conf, userPermissionRowKey(userPerm)); + List permsList = + getUserPermissions(conn.getConfiguration(), userPermissionRowKey(userPerm)); List remainingActions = new ArrayList<>(); List dropActions = Arrays.asList(userPerm.getActions()); for (UserPermission perm : permsList) { @@ -233,110 +210,55 @@ public class AccessControlLists { } } if (!remainingActions.isEmpty()) { - perm.setActions(remainingActions.toArray(new Permission.Action[remainingActions.size()])); - addUserPermission(conf, perm, t); + perm.setActions( + remainingActions.toArray(new Permission.Action[remainingActions.size()])); + addUserPermission(conn, perm); } else { - removePermissionRecord(conf, userPerm, t); + Delete d = new Delete(userPermissionRowKey(userPerm)); + d.addColumns(ACL_LIST_FAMILY, userPermissionKey(userPerm)); + try (Table table = conn.getTable(ACL_TABLE_NAME)) { + table.delete(d); + } } break; } } } if (LOG.isDebugEnabled()) { - LOG.debug("Removed permission "+ userPerm.toString()); + LOG.debug("Removed permission " + userPerm.toString()); } } - private static void removePermissionRecord(Configuration conf, UserPermission userPerm, Table t) - throws IOException { - Delete d = new Delete(userPermissionRowKey(userPerm)); - d.addColumns(ACL_LIST_FAMILY, userPermissionKey(userPerm)); - try { - t.delete(d); - } finally { - t.close(); - } - } - - /** - * Remove specified table from the _acl_ table. - */ - static void removeTablePermissions(Configuration conf, TableName tableName, Table t) - throws IOException{ - Delete d = new Delete(tableName.getName()); - - if (LOG.isDebugEnabled()) { - LOG.debug("Removing permissions of removed table "+ tableName); - } - try { - t.delete(d); - } finally { - t.close(); + static void removeTablePermissions(Configuration conf, TableName tableName) throws IOException { + try (Connection conn = ConnectionFactory.createConnection(conf)) { + removeTablePermissions(conn, tableName); } } - /** - * Remove specified namespace from the acl table. - */ - static void removeNamespacePermissions(Configuration conf, String namespace, Table t) - throws IOException{ - Delete d = new Delete(Bytes.toBytes(toNamespaceEntry(namespace))); - + static void removeTablePermissions(Connection conn, TableName tableName) throws IOException { if (LOG.isDebugEnabled()) { - LOG.debug("Removing permissions of removed namespace "+ namespace); + LOG.debug("Removing permissions of removed table " + tableName); } - - try { - t.delete(d); - } finally { - t.close(); + Delete d = new Delete(tableName.getName()); + try (Table table = conn.getTable(ACL_TABLE_NAME)) { + table.delete(d); } } - static private void removeTablePermissions(TableName tableName, byte[] column, Table table, - boolean closeTable) throws IOException { - Scan scan = new Scan(); - scan.addFamily(ACL_LIST_FAMILY); - - String columnName = Bytes.toString(column); - scan.setFilter(new QualifierFilter(CompareOperator.EQUAL, new RegexStringComparator( - String.format("(%s%s%s)|(%s%s)$", - ACL_KEY_DELIMITER, columnName, ACL_KEY_DELIMITER, - ACL_KEY_DELIMITER, columnName)))); - - Set qualifierSet = new TreeSet<>(Bytes.BYTES_COMPARATOR); - ResultScanner scanner = null; - try { - scanner = table.getScanner(scan); - for (Result res : scanner) { - for (byte[] q : res.getFamilyMap(ACL_LIST_FAMILY).navigableKeySet()) { - qualifierSet.add(q); - } - } - - if (qualifierSet.size() > 0) { - Delete d = new Delete(tableName.getName()); - for (byte[] qualifier : qualifierSet) { - d.addColumns(ACL_LIST_FAMILY, qualifier); - } - table.delete(d); - } - } finally { - if (scanner != null) scanner.close(); - if (closeTable) table.close(); + static void removeNamespacePermissions(Configuration conf, String namespace) throws IOException { + try (Connection conn = ConnectionFactory.createConnection(conf)) { + removeNamespacePermissions(conn, namespace); } } - /** - * Remove specified table column from the acl table. - */ - static void removeTablePermissions(Configuration conf, TableName tableName, byte[] column, - Table t) throws IOException { + static void removeNamespacePermissions(Connection conn, String namespace) throws IOException { if (LOG.isDebugEnabled()) { - LOG.debug("Removing permissions of removed column " + Bytes.toString(column) + - " from table "+ tableName); + LOG.debug("Removing permissions of removed namespace "+ namespace); + } + Delete d = new Delete(Bytes.toBytes(toNamespaceEntry(namespace))); + try (Table table = conn.getTable(ACL_TABLE_NAME)) { + table.delete(d); } - removeTablePermissions(tableName, column, t, true); } static byte[] userPermissionRowKey(UserPermission userPerm) { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java index 05f9195..f82646c 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java @@ -63,6 +63,8 @@ import org.apache.hadoop.hbase.client.Admin; import org.apache.hadoop.hbase.client.Append; import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; +import org.apache.hadoop.hbase.client.Connection; +import org.apache.hadoop.hbase.client.ConnectionFactory; import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Durability; import org.apache.hadoop.hbase.client.Get; @@ -1085,11 +1087,7 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor, User.runAsLoginUser(new PrivilegedExceptionAction() { @Override public Void run() throws Exception { - try (Table table = c.getEnvironment().getConnection(). - getTable(AccessControlLists.ACL_TABLE_NAME)) { - AccessControlLists.addUserPermission(c.getEnvironment().getConfiguration(), - userperm, table); - } + AccessControlLists.addUserPermission(c.getEnvironment().getConfiguration(), userperm); return null; } }); @@ -1111,10 +1109,7 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor, User.runAsLoginUser(new PrivilegedExceptionAction() { @Override public Void run() throws Exception { - try (Table table = c.getEnvironment().getConnection(). - getTable(AccessControlLists.ACL_TABLE_NAME)) { - AccessControlLists.removeTablePermissions(conf, tableName, table); - } + AccessControlLists.removeTablePermissions(conf, tableName); return null; } }); @@ -1150,10 +1145,7 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor, List perms = tableAcls.get(tableName); if (perms != null) { for (UserPermission perm : perms) { - try (Table table = ctx.getEnvironment().getConnection(). - getTable(AccessControlLists.ACL_TABLE_NAME)) { - AccessControlLists.addUserPermission(conf, perm, table); - } + AccessControlLists.addUserPermission(conf, perm); } } tableAcls.remove(tableName); @@ -1182,10 +1174,7 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor, public Void run() throws Exception { UserPermission userperm = new UserPermission(Bytes.toBytes(owner), htd.getTableName(), null, Action.values()); - try (Table table = c.getEnvironment().getConnection(). - getTable(AccessControlLists.ACL_TABLE_NAME)) { - AccessControlLists.addUserPermission(conf, userperm, table); - } + AccessControlLists.addUserPermission(conf, userperm); return null; } }); @@ -1416,10 +1405,7 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor, User.runAsLoginUser(new PrivilegedExceptionAction() { @Override public Void run() throws Exception { - try (Table table = ctx.getEnvironment().getConnection(). - getTable(AccessControlLists.ACL_TABLE_NAME)) { - AccessControlLists.removeNamespacePermissions(conf, namespace, table); - } + AccessControlLists.removeNamespacePermissions(conf, namespace); return null; } }); @@ -2246,11 +2232,8 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor, @Override public Void run() throws Exception { // regionEnv is set at #start. Hopefully not null at this point. - try (Table table = regionEnv.getConnection(). - getTable(AccessControlLists.ACL_TABLE_NAME)) { - AccessControlLists.addUserPermission(regionEnv.getConfiguration(), perm, table, - request.getMergeExistingPermissions()); - } + AccessControlLists.addUserPermission(regionEnv.getConfiguration(), perm, + request.getMergeExistingPermissions()); return null; } }); @@ -2303,10 +2286,7 @@ public class AccessController implements MasterCoprocessor, RegionCoprocessor, @Override public Void run() throws Exception { // regionEnv is set at #start. Hopefully not null here. - try (Table table = regionEnv.getConnection(). - getTable(AccessControlLists.ACL_TABLE_NAME)) { - AccessControlLists.removeUserPermission(regionEnv.getConfiguration(), perm, table); - } + AccessControlLists.removeUserPermission(regionEnv.getConfiguration(), perm); return null; } }); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestTablePermissions.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestTablePermissions.java index 607ea8c..3b9786f 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestTablePermissions.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestTablePermissions.java @@ -112,23 +112,18 @@ public class TestTablePermissions { @After public void tearDown() throws Exception { Configuration conf = UTIL.getConfiguration(); - try (Connection connection = ConnectionFactory.createConnection(conf); - Table table = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) { - AccessControlLists.removeTablePermissions(conf, TEST_TABLE, table); - AccessControlLists.removeTablePermissions(conf, TEST_TABLE2, table); - AccessControlLists.removeTablePermissions(conf, AccessControlLists.ACL_TABLE_NAME, table); + try (Connection connection = ConnectionFactory.createConnection(conf)) { + AccessControlLists.removeTablePermissions(connection, TEST_TABLE); + AccessControlLists.removeTablePermissions(connection, TEST_TABLE2); + AccessControlLists.removeTablePermissions(connection, AccessControlLists.ACL_TABLE_NAME); } } /** * The AccessControlLists.addUserPermission may throw exception before closing the table. */ - private void addUserPermission(Configuration conf, UserPermission userPerm, Table t) throws IOException { - try { - AccessControlLists.addUserPermission(conf, userPerm, t); - } finally { - t.close(); - } + private void addUserPermission(Connection conn, UserPermission userPerm) throws IOException { + AccessControlLists.addUserPermission(conn, userPerm); } @Test @@ -136,19 +131,12 @@ public class TestTablePermissions { Configuration conf = UTIL.getConfiguration(); try (Connection connection = ConnectionFactory.createConnection(conf)) { // add some permissions - addUserPermission(conf, - new UserPermission(Bytes.toBytes("george"), TEST_TABLE, null, (byte[])null, - UserPermission.Action.READ, UserPermission.Action.WRITE), - connection.getTable(AccessControlLists.ACL_TABLE_NAME)); - addUserPermission(conf, - new UserPermission(Bytes.toBytes("hubert"), TEST_TABLE, null, (byte[])null, - UserPermission.Action.READ), - connection.getTable(AccessControlLists.ACL_TABLE_NAME)); - addUserPermission(conf, - new UserPermission(Bytes.toBytes("humphrey"), - TEST_TABLE, TEST_FAMILY, TEST_QUALIFIER, - UserPermission.Action.READ), - connection.getTable(AccessControlLists.ACL_TABLE_NAME)); + addUserPermission(connection, new UserPermission(Bytes.toBytes("george"), TEST_TABLE, null, + (byte[]) null, UserPermission.Action.READ, UserPermission.Action.WRITE)); + addUserPermission(connection, new UserPermission(Bytes.toBytes("hubert"), TEST_TABLE, null, + (byte[]) null, UserPermission.Action.READ)); + addUserPermission(connection, new UserPermission(Bytes.toBytes("humphrey"), TEST_TABLE, + TEST_FAMILY, TEST_QUALIFIER, UserPermission.Action.READ)); } // retrieve the same ListMultimap perms = @@ -202,11 +190,10 @@ public class TestTablePermissions { assertFalse(actions.contains(TablePermission.Action.WRITE)); // table 2 permissions - try (Connection connection = ConnectionFactory.createConnection(conf); - Table table = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) { - AccessControlLists.addUserPermission(conf, - new UserPermission(Bytes.toBytes("hubert"), TEST_TABLE2, null, (byte[])null, - TablePermission.Action.READ, TablePermission.Action.WRITE), table); + try (Connection connection = ConnectionFactory.createConnection(conf)) { + AccessControlLists.addUserPermission(connection, + new UserPermission(Bytes.toBytes("hubert"), TEST_TABLE2, null, (byte[]) null, + TablePermission.Action.READ, TablePermission.Action.WRITE)); } // check full load Map> allPerms = @@ -237,21 +224,14 @@ public class TestTablePermissions { public void testPersistence() throws Exception { Configuration conf = UTIL.getConfiguration(); try (Connection connection = ConnectionFactory.createConnection(conf)) { - addUserPermission(conf, - new UserPermission(Bytes.toBytes("albert"), TEST_TABLE, null, - (byte[])null, TablePermission.Action.READ), connection.getTable(AccessControlLists.ACL_TABLE_NAME)); - addUserPermission(conf, - new UserPermission(Bytes.toBytes("betty"), TEST_TABLE, null, - (byte[])null, TablePermission.Action.READ, - TablePermission.Action.WRITE), connection.getTable(AccessControlLists.ACL_TABLE_NAME)); - addUserPermission(conf, - new UserPermission(Bytes.toBytes("clark"), - TEST_TABLE, TEST_FAMILY, - TablePermission.Action.READ), connection.getTable(AccessControlLists.ACL_TABLE_NAME)); - addUserPermission(conf, - new UserPermission(Bytes.toBytes("dwight"), - TEST_TABLE, TEST_FAMILY, TEST_QUALIFIER, - TablePermission.Action.WRITE), connection.getTable(AccessControlLists.ACL_TABLE_NAME)); + addUserPermission(connection, new UserPermission(Bytes.toBytes("albert"), TEST_TABLE, null, + (byte[]) null, TablePermission.Action.READ)); + addUserPermission(connection, new UserPermission(Bytes.toBytes("betty"), TEST_TABLE, null, + (byte[]) null, TablePermission.Action.READ, TablePermission.Action.WRITE)); + addUserPermission(connection, new UserPermission(Bytes.toBytes("clark"), TEST_TABLE, + TEST_FAMILY, TablePermission.Action.READ)); + addUserPermission(connection, new UserPermission(Bytes.toBytes("dwight"), TEST_TABLE, + TEST_FAMILY, TEST_QUALIFIER, TablePermission.Action.WRITE)); } // verify permissions survive changes in table metadata ListMultimap preperms = @@ -386,16 +366,12 @@ public class TestTablePermissions { // add some permissions try (Connection connection = ConnectionFactory.createConnection(conf)) { - addUserPermission(conf, - new UserPermission(Bytes.toBytes("user1"), - Permission.Action.READ, Permission.Action.WRITE), connection.getTable(AccessControlLists.ACL_TABLE_NAME)); - addUserPermission(conf, - new UserPermission(Bytes.toBytes("user2"), - Permission.Action.CREATE), connection.getTable(AccessControlLists.ACL_TABLE_NAME)); - addUserPermission(conf, - new UserPermission(Bytes.toBytes("user3"), - Permission.Action.ADMIN, Permission.Action.READ, Permission.Action.CREATE), - connection.getTable(AccessControlLists.ACL_TABLE_NAME)); + addUserPermission(connection, new UserPermission(Bytes.toBytes("user1"), + Permission.Action.READ, Permission.Action.WRITE)); + addUserPermission(connection, + new UserPermission(Bytes.toBytes("user2"), Permission.Action.CREATE)); + addUserPermission(connection, new UserPermission(Bytes.toBytes("user3"), + Permission.Action.ADMIN, Permission.Action.READ, Permission.Action.CREATE)); } ListMultimap perms = AccessControlLists.getTablePermissions(conf, null); List user1Perms = perms.get("user1"); @@ -431,9 +407,8 @@ public class TestTablePermissions { assertTrue(authManager.authorize(currentUser, Permission.Action.ADMIN)); try (Connection connection = ConnectionFactory.createConnection(conf)) { for (int i=1; i<=50; i++) { - addUserPermission(conf, new UserPermission(Bytes.toBytes("testauth"+i), - Permission.Action.ADMIN, Permission.Action.READ, Permission.Action.WRITE), - connection.getTable(AccessControlLists.ACL_TABLE_NAME)); + addUserPermission(connection, new UserPermission(Bytes.toBytes("testauth"+i), + Permission.Action.ADMIN, Permission.Action.READ, Permission.Action.WRITE)); // make sure the system user still shows as authorized assertTrue("Failed current user auth check on iter "+i, authManager.authorize(currentUser, Permission.Action.ADMIN)); -- 1.9.1