appConfigs = new HashMap<>();
+
+ private LoginConfig() {
+ //Nothing.
+ }
+
+ /**
+ * 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:
+ *
+ *
+ * context:moduleName:controlFlag[:option1[:option2[:...]]]
+ *
+ *
+ *
+ *
+ * - context
+ * - String
+ *
+ * - moduleName
+ * - String
+ *
+ * - controlFlag
+ * - "required"
+ * - "requisite"
+ * - "sufficient"
+ * - "optional"
+ *
+ * - option
+ * - "key=value"
+ *
+ *
+ *
+ * Example:
+ *
+ *
+ * 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
+ *
+ *
+ * @param config The configuration in string format.
+ *
+ */
+ public LoginConfig(final List config) {
+ final Map> 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 contextConfig = retrieveContextConfig(
+ context, contextConfigs);
+
+ contextConfig.add(moduleConfig);
+ }
+
+ for (final Map.Entry> entry : contextConfigs.
+ entrySet()) {
+ addAppConfig(entry.getKey(), entry.getValue());
+ }
+ }
+
+ private List retrieveContextConfig(
+ final String context, final Map> contextConfigs) {
+ List contextConfig = contextConfigs.get(context);
+
+ if (contextConfig == null) {
+ contextConfig = new ArrayList<>();
+ contextConfigs.put(context, contextConfig);
+ }
+
+ return contextConfig;
+ }
+
+ private void addAppConfig(final String name, final List entries) {
+ final AppConfigurationEntry[] configEntries
+ = new AppConfigurationEntry[entries.size()];
+ for (int i = 0; i < entries.size(); i++) {
+ final List entry = Arrays.asList(entries.get(i).split(":"));
+ configEntries[i] = loadAppConfigEntry(entry);
+
+ }
+ appConfigs.put(name, configEntries);
+ }
+
+ private AppConfigurationEntry loadAppConfigEntry(final List 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 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 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));
+ }
+
+ @Override
+ public AppConfigurationEntry[] getAppConfigurationEntry(final String name) {
+ return appConfigs.get(name);
+ }
+
+ @Override
+ public void refresh() {
+ // Nothing
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/core/authentication/LoginConfigMalformedException.java b/ccm-core/src/main/java/org/libreccm/core/authentication/LoginConfigMalformedException.java
new file mode 100644
index 000000000..c349284c8
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/core/authentication/LoginConfigMalformedException.java
@@ -0,0 +1,45 @@
+/*
+ * 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 Jens Pelzetter
+ */
+public class LoginConfigMalformedException extends RuntimeException {
+ private static final long serialVersionUID = 8573796343232732323L;
+
+ /**
+ * Creates a new instance of NewException without detail
+ * message.
+ */
+ public LoginConfigMalformedException() {
+ super();
+ }
+
+ /**
+ * Constructs an instance of NewException with the specified
+ * detail message.
+ *
+ * @param msg the detail message.
+ */
+ public LoginConfigMalformedException(final String msg) {
+ super(msg);
+ }
+}