blob: 9f09ee4c8333d7b3bf0d09f4572d424d6c565a91 [file] [log] [blame]
/*
* 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.storm.security.auth;
import java.io.File;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import org.apache.storm.Config;
import org.apache.storm.shade.org.apache.commons.codec.binary.Hex;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;
public class ClientAuthUtilsTest {
// JUnit ensures that the temporary folder is removed after
// the test finishes
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Test(expected = IOException.class)
public void getOptionsThrowsOnMissingSectionTest() throws IOException {
Configuration mockConfig = Mockito.mock(Configuration.class);
ClientAuthUtils.get(mockConfig, "bogus-section", "");
}
@Test
public void getNonExistentSectionTest() throws IOException {
Map<String, String> optionMap = new HashMap<String, String>();
AppConfigurationEntry entry = Mockito.mock(AppConfigurationEntry.class);
Mockito.<Map<String, ?>>when(entry.getOptions()).thenReturn(optionMap);
String section = "bogus-section";
Configuration mockConfig = Mockito.mock(Configuration.class);
Mockito.when(mockConfig.getAppConfigurationEntry(section))
.thenReturn(new AppConfigurationEntry[]{ entry });
Assert.assertNull(
ClientAuthUtils.get(mockConfig, section, "nonexistent-key"));
}
@Test
public void getFirstValueForValidKeyTest() throws IOException {
String k = "the-key";
String expected = "good-value";
Map<String, String> optionMap = new HashMap<String, String>();
optionMap.put(k, expected);
Map<String, String> badOptionMap = new HashMap<String, String>();
badOptionMap.put(k, "bad-value");
AppConfigurationEntry emptyEntry = Mockito.mock(AppConfigurationEntry.class);
AppConfigurationEntry badEntry = Mockito.mock(AppConfigurationEntry.class);
AppConfigurationEntry goodEntry = Mockito.mock(AppConfigurationEntry.class);
Mockito.<Map<String, ?>>when(emptyEntry.getOptions()).thenReturn(new HashMap<String, String>());
Mockito.<Map<String, ?>>when(badEntry.getOptions()).thenReturn(badOptionMap);
Mockito.<Map<String, ?>>when(goodEntry.getOptions()).thenReturn(optionMap);
String section = "bogus-section";
Configuration mockConfig = Mockito.mock(Configuration.class);
Mockito.when(mockConfig.getAppConfigurationEntry(section))
.thenReturn(new AppConfigurationEntry[]{ emptyEntry, goodEntry, badEntry });
Assert.assertEquals(
ClientAuthUtils.get(mockConfig, section, k), expected);
}
@Test
public void objGettersReturnNullWithNullConfigTest() throws IOException {
Assert.assertNull(ClientAuthUtils.pullConfig(null, "foo"));
Assert.assertNull(ClientAuthUtils.get(null, "foo", "bar"));
Assert.assertNull(ClientAuthUtils.getConfiguration(Collections.emptyMap()));
}
@Test
public void getAutoCredentialsTest() {
Map<String, Object> map = new HashMap<>();
map.put(Config.TOPOLOGY_AUTO_CREDENTIALS,
Arrays.asList(new String[]{ "org.apache.storm.security.auth.AuthUtilsTestMock" }));
Assert.assertTrue(ClientAuthUtils.getAutoCredentials(Collections.emptyMap()).isEmpty());
Assert.assertEquals(ClientAuthUtils.getAutoCredentials(map).size(), 1);
}
@Test
public void getNimbusAutoCredPluginTest() {
Map<String, Object> map = new HashMap<>();
map.put(Config.NIMBUS_AUTO_CRED_PLUGINS,
Arrays.asList(new String[]{ "org.apache.storm.security.auth.AuthUtilsTestMock" }));
Assert.assertTrue(ClientAuthUtils.getNimbusAutoCredPlugins(Collections.emptyMap()).isEmpty());
Assert.assertEquals(ClientAuthUtils.getNimbusAutoCredPlugins(map).size(), 1);
}
@Test
public void GetCredentialRenewersTest() {
Map<String, Object> map = new HashMap<>();
map.put(Config.NIMBUS_CREDENTIAL_RENEWERS,
Arrays.asList(new String[]{ "org.apache.storm.security.auth.AuthUtilsTestMock" }));
Assert.assertTrue(ClientAuthUtils.getCredentialRenewers(Collections.emptyMap()).isEmpty());
Assert.assertEquals(ClientAuthUtils.getCredentialRenewers(map).size(), 1);
}
@Test
public void populateSubjectTest() {
AuthUtilsTestMock autoCred = Mockito.mock(AuthUtilsTestMock.class);
Subject subject = new Subject();
Map<String, String> cred = new HashMap<String, String>();
Collection<IAutoCredentials> autos = Arrays.asList(new IAutoCredentials[]{ autoCred });
ClientAuthUtils.populateSubject(subject, autos, cred);
Mockito.verify(autoCred, Mockito.times(1)).populateSubject(subject, cred);
}
@Test
public void makeDigestPayloadTest() throws NoSuchAlgorithmException {
String section = "user-pass-section";
Map<String, String> optionMap = new HashMap<String, String>();
String user = "user";
String pass = "pass";
optionMap.put("username", user);
optionMap.put("password", pass);
AppConfigurationEntry entry = Mockito.mock(AppConfigurationEntry.class);
Mockito.<Map<String, ?>>when(entry.getOptions()).thenReturn(optionMap);
Configuration mockConfig = Mockito.mock(Configuration.class);
Mockito.when(mockConfig.getAppConfigurationEntry(section))
.thenReturn(new AppConfigurationEntry[]{ entry });
MessageDigest digest = MessageDigest.getInstance("SHA-512");
byte[] output = digest.digest((user + ":" + pass).getBytes());
String sha = Hex.encodeHexString(output);
// previous code used this method to generate the string, ensure the two match
StringBuilder builder = new StringBuilder();
for (byte b : output) {
builder.append(String.format("%02x", b));
}
String stringFormatMethod = builder.toString();
Assert.assertEquals(
ClientAuthUtils.makeDigestPayload(mockConfig, "user-pass-section"),
sha);
Assert.assertEquals(sha, stringFormatMethod);
}
@Test(expected = RuntimeException.class)
public void invalidConfigResultsInIOException() throws RuntimeException {
HashMap<String, Object> conf = new HashMap<>();
conf.put("java.security.auth.login.config", "__FAKE_FILE__");
Assert.assertNotNull(ClientAuthUtils.getConfiguration(conf));
}
@Test
public void validConfigResultsInNotNullConfigurationTest() throws IOException {
File file1 = folder.newFile("mockfile.txt");
HashMap<String, Object> conf = new HashMap<>();
conf.put("java.security.auth.login.config", file1.getAbsolutePath());
Assert.assertNotNull(ClientAuthUtils.getConfiguration(conf));
}
@Test(expected = RuntimeException.class)
public void updateSubjectWithNullThrowsTest() {
ClientAuthUtils.updateSubject(null, null, null);
}
@Test(expected = RuntimeException.class)
public void updateSubjectWithNullAutosThrowsTest() {
ClientAuthUtils.updateSubject(new Subject(), null, null);
}
@Test
public void updateSubjectWithNullAutosTest() {
AuthUtilsTestMock mock = Mockito.mock(AuthUtilsTestMock.class);
Collection<IAutoCredentials> autos = Arrays.asList(new IAutoCredentials[]{ mock });
Subject s = new Subject();
ClientAuthUtils.updateSubject(s, autos, null);
Mockito.verify(mock, Mockito.times(1)).updateSubject(s, null);
}
@Test
public void pluginCreationTest() {
Map<String, Object> conf = new HashMap<>();
conf.put(
Config.STORM_PRINCIPAL_TO_LOCAL_PLUGIN, AuthUtilsTestMock.class.getName());
conf.put(
Config.STORM_GROUP_MAPPING_SERVICE_PROVIDER_PLUGIN, AuthUtilsTestMock.class.getName());
Assert.assertTrue(
ClientAuthUtils.getPrincipalToLocalPlugin(conf).getClass() == AuthUtilsTestMock.class);
Assert.assertTrue(
ClientAuthUtils.getGroupMappingServiceProviderPlugin(conf).getClass() == AuthUtilsTestMock.class);
}
}