001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.geronimo.console.securitymanager.realm;
018    
019    import java.io.BufferedReader;
020    import java.io.File;
021    import java.io.FileWriter;
022    import java.io.IOException;
023    import java.io.PrintWriter;
024    import java.io.Serializable;
025    import java.io.StringReader;
026    import java.io.StringWriter;
027    import java.io.Writer;
028    import java.net.MalformedURLException;
029    import java.net.URI;
030    import java.net.URL;
031    import java.net.URLClassLoader;
032    import java.util.ArrayList;
033    import java.util.Arrays;
034    import java.util.Collections;
035    import java.util.HashMap;
036    import java.util.Iterator;
037    import java.util.LinkedHashMap;
038    import java.util.List;
039    import java.util.Map;
040    import java.util.Set;
041    import java.util.SortedSet;
042    
043    import javax.enterprise.deploy.spi.DeploymentManager;
044    import javax.enterprise.deploy.spi.Target;
045    import javax.enterprise.deploy.spi.TargetModuleID;
046    import javax.enterprise.deploy.spi.status.ProgressObject;
047    import javax.management.MalformedObjectNameException;
048    import javax.management.ObjectName;
049    import javax.portlet.ActionRequest;
050    import javax.portlet.ActionResponse;
051    import javax.portlet.PortletConfig;
052    import javax.portlet.PortletException;
053    import javax.portlet.PortletRequest;
054    import javax.portlet.PortletRequestDispatcher;
055    import javax.portlet.PortletSession;
056    import javax.portlet.RenderRequest;
057    import javax.portlet.RenderResponse;
058    import javax.portlet.WindowState;
059    import javax.security.auth.Subject;
060    import javax.security.auth.spi.LoginModule;
061    import javax.xml.namespace.QName;
062    
063    import org.apache.commons.logging.Log;
064    import org.apache.commons.logging.LogFactory;
065    import org.apache.geronimo.console.BasePortlet;
066    import org.apache.geronimo.console.util.PortletManager;
067    import org.apache.geronimo.deployment.xbeans.AbstractServiceType;
068    import org.apache.geronimo.deployment.xbeans.ArtifactType;
069    import org.apache.geronimo.deployment.xbeans.AttributeType;
070    import org.apache.geronimo.deployment.xbeans.DependenciesType;
071    import org.apache.geronimo.deployment.xbeans.EnvironmentType;
072    import org.apache.geronimo.deployment.xbeans.GbeanType;
073    import org.apache.geronimo.deployment.xbeans.ModuleDocument;
074    import org.apache.geronimo.deployment.xbeans.ModuleType;
075    import org.apache.geronimo.deployment.xbeans.ReferenceType;
076    import org.apache.geronimo.deployment.xbeans.ServiceDocument;
077    import org.apache.geronimo.deployment.xbeans.XmlAttributeType;
078    import org.apache.geronimo.gbean.AbstractName;
079    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
080    import org.apache.geronimo.kernel.Kernel;
081    import org.apache.geronimo.kernel.KernelRegistry;
082    import org.apache.geronimo.kernel.config.Configuration;
083    import org.apache.geronimo.kernel.config.ConfigurationManager;
084    import org.apache.geronimo.kernel.config.ConfigurationModuleType;
085    import org.apache.geronimo.kernel.config.ConfigurationUtil;
086    import org.apache.geronimo.kernel.management.State;
087    import org.apache.geronimo.kernel.proxy.GeronimoManagedBean;
088    import org.apache.geronimo.kernel.repository.Artifact;
089    import org.apache.geronimo.kernel.repository.ListableRepository;
090    import org.apache.geronimo.management.geronimo.JCAManagedConnectionFactory;
091    import org.apache.geronimo.security.jaas.JaasLoginModuleChain;
092    import org.apache.geronimo.security.jaas.JaasLoginModuleUse;
093    import org.apache.geronimo.security.jaas.LoginModuleControlFlag;
094    import org.apache.geronimo.security.jaas.LoginModuleControlFlagEditor;
095    import org.apache.geronimo.security.jaas.LoginModuleSettings;
096    import org.apache.geronimo.security.jaas.NamedUPCredentialLoginModule;
097    import org.apache.geronimo.security.realm.SecurityRealm;
098    import org.apache.geronimo.security.realm.providers.FileAuditLoginModule;
099    import org.apache.geronimo.security.realm.providers.GeronimoPasswordCredentialLoginModule;
100    import org.apache.geronimo.security.realm.providers.RepeatedFailureLockoutLoginModule;
101    import org.apache.geronimo.xbeans.geronimo.loginconfig.GerControlFlagType;
102    import org.apache.geronimo.xbeans.geronimo.loginconfig.GerLoginConfigDocument;
103    import org.apache.geronimo.xbeans.geronimo.loginconfig.GerLoginConfigType;
104    import org.apache.geronimo.xbeans.geronimo.loginconfig.GerLoginModuleType;
105    import org.apache.geronimo.xbeans.geronimo.loginconfig.GerOptionType;
106    import org.apache.xmlbeans.XmlCursor;
107    import org.apache.xmlbeans.XmlObject;
108    import org.apache.xmlbeans.XmlOptions;
109    
110    /**
111     * A portlet that lists, creates, and edits security realms.
112     *
113     * @version $Rev: 565912 $ $Date: 2007-08-14 17:03:11 -0400 (Tue, 14 Aug 2007) $
114     */
115    public class SecurityRealmPortlet extends BasePortlet {
116        private final static Log log = LogFactory.getLog(SecurityRealmPortlet.class);
117        private final static String[] SKIP_ENTRIES_WITH = new String[]{"geronimo", "tomcat", "tranql", "commons", "directory", "activemq"};
118        private static final String LIST_VIEW = "/WEB-INF/view/realmwizard/list.jsp";
119        private static final String EDIT_VIEW = "/WEB-INF/view/realmwizard/edit.jsp";
120        private static final String SELECT_TYPE_VIEW = "/WEB-INF/view/realmwizard/selectType.jsp";
121        private static final String CONFIGURE_VIEW = "/WEB-INF/view/realmwizard/configure.jsp";
122        private static final String ADVANCED_VIEW = "/WEB-INF/view/realmwizard/advanced.jsp";
123        private static final String TEST_LOGIN_VIEW = "/WEB-INF/view/realmwizard/testLogin.jsp";
124        private static final String TEST_RESULTS_VIEW = "/WEB-INF/view/realmwizard/testResults.jsp";
125        private static final String SHOW_PLAN_VIEW = "/WEB-INF/view/realmwizard/showPlan.jsp";
126        private static final String USAGE_VIEW = "/WEB-INF/view/realmwizard/usage.jsp";
127        private static final String LIST_MODE = "list";
128        private static final String EDIT_MODE = "edit";
129        private static final String SELECT_TYPE_MODE = "type";
130        private static final String CONFIGURE_MODE = "configure";
131        private static final String ADVANCED_MODE = "advanced";
132        private static final String TEST_LOGIN_MODE = "test";
133        private static final String TEST_RESULTS_MODE = "results";
134        private static final String SHOW_PLAN_MODE = "plan";
135        private static final String EDIT_EXISTING_MODE = "editExisting";
136        private static final String USAGE_MODE = "usage";
137        private static final String SAVE_MODE = "save";
138        private static final String MODE_KEY = "mode";
139        private static final String CUSTOM_MODE = "custom";
140    
141        private static Kernel kernel;
142    
143        private PortletRequestDispatcher listView;
144        private PortletRequestDispatcher editView;
145        private PortletRequestDispatcher selectTypeView;
146        private PortletRequestDispatcher configureView;
147        private PortletRequestDispatcher advancedView;
148        private PortletRequestDispatcher testLoginView;
149        private PortletRequestDispatcher testResultsView;
150        private PortletRequestDispatcher planView;
151        private PortletRequestDispatcher usageView;
152        private static final QName GBEAN_QNAME = new QName(ServiceDocument.type.getDocumentElementName().getNamespaceURI(), "gbean");
153    
154        public void init(PortletConfig portletConfig) throws PortletException {
155            super.init(portletConfig);
156            kernel = KernelRegistry.getSingleKernel();
157            listView = portletConfig.getPortletContext().getRequestDispatcher(LIST_VIEW);
158            editView = portletConfig.getPortletContext().getRequestDispatcher(EDIT_VIEW);
159            selectTypeView = portletConfig.getPortletContext().getRequestDispatcher(SELECT_TYPE_VIEW);
160            configureView = portletConfig.getPortletContext().getRequestDispatcher(CONFIGURE_VIEW);
161            advancedView = portletConfig.getPortletContext().getRequestDispatcher(ADVANCED_VIEW);
162            testLoginView = portletConfig.getPortletContext().getRequestDispatcher(TEST_LOGIN_VIEW);
163            testResultsView = portletConfig.getPortletContext().getRequestDispatcher(TEST_RESULTS_VIEW);
164            planView = portletConfig.getPortletContext().getRequestDispatcher(SHOW_PLAN_VIEW);
165            usageView = portletConfig.getPortletContext().getRequestDispatcher(USAGE_VIEW);
166        }
167    
168        public void destroy() {
169            listView = null;
170            editView = null;
171            selectTypeView = null;
172            configureView = null;
173            advancedView = null;
174            testLoginView = null;
175            usageView = null;
176            planView = null;
177            super.destroy();
178        }
179    
180        public void processAction(ActionRequest actionRequest,
181                ActionResponse actionResponse) throws PortletException, IOException {
182            String mode = actionRequest.getParameter(MODE_KEY);
183            RealmData data = new RealmData();
184            data.load(actionRequest);
185            if (mode.equals(SELECT_TYPE_MODE)) {
186                data.realmType = "Properties File Realm";
187                actionResponse.setRenderParameter(MODE_KEY, SELECT_TYPE_MODE);
188            } else if (mode.equals("process-" + SELECT_TYPE_MODE)) {
189                if (data.getName() != null && !data.getName().trim().equals("")) {
190                    // Config properties have to be set in render since they have values of null
191                    if( doesRealmExist(actionRequest, data.getName())) {
192                        actionResponse.setRenderParameter("SecurityRealmNamingError", "Please provide a unique Security Realm Name, " + data.getName() + " is already in use");
193                        actionResponse.setRenderParameter(MODE_KEY, SELECT_TYPE_MODE);
194                    } else {
195                        if (data.getRealmType().equals("Other")) {
196                            actionResponse.setRenderParameter(MODE_KEY, CUSTOM_MODE);
197                        } else {
198                            actionResponse.setRenderParameter(MODE_KEY, CONFIGURE_MODE);
199                        }
200                    }
201                } else {
202                    actionResponse.setRenderParameter(MODE_KEY, SELECT_TYPE_MODE);
203                }
204            } else if (mode.equals("process-" + CONFIGURE_MODE)) {
205                final String error = actionTestLoginModuleLoad(actionRequest, data);
206                if (error == null) {
207                    actionResponse.setRenderParameter(MODE_KEY, ADVANCED_MODE);
208                } else {
209                    actionResponse.setRenderParameter("LoginModuleError", error);
210                    actionResponse.setRenderParameter(MODE_KEY, CONFIGURE_MODE);
211                }
212            } else if (mode.equals("process-" + ADVANCED_MODE)) {
213                String test = actionRequest.getParameter("test");
214                if (test == null || test.equals("true")) {
215                    actionResponse.setRenderParameter(MODE_KEY, TEST_LOGIN_MODE);
216                } else {
217                    actionSaveRealm(actionRequest, data);
218                    actionResponse.setRenderParameter(MODE_KEY, LIST_MODE);
219                }
220            } else if (mode.equals("process-" + TEST_LOGIN_MODE)) {
221                actionAttemptLogin(data, actionRequest, actionRequest.getPortletSession(true), actionRequest.getParameter("username"), actionRequest.getParameter("password"));
222                actionResponse.setRenderParameter(MODE_KEY, TEST_RESULTS_MODE);
223            } else if (mode.equals(SHOW_PLAN_MODE)) {
224                XmlObject object = actionGeneratePlan(actionRequest, data);
225                savePlanToSession(actionRequest.getPortletSession(true), object);
226                actionResponse.setRenderParameter(MODE_KEY, SHOW_PLAN_MODE);
227            } else if (mode.equals(EDIT_EXISTING_MODE)) {
228                actionLoadExistingRealm(actionRequest, data);
229                actionResponse.setRenderParameter(MODE_KEY, EDIT_MODE);
230            } else if (mode.equals(CONFIGURE_MODE)) {
231                if (data.getAbstractName() != null) {
232                    actionResponse.setRenderParameter(MODE_KEY, EDIT_MODE);
233                } else if((data.getRealmType() != null && data.getRealmType().equals("Other"))) {
234                    actionResponse.setRenderParameter(MODE_KEY, CUSTOM_MODE);
235                } else {
236                    actionResponse.setRenderParameter(MODE_KEY, CONFIGURE_MODE);
237                }
238            } else if (mode.equals(SAVE_MODE)) {
239                actionSaveRealm(actionRequest, data);
240                actionResponse.setRenderParameter(MODE_KEY, LIST_MODE);
241            } else {
242                actionResponse.setRenderParameter(MODE_KEY, mode);
243            }
244            data.store(actionResponse);
245        }
246    
247        protected void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException {
248            if (WindowState.MINIMIZED.equals(renderRequest.getWindowState())) {
249                return;
250            }
251            try {
252                String mode = renderRequest.getParameter(MODE_KEY);
253                RealmData data = new RealmData();
254                data.load(renderRequest);
255                renderRequest.setAttribute("realm", data);
256                if (mode == null || mode.equals("")) {
257                    mode = LIST_MODE;
258                }
259                if (mode.equals(LIST_MODE)) {
260                    renderList(renderRequest, renderResponse);
261                } else if (mode.equals(EDIT_MODE) || mode.equals(CUSTOM_MODE)) {
262                    renderRequest.setAttribute("mode", mode);
263                    if(mode.equals(CUSTOM_MODE)) loadDriverJARList(renderRequest);
264                    renderEdit(renderRequest, renderResponse, data);
265                } else if (mode.equals(SELECT_TYPE_MODE)) {
266                    renderSelectType(renderRequest, renderResponse);
267                } else if (mode.equals(CONFIGURE_MODE)) {
268                    renderConfigure(renderRequest, renderResponse, data);
269                } else if (mode.equals(ADVANCED_MODE)) {
270                    renderAdvanced(renderRequest, renderResponse, data);
271                } else if (mode.equals(TEST_LOGIN_MODE)) {
272                    renderTestLoginForm(renderRequest, renderResponse);
273                } else if (mode.equals(TEST_RESULTS_MODE)) {
274                    renderTestResults(renderRequest, renderResponse);
275                } else if (mode.equals(SHOW_PLAN_MODE)) {
276                    renderPlan(renderRequest, renderResponse);
277                } else if (mode.equals(USAGE_MODE)) {
278                    renderUsage(renderRequest, renderResponse);
279                }
280            } catch (Throwable e) {
281                log.error("Unable to render portlet", e);
282            }
283        }
284    
285        private String actionTestLoginModuleLoad(PortletRequest request, RealmData data) {
286            Map options = new HashMap();
287            try {
288                LoginModule module = loadModule(request, data, options);
289                log.warn("Testing with options " + options);
290                try {
291                    PortletManager.testLoginModule(request, module, options);
292                    return null;
293                } catch (Exception e) {
294                    log.warn("Unable to initialize LoginModule", e);
295                    return "Unable to initialize LoginModule: " + e.getMessage();
296                }
297            } catch (Exception e) {
298                log.warn("Unable to load LoginModule class", e);
299                return "Unable to load LoginModule class: " + e.getMessage();
300            }
301        }
302    
303        private LoginModule loadModule(PortletRequest request, RealmData data, Map options) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
304            ClassLoader loader = getClass().getClassLoader();
305            if (data.jar != null && !data.jar.equals("")) {
306                try {
307                    Artifact one = Artifact.create(data.getJar());
308                    ListableRepository[] repos = PortletManager.getCurrentServer(request).getRepositories();
309                    for (int i = 0; i < repos.length; i++) {
310                        ListableRepository repo = repos[i];
311                        File file = repo.getLocation(one);
312                        if (file != null) {
313                            loader = new URLClassLoader(new URL[]{file.toURL()}, loader);
314                            break;
315                        }
316                    }
317                } catch (MalformedURLException e) {
318                    log.warn("Repository unable to look up JAR file", e);
319                }
320            }
321            Class cls = loader.loadClass(getSelectedModule(data).getClassName());
322            LoginModule module = (LoginModule) cls.newInstance();
323            for (Iterator it = data.getOptions().keySet().iterator(); it.hasNext();) {
324                String key = (String) it.next();
325                final Object value = data.getOptions().get(key);
326                if (value != null && !value.equals("")) {
327                    options.put(key, value);
328                }
329            }
330            options.put(JaasLoginModuleUse.CLASSLOADER_LM_OPTION, loader);
331            return module;
332        }
333    
334        private void actionAttemptLogin(RealmData data, PortletRequest request, PortletSession session, String username, String password) {
335            session.removeAttribute("TestLoginPrincipals");
336            session.removeAttribute("TestLoginError");
337            Map options = new HashMap();
338            try {
339                LoginModule module = loadModule(request, data, options);
340                Subject sub = PortletManager.testLoginModule(request, module, options, username, password);
341                session.setAttribute("TestLoginPrincipals", sub.getPrincipals());
342            } catch (Exception e) {
343                log.warn("Test login failed", e);
344                session.setAttribute("TestLoginError", "Login Failed: " + (e.getMessage() == null ? "no message" : e.getMessage()));
345            }
346        }
347    
348        private XmlObject actionGeneratePlan(PortletRequest request, RealmData data) {
349            normalize(data);
350            ModuleDocument doc = ModuleDocument.Factory.newInstance();
351            ModuleType root = doc.addNewModule();
352            EnvironmentType environment = root.addNewEnvironment();
353            ArtifactType configId = environment.addNewModuleId();
354            configId.setGroupId("console.realm");
355            String artifactId = data.getName();
356            if(artifactId.indexOf('/') != -1) {
357                // slash in artifact-id results in invalid configuration-id and leads to deployment errors.
358                // Note: 0x002F = '/'
359                artifactId = artifactId.replaceAll("/", "%2F");
360            }
361            configId.setArtifactId(artifactId);
362            configId.setVersion("1.0");
363            configId.setType("car");
364    
365            // Parent
366    
367            DependenciesType dependenciesType = environment.addNewDependencies();
368            ArtifactType parent = dependenciesType.addNewDependency();
369            parent.setGroupId("org.apache.geronimo.configs");
370            parent.setArtifactId("j2ee-security");
371            parent.setType("car");
372            // Dependencies
373            if (data.getJar() != null) {
374                ArtifactType artifactType = dependenciesType.addNewDependency();
375                Artifact artifact = Artifact.create(data.getJar());
376                artifactType.setGroupId(artifact.getGroupId());
377                artifactType.setArtifactId(artifact.getArtifactId());
378                artifactType.setVersion(artifact.getVersion().toString());
379                artifactType.setType(artifact.getType());
380            }
381            // Build the realm GBean
382            GbeanType realm = GbeanType.Factory.newInstance();
383            realm.setName(data.getName());
384            realm.setClass1("org.apache.geronimo.security.realm.GenericSecurityRealm");
385            AttributeType realmName = realm.addNewAttribute();
386            realmName.setName("realmName");
387            realmName.setStringValue(data.getName());
388            ReferenceType serverInfo = realm.addNewReference();
389            serverInfo.setName2("ServerInfo");
390            serverInfo.setName((String) PortletManager.getNameFor(request, PortletManager.getCurrentServer(request).getServerInfo()).getName().get("name"));
391            XmlAttributeType config = realm.addNewXmlReference();
392            // Construct the content to put in the XmlAttributeType
393            GerLoginConfigDocument lcDoc = GerLoginConfigDocument.Factory.newInstance();
394            GerLoginConfigType login = lcDoc.addNewLoginConfig();
395            for (int i = 0; i < data.getModules().length; i++) {
396                LoginModuleDetails details = data.getModules()[i];
397                if (details.getLoginDomainName() == null || details.getLoginDomainName().equals("")) {
398                    continue;
399                }
400                GerLoginModuleType module = login.addNewLoginModule();
401                module.setControlFlag(details.getControlFlag().equals(LoginModuleControlFlag.OPTIONAL) ? GerControlFlagType.OPTIONAL :
402                        details.getControlFlag().equals(LoginModuleControlFlag.REQUIRED) ? GerControlFlagType.REQUIRED :
403                                details.getControlFlag().equals(LoginModuleControlFlag.REQUISITE) ? GerControlFlagType.REQUISITE :
404                                        details.getControlFlag().equals(LoginModuleControlFlag.SUFFICIENT) ? GerControlFlagType.SUFFICIENT :
405                                                GerControlFlagType.OPTIONAL);
406                module.setLoginDomainName(details.getLoginDomainName());
407                module.setLoginModuleClass(details.getClassName());
408                module.setWrapPrincipals(details.isWrapPrincipals());
409                for (Iterator it = details.getOptions().entrySet().iterator(); it.hasNext();) {
410                    Map.Entry entry = (Map.Entry) it.next();
411                    GerOptionType option = module.addNewOption();
412                    option.setName((String) entry.getKey());
413                    option.setStringValue((String) entry.getValue());
414                }
415    
416                // bit of a hack -- to put the DataSource module in as a parent for SQL modules
417                if (details.getClassName().indexOf("SQL") > -1) {
418                    String poolName = (String) details.getOptions().get("dataSourceName");
419                    String appName = (String) details.getOptions().get("dataSourceApplication");
420                    if (poolName != null) {
421                        if (appName == null) appName = "null";
422                        JCAManagedConnectionFactory[] factories = PortletManager.getOutboundFactoriesOfType(request, "javax.sql.DataSource");
423                        for (int j = 0; j < factories.length; j++) {
424                            JCAManagedConnectionFactory factory = factories[j];
425                            try {
426                                ObjectName objectName = ObjectName.getInstance(factory.getObjectName());
427                                final String testName = objectName.getKeyProperty(NameFactory.J2EE_NAME);
428                                final String testApp = objectName.getKeyProperty(NameFactory.J2EE_APPLICATION);
429                                if (testName.equals(poolName) && testApp.equals(appName)) {
430                                    String moduleName = objectName.getKeyProperty(NameFactory.JCA_RESOURCE);
431    
432                                    ArtifactType artifactType = dependenciesType.addNewDependency();
433                                    Artifact artifact = Artifact.create(moduleName);
434                                    artifactType.setGroupId(artifact.getGroupId());
435                                    artifactType.setArtifactId(artifact.getArtifactId());
436                                    artifactType.setVersion(artifact.getVersion().toString());
437                                    artifactType.setType(artifact.getType());
438                                    break;
439                                }
440                            } catch (MalformedObjectNameException e) {
441                                log.error("Unable to parse ObjectName", e);
442                            }
443                        }
444                    }
445                }
446            }
447            // Copy the content into the XmlAttributeType
448            XmlCursor loginCursor = lcDoc.newCursor();
449            loginCursor.toFirstContentToken();
450            XmlCursor destination = config.newCursor();
451            destination.toNextToken();
452            loginCursor.moveXml(destination);
453            loginCursor.dispose();
454            destination.dispose();
455            config.setName("LoginModuleConfiguration");
456            root.setServiceArray(new AbstractServiceType[]{realm});
457    
458    
459            //Above code inserts gbean using xsi:type=dep:GBeanType.  We also need to account for the substitution group
460            //by changing the qname:
461            XmlCursor gbeanCursor = root.newCursor();
462            try {
463                if (!gbeanCursor.toChild(ServiceDocument.type.getDocumentElementName())) {
464                    throw new RuntimeException("Could not find service element");
465                }
466                gbeanCursor.setName(GBEAN_QNAME);
467            } finally {
468                gbeanCursor.dispose();
469            }
470    
471            return doc;
472        }
473    
474        private void actionLoadExistingRealm(PortletRequest request, RealmData data) {
475            SecurityRealm realm = (SecurityRealm) PortletManager.getManagedBean(request, new AbstractName(URI.create(data.getAbstractName())));
476            data.name = realm.getRealmName();
477            List list = new ArrayList();
478            JaasLoginModuleChain node = realm.getLoginModuleChain();
479            while (node != null) {
480                LoginModuleDetails details = new LoginModuleDetails();
481                details.setControlFlag(node.getControlFlag());
482                LoginModuleSettings module = node.getLoginModule();
483                details.setLoginDomainName(module.getLoginDomainName());
484                details.setClassName(module.getLoginModuleClass());
485                details.setWrapPrincipals(module.isWrapPrincipals());
486                details.setOptions(module.getOptions());
487                list.add(details);
488                node = node.getNext();
489                if (node == null) {
490                    break;
491                }
492            }
493            data.modules = (LoginModuleDetails[]) list.toArray(new LoginModuleDetails[list.size()]);
494        }
495    
496        private void actionSaveRealm(PortletRequest request, RealmData data) {
497            normalize(data);
498            if (data.getAbstractName() == null || data.getAbstractName().equals("")) { // we're creating a new realm
499                try {
500                    XmlObject plan = actionGeneratePlan(request, data);
501                    data.name = data.name.replaceAll("\\s", "");
502                    DeploymentManager mgr = PortletManager.getDeploymentManager(request);
503                    File tempFile = File.createTempFile("console-deployment", ".xml");
504                    tempFile.deleteOnExit();
505                    log.debug("Writing security realm deployment plan to " + tempFile.getAbsolutePath());
506                    PrintWriter out = new PrintWriter(new FileWriter(tempFile));
507                    savePlanToStream(plan, out);
508                    out.flush();
509                    out.close();
510                    Target[] targets = mgr.getTargets();
511                    ProgressObject po = mgr.distribute(targets, null, tempFile);
512                    waitForProgress(po);
513                    if (po.getDeploymentStatus().isCompleted()) {
514                        TargetModuleID[] ids = po.getResultTargetModuleIDs();
515                        po = mgr.start(ids);
516                        waitForProgress(po);
517                        if (po.getDeploymentStatus().isCompleted()) {
518                            log.info("Deployment completed successfully!");
519                        }
520                    }
521                } catch (IOException e) {
522                    log.error("Unable to save security realm", e);
523                }
524            } else {
525                SecurityRealm realm = (SecurityRealm) PortletManager.getManagedBean(request, new AbstractName(URI.create(data.getAbstractName())));
526                // index existing modules
527                Map nodes = new HashMap();
528                JaasLoginModuleChain node = realm.getLoginModuleChain();
529                while (node != null) {
530                    LoginModuleSettings module = node.getLoginModule();
531                    nodes.put(module.getLoginDomainName(), node);
532                    node = node.getNext();
533                    if (node == null) {
534                        break;
535                    }
536                }
537                // apply settings
538                for (int i = 0; i < data.getModules().length; i++) {
539                    LoginModuleDetails details = data.getModules()[i];
540                    node = (JaasLoginModuleChain) nodes.get(details.getLoginDomainName());
541                    node.setControlFlag(details.getControlFlag());
542                    LoginModuleSettings module = node.getLoginModule();
543                    module.setOptions(details.getOptions());
544                    module.setWrapPrincipals(details.isWrapPrincipals());
545                    module.setLoginModuleClass(details.getClassName());
546                }
547            }
548        }
549    
550        private void renderList(RenderRequest request, RenderResponse response) throws IOException, PortletException {
551            // Unfortunately there are two classes named SecurityRealm; one extends the other
552            // The array type is management.geronimo.SecurityRealm (the superclass)
553            // The array entry types are security.realm.SecurityRealm (the subclass)
554            org.apache.geronimo.management.geronimo.SecurityRealm[] realms = PortletManager.getCurrentServer(request).getSecurityRealms();
555            ExistingRealm[] results = new ExistingRealm[realms.length];
556    
557            // ConfigurationManager is used to determine if the SecurityRealm is deployed as a "SERVICE", i.e., "Server-wide"
558            ConfigurationManager configMgr = null;
559            if(results.length > 0) {
560                // Needed only when there are any SecurityRealms
561                configMgr = ConfigurationUtil.getConfigurationManager(kernel);
562            }
563            for (int i = 0; i < results.length; i++) {
564                final GeronimoManagedBean managedBean = (GeronimoManagedBean) realms[i];
565                AbstractName abstractName = PortletManager.getNameFor(request, realms[i]);
566                String parent;
567                Configuration parentConfig = configMgr.getConfiguration(abstractName.getArtifact());
568                ConfigurationModuleType parentType = parentConfig.getModuleType();
569                if(ConfigurationModuleType.SERVICE.equals(parentType)) {
570                    parent = null; // Server-wide
571                } else {
572                    parent = abstractName.getArtifact().toString();
573                }
574                results[i] = new ExistingRealm(realms[i].getRealmName(), abstractName, managedBean.getState(), parent);
575            }
576            // Once done, release the ConfigurationManager
577            if(configMgr != null) {
578                ConfigurationUtil.releaseConfigurationManager(kernel, configMgr);
579            }
580            request.setAttribute("realms", results);
581            listView.include(request, response);
582        }
583    
584        private void renderEdit(RenderRequest request, RenderResponse response, RealmData data) throws IOException, PortletException {
585            normalize(data);
586            editView.include(request, response);
587        }
588    
589        private void renderSelectType(RenderRequest request, RenderResponse response) throws IOException, PortletException {
590            request.setAttribute("moduleTypes", MasterLoginModuleInfo.getAllModules());
591            if (request.getParameter("SecurityRealmNamingError") != null) {
592                request.setAttribute("SecurityRealmNamingError", request.getParameter("SecurityRealmNamingError"));
593            }
594            selectTypeView.include(request, response);
595        }
596    
597        private void renderConfigure(RenderRequest request, RenderResponse response, RealmData data) throws IOException, PortletException {
598            // Pass errors through
599            if (request.getParameter("LoginModuleError") != null) {
600                request.setAttribute("LoginModuleError", request.getParameter("LoginModuleError"));
601            }
602            // Clear out any cached modules
603            data.modules = null;
604            // Configure option list
605            MasterLoginModuleInfo info = getSelectedModule(data);
606            for (int i = 0; i < info.getOptions().length; i++) {
607                MasterLoginModuleInfo.OptionInfo option = info.getOptions()[i];
608                if (!data.getOptions().containsKey(option.getName())) {
609                    data.getOptions().put(option.getName(), null);
610                }
611            }
612            data.reorderOptions(info.getOptions());
613            request.setAttribute("optionMap", info.getOptionMap());
614            if (info.getName().indexOf("SQL") > -1) {
615                loadDriverJARList(request);
616                loadDatabasePoolList(request);
617            }
618            configureView.include(request, response);
619        }
620    
621        private void renderAdvanced(RenderRequest request, RenderResponse response, RealmData data) throws IOException, PortletException {
622            // Clear out any cached modules
623            data.modules = null;
624            // Show the page
625            advancedView.include(request, response);
626        }
627    
628        private void renderTestLoginForm(RenderRequest request, RenderResponse response) throws IOException, PortletException {
629            testLoginView.include(request, response);
630        }
631    
632        private void renderTestResults(RenderRequest request, RenderResponse response) throws IOException, PortletException {
633            PortletSession session = request.getPortletSession();
634            String status = (String) session.getAttribute("TestLoginError");
635            if (status == null) {
636                Set principals = (Set) session.getAttribute("TestLoginPrincipals");
637                status = "Login succeeded with " + (principals == null ? 0 : principals.size()) + " principals";
638                request.setAttribute("principals", principals);
639            }
640            request.setAttribute("LoginResults", status);
641            testResultsView.include(request, response);
642        }
643    
644        private void renderPlan(RenderRequest request, RenderResponse response) throws IOException, PortletException {
645            String plan = (String) request.getPortletSession().getAttribute("SecurityRealmPlan");
646            request.setAttribute("deploymentPlan", plan);
647            planView.include(request, response);
648        }
649    
650        private void renderUsage(RenderRequest request, RenderResponse response) throws IOException, PortletException {
651            usageView.include(request, response);
652        }
653    
654        private static MasterLoginModuleInfo getSelectedModule(RealmData data) {
655            MasterLoginModuleInfo[] all = MasterLoginModuleInfo.getAllModules();
656            for (int i = 0; i < all.length; i++) {
657                MasterLoginModuleInfo info = all[i];
658                if (info.getName().equals(data.getRealmType())) {
659                    return info;
660                }
661            }
662            return null;
663        }
664    
665        private void loadDatabasePoolList(RenderRequest renderRequest) {
666            JCAManagedConnectionFactory[] factories = PortletManager.getOutboundFactoriesOfType(renderRequest, "javax.sql.DataSource");
667            List pools = new ArrayList();
668            try {
669                for (int i = 0; i < factories.length; i++) {
670                    JCAManagedConnectionFactory factory = factories[i];
671                    ObjectName objectName = ObjectName.getInstance(factory.getObjectName());
672                    final String name = objectName.getKeyProperty(NameFactory.J2EE_NAME);
673                    String display = name;
674                    final String appName = objectName.getKeyProperty(NameFactory.J2EE_APPLICATION);
675                    if (appName != null && !appName.equals("null")) {
676                        display = display + " (" + appName + ")";
677                    }
678                    pools.add(new DatabasePool(name, display, appName, PortletManager.getNameFor(renderRequest, factory)));
679                }
680                renderRequest.setAttribute("pools", pools);
681            } catch (MalformedObjectNameException e) {
682                log.error("Unable to parse ObjectName", e);
683            }
684        }
685    
686        private void loadDriverJARList(RenderRequest renderRequest) {
687            // List the available JARs
688            List list = new ArrayList();
689            ListableRepository[] repos = PortletManager.getCurrentServer(renderRequest).getRepositories();
690            for (int i = 0; i < repos.length; i++) {
691                ListableRepository repo = repos[i];
692    
693                SortedSet artifacts = repo.list();
694                outer:
695                for (Iterator iterator = artifacts.iterator(); iterator.hasNext();) {
696                    Artifact artifact = (Artifact) iterator.next();
697                    String test = artifact.toString();
698                    // todo should only test groupId and should check for long (org.apache.geronimo) and short form
699                    for (int k = 0; k < SKIP_ENTRIES_WITH.length; k++) {
700                        String skip = SKIP_ENTRIES_WITH[k];
701                        if (test.indexOf(skip) > -1) {
702                            continue outer;
703                        }
704                    }
705                    list.add(test);
706                }
707            }
708            Collections.sort(list);
709            renderRequest.setAttribute("jars", list);
710        }
711    
712        private void savePlanToSession(PortletSession session, XmlObject object) {
713            StringWriter out = new StringWriter();
714            try {
715                savePlanToStream(object, out);
716                session.setAttribute("SecurityRealmPlan", out.getBuffer().toString());
717            } catch (IOException e) {
718                log.error("Unable to write deployment plan", e);
719            }
720        }
721    
722        private void savePlanToStream(XmlObject object, Writer out) throws IOException {
723            XmlOptions options = new XmlOptions();
724            options.setSavePrettyPrint();
725            options.setSavePrettyPrintIndent(4);
726            options.setUseDefaultNamespace();
727            object.save(out, options);
728            out.close();
729        }
730    
731        private static void waitForProgress(ProgressObject po) {
732            while (po.getDeploymentStatus().isRunning()) {
733                try {
734                    Thread.sleep(100);
735                } catch (InterruptedException e) {
736                    log.error(e.getMessage(), e);
737                }
738            }
739        }
740    
741        public static void normalize(RealmData data) {
742            List list = new ArrayList();
743            if (data.modules == null) {
744                LoginModuleDetails module = new LoginModuleDetails();
745                module.setClassName(getSelectedModule(data).getClassName());
746                module.setControlFlag(LoginModuleControlFlag.REQUIRED);
747                module.setLoginDomainName(data.getName());
748                Map<String, Object> props = module.getOptions();
749                for (Iterator it = data.getOptions().entrySet().iterator(); it.hasNext();) {
750                    Map.Entry entry = (Map.Entry) it.next();
751                    props.put((String) entry.getKey(), (String) entry.getValue());
752                }
753                list.add(module);
754                if (data.isStorePassword()) {
755                    module = new LoginModuleDetails();
756                    module.setClassName(GeronimoPasswordCredentialLoginModule.class.getName());
757                    module.setControlFlag(LoginModuleControlFlag.OPTIONAL);
758                    module.setLoginDomainName(data.getName() + "-Password");
759                    list.add(module);
760                }
761                if (data.getAuditPath() != null) {
762                    module = new LoginModuleDetails();
763                    module.setClassName(FileAuditLoginModule.class.getName());
764                    module.setControlFlag(LoginModuleControlFlag.OPTIONAL);
765                    module.setLoginDomainName(data.getName() + "-Audit");
766                    props = module.getOptions();
767                    props.put("file", data.getAuditPath());
768                    list.add(module);
769                }
770                if (data.isLockoutEnabled()) {
771                    module = new LoginModuleDetails();
772                    module.setClassName(RepeatedFailureLockoutLoginModule.class.getName());
773                    module.setControlFlag(LoginModuleControlFlag.REQUISITE);
774                    module.setLoginDomainName(data.getName() + "-Lockout");
775                    props = module.getOptions();
776                    props.put("failureCount", data.getLockoutCount());
777                    props.put("failurePeriodSecs", data.getLockoutWindow());
778                    props.put("lockoutDurationSecs", data.getLockoutDuration());
779                    list.add(module);
780                }
781                if (data.getCredentialName() != null) {
782                    module = new LoginModuleDetails();
783                    module.setClassName(NamedUPCredentialLoginModule.class.getName());
784                    module.setControlFlag(LoginModuleControlFlag.OPTIONAL);
785                    module.setLoginDomainName(data.getName() + "-NamedUPC");
786                    props = module.getOptions();
787                    props.put(NamedUPCredentialLoginModule.CREDENTIAL_NAME, data.getCredentialName());
788                    list.add(module);
789                }
790            } else {
791                list.addAll(Arrays.asList(data.modules));
792            }
793            if (data.getAbstractName() == null) {
794                for (int i = list.size(); i < 5; i++) {
795                    LoginModuleDetails module = new LoginModuleDetails();
796                    list.add(module);
797                }
798            }
799            data.modules = (LoginModuleDetails[]) list.toArray(new LoginModuleDetails[list.size()]);
800        }
801    
802        public static class RealmData implements Serializable {
803            private String name;
804            private String realmType;
805            private String jar;
806            private Map options = new LinkedHashMap();
807            private String auditPath;
808            private String lockoutCount;
809            private String lockoutWindow;
810            private String lockoutDuration;
811            private boolean storePassword;
812            private String abstractName; // used when editing existing realms
813            private LoginModuleDetails[] modules;
814            private String credentialName;
815    
816            public void load(PortletRequest request) {
817                name = request.getParameter("name");
818                if (name != null && name.equals("")) name = null;
819                realmType = request.getParameter("realmType");
820                if (realmType != null && realmType.equals("")) realmType = null;
821                jar = request.getParameter("jar");
822                if (jar != null && jar.equals("")) jar = null;
823                auditPath = request.getParameter("auditPath");
824                if (auditPath != null && auditPath.equals("")) auditPath = null;
825                lockoutCount = request.getParameter("lockoutCount");
826                if (lockoutCount != null && lockoutCount.equals("")) lockoutCount = null;
827                lockoutWindow = request.getParameter("lockoutWindow");
828                if (lockoutWindow != null && lockoutWindow.equals("")) lockoutWindow = null;
829                lockoutDuration = request.getParameter("lockoutDuration");
830                if (lockoutDuration != null && lockoutDuration.equals("")) lockoutDuration = null;
831                abstractName = request.getParameter("abstractName");
832                if (abstractName != null && abstractName.equals("")) abstractName = null;
833                String test = request.getParameter("storePassword");
834                storePassword = test != null && !test.equals("") && !test.equals("false");
835                credentialName = request.getParameter("credentialName");
836                if (credentialName != null && credentialName.equals("")) credentialName = null;
837                Map map = request.getParameterMap();
838                for (Iterator it = map.keySet().iterator(); it.hasNext();) {
839                    String key = (String) it.next();
840                    if (key.startsWith("option-")) {
841                        if (key.equals("option-databasePoolAbstractName"))
842                        { // special handling for a data source, where there's one select corresponding to two properties
843                            String nameString = request.getParameter(key);
844                            if (nameString != null && !nameString.equals("")) {
845                                AbstractName an = new AbstractName(URI.create(nameString));
846                                options.put("dataSourceName", an.getNameProperty(NameFactory.J2EE_NAME));
847                                options.put("dataSourceApplication", an.getNameProperty(NameFactory.J2EE_APPLICATION));
848                            }
849                        } else {
850                            final String optionName = key.substring(7);
851                            final String value = request.getParameter(key);
852                            if (value != null && !value.equals("")) {
853                                options.put(optionName, value);
854                            }
855                        }
856                    }
857                }
858                int count = 0;
859                List list = new ArrayList();
860                while (true) {
861                    int index = count;
862                    ++count;
863                    String name = request.getParameter("module-domain-" + index);
864                    if (name == null || name.equals("")) break;
865                    LoginModuleDetails details = new LoginModuleDetails();
866                    details.setLoginDomainName(name);
867                    String cls = request.getParameter("module-class-" + index);
868                    if (cls == null || cls.equals("")) continue;
869                    details.setClassName(cls);
870                    String flag = request.getParameter("module-control-" + index);
871                    if (flag == null || flag.equals("")) continue;
872                    details.setControlFlag(toFlag(flag));
873                    String wrap = request.getParameter("module-wrap-" + index);
874                    if (wrap == null || wrap.equals("")) continue;
875                    details.setWrapPrincipals(Boolean.valueOf(wrap).booleanValue());
876                    String options = request.getParameter("module-options-" + index);
877                    if (options != null && !options.equals("")) {
878                        BufferedReader in = new BufferedReader(new StringReader(options));
879                        String line;
880                        try {
881                            while ((line = in.readLine()) != null) {
882                                if (line.startsWith("#") || line.equals("")) {
883                                    continue;
884                                }
885                                int pos = line.indexOf('=');
886                                if (pos > -1) {
887                                    details.getOptions().put(line.substring(0, pos), line.substring(pos + 1));
888                                }
889                            }
890                        } catch (IOException e) {
891                            log.error("Unable to read properties '" + options + "'", e);
892                        }
893                    }
894                    list.add(details);
895                }
896                if (list.size() > 0) {
897                    modules = (LoginModuleDetails[]) list.toArray(new LoginModuleDetails[list.size()]);
898                }
899            }
900    
901            private LoginModuleControlFlag toFlag(String flag) {
902                LoginModuleControlFlagEditor editor = new LoginModuleControlFlagEditor();
903                editor.setAsText(flag);
904                return (LoginModuleControlFlag) editor.getValue();
905            }
906    
907            public void reorderOptions(MasterLoginModuleInfo.OptionInfo[] info) {
908                if (info == null || info.length == 0) {
909                    return; // Probably SQL or something that handles this manually
910                }
911                Map map = new LinkedHashMap();
912                for (int i = 0; i < info.length; i++) {
913                    if (options.containsKey(info[i].getName())) {
914                        map.put(info[i].getName(), options.get(info[i].getName()));
915                    }
916                }
917                options = map;
918            }
919    
920            public void store(ActionResponse response) {
921                if (name != null) response.setRenderParameter("name", name);
922                if (realmType != null) response.setRenderParameter("realmType", realmType);
923                if (jar != null) response.setRenderParameter("jar", jar);
924                if (auditPath != null) response.setRenderParameter("auditPath", auditPath);
925                if (lockoutCount != null) response.setRenderParameter("lockoutCount", lockoutCount);
926                if (lockoutWindow != null) response.setRenderParameter("lockoutWindow", lockoutWindow);
927                if (lockoutDuration != null) response.setRenderParameter("lockoutDuration", lockoutDuration);
928                if (abstractName != null) response.setRenderParameter("abstractName", abstractName);
929                if (storePassword) response.setRenderParameter("storePassword", "true");
930                if (credentialName != null) response.setRenderParameter("credentialName", credentialName);
931                for (Iterator it = options.keySet().iterator(); it.hasNext();) {
932                    String name = (String) it.next();
933                    String value = (String) options.get(name);
934                    if (value != null) {
935                        response.setRenderParameter("option-" + name, value);
936                    }
937                }
938                if (modules != null) {
939                    for (int i = 0; i < modules.length; i++) {
940                        LoginModuleDetails module = modules[i];
941                        if (module.getLoginDomainName() != null)
942                            response.setRenderParameter("module-domain-" + i, module.getLoginDomainName());
943                        if (module.getClassName() != null)
944                            response.setRenderParameter("module-class-" + i, module.getClassName());
945                        if (module.getControlFlag() != null)
946                            response.setRenderParameter("module-control-" + i,module.getControlFlag().toString());
947                        response.setRenderParameter("module-wrap-" + i, Boolean.toString(module.isWrapPrincipals()));
948                        if (module.getOptions().size() > 0)
949                            response.setRenderParameter("module-options-" + i, module.getOptionString());
950                    }
951                }
952            }
953    
954            public String getName() {
955                return name;
956            }
957    
958            public String getRealmType() {
959                return realmType;
960            }
961    
962            public Map getOptions() {
963                return options;
964            }
965    
966            public Set getOptionNames() {
967                return options.keySet();
968            }
969    
970            public String getJar() {
971                return jar;
972            }
973    
974            public String getAuditPath() {
975                return auditPath;
976            }
977    
978            public String getLockoutCount() {
979                return lockoutCount;
980            }
981    
982            public String getLockoutWindow() {
983                return lockoutWindow;
984            }
985    
986            public String getLockoutDuration() {
987                return lockoutDuration;
988            }
989    
990            public boolean isStorePassword() {
991                return storePassword;
992            }
993    
994            public boolean isLockoutEnabled() {
995                return lockoutCount != null || lockoutWindow != null || lockoutDuration != null;
996            }
997    
998            public String getCredentialName() {
999                return credentialName;
1000            }
1001    
1002            public String getAbstractName() {
1003                return abstractName;
1004            }
1005    
1006            public boolean isTestable() {
1007                return getSelectedModule(this).isTestable();
1008            }
1009    
1010            public LoginModuleDetails[] getModules() {
1011                return modules;
1012            }
1013        }
1014    
1015        public static class LoginModuleDetails implements Serializable {
1016            private String loginDomainName;
1017            private String className;
1018            private LoginModuleControlFlag controlFlag;
1019            private boolean wrapPrincipals = false;
1020            private Map<String, Object> options = new HashMap<String, Object>();
1021    
1022            public String getLoginDomainName() {
1023                return loginDomainName;
1024            }
1025    
1026            public void setLoginDomainName(String loginDomainName) {
1027                this.loginDomainName = loginDomainName;
1028            }
1029    
1030            public String getClassName() {
1031                return className;
1032            }
1033    
1034            public void setClassName(String className) {
1035                this.className = className;
1036            }
1037    
1038            public LoginModuleControlFlag getControlFlag() {
1039                return controlFlag;
1040            }
1041    
1042            public void setControlFlag(LoginModuleControlFlag controlFlag) {
1043                this.controlFlag = controlFlag;
1044            }
1045    
1046            public Map<String, Object> getOptions() {
1047                return options;
1048            }
1049    
1050            public void setOptions(Map<String, Object> options) {
1051                this.options = options;
1052            }
1053    
1054            public boolean isWrapPrincipals() {
1055                return wrapPrincipals;
1056            }
1057    
1058            public void setWrapPrincipals(boolean wrapPrincipals) {
1059                this.wrapPrincipals = wrapPrincipals;
1060            }
1061    
1062            public String getOptionString() {
1063                StringBuffer buf = new StringBuffer();
1064                for (Iterator it = options.keySet().iterator(); it.hasNext();) {
1065                    String key = (String) it.next();
1066                    buf.append(key).append("=").append(options.get(key)).append("\n");
1067                }
1068                return buf.toString();
1069            }
1070        }
1071    
1072        public static class ExistingRealm implements Serializable {
1073            private final String name;
1074            private final String abstractName;
1075            private final String parentName;
1076            private final int state;
1077    
1078            public ExistingRealm(String name, AbstractName abstractName, int state, String parent) {
1079                this.name = name;
1080                this.abstractName = abstractName.toString();
1081                parentName = parent;
1082                this.state = state;
1083    
1084            }
1085    
1086            public String getName() {
1087                return name;
1088            }
1089    
1090            public String getAbstractName() {
1091                return abstractName;
1092            }
1093    
1094            public String getParentName() {
1095                return parentName;
1096            }
1097    
1098            public int getState() {
1099                return state;
1100            }
1101    
1102            public String getStateName() {
1103                return State.toString(state);
1104            }
1105        }
1106    
1107        public static class DatabasePool implements Serializable, Comparable {
1108            private final String name;
1109            private final String displayName;
1110            private final String applicationName;
1111            private final String abstractName;
1112    
1113            public DatabasePool(String name, String displayName, String applicationName, AbstractName abstractName) {
1114                this.name = name;
1115                this.displayName = displayName;
1116                this.applicationName = applicationName;
1117                this.abstractName = abstractName.toString();
1118            }
1119    
1120            public String getName() {
1121                return name;
1122            }
1123    
1124            public String getApplicationName() {
1125                return applicationName;
1126            }
1127    
1128            public String getAbstractName() {
1129                return abstractName;
1130            }
1131    
1132            public String getDisplayName() {
1133                return displayName;
1134            }
1135    
1136            public int compareTo(Object o) {
1137                final DatabasePool pool = (DatabasePool) o;
1138                int names = name.compareTo(pool.name);
1139                if (applicationName == null) {
1140                    if (pool.applicationName == null) {
1141                        return names;
1142                    } else {
1143                        return -1;
1144                    }
1145                } else {
1146                    if (pool.applicationName == null) {
1147                        return 1;
1148                    } else {
1149                        int test = applicationName.compareTo(pool.applicationName);
1150                        if (test != 0) {
1151                            return test;
1152                        } else {
1153                            return names;
1154                        }
1155                    }
1156                }
1157            }
1158        }
1159    
1160        /**
1161         * When adding a new security determine if the realm name is already registered.
1162         *
1163         * @param request - the request associated with the current user
1164         * @param realmName -  the realm name to check and see if it already exists
1165         *
1166         * @return boolean - if the relam name already exists.
1167         */
1168        private boolean doesRealmExist(PortletRequest request, String realmName) {
1169            org.apache.geronimo.management.geronimo.SecurityRealm[] realms = PortletManager.getCurrentServer(request).getSecurityRealms();
1170            boolean exist = false;
1171            for (int i = 0; i < realms.length; i++) {
1172                org.apache.geronimo.management.geronimo.SecurityRealm result = realms[i];
1173    
1174                if( result.getRealmName().equalsIgnoreCase(realmName)){
1175                    exist = true;
1176                    break;
1177                }
1178            }
1179            return exist;
1180        }
1181    }