You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2019/09/18 13:09:15 UTC
[nifi] branch master updated: NIFI-6400 Better options,
consistent ids for ShellUserGroupProvider. NIFI-6400 Fixes to
address PR feedback. NIFI-6400 Accepts proposed changes.
This is an automated email from the ASF dual-hosted git repository.
mcgilman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/master by this push:
new 4596ef7 NIFI-6400 Better options, consistent ids for ShellUserGroupProvider. NIFI-6400 Fixes to address PR feedback. NIFI-6400 Accepts proposed changes.
4596ef7 is described below
commit 4596ef7c8a1b4a002dd81d210ceab4f99bc32fd6
Author: Troy Melhase <tr...@troy.io>
AuthorDate: Tue Aug 6 13:33:05 2019 -0800
NIFI-6400 Better options, consistent ids for ShellUserGroupProvider.
NIFI-6400 Fixes to address PR feedback.
NIFI-6400 Accepts proposed changes.
This closes #3637
---
.../src/main/asciidoc/administration-guide.adoc | 2 +
.../src/main/resources/conf/authorizers.xml | 6 +-
.../nifi/authorization/ShellUserGroupProvider.java | 100 +++++----
.../authorization/ShellUserGroupProviderBase.java | 176 ----------------
.../authorization/ShellUserGroupProviderIT.java | 234 +++++++++++++++------
5 files changed, 234 insertions(+), 284 deletions(-)
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index 9715ab0..24d9720 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -469,6 +469,8 @@ The ShellUserGroupProvider has the following properties:
| Property Name | Description
|`Initial Refresh Delay` | Duration of initial delay before first user and group refresh. (i.e. `10 secs`). Default is `5 mins`.
|`Refresh Delay` | Duration of delay between each user and group refresh. (i.e. `10 secs`). Default is `5 mins`.
+|`Exclude Groups` | Regular expression used to exclude groups. Default is '', which means no groups are excluded.
+|`Exclude Users` | Regular expression used to exclude users. Default is '', which means no users are excluded.
|==================================================================================================================================================
Like LdapUserGroupProvider, the ShellUserGroupProvider is commented out in the _authorizers.xml_ file. Refer to that comment for usage examples.
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml
index 3ee04b9..52f9bb6 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-resources/src/main/resources/conf/authorizers.xml
@@ -175,15 +175,17 @@
on systems that support `sh`. Implementations available for Linux and Mac OS, and are selected by the
provider based on the system property `os.name`.
- 'Initial Refresh Delay' - duration to wait before first refresh. Default is '5 mins'.
'Refresh Delay' - duration to wait between subsequent refreshes. Default is '5 mins'.
+ 'Exclude Groups' - regular expression used to exclude groups. Default is '', which means no groups are excluded.
+ 'Exclude Users' - regular expression used to exclude users. Default is '', which means no users are excluded.
-->
<!-- To enable the shell-user-group-provider remove 2 lines. This is 1 of 2.
<userGroupProvider>
<identifier>shell-user-group-provider</identifier>
<class>org.apache.nifi.authorization.ShellUserGroupProvider</class>
- <property name="Initial Refresh Delay">5 mins</property>
<property name="Refresh Delay">5 mins</property>
+ <property name="Exclude Groups"></property>
+ <property name="Exclude Users"></property>
</userGroupProvider>
To enable the shell-user-group-provider remove 2 lines. This is 2 of 2. -->
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-shell-authorizer/src/main/java/org/apache/nifi/authorization/ShellUserGroupProvider.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-shell-authorizer/src/main/java/org/apache/nifi/authorization/ShellUserGroupProvider.java
index e499b6e..d48255e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-shell-authorizer/src/main/java/org/apache/nifi/authorization/ShellUserGroupProvider.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-shell-authorizer/src/main/java/org/apache/nifi/authorization/ShellUserGroupProvider.java
@@ -16,6 +16,15 @@
*/
package org.apache.nifi.authorization;
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+import org.apache.nifi.authorization.util.ShellRunner;
+import org.apache.nifi.components.PropertyValue;
+import org.apache.nifi.util.FormatUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
@@ -26,21 +35,14 @@ import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-import org.apache.nifi.authorization.exception.AuthorizationAccessException;
-import org.apache.nifi.authorization.exception.AuthorizerCreationException;
-import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
-import org.apache.nifi.authorization.util.ShellRunner;
-import org.apache.nifi.components.PropertyValue;
-import org.apache.nifi.util.FormatUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
/*
* ShellUserGroupProvider implements UserGroupProvider by way of shell commands.
*/
public class ShellUserGroupProvider implements UserGroupProvider {
-
private final static Logger logger = LoggerFactory.getLogger(ShellUserGroupProvider.class);
private final static String OS_TYPE_ERROR = "Unsupported operating system.";
@@ -49,12 +51,15 @@ public class ShellUserGroupProvider implements UserGroupProvider {
private final static Map<String, User> usersByName = new HashMap<>(); // name == identity
private final static Map<String, Group> groupsById = new HashMap<>();
- public static final String INITIAL_REFRESH_DELAY_PROPERTY = "Initial Refresh Delay";
public static final String REFRESH_DELAY_PROPERTY = "Refresh Delay";
-
private static final long MINIMUM_SYNC_INTERVAL_MILLISECONDS = 10_000;
- private long initialDelay;
+
+ public static final String EXCLUDE_USER_PROPERTY = "Exclude Users";
+ public static final String EXCLUDE_GROUP_PROPERTY = "Exclude Groups";
+
private long fixedDelay;
+ private Pattern excludeUsers;
+ private Pattern excludeGroups;
// Our scheduler has one thread for users, one for groups:
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
@@ -99,11 +104,6 @@ public class ShellUserGroupProvider implements UserGroupProvider {
}
if (user == null) {
- refreshOneUser(selectedShellCommands.getUserById(identifier), "Get Single User by Id");
- user = usersById.get(identifier);
- }
-
- if (user == null) {
logger.debug("getUser (by id) user not found: " + identifier);
} else {
logger.debug("getUser (by id) found user: " + user + " for id: " + identifier);
@@ -235,7 +235,6 @@ public class ShellUserGroupProvider implements UserGroupProvider {
*/
@Override
public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
- initialDelay = getDelayProperty(configurationContext, INITIAL_REFRESH_DELAY_PROPERTY, "5 mins");
fixedDelay = getDelayProperty(configurationContext, REFRESH_DELAY_PROPERTY, "5 mins");
// Our next init step is to select the command set based on the operating system name:
@@ -255,11 +254,26 @@ public class ShellUserGroupProvider implements UserGroupProvider {
throw new AuthorizerCreationException(SYS_CHECK_ERROR, ioexc.getCause());
}
+ // The next step is to add the user and group exclude regexes:
+ try {
+ excludeGroups = Pattern.compile(getProperty(configurationContext, EXCLUDE_GROUP_PROPERTY, ""));
+ excludeUsers = Pattern.compile(getProperty(configurationContext, EXCLUDE_USER_PROPERTY, ""));
+ } catch (final PatternSyntaxException e) {
+ throw new AuthorizerCreationException(e);
+ }
+
// With our command set selected, and our system check passed, we can pull in the users and groups:
refreshUsersAndGroups();
// And finally, our last init step is to fire off the refresh thread:
- scheduler.scheduleWithFixedDelay(this::refreshUsersAndGroups, initialDelay, fixedDelay, TimeUnit.SECONDS);
+ scheduler.scheduleWithFixedDelay(() -> {
+ try {
+ refreshUsersAndGroups();
+ }catch (final Throwable t) {
+ logger.error("", t);
+ }
+ }, fixedDelay, fixedDelay, TimeUnit.SECONDS);
+
}
private static ShellCommandsProvider getCommandsProviderFromName(String osName) {
@@ -280,6 +294,19 @@ public class ShellUserGroupProvider implements UserGroupProvider {
return commands;
}
+ private String getProperty(AuthorizerConfigurationContext authContext, String propertyName, String defaultValue) {
+ final PropertyValue property = authContext.getProperty(propertyName);
+ final String value;
+
+ if (property != null && property.isSet()) {
+ value = property.getValue();
+ } else {
+ value = defaultValue;
+ }
+ return value;
+
+ }
+
private long getDelayProperty(AuthorizerConfigurationContext authContext, String propertyName, String defaultValue) {
final PropertyValue intervalProperty = authContext.getProperty(propertyName);
final String propertyValue;
@@ -445,20 +472,21 @@ public class ShellUserGroupProvider implements UserGroupProvider {
if (record.length > 2) {
String name = record[0], id = record[1], gid = record[2];
- if (name != null && id != null && !name.equals("") && !id.equals("")) {
-
- User user = new User.Builder().identity(name).identifier(id).build();
- idToUser.put(id, user);
+ if (name != null && id != null && !name.equals("") && !id.equals("") && !excludeUsers.matcher(name).matches()) {
+ User user = new User.Builder().identity(name).identifierGenerateFromSeed(id).build();
+ idToUser.put(user.getIdentifier(), user);
usernameToUser.put(name, user);
if (gid != null && !gid.equals("")) {
- gidToUser.put(gid, user);
+ // create a temporary group to deterministically generate the group id and associate this user
+ Group group = new Group.Builder().name(gid).identifierGenerateFromSeed(gid).build();
+ gidToUser.put(group.getIdentifier(), user);
} else {
logger.warn("Null or empty primary group id for: " + name);
}
} else {
- logger.warn("Null or empty user name: " + name + " or id: " + id);
+ logger.warn("Null, empty, or skipped user name: " + name + " or id: " + id);
}
} else {
logger.warn("Unexpected record format. Expected 3 or more colon separated values per line.");
@@ -499,12 +527,12 @@ public class ShellUserGroupProvider implements UserGroupProvider {
logger.error("list membership shell exception: " + ioexc);
}
- if (name != null && id != null && !name.equals("") && !id.equals("")) {
- Group group = new Group.Builder().name(name).identifier(id).addUsers(users).build();
- groupsById.put(id, group);
+ if (name != null && id != null && !name.equals("") && !id.equals("") && !excludeGroups.matcher(name).matches()) {
+ Group group = new Group.Builder().name(name).identifierGenerateFromSeed(id).addUsers(users).build();
+ groupsById.put(group.getIdentifier(), group);
logger.debug("Refreshed group: " + group);
} else {
- logger.warn("Null or empty group name: " + name + " or id: " + id);
+ logger.warn("Null, empty, or skipped group name: " + name + " or id: " + id);
}
} else {
logger.warn("Unexpected record format. Expected 1 or more comma separated values.");
@@ -525,27 +553,19 @@ public class ShellUserGroupProvider implements UserGroupProvider {
if (primaryGroup == null) {
logger.warn("user: " + primaryUser + " primary group not found");
- } else {
+ } else if (!excludeGroups.matcher(primaryGroup.getName()).matches()) {
Set<String> groupUsers = primaryGroup.getUsers();
if (!groupUsers.contains(primaryUser.getIdentity())) {
Set<String> secondSet = new HashSet<>(groupUsers);
secondSet.add(primaryUser.getIdentity());
- Group group = new Group.Builder().name(primaryGroup.getName()).identifier(primaryGid).addUsers(secondSet).build();
- gidToGroup.put(primaryGid, group);
+ Group group = new Group.Builder().name(primaryGroup.getName()).identifierGenerateFromSeed(primaryGid).addUsers(secondSet).build();
+ gidToGroup.put(group.getIdentifier(), group);
}
}
});
}
/**
- * @return The initial refresh delay.
- */
- public long getInitialRefreshDelay() {
- return initialDelay;
- }
-
-
- /**
* @return The fixed refresh delay.
*/
public long getRefreshDelay() {
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-shell-authorizer/src/test/java/org/apache/nifi/authorization/ShellUserGroupProviderBase.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-shell-authorizer/src/test/java/org/apache/nifi/authorization/ShellUserGroupProviderBase.java
deleted file mode 100644
index fa760b2..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-shell-authorizer/src/test/java/org/apache/nifi/authorization/ShellUserGroupProviderBase.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * 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.nifi.authorization;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
-
-import java.util.Set;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-abstract class ShellUserGroupProviderBase {
- private static final Logger logger = LoggerFactory.getLogger(ShellUserGroupProviderBase.class);
-
- private final String KNOWN_USER = "root";
- private final String KNOWN_UID = "0";
-
- @SuppressWarnings("FieldCanBeLocal")
- private final String KNOWN_GROUP = "root";
-
- @SuppressWarnings("FieldCanBeLocal")
- private final String OTHER_GROUP = "wheel"; // e.g., macos
- private final String KNOWN_GID = "0";
-
- // We're using this knob to control the test runs on Travis. The issue there is that tests
- // running on Travis do not have `getent`, thus not behaving like a typical Linux installation.
- protected static boolean systemCheckFailed = false;
-
- /**
- * Ensures that the test can run because Docker is available and the remote instance can be reached via ssh.
- *
- * @return true if Docker is available on this OS
- */
- protected boolean isSSHAvailable() {
- return !systemCheckFailed;
- }
-
-
- /**
- * Tests the provider behavior by getting its users and checking minimum size.
- *
- * @param provider {@link UserGroupProvider}
- */
- void testGetUsersAndUsersMinimumCount(UserGroupProvider provider) {
- assumeTrue(isSSHAvailable());
-
- Set<User> users = provider.getUsers();
- assertNotNull(users);
- assertTrue(users.size() > 0);
- }
-
-
- /**
- * Tests the provider behavior by getting a known user by uid.
- *
- * @param provider {@link UserGroupProvider}
- */
- void testGetKnownUserByUsername(UserGroupProvider provider) {
- // assumeTrue(isSSHAvailable());
-
- User root = provider.getUser(KNOWN_UID);
- assertNotNull(root);
- assertEquals(KNOWN_USER, root.getIdentity());
- assertEquals(KNOWN_UID, root.getIdentifier());
- }
-
- /**
- * Tests the provider behavior by getting a known user by id.
- *
- * @param provider {@link UserGroupProvider}
- */
- void testGetKnownUserByUid(UserGroupProvider provider) {
- assumeTrue(isSSHAvailable());
-
- User root = provider.getUserByIdentity(KNOWN_USER);
- assertNotNull(root);
- assertEquals(KNOWN_USER, root.getIdentity());
- assertEquals(KNOWN_UID, root.getIdentifier());
- }
-
- /**
- * Tests the provider behavior by getting its groups and checking minimum size.
- *
- * @param provider {@link UserGroupProvider}
- */
- void testGetGroupsAndMinimumGroupCount(UserGroupProvider provider) {
- assumeTrue(isSSHAvailable());
-
- Set<Group> groups = provider.getGroups();
- assertNotNull(groups);
- assertTrue(groups.size() > 0);
- }
-
- /**
- * Tests the provider behavior by getting a known group by GID.
- *
- * @param provider {@link UserGroupProvider}
- */
- void testGetKnownGroupByGid(UserGroupProvider provider) {
- assumeTrue(isSSHAvailable());
-
- Group group = provider.getGroup(KNOWN_GID);
- assertNotNull(group);
- assertTrue(group.getName().equals(KNOWN_GROUP) || group.getName().equals(OTHER_GROUP));
- assertEquals(KNOWN_GID, group.getIdentifier());
- }
-
- /**
- * Tests the provider behavior by getting a known group and checking for a known member of it.
- *
- * @param provider {@link UserGroupProvider}
- */
- void testGetGroupByGidAndGetGroupMembership(UserGroupProvider provider) {
- assumeTrue(isSSHAvailable());
-
- Group group = provider.getGroup(KNOWN_GID);
- assertNotNull(group);
-
- // These next few try/catch blocks are here for debugging. The user-to-group relationship
- // is delicate with this implementation, and this approach allows us a measure of control.
- // Check your logs if you're having problems!
-
- try {
- assertTrue(group.getUsers().size() > 0);
- logger.info("root group count: " + group.getUsers().size());
- } catch (final AssertionError ignored) {
- logger.info("root group count zero on this system");
- }
-
- try {
- assertTrue(group.getUsers().contains(KNOWN_USER));
- logger.info("root group membership: " + group.getUsers());
- } catch (final AssertionError ignored) {
- logger.info("root group membership unexpected on this system");
- }
- }
-
- /**
- * Tests the provider behavior by getting a known user and checking its group membership.
- *
- * @param provider {@link UserGroupProvider}
- */
- void testGetUserByIdentityAndGetGroupMembership(UserGroupProvider provider) {
- assumeTrue(isSSHAvailable());
-
- UserAndGroups user = provider.getUserAndGroups(KNOWN_USER);
- assertNotNull(user);
-
- try {
- assertTrue(user.getGroups().size() > 0);
- logger.info("root user group count: " + user.getGroups().size());
- } catch (final AssertionError ignored) {
- logger.info("root user and groups group count zero on this system");
- }
-
- Set<Group> groups = provider.getGroups();
- assertTrue(groups.size() > user.getGroups().size());
- }
-}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-shell-authorizer/src/test/java/org/apache/nifi/authorization/ShellUserGroupProviderIT.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-shell-authorizer/src/test/java/org/apache/nifi/authorization/ShellUserGroupProviderIT.java
index 1525ae5..65bb884 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-shell-authorizer/src/test/java/org/apache/nifi/authorization/ShellUserGroupProviderIT.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-shell-authorizer/src/test/java/org/apache/nifi/authorization/ShellUserGroupProviderIT.java
@@ -20,6 +20,8 @@ import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
+
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.util.ShellRunner;
import org.apache.nifi.util.MockPropertyValue;
@@ -29,6 +31,7 @@ import org.junit.Assume;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -40,7 +43,7 @@ import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.MountableFile;
-public class ShellUserGroupProviderIT extends ShellUserGroupProviderBase {
+public class ShellUserGroupProviderIT {
private static final Logger logger = LoggerFactory.getLogger(ShellUserGroupProviderIT.class);
// These images are publicly available on the hub.docker.com, and the source to each
@@ -61,10 +64,24 @@ public class ShellUserGroupProviderIT extends ShellUserGroupProviderBase {
private final static String CONTAINER_SSH_AUTH_KEYS = "/root/.ssh/authorized_keys";
private final static Integer CONTAINER_SSH_PORT = 22;
+ private final String KNOWN_USER = "root";
+ private final String KNOWN_UID = "0";
+
+ @SuppressWarnings("FieldCanBeLocal")
+ private final String KNOWN_GROUP = "root";
+
+ @SuppressWarnings("FieldCanBeLocal")
+ private final String OTHER_GROUP = "wheel"; // e.g., macos
+ private final String KNOWN_GID = "0";
+
+ // We're using this knob to control the test runs on Travis. The issue there is that tests
+ // running on Travis do not have `getent`, thus not behaving like a typical Linux installation.
+ protected static boolean systemCheckFailed = false;
+
private static String sshPrivKeyFile;
private static String sshPubKeyFile;
- private AuthorizerConfigurationContext authContext;
+ private AuthorizerConfigurationContext authContext = Mockito.mock(AuthorizerConfigurationContext.class);
private ShellUserGroupProvider localProvider;
private UserGroupProviderInitializationContext initContext;
@@ -103,8 +120,9 @@ public class ShellUserGroupProviderIT extends ShellUserGroupProviderBase {
authContext = Mockito.mock(AuthorizerConfigurationContext.class);
initContext = Mockito.mock(UserGroupProviderInitializationContext.class);
- Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.INITIAL_REFRESH_DELAY_PROPERTY))).thenReturn(new MockPropertyValue("10 sec"));
- Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.REFRESH_DELAY_PROPERTY))).thenReturn(new MockPropertyValue("15 sec"));
+ Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.REFRESH_DELAY_PROPERTY))).thenReturn(new MockPropertyValue("10 sec"));
+ Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.EXCLUDE_GROUP_PROPERTY))).thenReturn(new MockPropertyValue(".*d$"));
+ Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.EXCLUDE_USER_PROPERTY))).thenReturn(new MockPropertyValue("^s.*"));
localProvider = new ShellUserGroupProvider();
try {
@@ -115,8 +133,7 @@ public class ShellUserGroupProviderIT extends ShellUserGroupProviderBase {
logger.error("setup() exception: " + exc + "; tests cannot run on this system.");
return;
}
- Assert.assertEquals(10000, localProvider.getInitialRefreshDelay());
- Assert.assertEquals(15000, localProvider.getRefreshDelay());
+ Assert.assertEquals(10000, localProvider.getRefreshDelay());
}
@After
@@ -124,45 +141,6 @@ public class ShellUserGroupProviderIT extends ShellUserGroupProviderBase {
localProvider.preDestruction();
}
- // Our primary test methods all accept a provider; here we define overloads to those methods to
- // use the local provider. This allows the reuse of those test methods with the remote provider.
-
- @Test
- public void testGetUsersAndUsersMinimumCount() {
- testGetUsersAndUsersMinimumCount(localProvider);
- }
-
- @Test
- public void testGetKnownUserByUsername() {
- testGetKnownUserByUsername(localProvider);
- }
-
- @Test
- public void testGetKnownUserByUid() {
- testGetKnownUserByUid(localProvider);
- }
-
- @Test
- public void testGetGroupsAndMinimumGroupCount() {
- testGetGroupsAndMinimumGroupCount(localProvider);
- }
-
- @Test
- public void testGetKnownGroupByGid() {
- testGetKnownGroupByGid(localProvider);
- }
-
- @Test
- public void testGetGroupByGidAndGetGroupMembership() {
- testGetGroupByGidAndGetGroupMembership(localProvider);
- }
-
- @Test
- public void testGetUserByIdentityAndGetGroupMembership() {
- testGetUserByIdentityAndGetGroupMembership(localProvider);
- }
-
- @SuppressWarnings("RedundantThrows")
private GenericContainer createContainer(String image) throws IOException, InterruptedException {
GenericContainer container = new GenericContainer(image)
.withEnv("SSH_ENABLE_ROOT", "true").withExposedPorts(CONTAINER_SSH_PORT);
@@ -192,22 +170,59 @@ public class ShellUserGroupProviderIT extends ShellUserGroupProviderBase {
public void testTooShortDelayIntervalThrowsException() throws AuthorizerCreationException {
final AuthorizerConfigurationContext authContext = Mockito.mock(AuthorizerConfigurationContext.class);
final ShellUserGroupProvider localProvider = new ShellUserGroupProvider();
- Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.INITIAL_REFRESH_DELAY_PROPERTY))).thenReturn(new MockPropertyValue("1 milliseconds"));
+ Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.REFRESH_DELAY_PROPERTY))).thenReturn(new MockPropertyValue("1 milliseconds"));
expectedException.expect(AuthorizerCreationException.class);
- expectedException.expectMessage("The Initial Refresh Delay '1 milliseconds' is below the minimum value of '10000 ms'");
+ expectedException.expectMessage("The Refresh Delay '1 milliseconds' is below the minimum value of '10000 ms'");
localProvider.onConfigured(authContext);
}
+
+ @Test
+ public void testInvalidGroupExcludeExpressionsThrowsException() throws AuthorizerCreationException {
+ AuthorizerConfigurationContext authContext = Mockito.mock(AuthorizerConfigurationContext.class);
+ ShellUserGroupProvider localProvider = new ShellUserGroupProvider();
+ Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.REFRESH_DELAY_PROPERTY))).thenReturn(new MockPropertyValue("3 minutes"));
+ Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.EXCLUDE_GROUP_PROPERTY))).thenReturn(new MockPropertyValue("(3"));
+
+ expectedException.expect(AuthorizerCreationException.class);
+ expectedException.expectMessage("Unclosed group near index");
+ localProvider.onConfigured(authContext);
+
+
+ }
+
+ @Test
+ public void testInvalidUserExcludeExpressionsThrowsException() throws AuthorizerCreationException {
+ AuthorizerConfigurationContext authContext = Mockito.mock(AuthorizerConfigurationContext.class);
+ ShellUserGroupProvider localProvider = new ShellUserGroupProvider();
+ Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.REFRESH_DELAY_PROPERTY))).thenReturn(new MockPropertyValue("3 minutes"));
+ Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.EXCLUDE_USER_PROPERTY))).thenReturn(new MockPropertyValue("*"));
+
+ expectedException.expect(AuthorizerCreationException.class);
+ expectedException.expectMessage("Dangling meta character");
+ localProvider.onConfigured(authContext);
+ }
+
+ @Test
+ public void testMissingExcludeExpressionsAllowed() throws AuthorizerCreationException {
+ AuthorizerConfigurationContext authContext = Mockito.mock(AuthorizerConfigurationContext.class);
+ ShellUserGroupProvider localProvider = new ShellUserGroupProvider();
+ Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.REFRESH_DELAY_PROPERTY))).thenReturn(new MockPropertyValue("3 minutes"));
+
+ localProvider.onConfigured(authContext);
+ verifyUsersAndUsersMinimumCount(localProvider);
+ }
+
@Test
public void testInvalidDelayIntervalThrowsException() throws AuthorizerCreationException {
final AuthorizerConfigurationContext authContext = Mockito.mock(AuthorizerConfigurationContext.class);
final ShellUserGroupProvider localProvider = new ShellUserGroupProvider();
- Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.INITIAL_REFRESH_DELAY_PROPERTY))).thenReturn(new MockPropertyValue("Not an interval"));
+ Mockito.when(authContext.getProperty(Mockito.eq(ShellUserGroupProvider.REFRESH_DELAY_PROPERTY))).thenReturn(new MockPropertyValue("Not an interval"));
expectedException.expect(AuthorizerCreationException.class);
- expectedException.expectMessage("The Initial Refresh Delay 'Not an interval' is not a valid time interval.");
+ expectedException.expectMessage("The Refresh Delay 'Not an interval' is not a valid time interval.");
localProvider.onConfigured(authContext);
}
@@ -220,24 +235,27 @@ public class ShellUserGroupProviderIT extends ShellUserGroupProviderBase {
}
@Test
- public void testGetOneUserAfterClearingCaches() {
- // assert known state: empty, testable, not empty
- localProvider.clearCaches();
- testGetKnownUserByUid(localProvider);
- assert localProvider.userCacheSize() > 0;
+ public void testLocalGetUsersAndUsersMinimumCount() {
+ verifyUsersAndUsersMinimumCount(localProvider);
}
@Test
- public void testGetOneGroupAfterClearingCaches() {
- Assume.assumeTrue(isSSHAvailable());
+ public void testLocalGetKnownUserByUsername() {
+ verifyKnownUserByUsername(localProvider);
+ }
- // assert known state: empty, testable, not empty
- localProvider.clearCaches();
- testGetKnownGroupByGid(localProvider);
- assert localProvider.groupCacheSize() > 0;
+ @Test
+ public void testLocalGetGroupsAndMinimumGroupCount() {
+ verifyGroupsAndMinimumGroupCount(localProvider);
}
@Test
+ public void testLocalGetUserByIdentityAndGetGroupMembership() {
+ verifyGetUserByIdentityAndGetGroupMembership(localProvider);
+ }
+
+ // @Ignore // for now
+ @Test
public void testVariousSystemImages() {
// Here we explicitly clear the system check flag to allow the remote checks that follow:
systemCheckFailed = false;
@@ -262,12 +280,10 @@ public class ShellUserGroupProviderIT extends ShellUserGroupProviderBase {
}
try {
- testGetUsersAndUsersMinimumCount(remoteProvider);
- testGetKnownUserByUsername(remoteProvider);
- testGetGroupsAndMinimumGroupCount(remoteProvider);
- testGetKnownGroupByGid(remoteProvider);
- testGetGroupByGidAndGetGroupMembership(remoteProvider);
- testGetUserByIdentityAndGetGroupMembership(remoteProvider);
+ verifyUsersAndUsersMinimumCount(remoteProvider);
+ verifyKnownUserByUsername(remoteProvider);
+ verifyGroupsAndMinimumGroupCount(remoteProvider);
+ verifyGetUserByIdentityAndGetGroupMembership(remoteProvider);
} catch (final Exception e) {
// Some environments don't allow our tests to work.
logger.error("Exception running remote provider on image: " + image + ", exception: " + e);
@@ -280,4 +296,90 @@ public class ShellUserGroupProviderIT extends ShellUserGroupProviderBase {
}
// TODO: Make test which retrieves list of users and then getUserByIdentity to ensure the user is populated in the response
+
+
+
+ /**
+ * Ensures that the test can run because Docker is available and the remote instance can be reached via ssh.
+ *
+ * @return true if Docker is available on this OS
+ */
+ private boolean isSSHAvailable() {
+ return !systemCheckFailed;
+ }
+
+ /**
+ * Tests the provider behavior by getting its users and checking minimum size.
+ *
+ * @param provider {@link UserGroupProvider}
+ */
+ private void verifyUsersAndUsersMinimumCount(UserGroupProvider provider) {
+ Assume.assumeTrue(isSSHAvailable());
+
+ Set<User> users = provider.getUsers();
+
+ // This shows that we don't have any users matching the exclude regex, which is likely because those users
+ // exist but were excluded:
+ for (User user : users) {
+ Assert.assertFalse(user.getIdentifier().startsWith("s"));
+ }
+
+ Assert.assertNotNull(users);
+ Assert.assertTrue(users.size() > 0);
+ }
+
+ /**
+ * Tests the provider behavior by getting a known user by id.
+ *
+ * @param provider {@link UserGroupProvider}
+ */
+ private void verifyKnownUserByUsername(UserGroupProvider provider) {
+ Assume.assumeTrue(isSSHAvailable());
+
+ User root = provider.getUserByIdentity(KNOWN_USER);
+ Assert.assertNotNull(root);
+ Assert.assertEquals(KNOWN_USER, root.getIdentity());
+ }
+
+ /**
+ * Tests the provider behavior by getting its groups and checking minimum size.
+ *
+ * @param provider {@link UserGroupProvider}
+ */
+ private void verifyGroupsAndMinimumGroupCount(UserGroupProvider provider) {
+ Assume.assumeTrue(isSSHAvailable());
+
+ Set<Group> groups = provider.getGroups();
+
+ // This shows that we don't have any groups matching the exclude regex, which is likely because those groups
+ // exist but were excluded:
+ for (Group group : groups) {
+ Assert.assertFalse(group.getName().endsWith("d"));
+ }
+
+ Assert.assertNotNull(groups);
+ Assert.assertTrue(groups.size() > 0);
+ }
+
+ /**
+ * Tests the provider behavior by getting a known user and checking its group membership.
+ *
+ * @param provider {@link UserGroupProvider}
+ */
+ private void verifyGetUserByIdentityAndGetGroupMembership(UserGroupProvider provider) {
+ Assume.assumeTrue(isSSHAvailable());
+
+ UserAndGroups user = provider.getUserAndGroups(KNOWN_USER);
+ Assert.assertNotNull(user);
+
+ try {
+ Assert.assertTrue(user.getGroups().size() > 0);
+ logger.info("root user group count: " + user.getGroups().size());
+ } catch (final AssertionError ignored) {
+ logger.info("root user and groups group count zero on this system");
+ }
+
+ Set<Group> groups = provider.getGroups();
+ Assert.assertTrue(groups.size() > user.getGroups().size());
+ }
}