001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
018 */
019
020package org.nuxeo.ecm.platform.login;
021
022import java.util.HashMap;
023import java.util.Map;
024
025import javax.security.auth.callback.CallbackHandler;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029import org.nuxeo.runtime.model.ComponentContext;
030import org.nuxeo.runtime.model.ComponentInstance;
031import org.nuxeo.runtime.model.ComponentName;
032import org.nuxeo.runtime.model.DefaultComponent;
033import org.nuxeo.runtime.model.Extension;
034
035public class LoginPluginRegistry extends DefaultComponent {
036
037    public static final ComponentName NAME = new ComponentName("org.nuxeo.ecm.platform.login.LoginPluginRegistry");
038
039    public static final String EP_PLUGIN = "plugin";
040
041    public static final String EP_CBFACTORY = "callbackFactory";
042
043    private static final Log log = LogFactory.getLog(LoginPluginRegistry.class);
044
045    private LoginPlugin currentLoginPlugin;
046
047    private Map<String, LoginPlugin> loginPluginStack;
048
049    private CallbackFactory callbackFactory;
050
051    private Map<String, LoginPluginDescriptor> pluginDescriptorStack;
052
053    public LoginPluginRegistry() {
054        currentLoginPlugin = null;
055    }
056
057    @Override
058    public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) {
059        if (extensionPoint.equals(EP_PLUGIN)) {
060            log.info("registering Login Plugin ... ");
061            registerPlugin((LoginPluginDescriptor) contribution);
062        } else if (extensionPoint.equals(EP_CBFACTORY)) {
063            log.info("registering Callback factory ... ");
064            registerCBFactory((CallbackFactoryDescriptor) contribution);
065        } else {
066            log.error("Extension point " + extensionPoint + " is unknown!");
067        }
068    }
069
070    private void registerCBFactory(CallbackFactoryDescriptor cbfExtension) {
071        try {
072            callbackFactory = (CallbackFactory) cbfExtension.getClassName().newInstance();
073        } catch (ReflectiveOperationException e) {
074            log.error("Unable to create Factory", e);
075        }
076    }
077
078    private void registerPlugin(LoginPluginDescriptor pluginExtension) {
079        Boolean enabled = pluginExtension.getEnabled();
080        Class<LoginPlugin> className = pluginExtension.getClassName();
081        String pluginName = pluginExtension.getPluginName();
082
083        if (loginPluginStack.containsKey(pluginName)) {
084            // merge
085            LoginPlugin oldLoginPlugin = loginPluginStack.get(pluginName);
086            LoginPluginDescriptor oldLoginPluginDescriptor = pluginDescriptorStack.get(pluginName);
087
088            Map<String, String> mergedParams = oldLoginPluginDescriptor.getParameters();
089            mergedParams.putAll(pluginExtension.getParameters());
090
091            oldLoginPlugin.setParameters(mergedParams);
092            if (!oldLoginPlugin.initLoginModule()) {
093                oldLoginPluginDescriptor.setInitialized(false);
094                log.warn("Unable to initialize LoginPlugin for class " + className.getName());
095            } else {
096                oldLoginPluginDescriptor.setInitialized(true);
097            }
098            if (enabled != null) {
099                oldLoginPluginDescriptor.setEnabled(enabled);
100            }
101        } else {
102            LoginPlugin newLoginPlugin = null;
103            try {
104                newLoginPlugin = className.newInstance();
105            } catch (InstantiationException e) {
106                log.error("Unable to create LoginPlugin for class " + className.getName() + ":" + e.getMessage(), e);
107                return;
108            } catch (IllegalAccessException e) {
109                log.error("Unable to create LoginPlugin for class " + className.getName() + ":" + e.getMessage(), e);
110                return;
111            }
112            newLoginPlugin.setParameters(pluginExtension.getParameters());
113            if (newLoginPlugin.initLoginModule()) {
114                pluginExtension.setInitialized(true);
115                log.info("LoginPlugin initialized for class " + className.getName());
116            } else {
117                pluginExtension.setInitialized(false);
118                log.warn("Unable to initialize LoginPlugin for class " + className.getName());
119            }
120            pluginDescriptorStack.put(pluginName, pluginExtension);
121            loginPluginStack.put(pluginName, newLoginPlugin);
122        }
123    }
124
125    @Override
126    public void unregisterExtension(Extension extension) {
127        currentLoginPlugin = null;
128    }
129
130    @Override
131    public void activate(ComponentContext context) {
132        super.activate(context);
133        loginPluginStack = new HashMap<String, LoginPlugin>();
134        pluginDescriptorStack = new HashMap<String, LoginPluginDescriptor>();
135    }
136
137    @Deprecated
138    public LoginPlugin getPlugin() {
139        return currentLoginPlugin;
140    }
141
142    @Deprecated
143    public Boolean useCustomLoginPlugin() {
144        return currentLoginPlugin != null;
145    }
146
147    public CallbackResult handleSpecifcCallbacks(CallbackHandler callbackHandler) {
148        if (callbackFactory == null) {
149            return null;
150        }
151        return callbackFactory.handleSpecificCallbacks(callbackHandler);
152    }
153
154    public LoginPlugin getPlugin(String pluginName) {
155        if (!pluginDescriptorStack.containsKey(pluginName)) {
156            log.error("Unable to find needed Login Plugin : " + pluginName);
157            return null;
158        }
159
160        LoginPlugin loginPlugin = loginPluginStack.get(pluginName);
161        LoginPluginDescriptor loginPluginDescriptor = pluginDescriptorStack.get(pluginName);
162
163        if (loginPlugin == null) {
164            log.error("Login Plugin : " + pluginName + " is null ");
165            return null;
166        }
167
168        if (!loginPluginDescriptor.getEnabled()) {
169            log.error("Login Plugin : " + pluginName + " is not Enabled ");
170            return null;
171        }
172        return loginPlugin;
173    }
174
175    public LoginPluginDescriptor getPluginDescriptor(String pluginName) {
176        if (!pluginDescriptorStack.containsKey(pluginName)) {
177            log.error("Unable to find needed Login Plugin : " + pluginName);
178            return null;
179        }
180
181        LoginPlugin loginPlugin = loginPluginStack.get(pluginName);
182        LoginPluginDescriptor loginPluginDescriptor = pluginDescriptorStack.get(pluginName);
183
184        if (loginPlugin == null) {
185            log.error("Login Plugin : " + pluginName + " is null ");
186            return null;
187        }
188
189        if (!loginPluginDescriptor.getEnabled()) {
190            log.error("Login Plugin : " + pluginName + " is not Enabled ");
191            return null;
192        }
193        return loginPluginDescriptor;
194    }
195
196}