- LoginManager finished, works now
    - Utility class for looking up CDI beans in classes which are not eligible for injection
    - Some clean up (removing FindBugs and PMD warnings)


git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3528 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2015-07-21 17:21:11 +00:00
parent 5282e63ebd
commit 1071d2466b
13 changed files with 231 additions and 61 deletions

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.cdi.utils;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CdiLookupException extends Exception {
private static final long serialVersionUID = 1L;
/**
* Creates a new instance of <code>CdiLookupException</code> without detail message.
*/
public CdiLookupException() {
super();
}
/**
* Constructs an instance of <code>CdiLookupException</code> with the specified detail message.
*
* @param msg The detail message.
*/
public CdiLookupException(final String msg) {
super(msg);
}
/**
* Constructs an instance of <code>CdiLookupException</code> which wraps the
* specified exception.
*
* @param exception The exception to wrap.
*/
public CdiLookupException(final Exception exception) {
super(exception);
}
/**
* Constructs an instance of <code>CdiLookupException</code> with the specified message which also wraps the
* specified exception.
*
* @param msg The detail message.
* @param exception The exception to wrap.
*/
public CdiLookupException(final String msg, final Exception exception) {
super(msg, exception);
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.cdi.utils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.logging.log4j.message.ParameterizedMessage;
import java.util.Iterator;
import java.util.Set;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.CDI;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CdiUtil {
private final static Logger LOGGER = LogManager.getLogger(CdiUtil.class);
private final transient BeanManager beanManager;
public CdiUtil() {
beanManager = CDI.current().getBeanManager();
}
@SuppressWarnings("unchecked")
public <T> T findBean(final Class<T> beanType) throws CdiLookupException {
final Set<Bean<?>> beans = beanManager.getBeans(beanType);
final Iterator<Bean<?>> iterator = beans.iterator();
if (iterator.hasNext()) {
@SuppressWarnings("unchecked")
final Bean<T> bean = (Bean<T>) iterator.next();
final CreationalContext<T> ctx = beanManager.createCreationalContext(bean);
return (T) beanManager.getReference(bean, beanType, ctx);
} else {
LOGGER.error(new ParameterizedMessage(
"No CDI Bean for type {0} found.", beanType.getName()));
throw new CdiLookupException(String.format(
"No CDI Bean for type \"%s\" found", beanType.getName()));
}
}
}

View File

@ -18,11 +18,9 @@
*/ */
package org.libreccm.core; package org.libreccm.core;
import static org.libreccm.core.CoreConstants.*;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;

View File

@ -43,7 +43,7 @@ import javax.security.auth.spi.LoginModule;
* the shared data for use by other {@code LoginModule}s. * the shared data for use by other {@code LoginModule}s.
* *
* This class in a reworked version of * This class in a reworked version of
* {@code org.arsdigita.kernel.security.PasswordLoginModule} developed by Sameer * {@code org.arsdigita.kernel.security.AbstractPasswordLoginModule} developed by Sameer
* Ajmani (according to the JavaDoc). The main differences is that the new * Ajmani (according to the JavaDoc). The main differences is that the new
* version uses generics and multi-catch for exceptions. Also the code, * version uses generics and multi-catch for exceptions. Also the code,
* especially if clauses have been reworked to match the conventions enforced by * especially if clauses have been reworked to match the conventions enforced by
@ -59,10 +59,9 @@ import javax.security.auth.spi.LoginModule;
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
public abstract class PasswordLoginModule implements LoginModule { public abstract class AbstractPasswordLoginModule implements LoginModule {
private static final Logger LOGGER = LogManager.getLogger( private static final Logger LOGGER = LogManager.getLogger(AbstractPasswordLoginModule.class);
PasswordLoginModule.class);
/** /**
* Key for username in shared data map. * Key for username in shared data map.
*/ */
@ -78,8 +77,8 @@ public abstract class PasswordLoginModule implements LoginModule {
* method. * method.
* We only set the fields we use in this class. * We only set the fields we use in this class.
*/ */
private CallbackHandler callbackHandler; private transient CallbackHandler callbackHandler;
private Map<String, ?> sharedState; private transient Map<String, ?> sharedState;
/** /**
* {@inheritDoc } * {@inheritDoc }
@ -155,6 +154,7 @@ public abstract class PasswordLoginModule implements LoginModule {
* *
* @throws LoginException if an error occurs. * @throws LoginException if an error occurs.
*/ */
@SuppressWarnings("PMD.PreserveStackTrace")
private String retrieveUsername() throws LoginException { private String retrieveUsername() throws LoginException {
String username = (String) sharedState.get(NAME_KEY); String username = (String) sharedState.get(NAME_KEY);
if (username == null) { if (username == null) {
@ -178,6 +178,7 @@ public abstract class PasswordLoginModule implements LoginModule {
* *
* @throws LoginException if an error occurs. * @throws LoginException if an error occurs.
*/ */
@SuppressWarnings("PMD.StackTraceLost")
private String retrievePassword() throws LoginException { private String retrievePassword() throws LoginException {
String password = (String) sharedState.get(PASSWORD_KEY); String password = (String) sharedState.get(PASSWORD_KEY);

View File

@ -20,15 +20,14 @@ package org.libreccm.core.authentication;
import com.arsdigita.kernel.KernelConfig; import com.arsdigita.kernel.KernelConfig;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.User; import org.libreccm.core.User;
import org.libreccm.core.UserManager; import org.libreccm.core.UserManager;
import org.libreccm.core.UserRepository; import org.libreccm.core.UserRepository;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map; import java.util.Map;
import javax.inject.Inject;
import javax.security.auth.Subject; import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.AccountNotFoundException; import javax.security.auth.login.AccountNotFoundException;
@ -39,17 +38,7 @@ import javax.security.auth.login.LoginException;
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
public class LocalLoginModule extends PasswordLoginModule { public class LocalLoginModule extends AbstractPasswordLoginModule {
/**
* {@link UserRepository} instance for getting user accounts from the
* database.
*/
@Inject
private transient UserRepository userRepository;
@Inject
private transient UserManager userManager;
private transient Subject subject; private transient Subject subject;
@ -85,16 +74,38 @@ public class LocalLoginModule extends PasswordLoginModule {
* @param password The password to verify. * @param password The password to verify.
* *
* @return {@code true} if the password matches the password in the * @return {@code true} if the password matches the password in the
* database, {@code false} if not or if there is no user account identified * database, {@code false} if not or if there is no user account
* by the provided user name. * identified by the provided user name.
* *
* @throws LoginException If an error occurs in the process. * @throws LoginException If an error occurs in the process.
*/ */
@Override @Override
@SuppressWarnings("PMD.StackTraceLost")
protected boolean checkPassword(final String username, protected boolean checkPassword(final String username,
final String password) final String password)
throws LoginException { throws LoginException {
final CdiUtil cdiUtil = new CdiUtil();
final UserRepository userRepository;
try {
userRepository = cdiUtil.findBean(UserRepository.class);
} catch (CdiLookupException ex) {
throw new LoginException(
String.format(
"Failed to obtain reference for UserRepository: %s",
ex.getMessage()));
}
final UserManager userManager;
try {
userManager = cdiUtil.findBean(UserManager.class);
} catch (CdiLookupException ex) {
throw new LoginException(String.format(
"Failed to obtain reference for UserManager: %s",
ex.getMessage()));
}
//Depending on the configured user identifier retrieve the user account //Depending on the configured user identifier retrieve the user account
//using the screen name or the email address. //using the screen name or the email address.
final User user; final User user;
@ -110,7 +121,15 @@ public class LocalLoginModule extends PasswordLoginModule {
"No user account identified by '%s' found.", username)); "No user account identified by '%s' found.", username));
} }
return userManager.verifyPasswordForUser(user, password); final boolean result = userManager.verifyPasswordForUser(user, password);
if (result) {
final UserPrincipal userPrincipal = new UserPrincipal(user);
subject.getPrincipals().add(userPrincipal);
return true;
} else {
return false;
}
// Verify the password. The algorithm used for hashing is stored in the // Verify the password. The algorithm used for hashing is stored in the
// database so we need to retrieve the correct MessageDigest instance // database so we need to retrieve the correct MessageDigest instance
@ -137,7 +156,6 @@ public class LocalLoginModule extends PasswordLoginModule {
// + "which is not avialable.", // + "which is not avialable.",
// username, user.getHashAlgorithm())); // username, user.getHashAlgorithm()));
// } // }
} }
} }

View File

@ -46,7 +46,7 @@ public class LoginConfig extends Configuration {
/** /**
* The configuration entries. * The configuration entries.
*/ */
private final Map<String, AppConfigurationEntry[]> appConfigs; private final transient Map<String, AppConfigurationEntry[]> appConfigs;
private LoginConfig() { private LoginConfig() {
this.appConfigs = new HashMap<>(); this.appConfigs = new HashMap<>();

View File

@ -24,6 +24,7 @@ import com.arsdigita.runtime.ConfigError;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.security.auth.login.AppConfigurationEntry; import javax.security.auth.login.AppConfigurationEntry;
@ -108,8 +109,10 @@ public class LoginConfigBuilder {
* be created, as array of strings as provided by * be created, as array of strings as provided by
* {@link SecurityConfig#getLoginConfig()}. * {@link SecurityConfig#getLoginConfig()}.
*/ */
@SuppressWarnings("PMD.UseVarargs") //Can't use varargs here
public LoginConfigBuilder(final String[] config) { public LoginConfigBuilder(final String[] config) {
this.config = config; this.config = new String[config.length];
System.arraycopy(config, 0, this.config, 0, config.length);
} }
/** /**
@ -259,7 +262,7 @@ public class LoginConfigBuilder {
*/ */
private AppConfigurationEntry.LoginModuleControlFlag parseFlag( private AppConfigurationEntry.LoginModuleControlFlag parseFlag(
final String flag) { final String flag) {
switch (flag.toUpperCase()) { switch (flag.toUpperCase(Locale.ROOT)) {
case "REQUISITE": case "REQUISITE":
return AppConfigurationEntry.LoginModuleControlFlag.REQUISITE; return AppConfigurationEntry.LoginModuleControlFlag.REQUISITE;

View File

@ -20,7 +20,6 @@ package org.libreccm.core.authentication;
import org.libreccm.core.CcmSessionContext; import org.libreccm.core.CcmSessionContext;
import org.libreccm.core.User; import org.libreccm.core.User;
import org.libreccm.core.UserRepository;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
@ -53,7 +52,7 @@ public class LoginManager {
/** /**
* Name of the register login context. * Name of the register login context.
*/ */
private static final String REGISTER_LOGIN_CONTEXT = "Register"; private static final String LOGIN_CONTEXT = "Register";
@Inject @Inject
private transient CcmSessionContext sessionContext; private transient CcmSessionContext sessionContext;
@ -67,7 +66,7 @@ public class LoginManager {
final CallbackHandler callbackHandler = new LoginCallbackHandler( final CallbackHandler callbackHandler = new LoginCallbackHandler(
username, password); username, password);
final LoginContext loginContext = new LoginContext( final LoginContext loginContext = new LoginContext(
REGISTER_LOGIN_CONTEXT, LOGIN_CONTEXT,
callbackHandler); callbackHandler);
loginContext.login(); loginContext.login();
final Subject subject = loginContext.getSubject(); final Subject subject = loginContext.getSubject();
@ -85,10 +84,10 @@ public class LoginManager {
} }
} }
private class LoginCallbackHandler implements CallbackHandler { private static class LoginCallbackHandler implements CallbackHandler {
private final String username; private final transient String username;
private final String password; private final transient String password;
public LoginCallbackHandler(final String username, public LoginCallbackHandler(final String username,
final String password) { final String password) {
@ -97,10 +96,11 @@ public class LoginManager {
} }
@Override @Override
@SuppressWarnings("PMD.UseVarargs") //Can't use varargs here
public void handle(final Callback[] callbacks) public void handle(final Callback[] callbacks)
throws IOException, UnsupportedCallbackException { throws IOException, UnsupportedCallbackException {
for (Callback callback : callbacks) { for (final Callback callback : callbacks) {
if (callback instanceof NameCallback) { if (callback instanceof NameCallback) {
((NameCallback) callback).setName(username); ((NameCallback) callback).setName(username);
} else if (callback instanceof PasswordCallback) { } else if (callback instanceof PasswordCallback) {

View File

@ -51,7 +51,7 @@ public final class UserPrincipal implements Principal {
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(final Object obj) {
if (obj == null) { if (obj == null) {
return false; return false;
} }

View File

@ -24,7 +24,6 @@ import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
@ -107,7 +106,7 @@ public class Portal extends Resource implements Serializable {
return false; return false;
} }
return (template == other.isTemplate()); return template == other.isTemplate();
} }
@Override @Override

View File

@ -23,13 +23,13 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
import org.libreccm.core.Group; import org.libreccm.core.Group;
import org.libreccm.core.Privilege; import org.libreccm.core.Privilege;
import org.libreccm.core.ResourceType; import org.libreccm.core.ResourceType;
@ -43,9 +43,11 @@ import org.libreccm.core.ResourceType;
public class ApplicationType extends ResourceType implements Serializable { public class ApplicationType extends ResourceType implements Serializable {
private static final long serialVersionUID = -1175728067001112457L; private static final long serialVersionUID = -1175728067001112457L;
private static final String PMD_LONG_VARIABLE = "PMD.LongVariable";
@OneToMany @OneToMany
@JoinColumn(name = "relevant_privilege_id") @JoinColumn(name = "relevant_privilege_id")
@SuppressWarnings(PMD_LONG_VARIABLE)
private List<Privilege> relevantPrivileges; private List<Privilege> relevantPrivileges;
@ManyToOne @ManyToOne
@ -54,9 +56,11 @@ public class ApplicationType extends ResourceType implements Serializable {
@ManyToOne @ManyToOne
@JoinColumn(name = "provider_app_type_id") @JoinColumn(name = "provider_app_type_id")
@SuppressWarnings(PMD_LONG_VARIABLE)
private ApplicationType providerApplicationType; private ApplicationType providerApplicationType;
@OneToMany(mappedBy = "providerApplicationType") @OneToMany(mappedBy = "providerApplicationType")
@SuppressWarnings(PMD_LONG_VARIABLE)
private List<ApplicationType> dependentApplicationTypes; private List<ApplicationType> dependentApplicationTypes;
public ApplicationType() { public ApplicationType() {
@ -70,6 +74,7 @@ public class ApplicationType extends ResourceType implements Serializable {
return Collections.unmodifiableList(relevantPrivileges); return Collections.unmodifiableList(relevantPrivileges);
} }
@SuppressWarnings(PMD_LONG_VARIABLE)
protected void setRelevantPrivileges( protected void setRelevantPrivileges(
final List<Privilege> relevantPrivileges) { final List<Privilege> relevantPrivileges) {
this.relevantPrivileges = relevantPrivileges; this.relevantPrivileges = relevantPrivileges;
@ -95,15 +100,18 @@ public class ApplicationType extends ResourceType implements Serializable {
return providerApplicationType; return providerApplicationType;
} }
@SuppressWarnings(PMD_LONG_VARIABLE)
protected void setProviderApplicationType( protected void setProviderApplicationType(
final ApplicationType providerApplicationType) { final ApplicationType providerApplicationType) {
this.providerApplicationType = providerApplicationType; this.providerApplicationType = providerApplicationType;
} }
@SuppressWarnings(PMD_LONG_VARIABLE)
public List<ApplicationType> getDependentApplicationTypes() { public List<ApplicationType> getDependentApplicationTypes() {
return Collections.unmodifiableList(dependentApplicationTypes); return Collections.unmodifiableList(dependentApplicationTypes);
} }
@SuppressWarnings(PMD_LONG_VARIABLE)
protected void setDependentApplicationTypes( protected void setDependentApplicationTypes(
final List<ApplicationType> dependentApplicationTypes) { final List<ApplicationType> dependentApplicationTypes) {
this.dependentApplicationTypes = dependentApplicationTypes; this.dependentApplicationTypes = dependentApplicationTypes;
@ -167,4 +175,5 @@ public class ApplicationType extends ResourceType implements Serializable {
providerApplicationType), providerApplicationType),
data)); data));
} }
} }

View File

@ -115,8 +115,9 @@ public class LoginManagerTest {
.addPackage(org.libreccm.web.Application.class.getPackage()) .addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class. .addPackage(org.libreccm.categorization.Category.class.
getPackage()) getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()). .addPackage(org.libreccm.l10n.LocalizedString.class.getPackage())
addPackage(org.libreccm.jpa.EntityManagerProducer.class .addPackage(org.libreccm.cdi.utils.CdiUtil.class.getPackage())
.addPackage(org.libreccm.jpa.EntityManagerProducer.class
.getPackage()) .getPackage())
.addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class .addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
.getPackage()) .getPackage())
@ -130,6 +131,10 @@ public class LoginManagerTest {
.getPackage()) .getPackage())
.addPackage(com.arsdigita.util.UncheckedWrapperException.class .addPackage(com.arsdigita.util.UncheckedWrapperException.class
.getPackage()) .getPackage())
.addPackage(com.arsdigita.xml.XML.class
.getPackage())
.addPackage(com.arsdigita.xml.formatters.DateTimeFormatter.class
.getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class .addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage()) .getPackage())
.addPackage(com.arsdigita.web.CCMApplicationContextListener.class .addPackage(com.arsdigita.web.CCMApplicationContextListener.class
@ -168,11 +173,11 @@ public class LoginManagerTest {
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.json") "datasets/org/libreccm/core/authentication/LoginManagerTest/data.json")
@InSequence(10) @InSequence(10)
public void loginValidCredentials() throws LoginException { public void loginValidCredentials() throws LoginException {
loginManager.login("jdoe@example.com", "correct-pw"); loginManager.login("jdoe@example.com", "foobar");
assertThat(ccmSessionContext.getCurrentParty(), is(not(nullValue()))); assertThat(ccmSessionContext.getCurrentParty(), is(not(nullValue())));
final EmailAddress emailAddress = new EmailAddress(); final EmailAddress emailAddress = new EmailAddress();
emailAddress.setAddress("jdoe@example.org"); emailAddress.setAddress("jdoe@example.com");
emailAddress.setBouncing(false); emailAddress.setBouncing(false);
emailAddress.setVerified(true); emailAddress.setVerified(true);
assertThat(ccmSessionContext.getCurrentParty().getEmailAddresses(), assertThat(ccmSessionContext.getCurrentParty().getEmailAddresses(),
@ -188,6 +193,7 @@ public class LoginManagerTest {
loginManager.login("jdoe@example.com", "wrong-pw"); loginManager.login("jdoe@example.com", "wrong-pw");
} catch (LoginException ex) { } catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentParty(), is(nullValue())); assertThat(ccmSessionContext.getCurrentParty(), is(nullValue()));
return;
} }
fail("No login exception was thrown."); fail("No login exception was thrown.");
@ -202,6 +208,7 @@ public class LoginManagerTest {
loginManager.login("jdoe@example.com", ""); loginManager.login("jdoe@example.com", "");
} catch (LoginException ex) { } catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentParty(), is(nullValue())); assertThat(ccmSessionContext.getCurrentParty(), is(nullValue()));
return;
} }
fail("No login exception was thrown."); fail("No login exception was thrown.");
@ -216,6 +223,7 @@ public class LoginManagerTest {
loginManager.login("", "correct-pw"); loginManager.login("", "correct-pw");
} catch (LoginException ex) { } catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentParty(), is(nullValue())); assertThat(ccmSessionContext.getCurrentParty(), is(nullValue()));
return;
} }
fail("No login exception was thrown."); fail("No login exception was thrown.");
@ -230,6 +238,7 @@ public class LoginManagerTest {
loginManager.login("jdoe@example.com", null); loginManager.login("jdoe@example.com", null);
} catch (LoginException ex) { } catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentParty(), is(nullValue())); assertThat(ccmSessionContext.getCurrentParty(), is(nullValue()));
return;
} }
fail("No login exception was thrown."); fail("No login exception was thrown.");
@ -244,6 +253,7 @@ public class LoginManagerTest {
loginManager.login(null, "correct-pw"); loginManager.login(null, "correct-pw");
} catch (LoginException ex) { } catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentParty(), is(nullValue())); assertThat(ccmSessionContext.getCurrentParty(), is(nullValue()));
return;
} }
fail("No login exception was thrown."); fail("No login exception was thrown.");

View File

@ -21,8 +21,9 @@
"hash_algorithm": "SHA-512", "hash_algorithm": "SHA-512",
"family_name": "Doe", "family_name": "Doe",
"given_name": "John", "given_name": "John",
"password": "abc8f796612f5c5b5d0c89cf86ea3b8d1c7d15f9c06851f85708013b0248b2e6d9b315b48f586168fe6cc29296e5a9090a5aab14a85b3ffd0633ca8ccc587a09", "password": "C+o2w6mp+eLrbluMEgKMVSdP50A9BMethXN8R3yihtkbzt7WfWsde2nmq/t5gq6im3J8i3jw4Y3YrKHou8JQ2A==",
"salt": "fiagaifa", "salt": "Fu8FPgqAal4GZp1hDjkOB+t6ITRCcO7HBoN5Xqf29UnVj5NUdUFZRTyKYMBEx6JmZGmHcMDG9OGVCKcEM9oyScSRreJs4B51wM44NM6KeRwbCf+VhBn14DkBrl40ygraNf+AJacKpMyCpFI0O/Am7mMDWL4flskBsylkxaQn3vKfzgN5MVG2szW//I6Q6YEH9AuL8LauS6fKaVynMzzu3xzD8Hjqvvlnzym898eom2lqScPfg5g4e8Ww13HCHAYe6twupAW/BjUNax5HSioEisZN/P1UGrde8uFEj+hbbavrWYZuilPuEu25+/98jyXx6542agqrWN8j0SFYcIyOgA==",
"password_reset_required": false,
"screen_name": "jdoe", "screen_name": "jdoe",
"subject_id": -10 "subject_id": -10
} }