Author: angela
Date: Thu Apr 11 16:40:58 2019
New Revision: 1857352
URL: http://svn.apache.org/viewvc?rev=1857352&view=rev
Log:
OAK-8229 : LoginModuleImpl.commit will end in NPE if credentials are null
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImpl.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImplTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImpl.java?rev=1857352&r1=1857351&r2=1857352&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImpl.java
Thu Apr 11 16:40:58 2019
@@ -167,7 +167,9 @@ public final class LoginModuleImpl exten
} else if (userId != null) {
principals.addAll(getPrincipals(userId));
}
- subject.getPublicCredentials().add(credentials);
+ if (credentials != null) {
+ subject.getPublicCredentials().add(credentials);
+ }
setAuthInfo(createAuthInfo(principals), subject);
} else {
log.debug("Could not add information to read only subject {}",
subject);
@@ -229,6 +231,7 @@ public final class LoginModuleImpl exten
return uid;
}
+ @Nullable
private String getAnonymousId() {
SecurityProvider sp = getSecurityProvider();
if (sp == null) {
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImplTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImplTest.java?rev=1857352&r1=1857351&r2=1857352&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImplTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authentication/user/LoginModuleImplTest.java
Thu Apr 11 16:40:58 2019
@@ -16,20 +16,6 @@
*/
package org.apache.jackrabbit.oak.security.authentication.user;
-import java.io.IOException;
-import java.security.Principal;
-import java.util.Arrays;
-import javax.jcr.Credentials;
-import javax.jcr.GuestCredentials;
-import javax.jcr.RepositoryException;
-import javax.jcr.SimpleCredentials;
-import javax.security.auth.Subject;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.auth.login.Configuration;
-import javax.security.auth.login.LoginException;
-
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -44,9 +30,11 @@ import org.apache.jackrabbit.oak.api.Roo
import org.apache.jackrabbit.oak.security.internal.SecurityProviderBuilder;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authentication.AuthInfoImpl;
import org.apache.jackrabbit.oak.spi.security.authentication.Authentication;
import org.apache.jackrabbit.oak.spi.security.authentication.ConfigurationUtil;
import
org.apache.jackrabbit.oak.spi.security.authentication.ImpersonationCredentials;
+import
org.apache.jackrabbit.oak.spi.security.authentication.PreAuthenticatedLogin;
import
org.apache.jackrabbit.oak.spi.security.authentication.callback.RepositoryCallback;
import org.apache.jackrabbit.oak.spi.security.user.UserAuthenticationFactory;
import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
@@ -55,13 +43,33 @@ import org.apache.jackrabbit.oak.spi.sec
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;
-import org.mockito.Mockito;
+import javax.jcr.Credentials;
+import javax.jcr.GuestCredentials;
+import javax.jcr.RepositoryException;
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginException;
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+import static
org.apache.jackrabbit.oak.spi.security.authentication.AbstractLoginModule.SHARED_KEY_PRE_AUTH_LOGIN;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class LoginModuleImplTest extends AbstractSecurityTest {
@@ -83,27 +91,18 @@ public class LoginModuleImplTest extends
return
ConfigurationUtil.getDefaultConfiguration(ConfigurationParameters.EMPTY);
}
- private User createTestUser() throws RepositoryException,
CommitFailedException {
+ private void createTestUser() throws RepositoryException,
CommitFailedException {
if (user == null) {
UserManager userManager = getUserManager(root);
user = userManager.createUser(USER_ID, USER_PW);
root.commit();
}
- return user;
}
- @Test
+ @Test(expected = LoginException.class)
public void testNullLogin() throws Exception {
- ContentSession cs = null;
- try {
- cs = login(null);
+ try (ContentSession cs = login(null)) {
fail("Null login should fail");
- } catch (LoginException e) {
- // success
- } finally {
- if (cs != null) {
- cs.close();
- }
}
}
@@ -116,7 +115,7 @@ public class LoginModuleImplTest extends
}
}
- @Test
+ @Test(expected = LoginException.class)
public void testAnonymousLogin() throws Exception {
String anonymousID =
UserUtil.getAnonymousId(getUserConfiguration().getParameters());
@@ -127,268 +126,353 @@ public class LoginModuleImplTest extends
assertNotNull(anonymous);
assertFalse(root.getTree(anonymous.getPath()).hasProperty(UserConstants.REP_PASSWORD));
- ContentSession cs = null;
- try {
- cs = login(new SimpleCredentials(anonymousID, new char[0]));
+ try (ContentSession cs = login(new SimpleCredentials(anonymousID, new
char[0]))) {
fail("Login with anonymousID should fail since the initial setup
doesn't provide a password.");
- } catch (LoginException e) {
- // success
- } finally {
- if (cs != null) {
- cs.close();
- }
}
}
@Test
public void testUserLogin() throws Exception {
- ContentSession cs = null;
- try {
- createTestUser();
-
- cs = login(new SimpleCredentials(USER_ID, USER_PW.toCharArray()));
+ createTestUser();
+ try (ContentSession cs = login(new SimpleCredentials(USER_ID,
USER_PW.toCharArray()))) {
AuthInfo authInfo = cs.getAuthInfo();
assertEquals(USER_ID, authInfo.getUserID());
- } finally {
- if (cs != null) {
- cs.close();
- }
}
}
@Test
public void testAuthInfoContainsUserId() throws Exception {
- ContentSession cs = null;
- try {
- createTestUser();
-
- cs = login(new SimpleCredentials(USER_ID_CASED,
USER_PW.toCharArray()));
+ createTestUser();
+ try (ContentSession cs = login(new SimpleCredentials(USER_ID_CASED,
USER_PW.toCharArray()))) {
AuthInfo authInfo = cs.getAuthInfo();
assertEquals(user.getID(), authInfo.getUserID());
- } finally {
- if (cs != null) {
- cs.close();
- }
}
}
@Test
public void testUserLoginIsCaseInsensitive() throws Exception {
- ContentSession cs = null;
- try {
- createTestUser();
-
- cs = login(new SimpleCredentials(USER_ID_CASED,
USER_PW.toCharArray()));
+ createTestUser();
+ try (ContentSession cs = login(new SimpleCredentials(USER_ID_CASED,
USER_PW.toCharArray()))) {
AuthInfo authInfo = cs.getAuthInfo();
UserManager userMgr = getUserManager(root);
Authorizable auth = userMgr.getAuthorizable(authInfo.getUserID());
assertNotNull(auth);
assertTrue(auth.getID().equalsIgnoreCase(USER_ID_CASED));
- } finally {
- if (cs != null) {
- cs.close();
- }
}
}
@Test
public void testUserLoginIsCaseInsensitive2() throws Exception {
- ContentSession cs = null;
- try {
- createTestUser();
- cs = login(new SimpleCredentials(USER_ID_CASED,
USER_PW.toCharArray()));
+ createTestUser();
+ try (ContentSession cs = login(new SimpleCredentials(USER_ID_CASED,
USER_PW.toCharArray()))) {
AuthInfo authInfo = cs.getAuthInfo();
assertEquals(user.getID(), authInfo.getUserID());
assertTrue(USER_ID_CASED.equalsIgnoreCase(authInfo.getUserID()));
- } finally {
- if (cs != null) {
- cs.close();
- }
}
}
- @Test
+ @Test(expected = LoginException.class)
public void testUnknownUserLogin() throws Exception {
- ContentSession cs = null;
- try {
- cs = login(new SimpleCredentials("unknown", "".toCharArray()));
+ try (ContentSession cs = login(new SimpleCredentials("unknown",
"".toCharArray()))) {
fail("Unknown user must not be able to login");
- } catch (LoginException e) {
- // success
- } finally {
- if (cs != null) {
- cs.close();
- }
}
}
@Test
public void testSelfImpersonation() throws Exception {
- ContentSession cs = null;
- try {
- createTestUser();
-
- SimpleCredentials sc = new SimpleCredentials(USER_ID,
USER_PW.toCharArray());
- cs = login(sc);
-
- AuthInfo authInfo = cs.getAuthInfo();
+ createTestUser();
+ AuthInfo authInfo;
+ try (ContentSession cs = login(new SimpleCredentials(USER_ID,
USER_PW.toCharArray()))) {
+ authInfo = cs.getAuthInfo();
assertEquals(USER_ID, authInfo.getUserID());
+ }
- cs.close();
-
- sc = new SimpleCredentials(USER_ID, new char[0]);
- ImpersonationCredentials ic = new ImpersonationCredentials(sc,
authInfo);
- cs = login(ic);
-
+ SimpleCredentials sc = new SimpleCredentials(USER_ID, new char[0]);
+ ImpersonationCredentials ic = new ImpersonationCredentials(sc,
authInfo);
+ try (ContentSession cs = login(ic)) {
authInfo = cs.getAuthInfo();
assertEquals(USER_ID, authInfo.getUserID());
- } finally {
- if (cs != null) {
- cs.close();
- }
}
}
- @Test
+ @Test(expected = LoginException.class)
public void testInvalidImpersonation() throws Exception {
- ContentSession cs = null;
- try {
- createTestUser();
+ createTestUser();
+ AuthInfo authInfo;
+ try (ContentSession cs = login(new SimpleCredentials(USER_ID,
USER_PW.toCharArray()))) {
+ authInfo = cs.getAuthInfo();
+ assertEquals(USER_ID, authInfo.getUserID());
+ }
- SimpleCredentials sc = new SimpleCredentials(USER_ID,
USER_PW.toCharArray());
- cs = login(sc);
+ ConfigurationParameters config =
securityProvider.getConfiguration(UserConfiguration.class).getParameters();
+ String adminId = UserUtil.getAdminId(config);
+ SimpleCredentials sc = new SimpleCredentials(adminId, new char[0]);
+ ImpersonationCredentials ic = new ImpersonationCredentials(sc,
authInfo);
+ // test-user should not be allowed to impersonate admin -> exception
expected
+ try (ContentSession cs = login(ic)) {
+ fail("User 'test' should not be allowed to impersonate " +
adminId);
+ }
+ }
+ @Test
+ public void testLoginWithAttributes( ) throws Exception {
+ createTestUser();
+ SimpleCredentials sc = new SimpleCredentials(USER_ID,
USER_PW.toCharArray());
+ sc.setAttribute("attr", "value");
+ try (ContentSession cs = login(sc)){
AuthInfo authInfo = cs.getAuthInfo();
- assertEquals(USER_ID, authInfo.getUserID());
+
assertTrue(Arrays.asList(authInfo.getAttributeNames()).contains("attr"));
+ assertEquals("value", authInfo.getAttribute("attr"));
+ }
+ }
- cs.close();
- cs = null;
+ @Test
+ public void testImpersonationWithAttributes() throws Exception {
+ createTestUser();
+ AuthInfo authInfo;
+ try (ContentSession cs = login(new SimpleCredentials(USER_ID,
USER_PW.toCharArray()))) {
+ authInfo = cs.getAuthInfo();
+ }
- ConfigurationParameters config =
securityProvider.getConfiguration(UserConfiguration.class).getParameters();
- String adminId = UserUtil.getAdminId(config);
- sc = new SimpleCredentials(adminId, new char[0]);
- ImpersonationCredentials ic = new ImpersonationCredentials(sc,
authInfo);
-
- try {
- cs = login(ic);
- fail("User 'test' should not be allowed to impersonate " +
adminId);
- } catch (LoginException e) {
- // success
- }
- } finally {
- if (cs != null) {
- cs.close();
- }
+ SimpleCredentials sc = new SimpleCredentials(USER_ID, new char[0]);
+ sc.setAttribute("attr", "value");
+ ImpersonationCredentials ic = new ImpersonationCredentials(sc,
authInfo);
+ try (ContentSession cs = login(ic)) {
+ authInfo = cs.getAuthInfo();
+
assertTrue(Arrays.asList(authInfo.getAttributeNames()).contains("attr"));
+ assertEquals("value", authInfo.getAttribute("attr"));
+ }
+ }
+
+ @Test(expected = LoginException.class)
+ public void testImpersonationWithUnsupportedBaseCredentials() throws
Exception {
+ Credentials baseCredentials = mock(Credentials.class);
+ ImpersonationCredentials ic = new
ImpersonationCredentials(baseCredentials, new AuthInfoImpl(USER_ID, null,
null));
+ try (ContentSession cs = login(ic)) {
+ fail("Base credentials of ImpersonationCredentials can only be
SimpleCredentials.");
}
}
@Test
- public void testLoginWithAttributes( ) throws Exception {
- ContentSession cs = null;
- try {
- createTestUser();
+ public void testLoginPreAuthenticated() throws Exception {
+ Authentication authentication = mock(Authentication.class);
+
when(authentication.authenticate(any(Credentials.class))).thenReturn(true).getMock();
+ when(authentication.getUserId()).thenReturn("uid"); // but
getUserPrincipal returns null
- SimpleCredentials sc = new SimpleCredentials(USER_ID,
USER_PW.toCharArray());
- sc.setAttribute("attr", "value");
+ UserAuthenticationFactory uaf =
when(mock(UserAuthenticationFactory.class).getAuthentication(any(UserConfiguration.class),
any(Root.class), anyString())).thenReturn(authentication).getMock();
+ Map<String, Object> sharedState = Maps.newHashMap();
+ sharedState.put(SHARED_KEY_PRE_AUTH_LOGIN, new
PreAuthenticatedLogin("uid"));
- cs = login(sc);
+ Subject subject = new Subject();
+ LoginModuleImpl lm = new LoginModuleImpl();
+ lm.initialize(subject, new TestCallbackHandler(uaf), sharedState,
Maps.newHashMap());
+ assertTrue(lm.login());
+ assertTrue(lm.commit());
- AuthInfo authInfo = cs.getAuthInfo();
-
assertTrue(Arrays.asList(authInfo.getAttributeNames()).contains("attr"));
- assertEquals("value", authInfo.getAttribute("attr"));
+ assertTrue(subject.getPrincipals().isEmpty());
+ // no other public credentials than the AuthInfo
+ assertEquals(1, subject.getPublicCredentials().size());
+ // verify AuthInfo
+ Set<AuthInfo> authInfos = subject.getPublicCredentials(AuthInfo.class);
+ assertFalse(authInfos.isEmpty());
+ assertEquals("uid", authInfos.iterator().next().getUserID());
+ }
+
+ @Test
+ public void testLoginPreAuthenticatedWithReadOnlySubject() throws
Exception {
+ Authentication authentication =
when(mock(Authentication.class).authenticate(any(Credentials.class))).thenReturn(true).getMock();
+ UserAuthenticationFactory uaf =
when(mock(UserAuthenticationFactory.class).getAuthentication(any(UserConfiguration.class),
any(Root.class), anyString())).thenReturn(authentication).getMock();
+
+ Map<String, Object> sharedState = Maps.newHashMap();
+ sharedState.put(SHARED_KEY_PRE_AUTH_LOGIN, new
PreAuthenticatedLogin("uid"));
- cs.close();
- } finally {
- if (cs != null) {
- cs.close();
+ Subject subject = new Subject();
+ subject.setReadOnly();
+ LoginModuleImpl lm = new LoginModuleImpl();
+ lm.initialize(subject, new TestCallbackHandler(uaf), sharedState,
Maps.newHashMap());
+ assertTrue(lm.login());
+ assertTrue(lm.commit());
+
+ assertTrue(subject.getPrincipals().isEmpty());
+ assertTrue(subject.getPublicCredentials().isEmpty());
+ }
+
+ @Test
+ public void testNullUserAuthentication() throws Exception {
+ LoginModuleImpl loginModule = new LoginModuleImpl();
+ CallbackHandler cbh = new
TestCallbackHandler(mock(UserAuthenticationFactory.class));
+ loginModule.initialize(new Subject(), cbh, Maps.newHashMap(),
Maps.newHashMap());
+
+ assertFalse(loginModule.login());
+ assertFalse(loginModule.commit());
+ }
+
+ @Test
+ public void testMissingUserAuthenticationFactory() throws Exception {
+ CallbackHandler cbh = callbacks -> {
+ for (Callback callback : callbacks) {
+ if (callback instanceof RepositoryCallback) {
+ UserConfiguration uc =
when(mock(UserConfiguration.class).getParameters()).thenReturn(ConfigurationParameters.EMPTY).getMock();
+ SecurityProvider sp =
when(mock(SecurityProvider.class).getConfiguration(UserConfiguration.class)).thenReturn(uc).getMock();
+ ((RepositoryCallback) callback).setSecurityProvider(sp);
+ ((RepositoryCallback)
callback).setContentRepository(getContentRepository());
+ } else {
+ throw new UnsupportedCallbackException(callback);
+ }
}
- }
+ };
+
+ LoginModuleImpl loginModule = new LoginModuleImpl();
+ loginModule.initialize(new Subject(), cbh, Maps.newHashMap(),
Maps.newHashMap());
+
+ assertFalse(loginModule.login());
+ assertFalse(loginModule.commit());
}
@Test
- public void testImpersonationWithAttributes() throws Exception {
- ContentSession cs = null;
- try {
- createTestUser();
+ public void testMissingSecurityProviderGuestLogin() throws Exception {
+ CallbackHandler cbh = callbacks -> {
+ for (Callback callback : callbacks) {
+ if (callback instanceof RepositoryCallback) {
+ ((RepositoryCallback) callback).setSecurityProvider(null);
+ ((RepositoryCallback)
callback).setContentRepository(getContentRepository());
+ } else {
+ throw new UnsupportedCallbackException(callback);
+ }
+ }
+ };
- SimpleCredentials sc = new SimpleCredentials(USER_ID,
USER_PW.toCharArray());
- cs = login(sc);
- AuthInfo authInfo = cs.getAuthInfo();
- cs.close();
- cs = null;
+ LoginModuleImpl loginModule = new LoginModuleImpl();
+ loginModule.initialize(new Subject(false, ImmutableSet.of(),
ImmutableSet.of(new GuestCredentials()), ImmutableSet.of()), cbh,
Maps.newHashMap(), Maps.newHashMap());
- sc = new SimpleCredentials(USER_ID, new char[0]);
- sc.setAttribute("attr", "value");
- ImpersonationCredentials ic = new ImpersonationCredentials(sc,
authInfo);
- cs = login(ic);
+ assertFalse(loginModule.login());
+ assertFalse(loginModule.commit());
+ }
- authInfo = cs.getAuthInfo();
-
assertTrue(Arrays.asList(authInfo.getAttributeNames()).contains("attr"));
- assertEquals("value", authInfo.getAttribute("attr"));
- } finally {
- if (cs != null) {
- cs.close();
+ @Test
+ public void testMissingSecurityProvider() throws Exception {
+ CallbackHandler cbh = callbacks -> {
+ for (Callback callback : callbacks) {
+ if (callback instanceof RepositoryCallback) {
+ ((RepositoryCallback) callback).setSecurityProvider(null);
+ ((RepositoryCallback)
callback).setContentRepository(getContentRepository());
+ } else {
+ throw new UnsupportedCallbackException(callback);
+ }
}
- }
+ };
+
+ LoginModuleImpl loginModule = new LoginModuleImpl();
+ loginModule.initialize(new Subject(), cbh, Maps.newHashMap(),
Maps.newHashMap());
+
+ assertFalse(loginModule.login());
+ assertFalse(loginModule.commit());
}
@Test
- public void testGetNullUserAuthentication() throws Exception {
+ public void testMissingRoot() throws Exception {
+ CallbackHandler cbh = callbacks -> {
+ for (Callback callback : callbacks) {
+ if (callback instanceof RepositoryCallback) {
+ ((RepositoryCallback)
callback).setSecurityProvider(getSecurityProvider());
+ ((RepositoryCallback) callback).setContentRepository(null);
+ } else {
+ throw new UnsupportedCallbackException(callback);
+ }
+ }
+ };
+
LoginModuleImpl loginModule = new LoginModuleImpl();
- CallbackHandler cbh = new
TestCallbackHandler(Mockito.mock(UserAuthenticationFactory.class));
- loginModule.initialize(new Subject(), cbh, Maps.<String,
Object>newHashMap(), Maps.<String, Object>newHashMap());
+ loginModule.initialize(new Subject(), cbh, Maps.newHashMap(),
Maps.newHashMap());
assertFalse(loginModule.login());
assertFalse(loginModule.commit());
}
@Test
- public void testCustomUserAuthentication() throws Exception {
+ public void testMissingCallbackHandler() throws Exception {
LoginModuleImpl loginModule = new LoginModuleImpl();
+ loginModule.initialize(new Subject(), null, Maps.newHashMap(),
Maps.newHashMap());
+
+ assertFalse(loginModule.login());
+ assertFalse(loginModule.commit());
+ }
+
+ @Test
+ public void testLoginCustomUserAuthenticationFactory() throws Exception {
+ UserAuthenticationFactory factory = (configuration, root, userId) ->
new Authentication() {
+ @Override
+ public boolean authenticate(@Nullable Credentials credentials) {
+ return true;
+ }
- UserAuthenticationFactory factory = new UserAuthenticationFactory() {
@Nullable
@Override
- public Authentication getAuthentication(@NotNull UserConfiguration
configuration, @NotNull Root root, @Nullable String userId) {
- return new Authentication() {
- @Override
- public boolean authenticate(@Nullable Credentials
credentials) throws LoginException {
- return true;
- }
-
- @Nullable
- @Override
- public String getUserId() {
- return null;
- }
-
- @Nullable
- @Override
- public Principal getUserPrincipal() {
- return null;
- }
- };
+ public String getUserId() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Principal getUserPrincipal() {
+ return null;
}
};
CallbackHandler cbh = new TestCallbackHandler(factory);
SimpleCredentials creds = new SimpleCredentials("loginId", new
char[0]);
- Subject subject = new Subject(false, Sets.<Principal>newHashSet(),
ImmutableSet.of(creds), Sets.newHashSet());
+ Subject subject = new Subject(false, Sets.newHashSet(),
ImmutableSet.of(creds), Sets.newHashSet());
- loginModule.initialize(subject, cbh, Maps.<String,
Object>newHashMap(), Maps.<String, Object>newHashMap());
+ LoginModuleImpl loginModule = new LoginModuleImpl();
+ loginModule.initialize(subject, cbh, Maps.newHashMap(),
Maps.newHashMap());
assertTrue(loginModule.login());
assertTrue(loginModule.commit());
+ // authinfo falls back to loginId because Authentication.getUserId
returned null
AuthInfo authInfo =
subject.getPublicCredentials(AuthInfo.class).iterator().next();
assertEquals("loginId", authInfo.getUserID());
}
+ @Test
+ public void testMissingUserId() throws Exception {
+ UserAuthenticationFactory factory = (configuration, root, userId) ->
new Authentication() {
+ @Override
+ public boolean authenticate(@Nullable Credentials credentials) {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public String getUserId() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Principal getUserPrincipal() {
+ return null;
+ }
+ };
+
+ CallbackHandler cbh = new TestCallbackHandler(factory);
+ Subject subject = new Subject(false, Sets.newHashSet(),
ImmutableSet.of(), Sets.newHashSet());
+
+ LoginModuleImpl loginModule = new LoginModuleImpl();
+ loginModule.initialize(subject, cbh, Maps.newHashMap(),
Maps.newHashMap());
+ assertTrue(loginModule.login());
+ assertTrue(loginModule.commit());
+
+ AuthInfo authInfo =
subject.getPublicCredentials(AuthInfo.class).iterator().next();
+ assertNull(authInfo.getUserID());
+ assertTrue(subject.getPrincipals().isEmpty());
+ }
+
private class TestCallbackHandler implements CallbackHandler {
private final SecurityProvider sp;
- private TestCallbackHandler(@Nullable UserAuthenticationFactory
authenticationFactory) {
+ private TestCallbackHandler(@NotNull UserAuthenticationFactory
authenticationFactory) {
ConfigurationParameters params = ConfigurationParameters.of(
UserConfiguration.NAME,
ConfigurationParameters.of(
@@ -397,7 +481,7 @@ public class LoginModuleImplTest extends
}
@Override
- public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
+ public void handle(Callback[] callbacks) throws
UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof RepositoryCallback) {
((RepositoryCallback) callback).setSecurityProvider(sp);
@@ -408,5 +492,4 @@ public class LoginModuleImplTest extends
}
}
}
-
}