CCM NG: LoginManagerTest. Note: LoginManager does not work yet, Test class and LoginManager etc still need some work

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3527 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2015-07-20 20:12:10 +00:00
parent c9b854a723
commit 5282e63ebd
10 changed files with 681 additions and 231 deletions

View File

@ -26,6 +26,8 @@ import com.arsdigita.util.parameter.SpecificClassParameter;
import com.arsdigita.util.parameter.StringArrayParameter;
import com.arsdigita.util.parameter.StringParameter;
import org.libreccm.core.authentication.LocalLoginModule;
import java.util.Arrays;
import java.util.List;
@ -79,7 +81,8 @@ public class SecurityConfig extends AbstractConfig {
private final Parameter m_loginConfig = new StringArrayParameter(
"waf.login_config", Parameter.REQUIRED,
new String[]{
"Register:com.arsdigita.kernel.security.LocalLoginModule:requisite",});
String.format("Register:%s:requisite",
LocalLoginModule.class.getName())});
private final Parameter m_adminEmail = new StringParameter(
"waf.admin.contact_email", Parameter.OPTIONAL, null);
@ -223,7 +226,6 @@ public class SecurityConfig extends AbstractConfig {
// }
// return s_systemAdministratorEmailAddress;
// }
public final boolean isAutoRegistrationOn() {
return ((Boolean) get(m_autoRegistrationOn)).booleanValue();
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.runtime;
import com.arsdigita.util.Assert;
import org.apache.log4j.Logger;
/**
* Subject to change.
*
* An error to indicate invalid configurations.
*
* Usage: throw new ConfigError( "message" );
*
* @author Justin Ross <jross@redhat.com>
*/
public class ConfigError extends Error {
private static final long serialVersionUID = 5224480607138738741L;
/**
* Constructs a new configuration error with the content
* <code>message</code>.
*
* @param message A <code>String</code> describing what's wrong; it cannot
* be null
*/
public ConfigError(final String message) {
super(message);
Assert.exists(message, String.class);
}
/**
* Constructs a new configuration error with a default message.
*/
public ConfigError() {
super("Configuration is invalid");
}
}

View File

@ -18,197 +18,42 @@
*/
package org.libreccm.core.authentication;
import java.util.ArrayList;
import java.util.Arrays;
import com.arsdigita.kernel.security.SecurityConfig;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.security.auth.spi.LoginModule;
/**
* Parses a string array/list of strings to create an configuration for JAAS.
* Configuration for JAAS containing all active {@link LoginModule}
* implementations.
*
* This class is based on the {@code com.arsdigita.kernel.security.LoginConfig}
* class. The code itself has been heavily refactored using features like
* Generics and other things added to the Java language and the Java Standard
* Library in the last ten years since the original class was written.
* The active modules are stored in the {@link SecurityConfig} as an array
* of strings. The original {@code com.arsdigita.kernel.security.LoginConfig}
* class parsed this string array in its constructor. For LibreCCM 7 the code
* has been split up. The logic for parsing the configuration is now provided
* by the {@link LoginConfigBuilder} class. This allowed us the greatly
* simplify this class. Also now we don't have a constructor which throws
* Exceptions.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class LoginConfig extends Configuration {
/**
* Maps application names to {@code AppConfigurationEntry[]}.
*
* ToDo: To create a configuration this class parses strings. Of course the
* parsing may fails. In this case the constructor throws an exception.
* Throwing exceptions from a constructor is considered a bad practise
* because this may leaves a party created object. Instead the better option
* would be a factory method or a builder.
* The configuration entries.
*/
private final Map<String, AppConfigurationEntry[]> appConfigs = new HashMap<>();
private final Map<String, AppConfigurationEntry[]> appConfigs;
private LoginConfig() {
//Nothing.
this.appConfigs = new HashMap<>();
}
/**
* Creates a new login configuration from a list of string. {@code Request}
* and {@code Register} are mandatory contexts, WAF refuses to start if they
* are not configured. Each login context can span multiple modules.
*
* The input list comprises of strings adhering to the following format:
*
* <pre>
* context:moduleName:controlFlag[:option1[:option2[:...]]]
* </pre>
*
* <dl>
*
* <dt>context</dt>
* <dd>String</dd>
*
* <dt>moduleName</dt>
* <dd>String</dd>
*
* <dt>controlFlag</dt>
* <dd>"required"</dd>
* <dd>"requisite"</dd>
* <dd>"sufficient"</dd>
* <dd>"optional"</dd>
*
* <dt>option</dt>
* <dd>"key=value"</dd>
* </dl>
*
* <p>
* Example:</p>
*
* <pre>
* Request:com.arsdigita.kernel.security.CredentialLoginModule:requisite:debug=true
* Register:com.arsdigita.kernel.security.LocalLoginModule:requisite
* Register:com.arsdigita.kernel.security.UserIDLoginModule:requisite
* Register:com.arsdigita.kernel.security.CredentialLoginModule:optional
* </pre>
*
* @param config The configuration in string format.
*
*/
public LoginConfig(final List<String> config) {
final Map<String, List<String>> contextConfigs = new HashMap<>();
for (String tuple : config) {
final int pos = tuple.indexOf(':');
final String context = tuple.substring(0, pos);
final String moduleConfig = tuple.substring(pos + 1);
final List<String> contextConfig = retrieveContextConfig(
context, contextConfigs);
contextConfig.add(moduleConfig);
}
for (final Map.Entry<String, List<String>> entry : contextConfigs.
entrySet()) {
addAppConfig(entry.getKey(), entry.getValue());
}
}
private List<String> retrieveContextConfig(
final String context, final Map<String, List<String>> contextConfigs) {
List<String> contextConfig = contextConfigs.get(context);
if (contextConfig == null) {
contextConfig = new ArrayList<>();
contextConfigs.put(context, contextConfig);
}
return contextConfig;
}
private void addAppConfig(final String name, final List<String> entries) {
final AppConfigurationEntry[] configEntries
= new AppConfigurationEntry[entries.size()];
for (int i = 0; i < entries.size(); i++) {
final List<String> entry = Arrays.asList(entries.get(i).split(":"));
configEntries[i] = loadAppConfigEntry(entry);
}
appConfigs.put(name, configEntries);
}
private AppConfigurationEntry loadAppConfigEntry(final List<String> entry) {
if (entry.size() < 2) {
throw new LoginConfigMalformedException("LoginConfig is malformed.");
}
final String name = entry.get(0);
final AppConfigurationEntry.LoginModuleControlFlag flag = parseFlag(
entry.get(1));
final Map<String, String> options = new HashMap<>();
if (entry.size() > 2) {
for (int i = 2; i < entry.size(); i++) {
addOption(entry.get(i), options);
}
}
return new AppConfigurationEntry(name, flag, options);
}
private AppConfigurationEntry.LoginModuleControlFlag parseFlag(
final String flagStr) {
switch (flagStr) {
case "REQUISITE":
return AppConfigurationEntry.LoginModuleControlFlag.REQUISITE;
case "REQUIRED":
return AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
case "SUFFICIENT":
return AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;
case "OPTIONAL":
return AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;
default:
throw new LoginConfigMalformedException(String.format(
"Unknown flag \"%s\". Valid flags are: REQUISITE, "
+ "REQUIRED, SUFFICIENT, OPTIONAL",
flagStr));
}
}
private void addOption(final String option,
final Map<String, String> options) {
final int index = option.indexOf('=');
if (index == -1) {
throw new LoginConfigMalformedException(String.format(
"The option string \"%s\" is malformed.", option));
}
final String key = option.substring(0, index);
final String value = option.substring(index + 1);
options.put(key, value);
}
public static void foo(final LoginConfig config) {
if (config.appConfigs.get("foo") != null) {
config.appConfigs.remove("foo");
}
}
/**
* Convenient constructor taking an arrays of strings containing the
* configuration. Internally this constructor converts the array to a list
* and calls {@link #LoginConfig(java.util.List)}.
*
* @param config The configuration in string form.
*
* @see #LoginConfig(java.util.List)
*/
public LoginConfig(final String[] config) {
this(Arrays.asList(config));
LoginConfig(final Map<String, AppConfigurationEntry[]> appConfigs) {
this.appConfigs = appConfigs;
}
@Override

View File

@ -0,0 +1,308 @@
/*
* 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.core.authentication;
import com.arsdigita.kernel.security.SecurityConfig;
import com.arsdigita.runtime.ConfigError;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.spi.LoginModule;
/**
* Creates a {@link LoginConfig} instance from an array or an list of strings.
*
* The process of creating a {@link LoginConfig} instance from the string values
* like those stored in the {@link SecurityConfig} is a complex process.
* Originally the constructor of the
* {@code com.arsdigita.kernel.security.LoginConfig} class has done all this
* work. Some parts were outsourced to private methods.
*
* The problem with this approach is that several of this method may throw an
* exception/error. But throwing exceptions from a constructor is considered a
* bad practise. Also the private support methods made the original
* {@code LoginConfig} class quite big and complex. Therefore the code has been
* split up. The construction process is now done by this class which creates
* {@code LoginConfig} from a provided list or array of strings. The strings
* must be in the correct format:
*
* <pre>
* context:moduleName:controlFlag[:option1[:option2[:...]]]
* </pre>
*
* <dl>
* <dt>{@code context}</dt>
* <dd>String</dd>
*
* <dt>{@code moduleName}</dt>
* <dd>Fully qualified class name of a {@link LoginModule}.</dd>
*
* <dt>{@code controlFlag}</dt>
* <dd>
* One of the following flags:
* <ul>
* <li>{@code required}</li>
* <li>{@code requisite}</li>
* <li>{@code sufficient}</li>
* <li>{@code optional}</li>
* </ul>
* </dd>
*
* <dt>option</dt>
* <dd>Options for the module in the following format: {@code key=value}</dd>
* </dl>
*
* Examples:
*
* <pre>
* Request:com.arsdigita.kernel.security.CredentialLoginModule:requisite:debug=true
* Register:com.arsdigita.kernel.security.LocalLoginModule:requisite
* Register:com.arsdigita.kernel.security.UserIDLoginModule:requisite
* Register:com.arsdigita.kernel.security.CredentialLoginModule:optional
* </pre>
*
* The build a {@link LoginConfig} first construct an instance of this class and
* pass the string array containing the configuration. For example:
*
* <pre>
* final LoginConfigBuilder loginConfigBuilder =
* new LoginConfigBuilder(SecurityConfig.getInstance().getLoginConfig());
* </pre>
*
* Then call the {@link #build()} method which does all the work:
*
* <pre>
* final LoginConfig loginConfig = loginConfigBuilder.build();
* </pre>
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class LoginConfigBuilder {
private final transient String[] config;
/**
* Creates a new {@code LoginConfigBuilder} for the provided configuration.
*
* @param config The configuration for which an {@link LoginConfig} should
* be created, as array of strings as provided by
* {@link SecurityConfig#getLoginConfig()}.
*/
public LoginConfigBuilder(final String[] config) {
this.config = config;
}
/**
* Creates a {@link LoginConfig} from {@link #config}.
*
* If one entry of the {@link #config} is malformed a {@link ConfigError}
* will be thrown.
*
* @return A {@link LoginConfig} object.
*/
public LoginConfig build() {
//Temporary storage for the data extracted from the config string array.
final Map<String, List<String>> contextConfigs = new HashMap<>();
//Parse the tuples in the config string array.
for (final String tuple : config) {
//Find the index of the first ':'.
final int index = tuple.indexOf(':');
//Extract context and module config parts from the tuple.
final String context = tuple.substring(0, index);
final String moduleConfig = tuple.substring(index + 1);
//Put them in the list for the context.
final List<String> contextConfig = retrieveContextConfig(
context, contextConfigs);
contextConfig.add(moduleConfig);
}
//Create the map of AppConfigurationEntry objects.
final Map<String, AppConfigurationEntry[]> appConfigs = new HashMap<>();
for (final Map.Entry<String, List<String>> entry : contextConfigs
.entrySet()) {
//Add the config entry. The helper method called creates the
//AppConfigurationEntry object from the string value.
addAppConfig(appConfigs, entry.getKey(), entry.getValue());
}
//Create the LoginConfig object with the Map of AppConfigurationEntries.
return new LoginConfig(appConfigs);
}
/**
* Helper method for retrieving a list for specific context from the context
* maps. Used by {@link #build()}. If the map has no entry with the provided
* name a new list is created a put into the list.
*
* @param context The name of the context, used as key in the
* provided map.
* @param contextConfigs The map of context configs.
*
* @return The context configs list for the provided context.
*/
private List<String> retrieveContextConfig(
final String context, final Map<String, List<String>> contextConfigs) {
List<String> contextConfig = contextConfigs.get(context);
if (contextConfig == null) {
contextConfig = new ArrayList<>();
contextConfigs.put(context, contextConfig);
}
return contextConfig;
}
/**
* Helper method for creating an {@link AppConfigurationEntry} object from a
* string.
*
* @param appConfigs The map of {@link AppConfigurationEntry} objects in
* which the created entry will be stored.
* @param name The name of the context for which the
* {@link AppConfigurationEntry} is created.
* @param entries The list of configuration entries to parse.
*/
private void addAppConfig(
final Map<String, AppConfigurationEntry[]> appConfigs,
final String name,
final List<String> entries) {
//Map containing the parsed entries
final AppConfigurationEntry[] configEntries
= new AppConfigurationEntry[entries
.size()];
//Parse all entries. We use a "traditional" for loop here because we
//need the position in the array.
for (int i = 0; i < entries.size(); i++) {
//Load the current configuration entry.
configEntries[i] = loadAppConfigEntry(entries.get(i));
}
//Put the parsed entires into the map
appConfigs.put(name, configEntries);
}
/**
* Helper method for parsing a single configuration entry. The
*
* tokens entry
*
* @return
*/
private AppConfigurationEntry loadAppConfigEntry(final String entry) {
//Split the string tokens. The tokens are limited by the ':' character.
final String[] tokens = entry.split(":");
//If there less then two tokens the entry is malformed and we throw an
//ConfigError.
if (tokens.length < 2) {
final StringBuilder builder = new StringBuilder();
for (final String str : tokens) {
builder.append(str);
}
throw new ConfigError(String.format(
"Malformed SecurityConfig entry: %s", builder.toString()));
}
//Extract the name of the configured module (the first token)
final String name = tokens[0];
//Extract the flat (second token)
final AppConfigurationEntry.LoginModuleControlFlag flag = parseFlag(
tokens[1]);
//Extract the provided options if any
final Map<String, String> options = new HashMap<>();
if (tokens.length > 2) {
for (int i = 2; i < tokens.length; i++) {
//The the option to the map of options.
addOption(tokens[i], options);
}
}
//Create an AppConfguration using the extracted data.
return new AppConfigurationEntry(name, flag, options);
}
/**
* Helper method to convert a string to a
* {@link AppConfigurationEntry.LoginModuleControlFlag}. If the provided
* string is not a valid flag a {@link ConfigError} is thrown.
*
* @param flag The string to convert.
*
* @return {@link AppConfigurationEntry.LoginModuleControlFlag} instance.
*/
private AppConfigurationEntry.LoginModuleControlFlag parseFlag(
final String flag) {
switch (flag.toUpperCase()) {
case "REQUISITE":
return AppConfigurationEntry.LoginModuleControlFlag.REQUISITE;
case "REQUIRED":
return AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
case "SUFFICIENT":
return AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;
case "OPTIONAL":
return AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;
default:
throw new ConfigError(String.format(
"Unknown flag \"%s\". Valid flags are: REQUISITE, "
+ "REQUIRED, SUFFICIENT, OPTIONAL",
flag));
}
}
/**
* Helper method for extracting the key and value parts from an module
* option string. If the option string is malformed an {@link ConfigError}
* is thrown.
*
* @param option The option string to parse.
* @param options The map of options to which the parsed option we be added.
*/
private void addOption(final String option,
final Map<String, String> options) {
//Find the index of the '=' character.
final int index = option.indexOf('=');
//If there is no '=' in the string the option string is invalid
if (index == -1) {
throw new ConfigError(String.format(
"The option string \"%s\" is malformed.", option));
}
//Extract key and value an put them into the options map.
final String key = option.substring(0, index);
final String value = option.substring(index + 1);
options.put(key, value);
}
}

View File

@ -1,45 +0,0 @@
/*
* 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.core.authentication;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class LoginConfigMalformedException extends RuntimeException {
private static final long serialVersionUID = 8573796343232732323L;
/**
* Creates a new instance of <code>NewException</code> without detail
* message.
*/
public LoginConfigMalformedException() {
super();
}
/**
* Constructs an instance of <code>NewException</code> with the specified
* detail message.
*
* @param msg the detail message.
*/
public LoginConfigMalformedException(final String msg) {
super(msg);
}
}

View File

@ -53,13 +53,13 @@ public class LoginManager {
/**
* Name of the register login context.
*/
private static final String REGISTER_LOGIN_CONTEXT = "RegisterLoginContext";
private static final String REGISTER_LOGIN_CONTEXT = "Register";
@Inject
private transient CcmSessionContext sessionContext;
@Inject
private transient UserRepository userRepository;
// @Inject
// private transient UserRepository userRepository;
public void login(final String username, final String password)
throws LoginException {

View File

@ -103,6 +103,7 @@ public class SecurityConfigTest {
.getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage())
.addPackage(org.libreccm.core.authentication.LocalLoginModule.class.getPackage())
.addAsLibraries(libs)
.addAsResource(
"configtests/com/arsdigita/kernel/security/SecurityConfigTest/ccm-core.config",

View File

@ -112,7 +112,7 @@ public class UserManagerTest {
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
"LibreCCM-org.libreccm.core.UserManagerTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.

View File

@ -0,0 +1,252 @@
/*
* 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.core.authentication;
import static org.hamcrest.Matchers.*;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.persistence.PersistenceTest;
import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.libreccm.core.CcmObject;
import org.libreccm.core.CcmSessionContext;
import org.libreccm.core.EmailAddress;
import org.libreccm.tests.categories.IntegrationTest;
import java.io.File;
import javax.inject.Inject;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginException;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Category(IntegrationTest.class)
@RunWith(Arquillian.class)
@PersistenceTest
@Transactional(TransactionMode.COMMIT)
public class LoginManagerTest {
@Inject
private transient LoginManager loginManager;
@Inject
private transient CcmSessionContext ccmSessionContext;
public LoginManagerTest() {
}
@BeforeClass
public static void setUpClass() {
final String[] config = new String[]{
String.format("Register:%s:requisite",
LocalLoginModule.class.getName())};
final LoginConfigBuilder loginConfigBuilder = new LoginConfigBuilder(
config);
Configuration.setConfiguration(loginConfigBuilder.build());
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Deployment
public static WebArchive createDeployment() {
final PomEquippedResolveStage pom = Maven
.resolver()
.loadPomFromFile("pom.xml");
final PomEquippedResolveStage dependencies = pom
.importCompileAndRuntimeDependencies();
final File[] libs = dependencies.resolve().withTransitivity().asFile();
for (File lib : libs) {
System.err.printf("Adding file '%s' to test archive...%n",
lib.getName());
}
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.authentication.LoginManagerTest.war")
.addPackage(CcmObject.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
addPackage(org.libreccm.jpa.EntityManagerProducer.class
.getPackage())
.addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
.getPackage())
.addPackage(org.libreccm.testutils.EqualsVerifier.class.
getPackage())
.addPackage(org.libreccm.core.authentication.LoginManager.class
.getPackage())
.addPackage(com.arsdigita.kernel.KernelConfig.class.getPackage())
.addPackage(com.arsdigita.runtime.AbstractConfig.class.getPackage())
.addPackage(com.arsdigita.util.parameter.AbstractParameter.class
.getPackage())
.addPackage(com.arsdigita.util.UncheckedWrapperException.class
.getPackage())
.addPackage(org.libreccm.tests.categories.IntegrationTest.class
.getPackage())
.addPackage(com.arsdigita.web.CCMApplicationContextListener.class
.getPackage())
.addAsLibraries(libs)
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
.addAsResource(
"configtests/com/arsdigita/kernel/KernelConfigTest/ccm-core.config",
"ccm-core.config")
.addAsWebInfResource(
"configtests/com/arsdigita/kernel/KernelConfigTest/registry.properties",
"conf/registry/registry.properties")
.addAsWebInfResource(
"configtests/com/arsdigita/kernel/KernelConfigTest/kernel.properties",
"conf/registry/ccm-core/kernel.properties")
.addAsResource(
"com/arsdigita/kernel/KernelConfig_parameter.properties",
"com/arsdigita/kernel/KernelConfig_parameter.properties")
.addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
}
@InSequence(1)
public void isLoginManagerInjected() {
assertThat(loginManager, is(not(nullValue())));
}
@InSequence(2)
public void isCcmSessionContextInjected() {
assertThat(ccmSessionContext, is(not(nullValue())));
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.json")
@InSequence(10)
public void loginValidCredentials() throws LoginException {
loginManager.login("jdoe@example.com", "correct-pw");
assertThat(ccmSessionContext.getCurrentParty(), is(not(nullValue())));
final EmailAddress emailAddress = new EmailAddress();
emailAddress.setAddress("jdoe@example.org");
emailAddress.setBouncing(false);
emailAddress.setVerified(true);
assertThat(ccmSessionContext.getCurrentParty().getEmailAddresses(),
contains(equalTo(emailAddress)));
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.json")
@InSequence(20)
public void loginWrongCredentials() throws LoginException {
try {
loginManager.login("jdoe@example.com", "wrong-pw");
} catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentParty(), is(nullValue()));
}
fail("No login exception was thrown.");
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.json")
@InSequence(30)
public void loginEmptyPassword() {
try {
loginManager.login("jdoe@example.com", "");
} catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentParty(), is(nullValue()));
}
fail("No login exception was thrown.");
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.json")
@InSequence(40)
public void loginEmptyUserName() {
try {
loginManager.login("", "correct-pw");
} catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentParty(), is(nullValue()));
}
fail("No login exception was thrown.");
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.json")
@InSequence(50)
public void loginNullPassword() {
try {
loginManager.login("jdoe@example.com", null);
} catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentParty(), is(nullValue()));
}
fail("No login exception was thrown.");
}
@Test
@UsingDataSet(
"datasets/org/libreccm/core/authentication/LoginManagerTest/data.json")
@InSequence(60)
public void loginNullUsername() {
try {
loginManager.login(null, "correct-pw");
} catch (LoginException ex) {
assertThat(ccmSessionContext.getCurrentParty(), is(nullValue()));
}
fail("No login exception was thrown.");
}
}

View File

@ -0,0 +1,30 @@
{
"subjects":
[
{
"subject_id": -10
}
],
"subject_email_addresses":
[
{
"subject_id": -10,
"email_address": "jdoe@example.com",
"bouncing": false,
"verified": true
}
],
"ccm_users":
[
{
"banned": false,
"hash_algorithm": "SHA-512",
"family_name": "Doe",
"given_name": "John",
"password": "abc8f796612f5c5b5d0c89cf86ea3b8d1c7d15f9c06851f85708013b0248b2e6d9b315b48f586168fe6cc29296e5a9090a5aab14a85b3ffd0633ca8ccc587a09",
"salt": "fiagaifa",
"screen_name": "jdoe",
"subject_id": -10
}
]
}