CCM NG: Old login app ported to CCM NG including UI. Compiles but is not tested yet!

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3673 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2015-10-08 09:12:25 +00:00
parent 33cfd945a3
commit 56d545d175
81 changed files with 7064 additions and 399 deletions

View File

@ -101,6 +101,11 @@
<groupId>oro</groupId>
<artifactId>oro</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
<dependency>
<groupId>net.sf.jtidy</groupId>

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2001-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.bebop;
import com.arsdigita.xml.Element;
import org.apache.log4j.Logger;
/**
* A component that gets its text entirely from a single XSL element.
*
* @author Sameer Ajmani
* @version $Id$
**/
public class ElementComponent extends SimpleComponent {
private static final Logger s_log =
Logger.getLogger(ElementComponent.class.getName());
private String m_name;
private String m_uri;
/**
* Constructs an ElementComponent that uses the element with the given
* name under the given XSL namespace URI.
*
* @param name the name of the element to use
* @param uri the URI of the XSL namespace
**/
public ElementComponent(String name, String uri) {
m_name = name;
m_uri = uri;
}
/**
* Constructs a new element with the name and namespace given in this
* component's constructor, and adds the element to the parent element.
* @param state the current page state
* @param parent the parent element for this new element
**/
public void generateXML(PageState state, Element parent) {
parent.newChildElement(m_name, m_uri);
}
}

View File

@ -0,0 +1,323 @@
/*
* Copyright (C) 2001-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.bebop;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.arsdigita.xml.Element;
import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.util.Assert;
import com.arsdigita.web.URL;
import com.arsdigita.web.ParameterMap;
import org.apache.log4j.Logger;
/**
* A URL on a page. May contain a label, an image, or any other component.
* A Link is a BaseLink that manages URL variables.
*
* <p> <b>Example:</b> The common usage for a Link component is
* illustrated in the code fragment below:
*
* <pre>
* Page p = new Page("Link Example");
* Link link = new Link(new Label(GlobalizedMessage),"path/to/target/");
* link.setVar("foo","1");
* p.add(link);
* </pre>
*
* <p> The target of the link above will be rendered in HTML as:
* <tt>href="path/to/target/?foo=1"</tt>
* If either the link text or the URL needs to be changed for a link
* within a locked page, a {@link PrintListener} should be used.
*
* @version $Id$
*/
public class Link extends BaseLink {
private static final Logger s_log = Logger.getLogger(ParameterMap.class);
private static final String FRAME_TARGET_ATTR = "target";
private URL m_webURL = null;
private ParameterMap m_params = new ParameterMap();
/**
* The value for the XML type attribute for a plain link.
*/
protected final String TYPE_LINK = "link";
/**
* <p>Passing this value to {@link #setTargetFrame setTargetFrame} will
* create a link that opens a new browser window whenever it is clicked.
*</p>
*
* @see #setTargetFrame
*/
public static final String NEW_FRAME = "_blank";
/** initialization steps common to all constructors */
private void init() {
setTypeAttr(TYPE_LINK);
}
/**
* Constructor creates a link taking url as the target and display it to
* the user at the same time. It is the only allowed way to present the
* user with a not globlized information. The implementation currently
* miss-uses the Label component to display just a not globalized String
* which is deprecated.
*
* @param url
* @deprecated use BaseLink(Component,url) instead with a Label using a
* GlobalizedMessage instead
*/
public Link(final String url) {
super(new Label(url), url);
}
/**
* Constructor, creates a link with a globalized label or an image as label.
*
* @param child The <tt>Component</tt> parameter in this constructor is
* usually a {@link Label} or {@link Image}.
* @param url Starting with release 5.2, this method prefixes the passed-in
* url with the path to the CCM dispatcher. Code using this
* constructor should not prefix <code>url</code> with the
* webapp context path or the dispatcher servlet path.
*
* The vast majority of CCM UI code expects to link through
* the dispatcher. Code that does not should use the
* <code>Link</code> constructor taking a <code>URL</code>.
* @see #Link(String,URL)
*/
public Link(Component child, String url) {
super(child, url);
init();
}
/**
* Constructors with <tt>PrintListener</tt> parameters allow for a
* {@link PrintListener} to be set for the Link, without the need
* to make a separate call to the <tt>addPrintListener</tt> method.
* PrintListeners are a convenient way to alter underlying Link
* attributes such as Link text or target URL within a locked page
* on a per request basis.
*
* @param child
* @param l
*/
public Link(Component child, PrintListener l) {
super(child, l);
init();
}
/**
* Constructors with <tt>PrintListener</tt> parameters allow for a
* {@link PrintListener} to be set for the Link, without the need to make a
* separate call to the <tt>addPrintListener</tt> method. PrintListeners
* are a convenient way to alter underlying Link attributes such as Link
* text or target URL within a locked page on a per request basis.
*
* @deprecated refactor to use Link(Component,PrintListener) to provide a
* globalized label for the link.
*/
public Link(String label, PrintListener l) {
super(label,l);
init();
}
/**
* Constructors with <tt>PrintListener</tt> parameters allow for a
* {@link PrintListener} to be set for the Link, without the need to make a
* separate call to the <tt>addPrintListener</tt> method. PrintListeners
* are a convenient way to alter underlying Link attributes such as Link
* text or target URL within a locked page on a per request basis.
*
* @param listener PrintListener, may be used to change either the Display
* text or the url within a locked page.
*/
public Link(PrintListener listener) {
super(listener);
init();
}
/**
* <p>This constructor is a common one for a Link component, as it allows
* for the Link text and the target URL to be set at the same time during
* construction.</p>
*
* <p>Starting with release 5.2, this method prefixes the
* passed-in <code>url</code> with the path to the CCM dispatcher.
* Code using this constructor should not prefix <code>url</code>
* with the webapp context path or the dispatcher servlet
* path.</p>
*
* <p>The vast majority of CCM UI code expects to link through the
* dispatcher. Code that does not should use the
* <code>Link</code> constructor taking a <code>URL</code>.</p>
*
* @see #Link(String,URL)
* @deprecated refactor to use Link(Component,PrintListener) to provide a
* globalized label for the link.
*/
public Link(String label, String url) {
super(label, url);
init();
}
/**
* <p>Constructs a Link using a <code>URL</code>. When this constructor is
* used, the method {@link #setVar(String,String)} and its deprecated
* equivalent have no effect on the resulting hyperlink. Instead, use the
* <code>ParameterMap</code> argument to <code>URL</code>.</p>
*
* @see com.arsdigita.web.URL
* @see com.arsdigita.web.ParameterMap
* @param label a <code>String</code> of label text
* @param url a <code>URL</code> for the link's target
* @deprecated refactor to use Link(Component,URL) to provide a
* globalized label for the link.
*/
public Link(String label, URL url) {
super(label, url.toString());
init();
m_webURL = url;
}
@Override
public Object clone() throws CloneNotSupportedException {
Link result = (Link) super.clone();
result.m_params = (ParameterMap) m_params.clone();
return result;
}
/**
* Sets a query variable and its value. Overwrites any values that may
* have been set previously under the specified name.
* <p>
* All the variables set with this method are appended to the
* query string in the URL that is output for this <code>Link</code>.
*
* @param name the name of the query
* @param value the value for the query
* @pre name != null
*/
public void setVar(String name, String value) {
Assert.isUnlocked(this);
m_params.setParameter(name, value);
}
// No longer used anywhere in the code base
// /**
// * Set a query variable and its value
// * @deprecated use {@link #setVar setVar}
// */
// public void addURLVars(String name, String value) {
// setVar(name, value);
// }
/**
*
* @return
* may be this method should be deprecated as well as addURLVars?
*/
public String getURLVarString() {
return m_params.toString();
}
/**
* <p>Get the "target" attribute of the link, which determines
* which browser frame will load the new page when this link is
* clicked.</p>
*/
public String getTargetFrame() {
return getAttribute(FRAME_TARGET_ATTR);
}
/**
* <p>Set the "target" attribute of the link, which determines
* which browser frame will load the new page when this link is
* clicked.</p>
*/
public void setTargetFrame(String frameName) {
setAttribute(FRAME_TARGET_ATTR, frameName);
}
/**
*
* @param state
* @param parent
*/
protected void generateURL(PageState state, Element parent) {
parent.addAttribute("href", prepareURL(state, getTarget()));
exportAttributes(parent);
}
/**
* Processes the URL for this link after the print listener runs.
*
* @param location the original URL
*
* @return the URL appended with ACS-specific URL parameters.
*/
protected String prepareURL(final PageState state, String location) {
final HttpServletRequest req = state.getRequest();
final HttpServletResponse resp = state.getResponse();
if (m_webURL == null) {
m_params.runListeners(req);
if (location.startsWith("/")) {
location = URL.getDispatcherPath() + location;
}
if (location.indexOf("?") == -1) {
// m_params adds the "?" as needed.
return resp.encodeURL(location + m_params);
} else {
// The location already includes a query string, so
// append to it without including a "?".
if (location.endsWith("&")) {
return resp.encodeURL(location +
m_params.getQueryString());
} else {
return resp.encodeURL(location +
"&" + m_params.getQueryString());
}
}
} else {
return m_webURL.toString();
}
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright (C) 2001-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.bebop;
import static com.arsdigita.bebop.Component.*;
import java.util.Iterator;
import com.arsdigita.xml.Element;
/**
* A container that outputs its components in a &lt;list&gt;. Each child is
* printed in its own list item. The components are put into the list
* in the order in which they were added to the
* <code>ListPanel</code>, progressing from top to bottom.
*
* <p> ListPanels can be ordered or unordered.</p>
*
* @author Christian Brechb&uuml;hler (christian@arsdigita.com)
*
* @version $Id$
* */
public class ListPanel extends SimpleContainer {
public static final boolean ORDERED = true ;
public static final boolean UNORDERED = false;
private boolean m_ordered;
/**
* Creates a simple list.
* @param ordered <code>true</code> is an ordered (numbered) list;
* <code>false</code> is an unordered (bulleted) list
*
*/
public ListPanel(boolean ordered) {
m_ordered = ordered;
}
/**
* Adds child components as a subtree under list-item nodes.
* <p>Generates a DOM fragment:
* <p><pre>
* &lt;bebop:listPanel>
* &lt;bebop:cell> ... cell contents &lt;/bebop:cell>
* &lt;bebop:cell> ... cell contents &lt;/bebop:cell>
* ...
* &lt;/bebop:list></pre></p>
* @param state the state of the current request
* @param parent the node under which this subtree will be added
*/
public void generateXML(PageState state, Element parent) {
if ( ! isVisible(state) ) {
return;
}
Element list = parent.newChildElement("bebop:listPanel", BEBOP_XML_NS);
list.addAttribute("ordered", String.valueOf(m_ordered));
exportAttributes(list);
// generate XML for children
for (Iterator i = children(); i.hasNext(); ) {
Component c = (Component) i.next();
Element item = list.newChildElement("bebop:cell", BEBOP_XML_NS);
c.generateXML(state, item);
}
}
}

View File

@ -0,0 +1,291 @@
/*
* Copyright (C) 2002-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.bebop;
import com.arsdigita.util.UncheckedWrapperException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* <p>The <code>PageFactory</code> provides a framework for
* instantiating instances of the Bebop <code>Page</code> class in a
* project- and application-independant manner.</p>
*
* <h3>History</h3>
*
* <p>The traditional approach to writing bebop applications is to
* subclass the com.arsdigita.bebop.Page, adding various components to
* provide navigation & layout and writing custom XSL for styling
* purposes.</p>
*
* <p>The problem of this approach is that when multiple applications
* are combined to form a complete site, is it difficult to produce an
* integrated navigation infrastructure & uniform styling across all
* pages. In addition, by placing application specific functionality
* in a subclass of Page, the ability to reuse & embed applications
* within each other is hampered since Page objects cannot be
* nested.</p>
*
* <h3>Use Case</h3>
*
* <p>The PageFactory addresses the following situations</p>
*
* <ol>
* <li>It is common for all pages on a site to have a particular
* structure. ie, header, footer, left sidebar & main content area. </li>
*
* <li>It is desirable to customize page structure without making code changes
* to individual applications. </li>
* </ol>
*
* <h3>Example Usage</h3>
*
* <p>The point of interaction for PageFactory is typically in the
* application's Dispatcher class. Rather than invoking the Page
* constructor (ie <code>new Page(title)</code>), applications call
* <code>PageFactory.buildPage(title, "appname")</code> This method
* will return an instance of Page with the currently configured
* navigation components added.</p>
*
* <p>The two compulsory arguments to the <code>buildPage</code>
* method are the name of the application (ie, 'forum', 'cms'), and
* the page title (either as a String or Label object). The
* application name is used as key in both the enterprise.init file
* configuration & the XSL templates. There is optionally a third
* string <code>id</code> parameter which provides a unique identifier
* for the page within the application. If the page class is a
* subclass of ApplicationPage this will be used to set the XML
* <code>id</code> attribute.</p>
*
* <p>Consider the following example (based loosely on the Simple
* Survey application):</p>
*
* <pre>
* package com.arsdigita.simplesurvey.dispatcher;
*
* import com.arsdigita.simplesurvey.ui.IndexPanel;
* import com.arsdigita.simplesurvey.ui.AdminPanel;
* import com.arsdigita.simplesurvey.ui.SurveySelectionModel;
* import com.arsdigita.bebop.BigDecimalParameter;
* import com.arsdigita.bebop.page.BebopMapDispatcher;
*
* public class Dispatcher extends BebopMapDispatcher {
*
* public Dispatcher() {
* Page index = buildIndexPage();
* Page admin = buildAdminPage();
*
*
* addPage("index.jsp",index);
* addPage("", index);
* addPage("admin/index.jsp",index);
* addPage("admin", index);
* }
*
* private Page buildIndexPage() {
* SurveySelectionModel survey =
* new SurveySelectionModel(new BigDecimalParameter("survey"));
*
* Page page = PageFactory.buildPage("simplesurvey",
* "Simple Survey",
* "index");
* page.add(IndexPanel(survey));
* page.addGlobalStateParam(survey.getStateParameter());
* page.lock();
* return page;
* }
*
* private Page buildAdminPage() {
* SurveySelectionModel survey =
* new SurveySelectionModel(new BigDecimalParameter("survey"));
*
* Page page = PageFactory.buildPage("simplesurvey",
* "Simple Survey Administration",
* "admin");
* page.add(AdminPanel(survey));
* page.addGlobalStateParam(survey.getStateParameter());
* page.lock();
* return page;
* }
*
* }
* </pre>
*
* <h3>Updating existing applications</h3>
*
* <p>The process of updating existing applications to make use of the
* PageFactory varies according to the complexity of the application
* in question.</p>
*
* <p>In the simplest case where an application has not subclassed the
* Page class, then it is just a case of replacing calls to <code>new
* Page(title)</code> with <code>PageFactory.buildPage("appname",
* title)</code>.</p>
*
* <p>When an application has subclassed Page, then the initial
* approach is to change the subclass in question so that it derives
* from SimpleContainer instead of Page. Any calls to the
* <code>addGlobalStateParam</code> or <code>addRequestListener</code>
* methods can be moved from the constructor into the
* <code>register</code> method where there will be direct access to
* the <code>Page</code> object.</p>
*
* <h3>Configuring the page factory</h3>
*
* <p>The <code>com.arsdigita.bebop.base_page</code> system property
* may be used to specify the full name of a subclass of Page which
* provides the constructor signature detailed in the
* <code>setPageClass</code> method. If omitted it defaults to
* <code>BasePage</code>.</p>
*
* <p>The <code>com.arsdigita.ui</code> package provides an
* alternative subclass called <code>SimplePage</code> which supports
* specification.</p>
*
* @see com.arsdigita.bebop.BasePage
*/
public class PageFactory {
private static Class s_page;
private static Constructor s_cons;
private static boolean initialized = false;
static void init() {
if (initialized) {
return;
}
setPageClass(Bebop.getConfig().getBasePageClass());
}
/**
* Sets the page class to instantiate. The
* class should have a public constructor that
* takes three arguments. The first 'String'
* argument is the name of the application, the
* second 'Label' is the page title, and the
* third (optionally null) argument is a page
* id (unique string with this application).
*
* The common case is to inherit from ApplicationPage
* and pass these three arguments straight through
* to its constructor.
*
* @param page the page class
*/
public static void setPageClass(Class page) {
try {
s_cons = page.getConstructor(new Class[] {
String.class, Label.class, String.class
});
s_page = page;
initialized = true;
} catch (NoSuchMethodException ex) {
throw new UncheckedWrapperException(
"cannot find constructor " + s_page.getName() +
"(String application, Label title, String id)",
ex
);
} catch (SecurityException ex) {
throw new UncheckedWrapperException(
"cannot retrieve constructor for " + s_page.getName(),
ex
);
}
}
/**
* Instantiates a new instance of the Page class.
*
* @param application the application name
* @param title the page title
* @return a subclass of com.arsdigita.bebop.Page
*/
public static Page buildPage(String application,
String title) {
return buildPage(application, new Label(title));
}
/**
* Instantiates a new instance of the Page class,
* with the optional unique page id string.
*
* @param application the application name
* @param title the page title
* @param id the page id within the application
* @return a subclass of com.arsdigita.bebop.Page
*/
public static Page buildPage(String application,
String title,
String id) {
return buildPage(application, new Label(title), id);
}
/**
* Instantiates a new instance of the Page class.
*
* @param application the application name
* @param title the label for the page title
* @return a subclass of com.arsdigita.bebop.Page
*/
public static Page buildPage(String application,
Label title) {
return buildPage(application, title, null);
}
/**
* Instantiates a new instance of the Page class,
* with the optional unique page id string.
*
* @param application the application name
* @param title the label for the page title
* @param id the page id within the application
* @return a subclass of com.arsdigita.bebop.Page
*/
public static Page buildPage(String application,
Label title,
String id) {
init();
Page page = null;
try {
page = (Page)s_cons.newInstance(new Object[] {
application, title, id
});
} catch (InstantiationException ex) {
throw new UncheckedWrapperException(
"cannot instantiate page class " + s_page.getName(), ex
);
} catch (IllegalArgumentException ex) {
throw new UncheckedWrapperException(
"cannot instantiate page class " + s_page.getName(), ex
);
} catch (IllegalAccessException ex) {
throw new UncheckedWrapperException(
"constructor for page class " + s_page.getName() +
" is not public", ex
);
} catch (InvocationTargetException ex) {
throw new UncheckedWrapperException(
"cannot instantiate page class " + s_page.getName(), ex
);
}
return page;
}
}

View File

@ -0,0 +1,190 @@
/*
* 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.bebop.page;
import com.arsdigita.bebop.Page;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.templating.PresentationManager;
import com.arsdigita.templating.Templating;
import com.arsdigita.util.Assert;
import com.arsdigita.web.BaseApplicationServlet;
import com.arsdigita.xml.Document;
import org.apache.log4j.Logger;
import org.libreccm.web.CcmApplication;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A common servlet to provide a generic URL-to-Bebop-Page map based dispatch
* pattern. It provides methods to setup a url - page map. The doService method
* uses the request's URL to determine the page to display and forwards to the
* presentation manager for the Page handling.
*
* This class is a servlet based version of BebopMapDispatcher and associated
* classes and is generally used in the same way by legacy free applications.
*
* Subclasses usually overwrite the doInit() method to create Page objects and
* use this.put method to construct the mapping.
*
* Subclasses may overwrite the doService method to add additional
* functionality, e.g. permission checking.
*
* @author Justin Ross &lt;jross@redhat.com&gt;
* @author chris gilbert - allow BebopApplicationServlet pages to disable
* client/middleware
*/
public class BebopApplicationServlet extends BaseApplicationServlet {
private static final long serialVersionUID = -6004503025521189639L;
private static final Logger s_log = Logger.getLogger(
BebopApplicationServlet.class);
/**
* URL (pathinfo) -> Page object mapping. Based on it (and the http request
* url) the doService method to selects a page to display
*/
private final Map m_pages = new HashMap();
// Set of pathinfo
private final Set m_clientCacheDisabledPages = new HashSet();
/**
* Initializer uses parent class's initializer to setup the servlet request
* / response and application context. Usually a user of this class will NOT
* overwrite this method but the user extension point doInit() to perform
* local initialization tasks, in case of this servlet typically to setup
* the page-url mapping using the provided mapping methods of this class.
*
* @throws ServletException
*/
@Override
public void init() throws ServletException {
super.init();
}
/**
* User extension point, overwrite this method to setup a URL - page mapping
*
* @throws ServletException
*/
@Override
public void doInit() throws ServletException {
// nothing here
}
/**
* Adds one Url-Page mapping to the internal mapping table.
*
* @param pathInfo url stub for a page to display
* @param page Page object to display
*/
protected final void put(final String pathInfo,
final Page page) {
Assert.exists(pathInfo, String.class);
Assert.exists(page, Page.class);
// Current Implementation requires pathInfo to start with a leading '/'
// SUN Servlet API specifies: "PathInfo *may be empty* or will start
// with a '/' character."
Assert.isTrue(pathInfo.startsWith("/"), "path starts not with '/'");
m_pages.put(pathInfo, page);
}
/**
* Adds the provided page as specified by its pathInfo information to an
* internal list of pages for which client/middleware caching will be
* disabled when serving the page (added by Chris Gilbert).
*
* @param pathInfo - the same path used to add the page when put was called
*/
protected final void disableClientCaching(String pathInfo) {
Assert.exists(pathInfo, String.class);
Assert.isTrue(m_pages.containsKey(pathInfo),
"Page " + pathInfo + " has not been put in servlet");
m_clientCacheDisabledPages.add(pathInfo);
}
/**
* Main processing unit searches in the page map for the request's url and
* forwards the page to display to the appropriate presentation manager to
* serve the page.
*
* @param sreq
* @param sresp
* @param app
*
* @throws ServletException
* @throws IOException
*/
@Override
protected final void doService(final HttpServletRequest sreq,
final HttpServletResponse sresp,
final CcmApplication app)
throws ServletException, IOException {
final String pathInfo = sreq.getPathInfo();
Assert.exists(pathInfo, "String pathInfo");
final Page page = (Page) m_pages.get(pathInfo);
if (page == null) {
sresp.sendError(404, "Application not found");
throw new IllegalStateException("No such page for path " + pathInfo);
} else {
if (m_clientCacheDisabledPages.contains(pathInfo)) {
DispatcherHelper.cacheDisable(sresp);
}
preprocessRequest(sreq, sresp, app, pathInfo);
final Document doc = page.buildDocument(sreq, sresp);
PresentationManager pm = Templating.getPresentationManager();
pm.servePage(doc, sreq, sresp);
}
}
/**
* Provides the opportunity for subclasses to do some preprocessing of a
* given url, before it is handed off to main service process. One typical
* action is to ensure permissions.
*
* @param sreq
* @param sresp
* @param app
* @param url
*
* @throws javax.servlet.ServletException
* @throws java.io.IOException
*/
protected void preprocessRequest(HttpServletRequest sreq,
HttpServletResponse sresp,
CcmApplication app,
String url)
throws ServletException, IOException {
// Nothing to do by default.
}
}

View File

@ -0,0 +1,113 @@
/*
* 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 com.arsdigita.kernel.security;
import com.arsdigita.util.Classes;
import java.util.Iterator;
import java.util.List;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class Util {
private static SecurityConfig s_conf = SecurityConfig.getConfig();
private static SecurityHelper s_helper = null;
/**
* list of excluded extensions
*/
private static List s_exclExts = null;
// private static List s_exclExts = s_conf.getExcludedExtensions();
/**
* This class needs not to be instantiated.
*/
private Util() {
}
/**
* Returns the security helper instance.
*
* @return the security helper instance.
*
*
*/
public static SecurityHelper getSecurityHelper() {
if (s_helper == null) {
s_helper = (SecurityHelper) Classes.newInstance(
DefaultSecurityHelper.class);
}
return s_helper;
}
/**
* Set the security helper instance. package local
*/
static void setSecurityHelper(Object helper) {
s_helper = (SecurityHelper) helper;
}
/**
* Get a using a callback.
*
* @return an HttpServletRequest
*
* @throws LoginException if an error occurs.
*/
// static HttpServletRequest getRequest(CallbackHandler handler)
// throws LoginException {
//
// try {
// HTTPRequestCallback cb = new HTTPRequestCallback();
// handler.handle(new Callback[]{cb});
// return cb.getRequest();
// } catch (IOException e) {
// throw new KernelLoginException("IO error getting HTTP request", e);
// } catch (UnsupportedCallbackException e) {
// throw new KernelLoginException("Error getting HTTP request", e);
// }
// }
/**
* Returns an iterator over the list of excluded extensions.
*
* @return an iterator over the list of excluded extensions.
*/
// TODO: Currently method is used by CredentialLoginModule only. If no other
// class will use it, it is trivial and should directly be moved over there.
public static Iterator getExcludedExtensions() {
// Alternativly we may introduce a setExkludedExtensions method as with
// setSecurityHelper and avoid a reference to config object here at all.
// Nevertheless, we shoul use it consistantly!
if (s_exclExts == null) {
s_exclExts = s_conf.getExcludedExtensions();
// return java.util.Collections.EMPTY_LIST.iterator();
}
return s_exclExts.iterator();
}
}

View File

@ -0,0 +1,180 @@
/*
* Copyright (C) 2001-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.mail;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import javax.activation.DataSource;
/**
* Provides a simple DataSource that allows in-memory data
* objects to be attached to a mail message.
*
* <p>Based on the sample code distributed with the JavaMail 1.2 API.
*
* @author Ron Henderson
* @version $Id$
*/
public class ByteArrayDataSource implements DataSource {
/**
* Holds the data for this DataSource
*/
private byte[] m_data;
/**
* MIME type of the data
*/
private String m_type;
/**
* Name of the data (optional)
*/
private String m_name;
/**
* Creates a data source from an input stream.
*
* @param is the InputStream to read from
* @param type the MIME type of the data
* @param name the name of the data
*/
public ByteArrayDataSource (InputStream is,
String type,
String name)
{
m_type = type;
m_name = name;
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
int ch;
while ((ch = is.read()) != -1) {
os.write(ch);
}
m_data = os.toByteArray();
} catch (IOException ioex) {
// do something
}
}
/**
* Creates a data source from a byte array.
*
* @param data the byte array containing the data
* @param type the MIME type of the data
* @param name the name of the data
*/
public ByteArrayDataSource (byte[] data,
String type,
String name)
{
m_data = data;
m_type = type;
m_name = name;
}
/**
* Creates a data source from a String, assuming the data only
* contains ASCII characters (iso-8859-1).
*
* @param data the String containing the data
* @param type the MIME type of the data
* @param name the name of the data
*/
public ByteArrayDataSource (String data,
String type,
String name)
{
this(data,type,name,"iso-8859-1");
}
/**
* Creates a data source from a String using a specified character
* set.
*
* @param data the String containing the data
* @param type the MIME type of the data
* @param name the name of the data
* @param charset the encoding used for the String
*/
public ByteArrayDataSource (String data,
String type,
String name,
String charset)
{
m_type = type;
m_name = name;
try {
m_data = data.getBytes(charset);
} catch (UnsupportedEncodingException uex) {
// do something
}
}
/**
* Returns an input stream for the data.
*/
public InputStream getInputStream() throws IOException {
if (m_data == null) {
throw new IOException("no data");
}
return new ByteArrayInputStream(m_data);
}
/**
* Required by the interface, but not available.
*/
public OutputStream getOutputStream() throws IOException {
throw new IOException("not implemented");
}
/**
* Returns the MIME type of the content.
*/
public String getContentType() {
return m_type;
}
/**
* Returns the name of the content.
*/
public String getName() {
return m_name;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
/*
* Copyright (C) 2001-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.mail;
// JavaMail API
import javax.mail.Session;
import javax.mail.MessagingException;
/**
* Extends the standard MimeMessage to supply the correct value for
* MessageID on all outbound email.
*
* @version $Id$
*/
final class MimeMessage extends javax.mail.internet.MimeMessage {
// Constants
private static final String MESSAGE_ID = "Message-ID";
private String m_messageID;
/**
* Default constructor.
*/
public MimeMessage (Session session) {
super(session);
}
/**
* Called by the saveChanges() method to update the MIME headers.
*/
protected void updateHeaders()
throws MessagingException
{
super.updateHeaders();
if (m_messageID != null) {
try {
setHeader(MESSAGE_ID, m_messageID);
} catch (MessagingException mex) {
// ignore
}
}
}
public void setMessageID(String messageID) {
m_messageID = messageID;
}
}

View File

@ -21,7 +21,7 @@ package com.arsdigita.templating;
import com.arsdigita.web.Web;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
import javax.servlet.http.HttpServletRequest;
@ -48,7 +48,7 @@ public class ApplicationOIDPatternGenerator implements PatternGenerator {
public String[] generateValues(String key,
HttpServletRequest req) {
final Application application = Web.getWebContext().getApplication();
final CcmApplication application = Web.getWebContext().getApplication();
if (application != null) {
String[] oid = new String[1];

View File

@ -26,8 +26,7 @@ import com.arsdigita.web.Web;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.libreccm.web.Application;
import org.libreccm.web.ApplicationType;
import org.libreccm.web.CcmApplication;
/**
* Generates a set of pattern values based on the application key, eg
@ -41,7 +40,7 @@ public class ApplicationPatternGenerator implements PatternGenerator {
private static final Logger s_log = Logger.getLogger(PatternGenerator.class);
/**
* Implementation iof the Interface class.
* Implementation of the Interface class.
*
* @param key
* @param req
@ -54,10 +53,9 @@ public class ApplicationPatternGenerator implements PatternGenerator {
s_log.debug("Processing Application with key: " + key);
final Application app = Web.getWebContext().getApplication();
final CcmApplication app = Web.getWebContext().getApplication();
if (app != null) {
String[] returnValue = {((ApplicationType) app.getResourceType())
.getTitle()};
String[] returnValue = {app.getApplicationType()};
s_log.debug("Found application >>" + returnValue
+ "<< in Application.");
return returnValue;

View File

@ -27,7 +27,7 @@ import com.arsdigita.web.Web;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
/**
@ -155,7 +155,7 @@ public class URLPatternGenerator implements PatternGenerator {
private String getBasePath() {
// retrieve the application of the request
Application app = Web.getWebContext().getApplication();
CcmApplication app = Web.getWebContext().getApplication();
if (app == null) {
return "/";
} else {

View File

@ -23,7 +23,7 @@ import com.arsdigita.web.Web;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
/**
* Generates a set of patterns corresponding to the current web application
@ -52,7 +52,7 @@ public class WebAppPatternGenerator implements PatternGenerator {
public String[] generateValues(String key,
HttpServletRequest req) {
Application app = Web.getWebContext().getApplication();
CcmApplication app = Web.getWebContext().getApplication();
String ctx = (app == null) ? null : "";
if (app == null || ctx == null || "".equals(ctx)) {

View File

@ -0,0 +1,233 @@
/*
*
* 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.ui;
import com.arsdigita.ui.login.LoginServlet;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
/**
* <p>A central location for commonly used UI services and their accessories.</p>
*
*
* @author pb
*/
public abstract class UI {
/** Private loggin instance. */
private static final Logger s_log = Logger.getLogger(UI.class);
/** The UI XML namespace. */
public static final String UI_XML_NS = "http://www.arsdigita.com/ui/1.0";
private static final UIConfig s_config = UIConfig.getConfig();
/** URL for systems public top level page (entry or start page). */
private static final String s_rootPageURL = s_config.getRootPage();
/** URL to page a user should be redirected to after login. */
private static final String s_userRedirectURL = s_config.getUserRedirect();
/** (Absolute) URL for workspace page. */
private static final String s_workspaceURL = s_config.getWorkspace();
/**
* Provides a handle to the UI config record.
*
* @return Instance of UIConfig
*/
public static UIConfig getConfig() {
return s_config;
}
/**
* Provides an absolute URL (leading slash) into the system top-level page
* (entry page / start page). It is relative to document root without any
* constant prefix if there is one configured.
*
* Method is typically called by servlets and especially by JSP's.
*
* Currently just a wrapper script to getRootPageURL() because req is
* currently ignored.
*
* @param req HttpServletRequest, may be used to determin the context of
* the current thread (application), currently not used and
* introduced here for backwards compatibility
*
* @return URL for top-level page as String
*/
public static String getRootPageURL(HttpServletRequest req) {
return getRootPageURL();
}
/**
* Provides an absolute URL (leading slash) into the system top-level page
* (entry page / start page). It is relative to document root without any
* constant prefix if there is one configured.
*
* Method is typically called by servlets and especially by JSP's.
*
* @return URL for top-level page as String
*/
public static String getRootPageURL() {
return s_rootPageURL;
}
/**
* Provides the absolute URL of a page, which redirects an incomming request
* based on some clients property, usually whether the user is logged in,
* either to a general public page or to a user (client) specific page.
*
* It is relative to document root including leading slash but without any
* constant prefix if there is one configured.
*
* It is typically used after login to redirect to an appropriate page, by
* default to /peremissions/. A site should configure an application
* to their specific purposes. e.g ccm-cms provides a page
* content-center/redirect.jsp which redirects a user to the content-center
* if logged in.
*
* @return full URL of a user redirect page, may be null
*/
public static String getUserRedirectURL() {
return s_userRedirectURL;
}
/**
* Wrapper method for {@see getUserRedirectURL()}
* which redirects a user to the content-center if logged in.
*
* Method is specifically used by various redirect JSP's.
*
* @param req HttpServletRequest, may be used to determin the context of
* the current thread (application), currently not used and
* introduced here for backwards compatibility
* @return full URL of a user redirect page, may be null
*/
public static String getUserRedirectURL(HttpServletRequest req) {
return getUserRedirectURL();
}
/**
* Provides the absolute URL for the system workspace page. It is relative
* to document root including leading slash but without any constant prefix
* if there is one configured.
*
* It is used by the user redirection page (see above) as redirection target
* if no logged in user exists or no user specific page is configured. By
* default it is configured as "pvt/" as well. An installation usually
* defines a different page according to their specific purposes, e.g.
* portal or navigation.
*
* @return URL for workspace page as String
*/
public static String getWorkspaceURL() {
return s_workspaceURL;
}
/**
* Provides the absolute URL for the system workspace page.
* It is relative to document root including leading slash but without any
* constant prefix if there is one configured.
*
* Method is typically called by servlets and especially by JSP's.
*
* Currently just a wrapper script to getWorkspaceURL() because req is
* currently ignored.
*
* @param req HttpServletRequest, may be used to determin the context of
* the current thread (application), currently not used and
* introduced here for backwards compatibility
*
* @return URL for workspace page as String
*/
// In old LegacyInitializer
// WORKSPACE_PAGE_KEY = page.kernel.workspace=pvt/ (mod- t0 portal/nav)
public static String getWorkspaceURL(HttpServletRequest req) {
return getWorkspaceURL();
}
// ////////////////////////////////////////////////////////////////////////
// Various deprfecated methods, to be removed as soon as invoking code is
// refactored.
// ////////////////////////////////////////////////////////////////////////
/**
* Provides an absolute URL (leading slash) into the system login page.
* It is relative to document root without any constant prefix if there is
* one configured.
*
* @return URL for login page as String
* @deprecated use Login.getLoginPageURL()() instead
*/
public static String getLoginPageURL() {
return LoginServlet.LOGIN_PAGE_URL;
}
/**
* Provides an absolute URL (leading slash) for a cookie explanation page.
* It is relative to document root without any constant prefix if there is
* one configured.
*
* @return url String for new user registration page as String
* @deprecated use LoginServlet.getCookiesExplainPageURL() instead
*/
public static String getCookiesExplainPageURL() {
return LoginServlet.getCookiesExplainPageURL();
}
/**
* Provides an absolute URL (leading slash) for a password recovery page.
* It is relative to document root without any constant prefix if there is
* one configured.
*
* @return url String for new user registration page as String
* @deprecated use LoginServlet.getRecoverPasswordPageURL() instead
*/
public static String getRecoverPasswordPageURL() {
return LoginServlet.getRecoverPasswordPageURL();
}
/**
* Provides an absolute URL (leading slash) to a user profile editing page.
* It is relative to document root without any constant prefix if there is
* one configured.
*
* @return url String for new user registration page as String
* @deprecated use LoginServlet.getEditUserProfilePageURL() instead
*/
public static String getEditUserProfilePageURL() {
return LoginServlet.getEditUserProfilePageURL();
}
/**
* Provides an absolute URL (leading slash) for the system logout page. It
* is relative to document root without any constant prefix if there is one
* configured.
*
* @return URL for logout page as String
* @deprecated use LoginServlet.getLogoutPageURL() instead
*/
public static String getLogoutPageURL() {
return LoginServlet.getLogoutPageURL();
}
}

View File

@ -0,0 +1,333 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Container;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormValidationListener;
import com.arsdigita.bebop.form.Hidden;
import com.arsdigita.bebop.form.Password;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.parameters.NotNullValidationListener;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.parameters.URLParameter;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.kernel.security.SecurityConfig;
import com.arsdigita.ui.UI;
import com.arsdigita.web.Web;
import com.arsdigita.web.URL;
import com.arsdigita.web.ReturnSignal;
import com.arsdigita.mail.Mail;
import com.arsdigita.util.UncheckedWrapperException;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.CcmSessionContext;
import org.libreccm.core.Subject;
import org.libreccm.core.User;
import org.libreccm.core.UserManager;
import org.libreccm.core.UserRepository;
import org.libreccm.core.authentication.LoginManager;
import java.util.logging.Level;
/**
* A Form that allows a user to change their password by entering their old
* password, a new password, and a confirmation of their new password. Requires
* that the user is logged in. Requires that new password differ from old and
* meet strong password requirements. If the user is recovering from a lost
* password (UserContext.isRecovering() is true), does not require or display
* the old password parameter and does not require that new password differ from
* old. Mails the user to notify of password change. Redirects user to workspace
* or return_url if set.
*
* @author Sameer Ajmani
*
*/
public class ChangePasswordForm extends Form
implements FormProcessListener,
FormValidationListener {
private static final Logger s_log = Logger.getLogger(
ChangePasswordForm.class.getName());
final static String CHANGE_PASSWORD_FORM_NAME = "change-password";
final static String OLD_PASSWORD_PARAM_NAME = "old-password";
final static String NEW_PASSWORD_PARAM_NAME = "new-password";
final static String CONFIRM_PASSWORD_PARAM_NAME = "confirm-password";
final static String RETURN_URL_PARAM_NAME
= LoginHelper.RETURN_URL_PARAM_NAME;
private final UserAuthenticationListener m_listener
= new UserAuthenticationListener();
private Hidden m_returnURL;
// private Hidden m_recovery;
private Label m_oldPasswordLabel;
private Password m_oldPassword;
private Password m_newPassword;
private Password m_confirmPassword;
public ChangePasswordForm() {
this(new BoxPanel());
}
@Override
public void register(final Page page) {
super.register(page);
page.addRequestListener(m_listener);
page.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent event) {
PageState state = event.getPageState();
m_oldPasswordLabel.setVisible(state, true);
m_oldPassword.setVisible(state, true);
}
});
}
public ChangePasswordForm(Container panel) {
super(CHANGE_PASSWORD_FORM_NAME, panel);
setMethod(Form.POST);
addValidationListener(this);
addProcessListener(this);
// save the recovery credential as a hidden parameter
// m_recovery = new Hidden(new StringParameter(RecoveryLoginModule.getParamName()));
// m_recovery.setPassIn(true);
// add(m_recovery);
// save the return URL as a hidden parameter
m_returnURL = new Hidden(new URLParameter(RETURN_URL_PARAM_NAME));
m_returnURL.setPassIn(true);
add(m_returnURL);
final CdiUtil cdiUtil = new CdiUtil();
final CcmSessionContext sessionContext;
try {
sessionContext = cdiUtil.findBean(CcmSessionContext.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException("");
}
final Subject subject = sessionContext.getCurrentSubject();
if (subject != null && subject instanceof User) {
final User user = (User) subject;
final Label greeting = new Label(
LoginHelper.getMessage(
"login.changePasswortForm.greeting",
new Object[]{String.format("%s %s",
user.getName().getGivenName(),
user.getName().getFamilyName())}));
greeting.setFontWeight(Label.BOLD);
greeting.setClassAttr("greeting");
add(greeting);
}
add(new Label(LoginHelper.getMessage(
"login.changePasswortForm.introText")));
// old password
m_oldPasswordLabel = new Label(LoginHelper.getMessage(
"login.changePasswordForm.oldPasswordLabel"));
add(m_oldPasswordLabel);
m_oldPassword = new Password(OLD_PASSWORD_PARAM_NAME);
// don't use NotNullValidationListener because
// old password may be null during password recovery
add(m_oldPassword);
// new password
Object[] params = new Object[]{PasswordValidationListener.MIN_LENGTH};
add(new Label(LoginHelper.getMessage(
"login.changePasswordForm.newPasswordLabel", params)));
m_newPassword = new Password(NEW_PASSWORD_PARAM_NAME);
m_newPassword.addValidationListener(new PasswordValidationListener());
add(m_newPassword);
// confirm new password
add(new Label(LoginHelper.getMessage(
"login.changePasswordForm.confirmPasswordLabel")));
m_confirmPassword = new Password(CONFIRM_PASSWORD_PARAM_NAME);
// don't use PasswordValidationListener to avoid duplicate errors
m_confirmPassword.addValidationListener(new NotNullValidationListener());
add(m_confirmPassword);
// submit
add(new Submit(LoginHelper.getMessage("login.changePasswordForm.submit")),
ColumnPanel.CENTER | ColumnPanel.FULL_WIDTH);
}
@Override
public void validate(final FormSectionEvent event)
throws FormProcessException {
PageState state = event.getPageState();
FormData data = event.getFormData();
try {
// get user object
if (!m_listener.isLoggedIn(state)) {
// this error should never appear
data.addError(LoginHelper.localize(
"login.changePasswordForm.noUserError",
state.getRequest()));
return;
}
User user = m_listener.getUser(state);
// get parameter values
String oldPassword = (String) m_oldPassword.getValue(state);
String newPassword = (String) m_newPassword.getValue(state);
String confirmPassword = (String) m_confirmPassword.getValue(state);
// check old password unless recovering
try {
// The old password can never be null or contain leading or
// trailing slashes.
if (oldPassword == null
|| !oldPassword.trim().equals(oldPassword)) {
data.addError(OLD_PASSWORD_PARAM_NAME, LoginHelper
.localize(
"login.changePasswordForm.badPasswordError",
state.getRequest()));
return;
}
final CdiUtil cdiUtil = new CdiUtil();
final UserManager userManager = cdiUtil.findBean(
UserManager.class);
if (!userManager.verifyPasswordForUser(
user, oldPassword)) {
data.addError(OLD_PASSWORD_PARAM_NAME,
LoginHelper.localize(
"login.changePasswordForm.badPasswordError",
state.getRequest()));
return;
}
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup UserManager", ex);
}
// check new password
if (newPassword.equals(oldPassword)) {
data.addError(NEW_PASSWORD_PARAM_NAME, LoginHelper.localize(
"login.changePasswordForm.mustDifferError",
state.getRequest()));
return;
}
if (!newPassword.equals(confirmPassword)) {
data.addError(CONFIRM_PASSWORD_PARAM_NAME, LoginHelper.localize(
"login.changePasswordForm.mustMatchError",
state.getRequest()));
return;
}
} finally {
if (!data.isValid()) {
// clear passwords from form data
m_oldPassword.setValue(state, "");
m_newPassword.setValue(state, "");
m_confirmPassword.setValue(state, "");
}
}
}
@Override
public void process(final FormSectionEvent event)
throws FormProcessException {
PageState state = event.getPageState();
FormData data = event.getFormData();
// get user object
if (!m_listener.isLoggedIn(state)) {
// this error should never appear (checked in validate)
data.addError(LoginHelper.localize(
"login.changePasswordForm.noUserError",
state.getRequest()));
return;
}
User user = m_listener.getUser(state);
// set new password
try {
final CdiUtil cdiUtil = new CdiUtil();
final UserManager userManager = cdiUtil.findBean(UserManager.class);
final UserRepository userRepository = cdiUtil.findBean(
UserRepository.class);
String newPassword = (String) m_newPassword.getValue(state);
userManager.updatePassword(user, newPassword);
userRepository.save(user);
s_log.debug("committing password change");
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup UserManager or UserRepository", ex);
}
// mail report to user
if (!user.getEmailAddresses().isEmpty()) {
final HttpServletRequest req = state.getRequest();
final String to = user.getEmailAddresses().get(0).getAddress();
final String from = SecurityConfig.getConfig()
.getAdminContactEmail();
final String name = user.getName().getGivenName();
final String subject = LoginHelper.localize(
"login.changePasswordForm.mailSubject", req);
final String body = LoginHelper.localize(
"login.changePasswordForm.mailBody",
new Object[]{name},
req);
// try to send the message, but don't throw the exception
// if it fails so that the password change is comitted
// anyway.
try {
Mail.send(to, from, subject, body);
} catch (javax.mail.MessagingException e) {
s_log.error("Could not notify user of password change", e);
}
} else {
s_log.debug("Could not notify user of password change: "
+ "null email, user ID: "
+ user.getSubjectId());
}
final HttpServletRequest req = state.getRequest();
final String path = UI.getWorkspaceURL(req);
final URL fallback = URL.there(req, path);
throw new ReturnSignal(req, fallback);
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Link;
import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.event.PrintListener;
// import com.arsdigita.kernel.security.LegacyInitializer;
/**
* Package-private class that generates the URL for a link dynamically from
* the kernel page map. This class will be removed or changes when the page
* map is replaced by package parameters.
*
* 2011-02-04: API change (pboy)
* The page map is no retrieved from a set of parameters. The target is now a
* String representation of the absolut url (leading slash) relativ to
* document root. The target is now a targetUrl, no longer a targetKey.
*
* @author Sameer Ajmani
* @version $Id$
*/
class DynamicLink extends Link {
DynamicLink(final String labelKey, final String targetUrl) {
super(new Label(LoginHelper.getMessage(labelKey)),
new PrintListener() {
public void prepare(PrintEvent e) {
Link link = (Link) e.getTarget();
// see {@link com.arsdigita.bebopLink#Link(String,URL)}
// Url is now expected without leading context wich is handled
// by the new dispatcher. Therefore the req. is not needed.
// anymore.
// String url = LegacyInitializer.getFullURL
// (targetKey, e.getPageState().getRequest());
link.setTarget(targetUrl);
}
});
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.web.Web;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.parameters.EmailParameter;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import org.apache.log4j.Logger;
import org.libreccm.core.CcmSessionContext;
import org.libreccm.core.User;
/**
* Initializes the value of the given parameter to the current user's email
* address. If the user is not logged in or the email address is invalid, the
* parameter is not modified.
*
* @author Sameer Ajmani
*
*/
public class EmailInitListener implements FormInitListener {
private static final Logger s_log = Logger.getLogger(EmailInitListener.class
.getName());
private EmailParameter m_param;
public EmailInitListener(EmailParameter param) {
m_param = param;
}
public void init(FormSectionEvent event) {
FormData data = event.getFormData();
s_log.debug("START");
final CcmSessionContext ctx = Web.getUserContext();
if (!ctx.isLoggedIn()) {
s_log.debug("FAILURE not logged in");
return;
}
User user = (User) ctx.getCurrentSubject();
if (user == null) {
s_log.debug("FAILURE no such user");
return;
}
if (user.getEmailAddresses().isEmpty()
|| user.getEmailAddresses().get(0) == null) {
s_log.debug("FAILURE null primary email");
return;
}
if (user.getEmailAddresses().get(0).getAddress() == null
|| user.getEmailAddresses().get(0).getAddress().isEmpty()) {
s_log.debug("FAILURE null email address");
return;
}
try {
InternetAddress addr = new InternetAddress(user.getEmailAddresses()
.get(0).getAddress());
data.put(m_param.getName(), addr);
} catch (AddressException e) {
s_log.debug("FAILURE badly formed address");
return;
}
s_log.debug("SUCCESS");
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.globalization.GlobalizedMessage;
/**
* Constants used by Login UI.
*
*/
public interface LoginConstants {
public final static GlobalizedMessage SUBMIT = LoginHelper.getMessage(
"login.submit");
public final static GlobalizedMessage PRIMARY_EMAIL = LoginHelper
.getMessage("login.primaryEmail");
public final static GlobalizedMessage ADDITIONAL_EMAIL = LoginHelper
.getMessage("login.additionalEmail");
public final static GlobalizedMessage SCREEN_NAME = LoginHelper.getMessage(
"login.screenName");
public final static GlobalizedMessage FIRST_NAME = LoginHelper.getMessage(
"login.firstName");
public final static GlobalizedMessage LAST_NAME = LoginHelper.getMessage(
"login.lastName");
public final static GlobalizedMessage PASSWORD = LoginHelper.getMessage(
"login.password", new Object[]{
PasswordValidationListener.MIN_LENGTH});
public final static GlobalizedMessage PASSWORD_CONFIRMATION = LoginHelper
.getMessage("login.passwordConfirm");
public final static GlobalizedMessage PASSWORD_QUESTION = LoginHelper
.getMessage("login.passwordQuestion");
public final static GlobalizedMessage PASSWORD_ANSWER = LoginHelper
.getMessage("login.passwordAnswer");
public final static GlobalizedMessage URL = LoginHelper.getMessage(
"login.url");
public final static GlobalizedMessage BIO = LoginHelper.getMessage(
"login.bio");
public final static GlobalizedMessage ERROR_DUPLICATE_SN = LoginHelper
.getMessage("login.error.duplicateScreenName");
public final static GlobalizedMessage ERROR_DUPLICATE_EMAIL = LoginHelper
.getMessage("login.error.duplicateEmail");
public final static GlobalizedMessage ERROR_MISMATCH_PASSWORD = LoginHelper
.getMessage("login.error.mismatchPassword");
public final static GlobalizedMessage ERROR_BAD_PASSWORD = LoginHelper
.getMessage("login.error.badPassword");
public final static GlobalizedMessage ERROR_LOGIN_FAIL = LoginHelper
.getMessage("login.error.loginFail");
public final static GlobalizedMessage ERROR_BAD_ANSWER = LoginHelper
.getMessage("login.error.badAnswer");
public final static GlobalizedMessage ERROR_BAD_EMAIL = LoginHelper
.getMessage("login.error.badEmail");
public final static GlobalizedMessage ERROR_BANNED_EMAIL = LoginHelper
.getMessage("login.error.bannedEmail");
public final static String FORM_EMAIL = "emailAddress";
public final static String FORM_SCREEN_NAME = "screenName";
// Should not really be named email. Kept this way due to external tests
// depending on this value.
public final static String FORM_LOGIN = "email";
public final static String FORM_ADDITIONAL_EMAIL = "additional_email";
public final static String FORM_FIRST_NAME = "firstname";
public final static String FORM_LAST_NAME = "lastname";
public final static String FORM_PASSWORD = "password";
public final static String FORM_PASSWORD_CONFIRMATION
= "password_confirmation";
public final static String FORM_PASSWORD_QUESTION = "question";
public final static String FORM_PASSWORD_ANSWER = "answer";
public final static String FORM_URL = "url";
public final static String FORM_URL_DEFAULT = "http://";
public final static String FORM_BIO = "biography";
public final static String FORM_TIMESTAMP = "timestamp";
public final static String FORM_PERSISTENT_LOGIN_P = "persistentCookieP";
public final static String FORM_PERSISTENT_LOGIN_P_DEFAULT = "1";
public final static int TIMESTAMP_LIFETIME_SECS = 300;
public final static int MAX_NAME_LEN = 60;
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (C) 2002-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.ui.login;
import com.arsdigita.globalization.Globalized;
import com.arsdigita.globalization.GlobalizedMessage;
/**
* Compilation of methods to simplify the handling of globalizing keys.
* Basically it adds the name of package's resource bundle files to the
* globalize methods and forwards to GlobalizedMessage, shortening the
* method invocation in the various application classes.
*
* @author tosmers
* @version $Revision$ $Date$
*/
public class LoginGlobalizationUtil implements Globalized {
/** Name of Java resource files to handle CMS's globalisation. */
private static final String BUNDLE_NAME = "com.arsdigita.ui.admin.LoginResources";
/**
* Returns a globalized message using the package specific bundle,
* provided by BUNDLE_NAME.
* @param key
* @return
*/
public static GlobalizedMessage globalize(String key) {
return new GlobalizedMessage(key, BUNDLE_NAME);
}
/**
* Returns a globalized message object, using the package specific bundle,
* as specified by BUNDLE_NAME. Also takes in an Object[] of arguments to
* interpolate into the retrieved message using the MessageFormat class.
* @param key
* @param args
* @return
*/
public static GlobalizedMessage globalize(String key, Object[] args) {
return new GlobalizedMessage(key, BUNDLE_NAME, args);
}
/**
* Returns the name of the package specific resource bundle.
*
* @return Name of resource bundle as String
*/
public static String getBundleName() {
return BUNDLE_NAME;
}
}

View File

@ -0,0 +1,141 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.bebop.PageState;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.web.ReturnSignal;
import java.io.IOException;
import org.apache.log4j.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Provides helper functions for the login UI.
*
* @author Sameer Ajmani
* @version $Id$
*/
public class LoginHelper {
private static final Logger s_log = Logger.getLogger(LoginHelper.class);
public static final String RETURN_URL_PARAM_NAME = "return_url";
/**
* Returns the name of the login UI resource bundle
*
* @return the name of the login UI resource bundle
**/
static String getBundleBaseName() {
return "com.arsdigita.ui.login.LoginResources";
}
/**
* Returns a new GlobalizedMessage constructed with the given
* parameters and the login UI resource bundle.
*
* @return a new GlobalizedMessage
**/
static GlobalizedMessage getMessage(String key, Object[] args) {
return new GlobalizedMessage(key, getBundleBaseName(), args);
}
/**
* Returns a new GlobalizedMessage constructed with the given
* parameters and the login UI resource bundle.
*
* @return a new GlobalizedMessage
**/
static GlobalizedMessage getMessage(String key) {
return new GlobalizedMessage(key, getBundleBaseName());
}
/**
* Constructs a new GlobalizedMessage with the given parameters and the
* login UI resource bundle, then localizes the message with the given
* request.
*
* @return the localized String
**/
static String localize(String key, Object[] args,
HttpServletRequest request) {
return (String)getMessage(key, args).localize(request);
}
/**
* Constructs a new GlobalizedMessage with the given parameters and the
* login UI resource bundle, then localizes the message with the given
* request.
*
* @return the localized String
**/
static String localize(String key, HttpServletRequest request) {
return (String)getMessage(key).localize(request);
}
/**
* Redirect the client to the URL stored in the return_url request
* parameter, or, if that parameter is not set, redirect to the given
* default URL.
*
* @param state the current page state
* @param def the default URL
**/
public static void doReturn(PageState state, String def) {
throw new ReturnSignal(state.getRequest(), def);
}
/**
* Redirect the client to the given URL unless the response has
* already been committed. Wrapper for {@link
* #sendRedirect(HttpServletRequest, HttpServletResponse, String)}
* that pulls out the request and response from the PageState.
*
* @throws IOException if the redirect fails.
**/
public static void sendRedirect(PageState state, String url)
throws IOException {
sendRedirect(state.getRequest(), state.getResponse(), url);
}
/**
* Redirect the client to the given URL unless the response has already
* been committed. Aborts further request processing.
*
* @throws IOException if the redirect fails.
**/
public static void sendRedirect(HttpServletRequest request,
HttpServletResponse response,
String url)
throws IOException {
if (!response.isCommitted()) {
s_log.debug("Redirecting to: "+url);
DispatcherHelper.sendRedirect(request, response, url);
response.flushBuffer();
DispatcherHelper.abortRequest();
} else {
s_log.debug("Redirect failed because "
+"response already committed");
}
}
}

View File

@ -0,0 +1,435 @@
/*
* Copyright (C) 2012 Peter Boy 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.ui.login;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ElementComponent;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageFactory;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.page.BebopApplicationServlet;
import com.arsdigita.dispatcher.DispatcherConfig;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.kernel.security.SecurityConfig;
import com.arsdigita.ui.UI;
import com.arsdigita.web.ReturnSignal;
import com.arsdigita.web.URL;
import org.apache.log4j.Logger;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
/**
* Login Application Servlet class, central entry point to create and process
* the Login application UI.
*
* It manages user registration page, new user page, user workspace, logout, and
* permissions admin pages.
*
* It just defines a mapping URL <-> various pages and uses the super class to
* actually server the pages. Additionally is provides service methods to expose
* various properties, especially the URL's of public subpages (e.g. logout) and
* initializes the creation of the UI.
*
* @author Peter Boy <pboy@barkhof.uni-bremen.de>
*/
@WebServlet(urlPatterns = {"/register*"})
public class LoginServlet extends BebopApplicationServlet {
private static final long serialVersionUID = 7783916040158924516L;
/**
* Logger instance for debugging
*/
private static final Logger s_log = Logger.getLogger(LoginServlet.class);
// ////////////////////////////////////////////////////////////////////////
// Define various URLs to subpages of Login to manage administrative tasks.
// ////////////////////////////////////////////////////////////////////////
/**
* PathInfo into the Login application to access the (optional) newUser *
* page. Ends with "/" because it is a servlet/directory
*/
public static final String EDIT_USER_PROFILE_PATH_INFO = "/edit-profile/";
/**
* PathInfo into the Login application to access the (optional) newUser *
* page. Ends with "/" because it is a servlet/directory
*/
public static final String NEW_USER_PATH_INFO = "/new-user/";
/**
* PathInfo into the Login application to access the (optional) newUser *
* page. Ends with "/" because it is a servlet/directory
*/
public static final String CHANGE_USER_PASSWORD_PATH_INFO
= "/change-password/";
/**
* PathInfo into the Login application to access the (optional) newUser
* page. Ends with "/" because it is a servlet/directory
*/
public static final String RECOVER_USER_PASSWORD_PATH_INFO
= "/recover-password/";
/**
* PathInfo into the Login application to access the (optional) newUser
* page. Ends with "/" because it is a servlet/directory
*/
public static final String EXPLAIN_PERSISTENT_COOKIES_PATH_INFO
= "/explain-persistent-cookies/";
/**
* PathInfo into the Login application to access the (optional) newUser
* page. Ends with "/" because it is a servlet/directory
*/
public static final String LOGIN_EXPIRED_PATH_INFO = "/login-expired/";
/**
* PathInfo into the Login application to access the (optional) newUser
* page. Ends with "/" because it is a servlet/directory
*/
public static final String LOGOUT_PATH_INFO = "/logout/";
/**
* URL stub of Login page in ServletPath format (with leading slash and
* without trailing slash
*/
// Don't modify without adapting instantiation in Loader class and
// updating existing databases (table applications)!
public static final String LOGIN_PAGE_URL = "/register";
/**
* Base URL of the Login application for internal use, fetched from Login
* domain class.
*/
private final static String s_loginURL = LOGIN_PAGE_URL;
// define namespace URI
final static String SUBSITE_NS_URI = "http://www.arsdigita.com/subsite/1.0";
public static final String APPLICATION_NAME = "login";
/**
* User extension point used to create the pages to server and setup a URL -
* page mapping.
*
* @throws ServletException
*/
@Override
public void doInit() throws ServletException {
// Allow world caching for pages without authentication,
// ie, /register, /register/explain-persistent-cookies,
// /register/login-expired, /register/recover-password
// NB, although you'd think /register is cachable, it
// stores a timestamp in the login form :(
/* Create and add login page (index page of Login application) to the
* page map. KernelSecurityConfig determines whether to create a link
* to a NewUserRegistrationForm or to skip.*/
put("/",
buildSimplePage("login.userRegistrationForm.title",
new UserLoginForm(SecurityConfig.getConfig()
.isAutoRegistrationOn()),
"login"));
disableClientCaching("/");
/* Create and add userEditPage to the page map. */
put(EDIT_USER_PROFILE_PATH_INFO,
buildSimplePage("login.userEditPage.title",
new UserEditForm(), "edit"));
disableClientCaching(EDIT_USER_PROFILE_PATH_INFO);
/* Determines if a NewUserRegistrationForm has to be created by quering
* Kernel.getSecurityConfig() and acts appropriately */
if (SecurityConfig.getConfig().isAutoRegistrationOn()) {
put(NEW_USER_PATH_INFO,
buildSimplePage("login.userNewForm.title",
new UserNewForm(),
"register"));
disableClientCaching(NEW_USER_PATH_INFO);
}
/* Create ExplainPersistentCookiesPage and add to the page map */
put(EXPLAIN_PERSISTENT_COOKIES_PATH_INFO,
buildSimplePage("login.explainCookiesPage.title",
new ElementComponent(
"subsite:explainPersistentCookies",
SUBSITE_NS_URI),
"cookies"));
/* Create ChangeUserPasswordPage and add to the page map */
put(CHANGE_USER_PASSWORD_PATH_INFO,
buildSimplePage("login.changePasswordPage.title",
new ChangePasswordForm(),
"changepassword"));
disableClientCaching(CHANGE_USER_PASSWORD_PATH_INFO);
/* Build the password recover page, retrieve its URL and store in map */
put(RECOVER_USER_PASSWORD_PATH_INFO,
buildSimplePage("login.recoverPasswordPage.title",
new RecoverPasswordPanel(),
"recoverpassword"));
// Build the login expire page, retrieve its URL and store in map
put(LOGIN_EXPIRED_PATH_INFO, buildExpiredPage());
/* Create Logout Page and add to the page map */
put(LOGOUT_PATH_INFO, buildLogOutPage());
disableClientCaching(LOGOUT_PATH_INFO);
Page workspace = checkForPageSubClass();
if (workspace == null) {
workspace = buildSimplePage("login.workspacePage.title",
new UserInfo(),
"workspace");
}
put(UI.getWorkspaceURL(), workspace); // usually navigation/ or portal/
disableClientCaching(UI.getWorkspaceURL());
// special case to handle pvt/home
// String url = LegacyInitializer.getURL(LegacyInitializer.WORKSPACE_PAGE_KEY);
// pboy: This page / url seems to be a left over from older versions,
// currently not contained in source code.
String url = UI.getWorkspaceURL();
if (url.equals("pvt/")) {
put("pvt/home", workspace);
disableClientCaching("pvt/home");
}
}
/**
* Check wether a custom base Page class (top-level container for all Bebop
* components and containersPages) is configured and return the appropriate
* Page. Here used (only) for UserInfo() workspace.
*
* @return Page to use for top-level container for all Bebop components and
* containersPage, null to use default class
*/
private static Page checkForPageSubClass() {
//check to see if there is subclass of Page defined in Config
DispatcherConfig dc = DispatcherHelper.getConfig();
String pageClass = dc.getDefaultPageClass();
Page p = null;
if (!pageClass.equals("com.arsdigita.bebop.Page")) {
try {
// afraid that we're assuming a no-arg constructor
Class c = Class.forName(pageClass);
p = (Page) c.newInstance();
} catch (Exception e) {
s_log.error(
"Unable to instantiate waf.dispatcher.default_page_class", e);
}
}
return p;
}
/**
* Creates a Page with the given title and body component.
*
* @return the new Page
*
*/
private static Page buildSimplePage(String title, Component body, String id) {
Page page = PageFactory.buildPage(APPLICATION_NAME,
new Label(LoginHelper
.getMessage(title)),
id);
page.add(body);
page.lock();
return page;
}
/**
* Creates a page informing the user the login has expired. Provides links
* to login again, etc.
*
* @return Page (login expired info)
*/
private static Page buildExpiredPage() {
Page page = PageFactory.buildPage(
APPLICATION_NAME,
new Label(LoginHelper.getMessage("login.loginExpiredPage.title"))
);
page.add(new SimpleContainer() {
{ // constructor
add(new Label(LoginHelper.getMessage(
"login.loginExpiredPage.before")));
add(new DynamicLink("login.loginExpiredPage.link",
LOGIN_PAGE_URL));
add(new Label(LoginHelper.getMessage(
"login.loginExpiredPage.after")));
add(new ElementComponent("subsite:explainLoginExpired",
SUBSITE_NS_URI));
}
});
page.lock();
return page;
}
/**
*
* @return
*/
private static Page buildLogOutPage() {
Page page = PageFactory.buildPage(
APPLICATION_NAME,
new Label(LoginHelper.getMessage("Logout"))
);
page.addActionListener(new UserLogoutListener());
page.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent event) {
final PageState state = event.getPageState();
final HttpServletRequest req = state.getRequest();
final String path = UI.getRootPageURL(req);
throw new ReturnSignal(req, URL.there(req, path));
}
});
page.lock();
return page;
}
/**
* Provides an (absolute) URL to a user profile editig page. It is relative
* to document root without any constant prefix if there is one configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL which also contains the context
* part. Since version 5.2 the context part is handled by (new) dispatcher.
* The leading slash it API change! It's impacts have to be checked.
* (2011-02)
*
* @return url to EditUserProfile page as String
*/
public static String getEditUserProfilePageURL() {
return s_loginURL + EDIT_USER_PROFILE_PATH_INFO;
}
public static String getChangePasswordPageURL() {
return s_loginURL + CHANGE_USER_PASSWORD_PATH_INFO;
}
/**
* Provides an (absolute URL) to an optional new user registration page
* (accessible only if activated). It is relative to document root without
* any constant prefix if there is one configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL which also contains the context
* part. Since version 5.2 the context part is handled by (new) dispatcher.
* The leading slash it API change! It's impacts have to be checked.
* (2011-02)
*
* @return url to new user registration page as String
*/
public static String getNewUserPageURL() {
return s_loginURL + NEW_USER_PATH_INFO;
}
/**
* Provides an absolute URL (leading slash) for a password recovery page. It
* is relative to document root without any constant prefix if there is one
* configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL which also contains the context
* part. Since version 5.2 the context part is handled by (new) dispatcher.
* The leading slash it API change! It's impacts have tp be checked.
* (2011-02)
*
* @return url String for new user registration page as String
*/
public static String getRecoverPasswordPageURL() {
return s_loginURL + RECOVER_USER_PASSWORD_PATH_INFO;
}
/**
* Provides an absolute URL (leading slash) for a cookie explanation page.
* It is relative to document root without any constant prefix if there is
* one configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL which also contains the context
* part. Since version 5.2 the context part is handled by (new) dispatcher.
* The leading slash it API change! It's impacts have tp be checked.
* (2011-02)
*
* @return url String for new user registration page as String
*/
public static String getCookiesExplainPageURL() {
return s_loginURL + EXPLAIN_PERSISTENT_COOKIES_PATH_INFO;
}
/**
* Provides an absolute URL (leading slash) for a login expired info page.
* It is relative to document root without any constant prefix if there is
* one configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL which also contains the context
* part. Since version 5.2 the context part is handled by (new) dispatcher.
* The leading slash it API change! It's impacts have tp be checked.
* (2011-02)
*
* @return url String for new user registration page as String
*/
public static String getLoginExpiredPageURL() {
return s_loginURL + LOGIN_EXPIRED_PATH_INFO;
}
/**
* Provides an absolute URL (leading slash) for the system logout page. It
* is relative to document root without any constant prefix if there is one
* configured.
*
* XXX This implementation starts with a leading slash and ends with a
* slash. In previous configurations String urls began without a slash in
* order to be able to provide a full URL which also contains the context
* part. Since version 5.2 the context part is handled by (new) dispatcher.
* The leading slash it API change! It's impacts have tp be checked.
* (2011-02)
*
* @return URL for logout page as String
*/
public static String getLogoutPageURL() {
return s_loginURL + LOGOUT_PATH_INFO;
}
}

View File

@ -0,0 +1,149 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.bebop.event.ParameterEvent;
import com.arsdigita.bebop.parameters.NotNullValidationListener;
import com.arsdigita.bebop.parameters.ParameterData;
/**
* A NotNullValidationListener that checks whether the string value of a
* parameter is a strong password.
*
* @author Sameer Ajmani
*/
public class PasswordValidationListener
extends NotNullValidationListener
{
/**
* Minimum length for passwords.
*/
public static final int MIN_LENGTH = 6;
/**
* Minimum number of character types for passwords. Valid values are on
* range [1,4].
*/
public static final int MIN_TYPES = 1;
public PasswordValidationListener() {
super();
}
public PasswordValidationListener(String label) {
super(label);
}
/**
* Checks whether the string value of the parameter meets minimum-length
* and composition requirements for strong passwords.
*/
@Override
public void validate(ParameterEvent e) {
super.validate(e);
ParameterData data = e.getParameterData();
if (!data.isValid()) {
// already has errors from superclass
return;
}
// check length
String password = data.getValue().toString();
if (password.length() < MIN_LENGTH) {
data.addError(LoginHelper.getMessage
("login.passwordValidation.minLengthError",
new Object[] { new Integer(MIN_LENGTH) }));
return;
}
// check for whitespace
if (contains(password, whites)) {
data.addError(LoginHelper.getMessage
("login.passwordValidation.whitespaceError"));
return;
}
// check character mix
int charSets = 0;
if (contains(password, uppers)) {
charSets++;
}
if (contains(password, lowers)) {
charSets++;
}
if (contains(password, digits)) {
charSets++;
}
if (contains(password, others)) {
charSets++;
}
if (charSets < MIN_TYPES) {
data.addError(LoginHelper.getMessage
("login.passwordValidation.minTypesError",
new Object[] { MIN_TYPES}));
}
}
private static interface CharSet {
public boolean contains(char c);
}
private static boolean contains(String s, CharSet set) {
for (int i = 0; i < s.length(); i++) {
if (set.contains(s.charAt(i))) {
return true;
}
}
return false;
}
private static CharSet whites = new CharSet() {
@Override
public boolean contains(char c) {
return Character.isWhitespace(c);
}
};
private static CharSet uppers = new CharSet() {
@Override
public boolean contains(char c) {
return (Character.isLetter(c)
&& Character.isUpperCase(c));
}
};
private static CharSet lowers = new CharSet() {
@Override
public boolean contains(char c) {
return (Character.isLetter(c)
&& Character.isLowerCase(c));
}
};
private static CharSet digits = new CharSet() {
@Override
public boolean contains(char c) {
return Character.isDigit(c);
}
};
private static CharSet others = new CharSet() {
@Override
public boolean contains(char c) {
return !(Character.isLetterOrDigit(c)
|| Character.isISOControl(c)
|| Character.isWhitespace(c));
}
};
}

View File

@ -0,0 +1,420 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ElementComponent;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormValidationListener;
import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.parameters.EmailParameter;
import com.arsdigita.bebop.parameters.NotNullValidationListener;
import com.arsdigita.bebop.parameters.ParameterModel;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.ui.UI;
import com.arsdigita.web.ParameterMap;
import com.arsdigita.web.URL;
import com.arsdigita.mail.Mail;
import static com.arsdigita.ui.login.LoginConstants.*;
import com.arsdigita.util.UncheckedWrapperException;
import org.apache.commons.lang.RandomStringUtils;
import java.math.BigDecimal;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.User;
import org.libreccm.core.UserManager;
import org.libreccm.core.UserRepository;
import java.security.SecureRandom;
/**
* A sequence of Forms and Panels that allows a user to recover from a forgotten
* password. First form requests the user's email address, and is pre-filled if
* the user is logged in. Second form presents the user's password question and
* requires the correct answer. Third panel informs the user that a mail has
* been sent that will allow them to change their password.
*
* @author Sameer Ajmani
*
*/
public class RecoverPasswordPanel extends SimpleContainer
implements LoginConstants {
private static final Logger s_log = Logger.getLogger(
RecoverPasswordPanel.class.getName());
private static ParameterModel DISPLAY_PARAM = new StringParameter("display");
private static ParameterModel USERID_PARAM = new BigDecimalParameter(
"userID");
private EnterEmailForm m_enterEmailForm;
private AnswerQuestionForm m_answerQuestionForm;
private MailSentPane m_mailSentPane;
private MailFailedPane m_mailFailedPane;
public void register(Page p) {
super.register(p);
p.addComponentStateParam(this, DISPLAY_PARAM);
p.addComponentStateParam(this, USERID_PARAM);
p.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PageState state = e.getPageState();
String display = (String) state.getValue(DISPLAY_PARAM);
s_log.debug("display == " + display);
boolean visible = false;
visible |= setVisible(state, display, m_enterEmailForm);
visible |= setVisible(state, display, m_answerQuestionForm);
visible |= setVisible(state, display, m_mailSentPane);
visible |= setVisible(state, display, m_mailFailedPane);
if (!visible) {
// default: show first form
m_enterEmailForm.setVisible(state, true);
}
}
private boolean setVisible(PageState state,
String display,
Component component) {
boolean visible = component.getClass().getName()
.equals(display);
component.setVisible(state, visible);
return visible;
}
});
}
public RecoverPasswordPanel() {
m_enterEmailForm = new EnterEmailForm();
add(m_enterEmailForm);
m_answerQuestionForm = new AnswerQuestionForm();
add(m_answerQuestionForm);
m_mailSentPane = new MailSentPane();
add(m_mailSentPane);
m_mailFailedPane = new MailFailedPane();
add(m_mailFailedPane);
}
private static class EnterEmailForm extends Form
implements FormValidationListener, FormProcessListener {
public EnterEmailForm() {
super("enter-email", new BoxPanel());
addValidationListener(this);
addProcessListener(this);
add(new Label(PRIMARY_EMAIL));
TextField email = new TextField(new EmailParameter(FORM_EMAIL));
email.addValidationListener(new NotNullValidationListener());
addInitListener(new EmailInitListener((EmailParameter) email
.getParameterModel()));
add(email);
add(new Submit(SUBMIT));
}
@Override
public void validate(final FormSectionEvent event)
throws FormProcessException {
FormData data = event.getFormData();
if (!data.isValid()) {
// data already has errors
return;
}
final String email = ((InternetAddress) data.get(FORM_EMAIL))
.getAddress();
final long userID;
try {
final CdiUtil cdiUtil = new CdiUtil();
final UserRepository userRepository = cdiUtil.findBean(
UserRepository.class);
final User user = userRepository.findByEmailAddress(email);
if (user == null) {
data.addError(FORM_EMAIL,
(String) ERROR_BAD_EMAIL.localize(event
.getPageState().getRequest()));
return;
}
userID = user.getSubjectId();
event.getPageState().setValue(USERID_PARAM, userID);
if (userID != 0) {
if (user.isBanned()) {
data.addError(FORM_EMAIL, (String) ERROR_BANNED_EMAIL
.localize(event.getPageState()
.getRequest()));
}
}
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup UserRepository", ex);
}
// if the user exists, we need to make sure they are not banned.
}
@Override
public void process(final FormSectionEvent event)
throws FormProcessException {
event.getPageState().setValue(DISPLAY_PARAM,
AnswerQuestionForm.class.getName());
}
}
private static class AnswerQuestionForm extends Form
implements FormValidationListener, FormProcessListener {
private final TextField m_answer;
public AnswerQuestionForm() {
super("answer-question", new BoxPanel());
addValidationListener(this);
addProcessListener(this);
add(new Label(PASSWORD_QUESTION));
Label question = new Label();
question.setIdAttr("question");
question.addPrintListener(new PrintListener() {
@Override
public void prepare(final PrintEvent event) {
final Label label = (Label) event.getTarget();
final long userID = (long) event.getPageState()
.getValue(USERID_PARAM);
if (userID == 0) {
throw new IllegalStateException(
"userID must not be 0");
}
try {
final CdiUtil cdiUtil = new CdiUtil();
final UserRepository userRepository = cdiUtil.findBean(
UserRepository.class);
final User user = userRepository.findById(userID);
if (user == null) {
throw new IllegalStateException(
"userID must be a valid user");
}
String theQuestion = user.getPasswordQuestion();
if (theQuestion == null) {
throw new IllegalStateException(
"password question must not be null "
+ "(userID == " + userID + ")");
}
label.setLabel(theQuestion);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup user repository", ex);
}
}
});
add(question);
add(new Label(PASSWORD_ANSWER));
m_answer = new TextField(new StringParameter(FORM_PASSWORD_ANSWER));
m_answer.addValidationListener(new NotNullValidationListener());
add(m_answer);
add(new Submit(SUBMIT));
}
@Override
public void validate(final FormSectionEvent event)
throws FormProcessException {
FormData data = event.getFormData();
if (!data.isValid()) {
// data already has errors
return;
}
final String answer = (String) data.get(FORM_PASSWORD_ANSWER);
// FIXME: same as code above; instead save UserAuth object
final long userID = (long) event.getPageState().getValue(
USERID_PARAM);
if (userID == 0) {
throw new IllegalStateException("userID must not be 0");
}
try {
final CdiUtil cdiUtil = new CdiUtil();
final UserRepository userRepository = cdiUtil.findBean(
UserRepository.class);
final User user = userRepository.findById(userID);
if (user == null) {
throw new IllegalStateException(
"userID must be a valid user");
}
final String correctAnswer = user.getPasswordAnswer();
if (!correctAnswer.equals(answer)) {
data.addError(FORM_PASSWORD_ANSWER,
(String) ERROR_BAD_ANSWER.localize(event
.getPageState().getRequest()));
}
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup UserRepository", ex);
}
}
@Override
public void process(final FormSectionEvent event)
throws FormProcessException {
final HttpServletRequest req = event.getPageState().getRequest();
final long userID = (long) event.getPageState().getValue(
USERID_PARAM);
if (userID == 0) {
throw new IllegalStateException("userID must not be 0");
}
final CdiUtil cdiUtil = new CdiUtil();
final UserRepository userRepository;
try {
userRepository = cdiUtil.findBean(UserRepository.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup UserRepository", ex);
}
final User user = userRepository.findById(userID);
if (user == null) {
throw new IllegalStateException("userID must be a valid user");
}
if (user.getEmailAddresses().isEmpty()) {
mailFailed(event, "null email, user ID: " + user.getSubjectId());
return;
}
String to = user.getEmailAddresses().get(0).getAddress();
String from = Mail.getConfig().getDefaultFrom();
// AFAICT this value below is hard coded to "" !
//KernelHelper.getSystemAdministratorEmailAddress();
String subject = LoginHelper.localize(
"login.recoverPassword.mailSubject", req);
String body = getNotification(user, event, req);
// send the message and set next panel to "mail sent" page
try {
Mail.send(to, from, subject, body);
event.getPageState().setValue(DISPLAY_PARAM, MailSentPane.class
.getName());
} catch (MessagingException e) {
mailFailed(event, e.toString());
}
}
}
/**
* Log a failure to notify the user and set the next panel to the "mail
* failed" page.
*/
private static void mailFailed(FormSectionEvent event,
String reason) {
s_log.warn("Could not notify user for recovery: " + reason);
event.getPageState().setValue(DISPLAY_PARAM, MailFailedPane.class
.getName());
}
/**
* Displays a message that password recovery information has been sent.
*
*/
private static class MailSentPane extends ElementComponent {
public MailSentPane() {
super("subsite:recoverPasswordMailSent",
LoginServlet.SUBSITE_NS_URI);
}
}
/**
* Constructs the notification to send users when recovering a password.
*
*/
private static String getNotification(final User user,
final FormSectionEvent event,
final HttpServletRequest req) {
final CdiUtil cdiUtil = new CdiUtil();
final UserManager userManager;
final UserRepository userRepository;
try {
userManager = cdiUtil.findBean(UserManager.class);
userRepository = cdiUtil.findBean(UserRepository.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup UserRepository or UserManager", ex);
}
final String name = user.getName().getGivenName();
String tmpPassword = RandomStringUtils.random(
16, 0, 0, false, false, null, new SecureRandom());
userManager.updatePassword(user, tmpPassword);
user.setPasswordResetRequired(true);
userRepository.save(user);
return LoginHelper.localize("login.recoverPassword.mailBody",
new Object[]{name, tmpPassword},
req);
}
/**
* Displays a message that password recovery information couldn't be sent.
* There must be a better way to do this!
*
*/
private static class MailFailedPane extends ElementComponent {
public MailFailedPane() {
super("subsite:recoverPasswordMailFailed",
LoginServlet.SUBSITE_NS_URI);
}
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2002-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.ui.login;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.web.Web;
import org.apache.log4j.Logger;
import org.libreccm.core.CcmSessionContext;
import org.libreccm.core.User;
// Note: Previously used SiteNodeRequestContext, nows using KernelRequestContext
// may be one cause that Login doesn't survive if the brwoser window is
// closed.
/**
* Initializes the value of the given parameter to the current user's
* screen name. Strangely similar to <code>EmailInitListener</code>.
*
* @author <a href="mailto:cwolfe@redhat.com">Crag Wolfe</a>
* @version $Id$
*/
public class ScreenNameInitListener implements FormInitListener {
private static Logger s_log =
Logger.getLogger(ScreenNameInitListener.class.getName());
private StringParameter m_param;
/**
*
* @param param
*/
public ScreenNameInitListener(StringParameter param) {
m_param = param;
}
/**
*
* @param event
*/
public void init(FormSectionEvent event) {
PageState state = event.getPageState();
FormData data = event.getFormData();
s_log.debug("START");
final CcmSessionContext ctx = Web.getUserContext();
if (!ctx.isLoggedIn()) {
s_log.debug("FAILURE not logged in");
return;
}
final User user = (User) ctx.getCurrentSubject();
if (user.getScreenName() == null) {
s_log.debug("FAILURE null screen name");
return;
}
data.put(m_param.getName(), user.getScreenName());
s_log.debug("SUCCESS");
}
}

View File

@ -0,0 +1,142 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.RequestEvent;
import com.arsdigita.bebop.event.RequestListener;
import com.arsdigita.kernel.security.Util;
import com.arsdigita.web.Web;
import com.arsdigita.web.LoginSignal;
import com.arsdigita.util.UncheckedWrapperException;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.CcmSessionContext;
import org.libreccm.core.User;
import javax.servlet.http.HttpServletRequest;
/**
* A RequestListener that redirects the user to register if not logged in. The
* redirection URL includes a return_url parameter to send the user back to this
* page after logging in. Pages must not continue processing if this listener
* redirects the user, since the response has already been committed
* (isLoggedIn() returns false in this case). In a future version, this listener
* will abort processing of the request if the user is not logged in.
*
* @author Phong Nguyen
* @author Sameer Ajmani
* @version 1.0
* @version $Id: UserAuthenticationListener.java 287 2005-02-22 00:29:02Z
* sskracic $
*/
public class UserAuthenticationListener implements RequestListener {
private static final Logger s_log = Logger.getLogger(
UserAuthenticationListener.class);
/**
* If the user is logged in, returns the User object.
*
* @param state
*
* @return the User object for the logged in user
*
* @throws IllegalStateException if user is not logged in. Call isLoggedIn()
* to check for this case.
*/
public User getUser(final PageState state) {
if (!isLoggedIn(state)) {
throw new IllegalStateException("User is not logged in");
}
// Note: aborts processing with an internal error if user not logged in!
// Not suiteable just to check log in status.
final CdiUtil cdiUtil = new CdiUtil();
try {
final CcmSessionContext context = cdiUtil.findBean(
CcmSessionContext.class);
return (User) context.getCurrentSubject();
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed get get CcmSessionContext.", ex);
}
}
/**
* Determines whether the user is logged in.
*
* @param state
*
* @return true if the user is logged in
*/
public boolean isLoggedIn(final PageState state) {
return Web.getUserContext().isLoggedIn();
}
/**
* Checks whether the user is logged in. If not, redirects the client to the
* login page.
*
* @param event
*/
@Override
public void pageRequested(final RequestEvent event) {
PageState state = event.getPageState();
final CcmSessionContext sessionContext;
try {
final CdiUtil cdiUtil = new CdiUtil();
sessionContext = cdiUtil.findBean(
CcmSessionContext.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup CcmSessionContext", ex);
}
if (!sessionContext.isLoggedIn()) {
s_log.debug("User is not logged in");
redirectToLoginPage(state);
}
}
/**
* Redirects the client to the login page.
*
* @param state
*/
private void redirectToLoginPage(final PageState state) {
HttpServletRequest req = state.getRequest();
String urlBase = Util.getSecurityHelper().getLoginURL(req);
// first make sure we're not already looking at the login
// page -- if we are, don't redirect!
if (urlBase.equals(Web.getWebContext().getRequestURL().getRequestURI())) {
s_log.debug("preventing cyclic redirect to: " + urlBase);
// return without redirect
return;
}
throw new LoginSignal(req);
}
}

View File

@ -0,0 +1,162 @@
/*
* Copyright (C) 2001-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.ui.login;
// import com.arsdigita.kernel.security.LegacyInitializer;
import com.arsdigita.ui.UI;
import com.arsdigita.web.URL;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.RequestLocal;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.form.Hidden;
import com.arsdigita.bebop.parameters.URLParameter;
import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.web.ReturnSignal;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.EmailAddress;
import org.libreccm.core.PersonName;
import org.libreccm.core.User;
import org.libreccm.core.UserRepository;
import java.util.logging.Level;
/**
* Edits a user. If returnURL is passed in to the form, then redirects to that
* URL; otherwise redirects to the user workspace.
*
*
* @author Sameer Ajmani
*
* @version $Id$
*
*
*/
public class UserEditForm extends UserForm
implements FormProcessListener {
// private static final Logger s_log = Logger.getLogger(UserEditForm.class);
private UserAuthenticationListener m_listener
= new UserAuthenticationListener();
private final Hidden m_returnURL;
private final RequestLocal m_user = new RequestLocal() {
@Override
public Object initialValue(final PageState ps) {
User result;
final long userId = m_listener.getUser(ps).getSubjectId();
final CdiUtil cdiUtil = new CdiUtil();
final UserRepository userRepository;
try {
userRepository = cdiUtil.findBean(UserRepository.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup UserRepository.", ex);
}
result = userRepository.findById(userId);
return result;
}
};
public UserEditForm() {
super("user-edit", new ColumnPanel(2), false);
addProcessListener(this);
// export return URL
m_returnURL = new Hidden(new URLParameter(
LoginHelper.RETURN_URL_PARAM_NAME));
m_returnURL.setPassIn(true);
add(m_returnURL);
}
@Override
public void register(final Page page) {
super.register(page);
page.addRequestListener(m_listener);
}
@Override
protected User getUser(final PageState state) {
return (User) m_user.get(state);
}
@Override
public void process(final FormSectionEvent event)
throws FormProcessException {
FormData data = event.getFormData();
PageState state = event.getPageState();
User user = getUser(state);
if (user == null) {
throw new UncheckedWrapperException(
"Failed to retrieve user from page state");
}
final PersonName name = user.getName();
name.setGivenName((String) m_firstName.getValue(state));
name.setFamilyName((String) m_lastName.getValue(state));
user.setScreenName((String) m_screenName.getValue(state));
final EmailAddress newAddress = new EmailAddress();
newAddress.setAddress(data.get(FORM_EMAIL).toString());
if (user.getEmailAddresses().isEmpty()) {
user.addEmailAddress(newAddress);
} else {
if (!user.getEmailAddresses().get(0).equals(newAddress)) {
user.getEmailAddresses().get(0).setAddress(newAddress.getAddress());
}
}
final CdiUtil cdiUtil = new CdiUtil();
final UserRepository userRepository;
try {
userRepository = cdiUtil.findBean(UserRepository.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup UserRepository", ex);
}
// redirect to workspace or return URL, if specified
final HttpServletRequest req = state.getRequest();
// final String path = LegacyInitializer.getFullURL
// (LegacyInitializer.WORKSPACE_PAGE_KEY, req);
final String path = UI.getWorkspaceURL();
final URL fallback = com.arsdigita.web.URL.there(req, path);
throw new ReturnSignal(req, fallback);
}
}

View File

@ -0,0 +1,351 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Container;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.FormSection;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormValidationListener;
import com.arsdigita.bebop.form.Password;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.parameters.EmailParameter;
import com.arsdigita.bebop.parameters.NotEmptyValidationListener;
import com.arsdigita.bebop.parameters.StringLengthValidationListener;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.util.UncheckedWrapperException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.PersonName;
import org.libreccm.core.User;
import org.libreccm.core.UserRepository;
/**
* Common code for user new / add / edit forms.
*
* @author Admin UI Team
* @version $Id$
*
*/
public abstract class UserForm extends Form
implements LoginConstants, FormInitListener, FormValidationListener {
private static final Logger s_log = Logger.getLogger(UserForm.class
.getName());
private boolean m_newUser;
protected TextField m_firstName;
protected TextField m_lastName;
protected TextField m_email;
protected TextField m_screenName;
//protected TextField m_additional;
protected Password m_password;
protected Password m_confirm;
protected TextField m_question;
protected TextField m_answer;
protected Label m_securitySectionHeader = new Label(LoginHelper
.getMessage("login.userNewForm.securitySectionHeader"), false);
protected Label m_securityBlurb = new Label(LoginHelper
.getMessage("login.userNewForm.securityBlurb"));
protected Label m_passwordBlurb = new Label(LoginHelper
.getMessage("login.userNewForm.passwordBlurb"));
protected Label m_passwordLabel = new Label(PASSWORD);
protected Label m_confirmationLabel = new Label(PASSWORD_CONFIRMATION);
protected Label m_questionBlurb = new Label(LoginHelper
.getMessage("login.userNewForm.questionBlurb"));
protected Label m_questionLabel = new Label(PASSWORD_QUESTION);
protected Label m_answerLabel = new Label(PASSWORD_ANSWER);
protected PasswordValidationListener m_passwordValidationListener
= new PasswordValidationListener();
protected NotEmptyValidationListener m_confirmationNotEmptyValidationListener
= new NotEmptyValidationListener();
protected Submit m_submit = new Submit(SUBMIT);
protected Label m_firstNameLabel = new Label(FIRST_NAME);
protected Label m_lastNameLabel = new Label(LAST_NAME);
protected Label m_urlLabel = new Label(URL);
protected Label m_screenNameLabel = new Label(SCREEN_NAME);
protected Label m_emailLabel = new Label(PRIMARY_EMAIL);
protected Container m_profilePart = new FormSection();
protected Container m_securityPart = new FormSection();
protected Container m_submitPart = new FormSection();
/**
* Create a UserForm with the given name and panel.
*
*/
public UserForm(String name, Container panel, boolean newUser) {
super(name, panel);
m_newUser = newUser;
setMethod(Form.POST);
addInitListener(this);
addValidationListener(this);
if (m_newUser) {
m_profilePart.add(new Label(LoginHelper
.getMessage("login.userNewForm.aboutYouSectionHeader"),
false), ColumnPanel.FULL_WIDTH);
}
// SDM #163373: add length checking for first/last names. We do
// this with both maximum length parameters in the user/add form and
// with validation of the value that come in for processing.
m_firstName = new TextField(new StringParameter(FORM_FIRST_NAME));
m_firstName.setMaxLength(MAX_NAME_LEN);
m_firstName.setSize(20);
m_firstName.addValidationListener(new NotEmptyValidationListener());
m_firstName.addValidationListener(new StringLengthValidationListener(
MAX_NAME_LEN));
m_profilePart.add(m_firstNameLabel);
m_profilePart.add(m_firstName);
m_lastName = new TextField(new StringParameter(FORM_LAST_NAME));
m_lastName.setMaxLength(MAX_NAME_LEN);
m_lastName.setSize(25);
m_lastName.addValidationListener(new NotEmptyValidationListener());
m_lastName.addValidationListener(new StringLengthValidationListener(
MAX_NAME_LEN));
m_profilePart.add(m_lastNameLabel);
m_profilePart.add(m_lastName);
m_profilePart.add(m_screenNameLabel);
m_screenName = new TextField(new StringParameter(FORM_SCREEN_NAME));
m_screenName.addValidationListener(new NotEmptyValidationListener());
m_profilePart.add(m_screenName);
// Primary email address
m_email = new TextField(new EmailParameter(FORM_EMAIL));
m_email.addValidationListener(new NotEmptyValidationListener());
m_profilePart.add(m_emailLabel);
m_profilePart.add(m_email);
// TODO: support additional emails
// Additional email addresses
//m_additional = new TextField(new EmailParameter
// (FORM_ADDITIONAL_EMAIL));
//add(new Label(ADDITIONAL_EMAIL));
//add(m_additional);
// SDM #162740: disable user bio for now, as there
// is no support for User Bio in the kernel level.
// add(new Label(BIO));
// TextArea bioText = new TextArea(new StringParameter(FORM_BIO));
// bioText.setCols(50);
// bioText.setRows(10);
// add(bioText);
// add(new Label(""));
if (m_newUser) {
m_securityPart.add(new Label(LoginHelper
.getMessage("login.userNewForm.securitySectionHeader"),
false), ColumnPanel.FULL_WIDTH);
m_securityPart.add(new Label(LoginHelper
.getMessage("login.userNewForm.securityBlurb")),
ColumnPanel.FULL_WIDTH);
m_securityPart.add(new Label(LoginHelper
.getMessage("login.userNewForm.passwordBlurb")),
ColumnPanel.FULL_WIDTH);
// Password
m_password = new Password(new StringParameter(FORM_PASSWORD));
m_password.addValidationListener(new PasswordValidationListener());
m_securityPart.add(m_passwordLabel);
m_securityPart.add(m_password);
// Password confirmation
m_confirm = new Password(new StringParameter(
FORM_PASSWORD_CONFIRMATION));
m_confirm.addValidationListener(new NotEmptyValidationListener());
m_securityPart.add(m_confirmationLabel);
m_securityPart.add(m_confirm);
m_securityPart.add(new Label(LoginHelper
.getMessage("login.userNewForm.questionBlurb")),
ColumnPanel.FULL_WIDTH);
// Password question
m_question = new TextField(new StringParameter(
FORM_PASSWORD_QUESTION));
m_question.setSize(30);
m_question.addValidationListener(new NotEmptyValidationListener());
m_securityPart.add(m_questionLabel);
m_securityPart.add(m_question);
// Password answer
m_answer = new TextField(new StringParameter(FORM_PASSWORD_ANSWER));
m_answer.setSize(30);
m_answer.addValidationListener(new NotEmptyValidationListener());
m_securityPart.add(m_answerLabel);
m_securityPart.add(m_answer);
}
// Submit
m_submitPart.add(m_submit, ColumnPanel.CENTER | ColumnPanel.FULL_WIDTH);
add(m_profilePart);
add(m_securityPart);
add(m_submitPart);
}
/**
* Initializes this form with data from the user.
*
* @param event
*
* @throws com.arsdigita.bebop.FormProcessException
*
*/
@Override
public void init(FormSectionEvent event)
throws FormProcessException {
PageState state = event.getPageState();
User user = getUser(state);
if (user == null) {
throw new FormProcessException(LoginGlobalizationUtil.globalize(
"login.userForm.couldnt_load_user"));
}
PersonName name = user.getName();
m_firstName.setValue(state, name.getGivenName());
m_lastName.setValue(state, name.getFamilyName());
InternetAddress address;
try {
address = new InternetAddress(user.getEmailAddresses().get(0)
.toString());
} catch (AddressException e) {
String[] errorMsg = new String[1];
errorMsg[0] = user.getEmailAddresses().get(0).toString();
throw new FormProcessException(
"Email address is bad: " + user.getEmailAddresses().get(0),
LoginHelper.getMessage("login.error.badEmail", errorMsg)
);
}
m_email.setValue(state, address);
m_screenName.setValue(state, user.getScreenName());
}
/**
* Gets the current user for initialising the form.
*
* @param state
* @return the current user, if the form should not be initialised with user
* data.
*/
protected abstract User getUser(final PageState state);
/**
* Validates this form. Verifies that the password and password-confirm
* fields match. If not it adds an error to the password-confirm field. Also
* verifies that primary email address and screen name are unique among all
* users.
*
* @param event
* @throws com.arsdigita.bebop.FormProcessException
*/
@Override
public void validate(final FormSectionEvent event)
throws FormProcessException {
PageState state = event.getPageState();
FormData data = event.getFormData();
try {
if (m_newUser) {
// Verify that password and confirmation match
String password = (String) m_password.getValue(state);
String confirm = (String) m_confirm.getValue(state);
if ((password != null) && (confirm != null)
&& !password.equals(confirm)) {
data.addError(FORM_PASSWORD_CONFIRMATION,
ERROR_MISMATCH_PASSWORD);
}
}
String email = null;
if (m_email.getValue(state) != null) {
InternetAddress address = (InternetAddress) m_email
.getValue(state);
email = address.getAddress();
}
final String screenName = (String) m_screenName.getValue(state);
// If this query returns with any rows we have a duplicate
// screen name, email address, or both. Check the results and
// produce appropriate error messages.
final boolean checkPrimaryEmail = KernelConfig.getConfig()
.emailIsPrimaryIdentifier();
final UserRepository userRepo;
try {
final CdiUtil cdiUtil = new CdiUtil();
userRepo = cdiUtil.findBean(
UserRepository.class);
} catch (CdiLookupException ex) {
throw new FormProcessException(ex);
}
final User userByEmail = userRepo.findByEmailAddress(email);
if (userByEmail != null && checkPrimaryEmail) {
data.addError(FORM_EMAIL, ERROR_DUPLICATE_EMAIL);
}
final User userByScreenname = userRepo.findByScreenName(screenName);
if (userByScreenname != null) {
data.addError(FORM_SCREEN_NAME, ERROR_DUPLICATE_SN);
}
} finally {
// if the form has errors, clear the password fields so we don't
// send the passwords back over the network
if (m_newUser && !data.isValid()) {
m_password.setValue(state, "");
m_confirm.setValue(state, "");
}
}
}
}

View File

@ -0,0 +1,220 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.bebop.ListPanel;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleComponent;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.web.URL;
import com.arsdigita.xml.Element;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.User;
import org.libreccm.web.ApplicationRepository;
import org.libreccm.web.CcmApplication;
/**
* A reusable Bebop component to display the primary attributes of the currently
* logged in user. Users can extend this class to provide information about
* another user by overriding the {@link
* UserInfo#register(Page)} and {@link UserInfo#getUser(PageState)} methods.
*
* @author Michael Bryzek
* @author Roger Hsueh
* @author Sameer Ajmani
* @author Peter Boy (refactored to eliminate old type kernel.Package* /
* SiteNode)
* @since 2001-06-01
* @version 1.0
* @version $Id$
*/
public class UserInfo extends SimpleContainer {
/**
* Logger instance for debugging support
*/
private static final Logger s_log = Logger.getLogger(UserInfo.class
.getName());
/**
* Holds a list of content centers (Application instances) that exist on
* this installation. Usually there is only ONE installed, but obviously
* care is taken that one content-center may be installed per subsite.
*/
private List<CcmApplication> m_contentCenters;
private UserAuthenticationListener m_listener
= new UserAuthenticationListener();
/**
* Constructor.
*/
public UserInfo() {
// add list of links
ListPanel list = new ListPanel(false);
list.add(new DynamicLink("login.userInfo.logoutLink",
LoginServlet.getLogoutPageURL()));
list.add(new DynamicLink("login.userInfo.editProfileLink",
LoginServlet.getEditUserProfilePageURL()));
list.add(new DynamicLink("login.userInfo.changePasswordLink",
LoginServlet.getRecoverPasswordPageURL()));
add(list);
// add user info text
add(new SimpleComponent() {
@Override
public void generateXML(PageState state, Element parent) {
if (!isLoggedIn(state)) {
s_log.debug("user is not logged in, so no XML generated");
return;
}
final User user = getUser(state);
final Element userElement = new Element(
"subsite:userInfo", LoginServlet.SUBSITE_NS_URI);
// check if Content-Center (CMS Workspace) is installed and
// instantiated, if so collect all instantiated workspace apps.
if (m_contentCenters == null) {
m_contentCenters = new ArrayList<>();
final CdiUtil cdiUtil = new CdiUtil();
final ApplicationRepository appRepo;
try {
appRepo = cdiUtil.findBean(
ApplicationRepository.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup ApplicationRepository", ex);
}
m_contentCenters = appRepo.findByType(
"com.arsdigita.cms.ContentCenter");
}
// work on the list of installed (instantiated)
// workspaces (content-centers) if any and add some attributes
// to XML generator
if (m_contentCenters.size() > 0) {
Element workspaceURL;
Element contentCenters = userElement.newChildElement(
"subsite:contentCenters",
LoginServlet.SUBSITE_NS_URI);
// step through instantiated workspaces (content-centers)
for (CcmApplication application : m_contentCenters) {
// for each instance of Workspace = for each installed
// (instantiated) Workspace application:
// Add an Element
final Element center = contentCenters
.newChildElement("subsite:center",
LoginServlet.SUBSITE_NS_URI);
// Add attribute name = URL without trailing/leading "/"
center.addAttribute("name", application.getTitle()
.getValue(DispatcherHelper
.getNegotiatedLocale()));
workspaceURL = center.newChildElement(
"subsite:url",
LoginServlet.SUBSITE_NS_URI);
// get URL of Workspace application (instance)
final URL url = URL.there(state.getRequest(),
application.getPrimaryUrl());
workspaceURL.setText(url.toString());
}
}
// in any case: add basic user attributes
userElement.addAttribute("id",
Long.toString(user.getSubjectId()));
if (!user.getEmailAddresses().isEmpty()) {
userElement.addAttribute("email",
user.getEmailAddresses().get(0)
.getAddress());
}
userElement.addAttribute(
"name", String.format("%s %s",
user.getName().getGivenName(),
user.getName().getFamilyName()));
userElement.addAttribute("screenName", user.getScreenName());
parent.addContent(userElement);
}
});
}
/**
* Adds a request listener to the page to ensure that the user is logged in.
* Subclasses should override this method if they do not require users to be
* logged in. This method may be changed as we find more examples of how
* people are using this class.
*
* @pre p != null
*
*/
@Override
public void register(Page p) {
super.register(p);
p.addRequestListener(m_listener);
}
/**
* @param state
* @return true if the user is logged in
*
*/
protected boolean isLoggedIn(final PageState state) {
return m_listener.isLoggedIn(state);
}
/**
* @param state
* @return the User object for which we are generating information
*
* @throws IllegalStateException if user is not logged in. Call
* isLoggedIn(state) to check for this case.
*
* @pre state != null
* @post return != null
*
*/
protected User getUser(final PageState state) {
if (!isLoggedIn(state)) {
throw new IllegalStateException("user is not logged in");
}
return m_listener.getUser(state);
}
}

View File

@ -0,0 +1,487 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Container;
import com.arsdigita.bebop.ElementComponent;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormValidationListener;
import com.arsdigita.bebop.form.CheckboxGroup;
import com.arsdigita.bebop.form.Hidden;
import com.arsdigita.bebop.form.Option;
import com.arsdigita.bebop.form.Password;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.parameters.EmailParameter;
import com.arsdigita.bebop.parameters.NotNullValidationListener;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.parameters.URLParameter;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.kernel.security.SecurityConfig;
import com.arsdigita.ui.UI;
import com.arsdigita.util.UncheckedWrapperException;
import static com.arsdigita.ui.login.LoginConstants.*;
import com.arsdigita.web.ParameterMap;
import com.arsdigita.web.RedirectSignal;
import com.arsdigita.web.ReturnSignal;
import com.arsdigita.web.URL;
import com.arsdigita.web.Web;
import javax.mail.internet.InternetAddress;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.CcmSessionContext;
import org.libreccm.core.authentication.LoginManager;
import java.util.logging.Level;
/**
* A Bebop form that accepts login and password from the user and attempts to
* authenticate and then log in the user.
*
* Depending on security configuration it may generate a link to a NewUser
* registration form, where a new user may register itself. LoginServlet has to
* ensure that this page is created appropriately and is available.
*
* According to documentation in r1230 Simple SSO implementation: /ccm/register
* first tries to do SSO login, falling back to normal form-based login. Set
* waf.sso_login=true only after you make sure webapp can *only* be accessed
* through the frontend webserver doing the authentication.
*
* To make this work with Tomcat/mod_jk/Apache HTTPD: - use latest mod_jk
* (tested with 1.2.15) - add attribute Connector@tomcatAuthentication="false"
* to JK definition in server.xml
*
* @author Roger Hsueh
* @author Michael Bryzek
* @author Sameer Ajmani
*
* @version $Id$
*/
public class UserLoginForm extends Form
implements LoginConstants, FormInitListener,
FormValidationListener, FormProcessListener {
private static final Logger s_log = Logger.getLogger(UserLoginForm.class);
// package friendly static form name makes writing HttpUnitTest easier
final static String FORM_NAME = "user-login";
private CheckboxGroup m_isPersistent;
private Hidden m_timestamp;
private Hidden m_returnURL;
private TextField m_loginName;
private Password m_password;
private boolean m_autoRegistrationOn;
private SecurityConfig securityConfig = SecurityConfig.getConfig();
/**
* Default constructor delegates to a constructor which creates a LoginForm
* without a link to a newUserRegistrationForm.
*/
public UserLoginForm() {
this(true);
}
public UserLoginForm(Container panel) {
this(panel, true);
}
public UserLoginForm(boolean autoRegistrationOn) {
this(new BoxPanel(), autoRegistrationOn);
}
/**
* Constructor which does the real work, other constructors delegate to it.
*
* @param panel
* @param autoRegistrationOn
*/
public UserLoginForm(Container panel, boolean autoRegistrationOn) {
super(FORM_NAME, panel);
setMethod(Form.POST);
addInitListener(this);
addValidationListener(this);
addProcessListener(this);
m_autoRegistrationOn = autoRegistrationOn;
m_timestamp = new Hidden(new StringParameter(FORM_TIMESTAMP));
add(m_timestamp);
m_returnURL = new Hidden(new URLParameter(
LoginHelper.RETURN_URL_PARAM_NAME));
m_returnURL.setPassIn(true);
add(m_returnURL);
setupLogin();
add(new Label(LoginHelper.getMessage(
"login.userRegistrationForm.password")));
m_password = new Password(new StringParameter(FORM_PASSWORD));
// Since new users should not enter a password, allow null.
//m_password.addValidationListener(new NotNullValidationListener());
add(m_password);
SimpleContainer cookiePanel = new BoxPanel(BoxPanel.HORIZONTAL);
m_isPersistent = new CheckboxGroup(FORM_PERSISTENT_LOGIN_P);
Label optLabel = new Label(LoginHelper.getMessage(
"login.userRegistrationForm.cookieOption"));
Option opt = new Option(FORM_PERSISTENT_LOGIN_P_DEFAULT, optLabel);
m_isPersistent.addOption(opt);
if (KernelConfig.getConfig().isLoginRemembered()) {
m_isPersistent.setOptionSelected(FORM_PERSISTENT_LOGIN_P_DEFAULT);
}
cookiePanel.add(m_isPersistent);
cookiePanel.add(new DynamicLink(
"login.userRegistrationForm.explainCookieLink",
LoginServlet.getCookiesExplainPageURL()));
add(cookiePanel);
add(new Submit(SUBMIT), ColumnPanel.CENTER | ColumnPanel.FULL_WIDTH);
if (securityConfig.getEnableQuestion()) {
add(new DynamicLink("login.userRegistrationForm.forgotPasswordLink",
LoginServlet.getRecoverPasswordPageURL()));
}
if (m_autoRegistrationOn) {
add(new DynamicLink("login.userRegistrationForm.newUserRegister",
LoginServlet.getNewUserPageURL()));
}
add(new ElementComponent("subsite:promptToEnableCookiesMsg",
LoginServlet.SUBSITE_NS_URI));
}
/**
* Sets up the login form parameters
*/
private void setupLogin() {
SimpleContainer loginMessage = new SimpleContainer(
"subsite:loginPromptMsg",
LoginServlet.SUBSITE_NS_URI);
if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) {
loginMessage.setClassAttr("email");
} else {
loginMessage.setClassAttr("screenName");
}
add(loginMessage);
if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) {
add(new Label(LoginHelper.getMessage(
"login.userRegistrationForm.email")));
m_loginName = new TextField(new EmailParameter(FORM_LOGIN));
addInitListener(new EmailInitListener((EmailParameter) m_loginName.
getParameterModel()));
} else {
add(new Label(LoginHelper.getMessage(
"login.userRegistrationForm.screenName")));
m_loginName = new TextField(new StringParameter(FORM_LOGIN));
addInitListener(new ScreenNameInitListener(
(StringParameter) m_loginName.
getParameterModel()));
}
m_loginName.addValidationListener(new NotNullValidationListener());
add(m_loginName);
}
/**
*
* @param event
*
* @throws FormProcessException
*/
@Override
public void init(FormSectionEvent event)
throws FormProcessException {
s_log.info("In init");
if (KernelConfig.getConfig().isSSOenabled()) {
// try SSO login
s_log.info("trying SSO");
// try {
throw new UnsupportedOperationException(
"SSO currently not supported");
// Web.getUserContext().loginSSO();
// s_log.info("loginSSO ok, now processing redirect_url");
// process(event);
// return;
// } catch (LoginException le) {
// // continue with standard form-based login
// s_log.debug("SSO failed", le);
// }
}
// try {
// // create timestamp
// String value = Credential.create(FORM_TIMESTAMP,
// 1000 * TIMESTAMP_LIFETIME_SECS).
// toString();
// m_timestamp.setValue(event.getPageState(), value);
// } catch (CredentialException e) {
// s_log.debug("Could not create timestamp", e);
// throw new FormProcessException(LoginGlobalizationUtil.globalize(
// "login.userLoginForm.couldnt_create_timestamp"));
// }
}
/**
*
* @param event
*
* @throws FormProcessException
*/
@Override
public void validate(FormSectionEvent event)
throws FormProcessException {
s_log.debug("In validate");
FormData data = event.getFormData();
PageState state = event.getPageState();
try {
// check timestamp
// try {
// Credential.parse((String) m_timestamp.getValue(state));
// } catch (CredentialException e) {
// s_log.info("Invalid credential");
//
// final String path = LoginServlet.getLoginExpiredPageURL();
// final URL url = com.arsdigita.web.URL.there(state.getRequest(),
// path);
//
// throw new RedirectSignal(url, false);
// }
// log in the user
if (m_loginName.getValue(state) != null) {
loginUser(event);
}
} finally {
if (!data.isValid()) {
// clear password from form data
m_password.setValue(state, "");
}
}
}
/**
*
* @param event
*
* @throws FormProcessException
*/
public void process(FormSectionEvent event) throws FormProcessException {
s_log.debug("In process");
final PageState state = event.getPageState();
final HttpServletRequest req = state.getRequest();
// Redirect to workspace or return URL, if specified.
final String path = UI.getUserRedirectURL(req);
final URL url = com.arsdigita.web.URL.there(req, path);
throw new ReturnSignal(req, url);
}
/**
* Logs in the user using the username, password, and "Remember this login?"
* request stored in the given form event. Subclasses can override this
* method or just one of the specific case handlers (onLoginSuccess,
* onBadPassword, onAccountNotFound, onLoginException).
*
* @param event
*
* @throws FormProcessException if there is an unexpected login error
*
*/
protected void loginUser(FormSectionEvent event)
throws FormProcessException {
PageState state = event.getPageState();
try {
final CcmSessionContext ctx = Web.getUserContext();
final String username;
if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) {
username = ((InternetAddress) m_loginName.getValue(state)).
getAddress();
} else {
username = (String) m_loginName.getValue(state);
}
final String password = ((String)m_password.getValue(state)).trim();
boolean forever = getPersistentLoginValue(event.getPageState(),
false);
// attempt to log in user
final CdiUtil cdiUtil = new CdiUtil();
final LoginManager loginManager;
try {
loginManager = cdiUtil.findBean(LoginManager.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup LoginManager", ex);
}
loginManager.login(username, password);
onLoginSuccess(event);
} catch (FailedLoginException e) {
onLoginFail(event, e);
} catch (LoginException e) {
onLoginException(event, e);
}
}
/**
* Executed when login succeeds. Default implementation does nothing.
*
* @param event
*
* @throws com.arsdigita.bebop.FormProcessException
*
*/
protected void onLoginSuccess(FormSectionEvent event)
throws FormProcessException {
// do nothing
}
/**
*
* @param event
* @param e
*
* @throws FormProcessException
*/
protected void onBadPassword(FormSectionEvent event,
FailedLoginException e)
throws FormProcessException {
onLoginFail(event, e);
}
/**
* Executed when login fails with a bad password or when autoLoginOn is set
* to false and the user doesn't exist. Default implementation marks
* password parameter with an error message.
*
* @param event
* @param e
*
* @throws com.arsdigita.bebop.FormProcessException
*
*/
protected void onLoginFail(FormSectionEvent event,
LoginException e)
throws FormProcessException {
s_log.debug("Login fail");
event.getFormData().addError((String) ERROR_LOGIN_FAIL.localize(event.
getPageState().getRequest()));
}
/**
* Executed when login fails for an unrecognized problem. Default
* implementation logs the error and throws FormProcessException.
*
*/
protected void onLoginException(FormSectionEvent event,
LoginException e)
throws FormProcessException {
// unexpected error happened during login
s_log.error("Login failed", e);
throw new FormProcessException(e);
}
/**
* Determines whether a persistent cookie is requested in the given form.
*
* @return true if the specified formdata has a field named
* FORM_PERSISTENT_LOGIN_P whose value is equal to "1". If there is
* no such field in the form data, returns the specified default
* value.
*
*/
protected boolean getPersistentLoginValue(PageState state,
boolean defaultValue) {
// Problem:
// getValue(state) returns an Object of type StringArray, if the
// Checkbox is marked.
// It returns an object of type String if it is not marked / left empty.
// Additionally, in some circumstances it may return null
// ODD!!
Object persistentLoginValue = m_isPersistent.getValue(state);
String value;
if (persistentLoginValue == null) {
return defaultValue;
}
if (persistentLoginValue instanceof String[]) {
value = ((String[]) persistentLoginValue)[0];
} else if (persistentLoginValue instanceof String) {
value = (String) persistentLoginValue;
} else {
value = "0";
}
return "1".equals(value);
}
/**
*
* @param state
*/
protected void redirectToNewUserPage(PageState state) {
String url = LoginServlet.getNewUserPageURL();
ParameterMap map = new ParameterMap();
map.setParameter(LoginHelper.RETURN_URL_PARAM_NAME,
m_returnURL.getValue(state));
map.setParameter(FORM_PERSISTENT_LOGIN_P,
m_isPersistent.getValue(state));
map.setParameter(FORM_EMAIL,
m_loginName.getValue(state));
final URL dest = com.arsdigita.web.URL.there(state.getRequest(),
url,
map);
throw new RedirectSignal(dest, true);
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.util.UncheckedWrapperException;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.authentication.LoginManager;
/**
* An ActionListener that logs out the user.
*
* @author Sameer Ajmani
*
*/
public class UserLogoutListener implements ActionListener {
private static final Logger s_log = Logger.getLogger(
UserLogoutListener.class);
/**
* Logs out the user.
*
* @param event
*
*/
@Override
public void actionPerformed(final ActionEvent event) {
final CdiUtil cdiUtil = new CdiUtil();
final LoginManager loginManager;
try {
loginManager = cdiUtil.findBean(LoginManager.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException("Failed to lookup LoginManager",
ex);
}
loginManager.logout();
}
}

View File

@ -0,0 +1,265 @@
/*
* Copyright (C) 2001-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.ui.login;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Container;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormValidationListener;
import com.arsdigita.bebop.form.Hidden;
import com.arsdigita.bebop.parameters.ArrayParameter;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.parameters.URLParameter;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.ui.UI;
import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.web.Web;
import com.arsdigita.web.URL;
import com.arsdigita.web.ReturnSignal;
import static com.arsdigita.ui.login.LoginConstants.*;
import javax.mail.internet.InternetAddress;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.dom4j.util.UserDataDocumentFactory;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.CcmSessionContext;
import org.libreccm.core.EmailAddress;
import org.libreccm.core.PermissionManager;
import org.libreccm.core.PersonName;
import org.libreccm.core.User;
import org.libreccm.core.UserManager;
import org.libreccm.core.UserRepository;
import org.libreccm.core.authentication.LoginManager;
/**
* Creates a new user. Collects user's basic info, such as email, password,
* first name, last name, etc; then tries to create the user in the database. If
* returnURL is passed in to the form, then redirects to that URL; otherwise
* redirects to the user workspace.
*
*
* @author Michael Bryzek
* @author Roger Hsueh
* @author Sameer Ajmani
*
* @version $Id$
*
*
*/
public class UserNewForm extends UserForm implements FormInitListener,
FormProcessListener,
FormValidationListener {
private static final Logger s_log = Logger.getLogger(UserNewForm.class);
static final String FORM_NAME = "user-new";
private Hidden m_loginName;
private Hidden m_returnURL;
private Hidden m_persistent;
public UserNewForm() {
this(new ColumnPanel(2));
}
@Override
protected User getUser(final PageState state) {
return null; // don't load any data into form
}
public UserNewForm(final Container panel) {
super(FORM_NAME, panel, true);
addInitListener(this);
addValidationListener(this);
addProcessListener(this);
// save return URL
m_returnURL = new Hidden(new URLParameter(
LoginHelper.RETURN_URL_PARAM_NAME));
m_returnURL.setPassIn(true);
add(m_returnURL);
// save email address or screen name
m_loginName = new Hidden(new StringParameter(FORM_LOGIN));
m_loginName.setPassIn(true);
add(m_loginName);
// save persistent flag
ArrayParameter cookieP = new ArrayParameter(FORM_PERSISTENT_LOGIN_P);
m_persistent = new Hidden(cookieP);
m_persistent.setPassIn(true);
add(m_persistent);
}
public void init(FormSectionEvent event)
throws FormProcessException {
PageState state = event.getPageState();
// clear passwords from form data
m_password.setValue(state, "");
m_confirm.setValue(state, "");
String loginName = (String) m_loginName.getValue(state);
if (loginName != null) {
if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) {
m_email.setValue(state, loginName);
} else {
m_screenName.setValue(state, loginName);
}
}
}
public void process(FormSectionEvent event)
throws FormProcessException {
PageState state = event.getPageState();
final InternetAddress address = (InternetAddress) m_email
.getValue(state);
final String email = address.getAddress();
// TODO: set additional emails
final String password = (String) m_password.getValue(state);
final String question = (String) m_question.getValue(state);
final String answer = (String) m_answer.getValue(state);
final String firstName = (String) m_firstName.getValue(state);
final String lastName = (String) m_lastName.getValue(state);
String sn = null;
if (!KernelConfig.getConfig().emailIsPrimaryIdentifier()) {
sn = (String) m_screenName.getValue(state);
}
final String screenName = sn;
final Exception[] formExceptions = new Exception[]{null};
final CdiUtil cdiUtil = new CdiUtil();
final CcmSessionContext sessionContext;
try {
sessionContext = cdiUtil.findBean(CcmSessionContext.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup CcmSessionContext", ex);
}
final UserRepository userRepository;
try {
userRepository = cdiUtil.findBean(UserRepository.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup UserRepository", ex);
}
final User systemUser = userRepository.retrieveSystemUser();
sessionContext.sudo(systemUser, new Runnable() {
@Override
public void run() {
final User user = new User();
final PersonName userName = new PersonName();
userName.setGivenName(firstName);
userName.setFamilyName(lastName);
final EmailAddress emailAddress = new EmailAddress();
emailAddress.setAddress(email);
user.addEmailAddress(emailAddress);
if (!KernelConfig.getConfig().emailIsPrimaryIdentifier()) {
user.setScreenName(screenName);
}
userRepository.save(user);
// final PermissionManager permissionManager;
// try {
// permissionManager = cdiUtil
// .findBean(PermissionManager.class);
// } catch (CdiLookupException ex) {
// throw new UncheckedWrapperException(
// "Failed to lookup PermissionManager", ex);
// }
//
// permissionManager.grantPermission(null, null, user);
final UserManager userManager;
try {
userManager = cdiUtil.findBean(UserManager.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup UserManager", ex);
}
userManager.updatePassword(user, password);
user.setPasswordQuestion(question);
user.setPasswordAnswer(answer);
}
});
try {
// finally log the user in (sets the
// appropriate session or permanent cookie)
String loginName = email;
if (!KernelConfig.getConfig().emailIsPrimaryIdentifier()) {
loginName = screenName;
}
final LoginManager loginManager;
try {
loginManager = cdiUtil.findBean(LoginManager.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(
"Failed to lookup LoginManager", ex);
}
loginManager.login(loginName, password);
} catch (LoginException e) {
// ERROR: login failed for new user
s_log.error("login failed for new user", e);
throw new FormProcessException(e);
}
// redirect to workspace or return URL, if specified
final HttpServletRequest req = state.getRequest();
// url = LegacyInitializer.getFullURL
// (LegacyInitializer.WORKSPACE_PAGE_KEY, req);
final String url = UI.getWorkspaceURL();
final URL fallback = com.arsdigita.web.URL.there(req, url);
throw new ReturnSignal(req, fallback);
}
protected boolean getPersistentLoginValue(PageState state,
boolean defaultValue) {
// CheckboxGroup gets you a StringArray
String[] values = (String[]) m_persistent.getValue(state);
if (values == null) {
return defaultValue;
}
String persistentLoginValue = (String) values[0];
return "1".equals(persistentLoginValue);
}
}

View File

@ -18,7 +18,7 @@
*/
package com.arsdigita.web;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -45,6 +45,6 @@ public interface ApplicationFileResolver {
RequestDispatcher resolve(String templatePath,
HttpServletRequest sreq,
HttpServletResponse sresp,
Application app);
CcmApplication app);
}

View File

@ -22,7 +22,7 @@ package com.arsdigita.web;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiLookupException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
import org.libreccm.web.ApplicationRepository;
import java.io.IOException;
@ -103,7 +103,7 @@ public abstract class BaseApplicationServlet extends BaseServlet {
final HttpServletResponse response)
throws ServletException, IOException {
final Application app = getApplication(request);
final CcmApplication app = getApplication(request);
if (app == null) {
response.sendError(404, "Application not found");
@ -141,7 +141,7 @@ public abstract class BaseApplicationServlet extends BaseServlet {
*/
protected abstract void doService(final HttpServletRequest sreq,
final HttpServletResponse sresp,
final Application app)
final CcmApplication app)
throws ServletException, IOException;
/**
@ -150,7 +150,7 @@ public abstract class BaseApplicationServlet extends BaseServlet {
*
* @return
*/
private Application getApplication(final HttpServletRequest request) {
private CcmApplication getApplication(final HttpServletRequest request) {
s_log.debug("Resolving the application that will handle this request");
Long appId = (Long) request.getAttribute(APPLICATION_ID_ATTRIBUTE);
@ -197,7 +197,7 @@ public abstract class BaseApplicationServlet extends BaseServlet {
* @return
*/
// private RequestContext makeLegacyContext(HttpServletRequest sreq,
// final Application app,
// final CcmApplication app,
// final UserContext uc) {
// s_log.debug("Setting up a legacy context object");
//

View File

@ -23,7 +23,7 @@ import com.arsdigita.util.Assert;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
import org.libreccm.web.ApplicationRepository;
import org.libreccm.web.ServletPath;
@ -239,7 +239,7 @@ public class CCMDispatcherServlet extends BaseServlet {
path + "' ***");
}
final Application application = appRepository
final CcmApplication application = appRepository
.retrieveApplicationForPath(path);
if (application == null) {
@ -278,7 +278,7 @@ public class CCMDispatcherServlet extends BaseServlet {
*
* @param app
*/
ApplicationSpec(Application app) {
ApplicationSpec(CcmApplication app) {
if ( app == null ) { throw new NullPointerException("app"); }
m_id = app.getObjectId();

View File

@ -23,7 +23,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.RequestDispatcher;
import org.apache.log4j.Logger;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
/**
@ -70,7 +70,7 @@ public class DefaultApplicationFileResolver implements ApplicationFileResolver {
public RequestDispatcher resolve(String templatePath,
HttpServletRequest sreq,
HttpServletResponse sresp,
Application app) {
CcmApplication app) {
String pathInfo = sreq.getPathInfo(); // effectively provides an url
if (s_log.isDebugEnabled()) { // with application part stripped

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2002-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.web;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
/**
* <p>
* A <code>RedirectSignal</code> that sends the client to the login UI.
* <code>LoginSignal</code> encodes the origin URL so that
* <code>ReturnSignal</code> can return the client to its starting point.</p>
*
* @see com.arsdigita.web.ReturnSignal
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id$
*/
public class LoginSignal extends RedirectSignal {
private static final long serialVersionUID = 6546166999255204832L;
/**
* Constructs a signal to redirect the client to log in. This constructor
* tells the base servlet to abandon the current transaction.
* @param sreq
*/
public LoginSignal(final HttpServletRequest sreq) {
this(sreq, false);
}
/**
* Constructs a signal to redirect the client to log in.
*
* @param sreq
* @param isCommitRequested
*/
public LoginSignal(final HttpServletRequest sreq,
final boolean isCommitRequested) {
super(URL.login(sreq), isCommitRequested);
}
}

View File

@ -0,0 +1,88 @@
/*
* Copyright (C) 2002-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.web;
import com.arsdigita.util.Assert;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
/**
* <p>A signal that returns the client to a return URL encoded in the
* current URL, or if the return URL is not found, uses a fallback
* URL.</p>
*
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id$
*/
public class ReturnSignal extends RedirectSignal {
private static final Logger s_log = Logger.getLogger(ReturnSignal.class);
private static final long serialVersionUID = -2923355745770322780L;
public ReturnSignal(final HttpServletRequest sreq) {
super(getReturnURL(sreq), true);
}
public ReturnSignal(final HttpServletRequest sreq, final String fallback) {
super(getReturnURL(sreq, fallback), true);
}
public ReturnSignal(final HttpServletRequest sreq, final URL fallback) {
this(sreq, fallback.toString());
}
private static String getReturnURL(final HttpServletRequest sreq) {
s_log.debug("Fetching the return URL to redirect to");
final String returnURL = sreq.getParameter("return_url");
Assert.exists(returnURL, "String returnURL");
if (s_log.isDebugEnabled()) {
s_log.debug("Redirecting to URL '" + returnURL + "'");
}
return returnURL;
}
private static String getReturnURL(final HttpServletRequest sreq,
final String fallback) {
s_log.debug("Fetching the return URL to redirect to");
Assert.exists(fallback, "String fallback");
final String returnURL = sreq.getParameter("return_url");
if (returnURL == null || returnURL.equals("")) {
if (s_log.isDebugEnabled()) {
s_log.debug("Cannot find the return URL parameter; " +
"using the fallback URL '" + fallback + "'");
}
return fallback;
} else {
if (s_log.isDebugEnabled()) {
s_log.debug("Redirecting to the value in the return URL " +
"parameter, '" + returnURL + "'");
}
return returnURL;
}
}
}

View File

@ -28,7 +28,7 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
/**
* <p>
@ -778,7 +778,7 @@ public class URL {
* indicating that the URL has no query string.</p>
*
* @param sreq the servlet request
* @param app the <code>Application</code> to dispatch to
* @param app the <code>CcmApplication</code> to dispatch to
* @param pathInfo a <code>String</code> of extra path info for the
* application
* @param params a <code>ParameterMap</code> of parameters to use
@ -787,7 +787,7 @@ public class URL {
* <code>pathInfo</code>
*/
public static final URL there(final HttpServletRequest sreq,
final Application app,
final CcmApplication app,
final String pathInfo,
final ParameterMap params) {
if (Assert.isEnabled() && pathInfo != null) {
@ -809,7 +809,7 @@ public class URL {
* specified application.
*
* @param sreq the servlet request
* @param app the <code>Application</code> to dispatch to
* @param app the <code>CcmApplication</code> to dispatch to
* @param pathInfo a <code>String</code> of extra path info for the
* application
*
@ -817,7 +817,7 @@ public class URL {
* <code>pathInfo</code>
*/
public static final URL there(final HttpServletRequest sreq,
final Application app,
final CcmApplication app,
final String pathInfo) {
if (Assert.isEnabled() && pathInfo != null) {
Assert.isTrue(pathInfo.startsWith("/"),
@ -868,7 +868,7 @@ public class URL {
* <code>HttpServletRequest</code> object as it will ignore any Host header
* given by the client.</p>
*/
public static final URL there(final Application app,
public static final URL there(final CcmApplication app,
final String pathInfo,
final ParameterMap params) {
return URL.there(app.getPrimaryUrl() + pathInfo, params);
@ -877,7 +877,7 @@ public class URL {
public static final URL here(final HttpServletRequest sreq,
final String pathInfo,
final ParameterMap params) {
final Application app = Web.getWebContext().getApplication();
final CcmApplication app = Web.getWebContext().getApplication();
Assert.exists(app, "Application app");
@ -886,7 +886,7 @@ public class URL {
public static final URL here(final HttpServletRequest sreq,
final String pathInfo) {
final Application app = Web.getWebContext().getApplication();
final CcmApplication app = Web.getWebContext().getApplication();
Assert.exists(app, "Application app");

View File

@ -18,14 +18,14 @@
*/
package com.arsdigita.web;
// import com.arsdigita.web.Application;
// import com.arsdigita.web.CcmApplication;
import com.arsdigita.util.Assert;
import com.arsdigita.util.Record;
import org.apache.log4j.Logger;
import org.libreccm.core.CcmSessionContext;
import org.libreccm.core.User;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
/**
* <p>
@ -51,7 +51,7 @@ public final class WebContext extends Record {
*/
private static final Logger s_log = Logger.getLogger(WebContext.class);
private Application m_application = null;
private CcmApplication m_application = null;
private URL m_requestURL = null;
/**
@ -90,7 +90,7 @@ public final class WebContext extends Record {
* @param app
* @param requestURL
*/
final void init(final Application app, final URL requestURL) {
final void init(final CcmApplication app, final URL requestURL) {
setApplication(app);
setRequestURL(requestURL);
}
@ -114,7 +114,7 @@ public final class WebContext extends Record {
*
* @return
*/
public final Application getApplication() {
public final CcmApplication getApplication() {
return m_application;
}
@ -122,7 +122,7 @@ public final class WebContext extends Record {
*
* @param app
*/
final void setApplication(final Application app) {
final void setApplication(final CcmApplication app) {
m_application = app;
mutated("Application");

View File

@ -29,7 +29,7 @@ import static org.libreccm.core.CoreConstants.*;
import org.libreccm.jpa.utils.UriConverter;
import org.libreccm.l10n.LocalizedString;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
import java.io.Serializable;
import java.net.URI;
@ -65,9 +65,9 @@ import javax.xml.bind.annotation.XmlRootElement;
* as well as the {@code CategoryPurpose} entity from the old
* {@code ccm-core module}.
*
* A {@code Domain} can be mapped to multiple {@link Application}s. Normally
* A {@code Domain} can be mapped to multiple {@link CcmApplication}s. Normally
* This is used to make a {@code Domain} available in the application. The
* {@link Application}s to which a {@code Domain} is mapped are called
* {@link CcmApplication}s to which a {@code Domain} is mapped are called
* <em>owners</em> of the domain.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>

View File

@ -18,14 +18,14 @@
*/
package org.libreccm.categorization;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
/**
* Provides several methods when managing the relations between {@link Domain}s
* and their owning {@link Application}s.
* and their owning {@link CcmApplication}s.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ -36,46 +36,46 @@ public class DomainManager {
private transient DomainRepository domainRepo;
/**
* Adds a {@code Application} to the owners of a {@link Domain}. If the
* provided {@code Application} is already an owner of the provided
* Adds a {@code CcmApplication} to the owners of a {@link Domain}. If the
* provided {@code CcmApplication} is already an owner of the provided
* {@code Domain} the method does nothing.
*
* @param application The {@code Application} to add to the owners of the
* @param application The {@code CcmApplication} to add to the owners of the
* {@code Domain}.
* @param domain The {@code Domain} to which owners the
* {@code Application is added}.
* {@code CcmApplication is added}.
*/
public void addDomainOwner(final Application application,
public void addDomainOwner(final CcmApplication application,
final Domain domain) {
// TODO implement method
throw new UnsupportedOperationException();
}
/**
* Removes a {@code Application} from the owners of a {@code Domain}. If the
* provided {@code Application} is not an owner of the provided
* Removes a {@code CcmApplication} from the owners of a {@code Domain}. If the
* provided {@code CcmApplication} is not an owner of the provided
* {@code Domain} the method does nothing.
*
* @param application The {@code Application} to remove from the owners of
* @param application The {@code CcmApplication} to remove from the owners of
* the provided {@code Domain}.
* @param domain The {@code Domain} from which owners the provided
* {@code Application} should be removed.
* {@code CcmApplication} should be removed.
*/
public void removeDomainOwner(final Application application,
public void removeDomainOwner(final CcmApplication application,
final Domain domain) {
// TODO implement method
throw new UnsupportedOperationException();
}
/**
* Determines if a {@link Application} is an owner of {@link Domain}.
* Determines if a {@link CcmApplication} is an owner of {@link Domain}.
*
* @param application The {@code Application} to test.
* @param application The {@code CcmApplication} to test.
* @param domain The {@code Domain} to test.
* @return {@code true} if the provided {@code Application} is an owner
* @return {@code true} if the provided {@code CcmApplication} is an owner
* of the provided {@code Domain}, {@code false} otherwise.
*/
public boolean isDomainOwner(final Application application,
public boolean isDomainOwner(final CcmApplication application,
final Domain domain) {
// TODO implement method
throw new UnsupportedOperationException();

View File

@ -33,7 +33,7 @@ import org.libreccm.core.CcmObject;
import static org.libreccm.core.CoreConstants.*;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
/**
@ -62,7 +62,7 @@ public class DomainOwnership implements Serializable {
* The {@link CcmObject} owning the {@link Domain}.
*/
@ManyToOne(optional = false)
private Application owner;
private CcmApplication owner;
/**
* The {@link Domain} owned by the {@link CcmObject}.
@ -98,11 +98,11 @@ public class DomainOwnership implements Serializable {
this.ownershipId = ownershipId;
}
public Application getOwner() {
public CcmApplication getOwner() {
return owner;
}
protected void setOwner(final Application owner) {
protected void setOwner(final CcmApplication owner) {
this.owner = owner;
}

View File

@ -75,8 +75,7 @@ import javax.persistence.EntityManager;
org.libreccm.runtime.Initalizer.class,
org.libreccm.search.lucene.Document.class,
org.libreccm.search.lucene.Index.class,
org.libreccm.web.Application.class,
org.libreccm.web.ApplicationType.class,
org.libreccm.web.CcmApplication.class,
org.libreccm.web.Host.class,
org.libreccm.workflow.Task.class,
org.libreccm.workflow.UserTask.class,

View File

@ -23,7 +23,7 @@ import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
/**
* This bean stores several datas about the current session, for example the
* This bean stores several data about the current session, for example the
* current party.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>

View File

@ -21,7 +21,7 @@ package org.libreccm.core;
import static org.libreccm.core.CoreConstants.*;
import org.libreccm.l10n.LocalizedString;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
import java.io.Serializable;
import java.util.Collections;
@ -43,7 +43,7 @@ import javax.persistence.TemporalType;
/**
* The {@code Resource} class is a base class for several other classes, for
* example the {@link Application} class.
* example the {@link CcmApplication} class.
*
* Resources can be nested, a resource can have multiple child resources.
*

View File

@ -37,9 +37,18 @@ import javax.persistence.Table;
import org.libreccm.l10n.LocalizedString;
/**
*
* This class is a port of the old {@code ResourceType} entity.
*
* @deprecated The real purpose of this class is not clear. Also the
* informations provided by the entities of this class are all quite static or
* can be interfered from the classes itself. In modern Java most if not all the
* informations provided by the entities of this class would be expressed as
* annotations. At the moment it is not clear of we can remove this class
* completely therefore it is still here but will maybe removed very soon.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Deprecated
@Entity
@Table(name = "RESOURCE_TYPES", schema = DB_SCHEMA)
@Inheritance(strategy = InheritanceType.JOINED)

View File

@ -219,11 +219,11 @@ public class User extends Subject implements Serializable {
this.emailAddresses = eMailAddresses;
}
protected void addEmailAddress(final EmailAddress emailAddress) {
public void addEmailAddress(final EmailAddress emailAddress) {
emailAddresses.add(emailAddress);
}
protected void removeEmailAddress(final EmailAddress emailAddress) {
public void removeEmailAddress(final EmailAddress emailAddress) {
emailAddresses.remove(emailAddress);
}

View File

@ -84,6 +84,10 @@ public class LoginManager {
}
}
public void logout() {
sessionContext.setCurrentSubject(null);
}
private static class LoginCallbackHandler implements CallbackHandler {
private final transient String username;

View File

@ -18,6 +18,8 @@
*/
package org.libreccm.modules;
import org.libreccm.web.ApplicationType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -67,6 +69,14 @@ public @interface Module {
*/
RequiredModule[] requiredModules() default {};
/**
* ApplicationType types provided by the annotated module.
*
* @return An array containing the type descriptions for all application
* types provided by the annotated module.
*/
ApplicationType[] applicationTypes() default {};
/**
* The JPA entities provided by the annotated module.
*

View File

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

View File

@ -0,0 +1,31 @@
/*
* 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.web;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @param <T>
*/
public interface ApplicationCreator<T extends CcmApplication> {
T createInstance(String primaryUrl,
ApplicationType type);
}

View File

@ -0,0 +1,139 @@
/*
* 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.web;
import org.libreccm.modules.CcmModule;
import org.libreccm.modules.Module;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ApplicationScoped
public class ApplicationManager {
@Inject
private transient EntityManager entityManager;
private Map<String, ApplicationType> applicationTypes;
@PostConstruct
private void loadApplicationTypes() {
final ServiceLoader<CcmModule> modules = ServiceLoader.load(
CcmModule.class);
for (CcmModule module : modules) {
final Module moduleData = module.getClass().getAnnotation(
Module.class);
final ApplicationType[] appTypes = moduleData.applicationTypes();
for (ApplicationType appType : appTypes) {
applicationTypes.put(appType.name(), appType);
}
}
}
public Map<String, ApplicationType> getApplicationTypes() {
return Collections.unmodifiableMap(applicationTypes);
}
public <T extends CcmApplication> T createInstance(
final ApplicationType type,
final String path,
final Class<T> applicationClass) throws ApplicationCreateException {
try {
@SuppressWarnings("unchecked")
final ApplicationCreator<T> creator = type.creator().newInstance();
final T application = creator.createInstance(path, type);
entityManager.persist(application);
return application;
} catch (InstantiationException | IllegalAccessException ex) {
throw new ApplicationCreateException("Failed to create application.",
ex);
}
}
public void deleteInstance(final CcmApplication application) {
entityManager.remove(application);
}
public CcmApplication findApplicationByPath(final String path) {
final TypedQuery<CcmApplication> query = entityManager.createNamedQuery(
"retrieveApplicationForPath", CcmApplication.class);
final List<CcmApplication> result = query.getResultList();
if (result.isEmpty()) {
return null;
} else if (result.size() > 1) {
throw new IllegalArgumentException("Ambiguous path.");
} else {
return result.get(0);
}
}
public String getServletPath(final CcmApplication application) {
final String typeName = application.getApplicationType();
final ApplicationType type = applicationTypes.get(typeName);
if (type == null) {
throw new IllegalArgumentException(String.format(
"Unknown application type \"%s\".", typeName));
}
if (type.servletPath().isEmpty()) {
if (type.servlet().equals(HttpServlet.class)) {
throw new IllegalArgumentException(String.format(
"Application type \"%s\" can no servlet path nor a serlet "
+ "definition.",
typeName));
} else {
final Class<? extends HttpServlet> servletClass = type.servlet();
if (servletClass.isAnnotationPresent(WebServlet.class)) {
return servletClass.getAnnotation(WebServlet.class)
.urlPatterns()[0];
} else {
throw new IllegalArgumentException(String.format(
"Provided servlet for application type \"%s\" has not "
+ "@WebServlet annotation.",
typeName));
}
}
} else {
return type.servletPath();
}
}
}

View File

@ -20,7 +20,10 @@ package org.libreccm.web;
import org.libreccm.core.AbstractEntityRepository;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
/**
@ -29,24 +32,52 @@ import javax.persistence.TypedQuery;
*/
@RequestScoped
public class ApplicationRepository
extends AbstractEntityRepository<Long, Application> {
extends AbstractEntityRepository<Long, CcmApplication> {
@Override
public Class<Application> getEntityClass() {
return Application.class;
public Class<CcmApplication> getEntityClass() {
return CcmApplication.class;
}
@Override
public boolean isNew(final Application application) {
public boolean isNew(final CcmApplication application) {
return application.getObjectId() == 0;
}
public Application retrieveApplicationForPath(final String path) {
final TypedQuery<Application> query = getEntityManager()
.createNamedQuery(
"retrieveApplicationForPath", Application.class);
/**
* Retrieve the application mounted at the provided {@code path}.
*
* @param path The path on which the application is mounted.
*
* @return The application mounted at {@code path} or {@code null} if there
* is no application mounted at that {@code path}.
*/
public CcmApplication retrieveApplicationForPath(final String path) {
final TypedQuery<CcmApplication> query = getEntityManager()
.createNamedQuery("retrieveApplicationForPath", CcmApplication.class);
query.setParameter("path", path);
try {
return query.getSingleResult();
} catch (NoResultException ex) {
return null;
}
}
return query.getSingleResult();
/**
* Find all applications of the specific {@code type}.
*
* @param type The type of the application.
*
* @return A list of the installed applications of the provided
* {@code type}.
*/
public List<CcmApplication> findByType(final String type) {
final TypedQuery<CcmApplication> query = getEntityManager()
.createNamedQuery(
"Application.findByType", CcmApplication.class);
query.setParameter("type", type);
return query.getResultList();
}
}

View File

@ -18,165 +18,29 @@
*/
package org.libreccm.web;
import static org.libreccm.core.CoreConstants.*;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.libreccm.core.Group;
import org.libreccm.core.Privilege;
import org.libreccm.core.ResourceType;
import javax.servlet.http.HttpServlet;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "APPLICATION_TYPES", schema = DB_SCHEMA)
@SuppressWarnings("PMD.LongVariable")
public class ApplicationType extends ResourceType implements Serializable {
private static final long serialVersionUID = -1175728067001112457L;
private static final String PMD_LONG_VARIABLE = "PMD.LongVariable";
@OneToMany
@JoinColumn(name = "RELEVANT_PRIVILEGE_ID")
@SuppressWarnings(PMD_LONG_VARIABLE)
private List<Privilege> relevantPrivileges;
@ManyToOne
@JoinColumn(name = "CONTAINER_GROUP_ID")
private Group containerGroup;
@ManyToOne
@JoinColumn(name = "PROVIDER_APP_TYPE_ID")
@SuppressWarnings(PMD_LONG_VARIABLE)
private ApplicationType providerApplicationType;
@OneToMany(mappedBy = "providerApplicationType")
@SuppressWarnings(PMD_LONG_VARIABLE)
private List<ApplicationType> dependentApplicationTypes;
public ApplicationType() {
super();
relevantPrivileges = new ArrayList<>();
dependentApplicationTypes = new ArrayList<>();
}
public List<Privilege> getRelevantPrivileges() {
return Collections.unmodifiableList(relevantPrivileges);
}
@SuppressWarnings(PMD_LONG_VARIABLE)
protected void setRelevantPrivileges(
final List<Privilege> relevantPrivileges) {
this.relevantPrivileges = relevantPrivileges;
}
protected void addRelevantPrivilege(final Privilege privilege) {
relevantPrivileges.add(privilege);
}
protected void removeRelevantPrivlege(final Privilege privilege) {
relevantPrivileges.remove(privilege);
}
public Group getContainerGroup() {
return containerGroup;
}
public void setContainerGroup(final Group containerGroup) {
this.containerGroup = containerGroup;
}
public ApplicationType getProviderApplicationType() {
return providerApplicationType;
}
@SuppressWarnings(PMD_LONG_VARIABLE)
protected void setProviderApplicationType(
final ApplicationType providerApplicationType) {
this.providerApplicationType = providerApplicationType;
}
@SuppressWarnings(PMD_LONG_VARIABLE)
public List<ApplicationType> getDependentApplicationTypes() {
return Collections.unmodifiableList(dependentApplicationTypes);
}
@SuppressWarnings(PMD_LONG_VARIABLE)
protected void setDependentApplicationTypes(
final List<ApplicationType> dependentApplicationTypes) {
this.dependentApplicationTypes = dependentApplicationTypes;
}
@Retention(RetentionPolicy.RUNTIME)
public @interface ApplicationType {
protected void addDependantApplicationType(
final ApplicationType applicationType) {
dependentApplicationTypes.add(applicationType);
}
protected void removeDependentApplicationType(
final ApplicationType applicationType) {
dependentApplicationTypes.remove(applicationType);
}
@Override
public int hashCode() {
int hash = super.hashCode();
hash = 97 * hash + Objects.hashCode(this.containerGroup);
hash = 97 * hash + Objects.hashCode(this.providerApplicationType);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof ApplicationType)) {
return false;
}
final ApplicationType other = (ApplicationType) obj;
if (!other.canEqual(this)) {
return false;
}
if (!Objects.equals(this.containerGroup, other.containerGroup)) {
return false;
}
return Objects.equals(this.providerApplicationType,
other.providerApplicationType);
}
@Override
public boolean canEqual(final Object obj) {
return obj instanceof ApplicationType;
}
@Override
public String toString(final String data) {
return super.toString(String.format(
", containerGroup = { %s },"
+ "providerApplicationType = { %s }%s",
Objects.toString(containerGroup),
Objects.toString(
providerApplicationType),
data));
}
String name();
String description();
Class<?> applicationClass() default CcmApplication.class;
boolean singleton() default false;
String servletPath() default "";
Class<? extends HttpServlet> servlet() default HttpServlet.class;
Class<? extends ApplicationCreator> creator();
}

View File

@ -58,17 +58,24 @@ import javax.xml.bind.annotation.XmlRootElement;
@Table(name = "APPLICATIONS", schema = DB_SCHEMA)
@NamedQueries({
@NamedQuery(name = "retrieveApplicationForPath",
query = "SELECT a FROM Application a WHERE a.primaryUrl = :path")
query = "SELECT a FROM CcmApplication a "
+ " WHERE a.primaryUrl = :path"),
@NamedQuery(name = "Application.findByType",
query = "SELECT A FROM CcmApplication a "
+ "WHERE a.applicationType = :type")
})
@XmlRootElement(name = "application", namespace = WEB_XML_NS)
public class Application extends Resource implements Serializable {
public class CcmApplication extends Resource implements Serializable {
private static final long serialVersionUID = 9205226362368890784L;
@Column(name = "APPLICATION_TYPE", length = 1024, nullable = false)
@XmlElement(name = "application-type", namespace = WEB_XML_NS)
private String applicationType;
@Column(name = "PRIMARY_URL", length = 1024, nullable = false)
@Convert(converter = UriConverter.class)
@XmlElement(name = "primary-url", namespace = WEB_XML_NS)
private URI primaryUrl;
private String primaryUrl;
@OneToOne
@JoinColumn(name = "CONTAINER_GROUP_ID")
@ -83,16 +90,24 @@ public class Application extends Resource implements Serializable {
@XmlElement(name = "domain", namespace = WEB_XML_NS)
private List<DomainOwnership> domains;
public Application() {
public CcmApplication() {
super();
domains = new ArrayList<>();
}
public URI getPrimaryUrl() {
public String getApplicationType() {
return applicationType;
}
public void setApplicationType(final String applicationType) {
this.applicationType = applicationType;
}
public String getPrimaryUrl() {
return primaryUrl;
}
public void setPrimaryUrl(final URI primaryUrl) {
public void setPrimaryUrl(final String primaryUrl) {
this.primaryUrl = primaryUrl;
}
@ -106,10 +121,10 @@ public class Application extends Resource implements Serializable {
/**
* Gets an <strong>unmodifiable</strong> list of the domains which are owned
* by the {@code Application}.
* by the {@code CcmApplication}.
*
* @return An unmodifiable list of the domain ownerships of this
* {@code Application}. Might be {@code null} or empty.
* {@code CcmApplication}. Might be {@code null} or empty.
*/
public List<DomainOwnership> getDomains() {
return Collections.unmodifiableList(domains);
@ -164,11 +179,11 @@ public class Application extends Resource implements Serializable {
return false;
}
if (!(obj instanceof Application)) {
if (!(obj instanceof CcmApplication)) {
return false;
}
final Application other = (Application) obj;
final CcmApplication other = (CcmApplication) obj;
if (!other.canEqual(this)) {
return false;
}
@ -181,7 +196,7 @@ public class Application extends Resource implements Serializable {
@Override
public boolean canEqual(final Object obj) {
return obj instanceof Application;
return obj instanceof CcmApplication;
}
@Override

View File

@ -0,0 +1,38 @@
/*
* 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.web;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class DefaultApplicationCreator
implements ApplicationCreator<CcmApplication> {
@Override
public CcmApplication createInstance(final String primaryUrl,
final ApplicationType type) {
final CcmApplication application = new CcmApplication();
application.setPrimaryUrl(primaryUrl);
application.setApplicationType(type.name());
return application;
}
}

View File

@ -0,0 +1,66 @@
login.userEditPage.title=Edit Profile
login.userEditPage.changePasswordLink=Change password
login.workspacePage.title=Your workspace
login.explainCookiesPage.title=Saving email address and password
login.userInfo.logoutLink=Log out
login.userInfo.editProfileLink=Edit profile
login.userInfo.changePasswordLink=Change password
login.userRegistrationForm.title=Log in
login.userRegistrationForm.email=Your email address:
login.userRegistrationForm.screenName=Your screen name:
login.userRegistrationForm.password=Your password:
login.userRegistrationForm.cookieOption=Remember this login?
login.userRegistrationForm.explainCookieLink=(help)
login.userRegistrationForm.forgotPasswordLink=Forgot your password?
login.userRegistrationForm.newUserRegister=New users register here
login.userNewForm.title=Register
login.userNewForm.aboutYouSectionHeader=<h3>About You</h3>
login.userNewForm.securitySectionHeader=<h3>Security</h3>
login.userNewForm.securityBlurb=We need a password from you to protect your identity as you contribute to the Q&A, discussion forums, and other community activities on this site.
login.userNewForm.passwordBlurb=Choose a password that contains a mix of uppercase letters, lowercase letters, digits, and other symbols. If you forget your password, our server will help you change it to a new one.
login.userNewForm.questionBlurb=We need a customized question and answer so we can make sure only you can change your password.
login.changePasswordForm.oldPasswordLabel=Old Password:
login.changePasswordForm.newPasswordLabel=New Password (at least {0} characters, no whitespace):
login.changePasswordForm.confirmPasswordLabel=Confirm Password:
login.changePasswordForm.submit=Submit
login.changePasswordForm.noUserError=User is not logged in
login.changePasswordForm.badPasswordError=Incorrect Password
login.changePasswordForm.mustDifferError=New password must differ from old
login.changePasswordForm.mustMatchError=New passwords must match
login.changePasswordForm.mailSubject=Your password has been changed
login.changePasswordForm.mailBody=Dear {0},\n\nYour password has been changed successfully.\nIf you did not intend to change your password,\nplease reply to this mail and report this problem.
login.changePasswordPage.title=Change Password
login.recoverPassword.mailSubject=Change your password
login.recoverPassword.mailBody=Dear {0},\n\nClick on this URL or paste it into your browser to change your password:\n{1}
login.recoverPasswordPage.title=Recover Password
login.loginExpiredPage.title=Login Expired
login.loginExpiredPage.before=The login page has expired. Please\u0020
login.loginExpiredPage.link=login
login.loginExpiredPage.after=\u0020again.
login.passwordValidation.minLengthError=Password must be at least {0} characters long
login.passwordValidation.whitespaceError=Password must not contain whitespace
login.passwordValidation.minTypesError=Password must contain {0} of these 4 character types: uppercase letters, lowercase letters, digits, and other symbols
login.submit=Submit
login.primaryEmail=Email Address:
login.additionalEmail=Additional Email:
login.firstName=First (Given) Name:
login.lastName=Last (Family) Name:
login.password=Password (at least {0} characters, no whitespace):
login.passwordConfirm=Confirm Password:
login.passwordQuestion=Question:
login.passwordAnswer=Answer:
login.url=Personal Home Page URL:
login.screenName=Screen Name:
login.bio=Biography:
login.error.duplicateScreenName=Some other user has this screen name
login.error.duplicateEmail=Some other user has this email address
login.error.mismatchPassword=New passwords must match
login.error.badPassword=Incorrect password
login.error.badAnswer=Incorrect answer
login.error.badEmail=Unrecognized email address {0}
login.error.bannedEmail=User cannot currently access system
login.error.loginFail=Login failed
login.changePasswortForm.greeting=Welcome {0}
login.changePasswortForm.introText=To change your passwort please fill out this form.
login.userForm.couldnt_load_user=Could not load User
login.userLoginForm.couldnt_create_timestamp=Could not create timestamp

View File

@ -0,0 +1,66 @@
login.userEditPage.title=Profil bearbeiten
login.userEditPage.changePasswordLink=Passwort \u00e4ndern
login.workspacePage.title=Ihr pers\u00f6nlicher Bereich
login.explainCookiesPage.title=E-Mail Adresse und Passwort werden gesichert
login.userInfo.logoutLink=Abmelden
login.userInfo.editProfileLink=Profil bearbeiten
login.userInfo.changePasswordLink=Passwort \u00e4ndern
login.userRegistrationForm.title=Anmelden
login.userRegistrationForm.email=Ihre E-Mail Adresse\:
login.userRegistrationForm.screenName=Ihr Benutzername\:
login.userRegistrationForm.password=Ihr Passwort\:
login.userRegistrationForm.cookieOption=An dieses Login erinnern?
login.userRegistrationForm.explainCookieLink=(Hilfe)
login.userRegistrationForm.forgotPasswordLink=Passwort vergessen?
login.userRegistrationForm.newUserRegister=Neue Benutzer registrieren sich hier
login.userNewForm.title=Registrieren
login.userNewForm.aboutYouSectionHeader=<h3>\u00dcber mich</h3>
login.userNewForm.securitySectionHeader=<h3>Sicherheit</h3>
login.userNewForm.securityBlurb=Wie ben\u00f6tigen ein Passwort, um Ihre Identit\u00e4t und Beitr\u00e4ge zu Foren und anderen Aktivit\u00e4ten zu sch\u00fctzen.
login.userNewForm.passwordBlurb=W\u00e4hlen Sie ein Passwort aus Gru\u00dfbuchstaben, Kleinbuchstaben, Zahlen und anderen Zeichen. Wenn sie es vergessen, unterst\u00fctzt Sie der Server bei der Festlegung eines neuen.
login.userNewForm.questionBlurb=Wir ben\u00f6tigen eine individuelle Frage und Antwort um sicher zu gehen, dass nur Sie das Passwort \u00e4ndern k\u00f6nnen.
login.changePasswordForm.oldPasswordLabel=Altes Passwort\:
login.changePasswordForm.newPasswordLabel=Neues Passwort (mindestens {0} Zeichen, keine Leertaste)\:
login.changePasswordForm.confirmPasswordLabel=Passwort best\u00e4tigen\:
login.changePasswordForm.submit=Ausf\u00fchren
login.changePasswordForm.noUserError=Benutzer ist nicht angemeldet
login.changePasswordForm.badPasswordError=Falsches Passwort
login.changePasswordForm.mustDifferError=Das neue Passwort muss sich vom bisherigen unterscheiden
login.changePasswordForm.mustMatchError=Die neuen Passw\u00f6rter m\u00fcssen gleich sein
login.changePasswordForm.mailSubject=Ihr Passwort wurde ge\u00e4ndert.
login.changePasswordForm.mailBody=Hallo {0},\n\nIhr Passwort wurde erfolgreich ge\u00e4ndert.\nWenn Sie Ihr Passwort nicht \u00e4ndern wollten,\nmelden Sie bitte diese Mail an uns.
login.changePasswordPage.title=Passwort \u00c4nderung
login.recoverPassword.mailSubject=\u00c4ndern Sie das Passwort
login.recoverPassword.mailBody=Hallo {0},\n\nKlicken Sie auf diese URL oder kopieren Sie sie in Ihren Browser, um Ihr Passwort zu \u00e4ndern\:\n{1}
login.recoverPasswordPage.title=Passwort holen
login.loginExpiredPage.title=Anmeldung abgelaufen
login.loginExpiredPage.before=Der Anmeldebildschirm ist nicht mehr g\u00fcltig
login.loginExpiredPage.link=Anmeldung
login.loginExpiredPage.after= erneut.
login.passwordValidation.minLengthError=Passwort muss aus mindestens {0} Zeichen bestehen
login.passwordValidation.whitespaceError=Das Passwort darf kein Leerzeichen enthalten
login.passwordValidation.minTypesError=Das Passwort muss aus {0} dieser 4 Typen gestehen\: Gro\u00dfbuchstaben, Kleinbuchstaben, Ziffern, andere Zeichen
login.submit=Ausf\u00fchren
login.primaryEmail=E-Mail Adresse\:
login.additionalEmail=Weitere E-Mail\:
login.firstName=Vorname\:
login.lastName=Nachname\:
login.password=Passwort (mindestens {0} Zeichen, kein Leerzeichen)\:
login.passwordConfirm=Passwort best\u00e4tigen\:
login.passwordQuestion=Frage\:
login.passwordAnswer=Antwort\:
login.url=URL der pers\u00f6nlichen Homepage\:
login.screenName=Benutzername\:
login.bio=Biographie\:
login.error.duplicateScreenName=Ein anderer Benutzer verwendet diesen Namen
login.error.duplicateEmail=Ein anderer Nutzer verwendet diese E-Mail Adresse
login.error.mismatchPassword=Die neuen Passw\u00f6rter m\u00fcssen gleich sein
login.error.badPassword=Falsches Passwort
login.error.badAnswer=Falsche Antwort
login.error.badEmail=Ung\u00fcltige E-Mail Adresse: {0}
login.error.bannedEmail=Benutzer kann zur Zeit das System nicht nutzen
login.error.loginFail=Anmeldung nicht erfolgreich
login.changePasswortForm.greeting=Willkommen {0}
login.changePasswortForm.introText=Um ihr Passwort zu \u00e4ndern, f\u00fcllen sie bitte das folgende Formular aus.
login.userForm.couldnt_load_user=User konnte nicht geladen werden
login.userLoginForm.couldnt_create_timestamp=Konnte den Timestamp nicht erstellen

View File

@ -0,0 +1,66 @@
login.userEditPage.title=Edit Profile
login.userEditPage.changePasswordLink=Change password
login.workspacePage.title=Your workspace
login.explainCookiesPage.title=Saving email address and password
login.userInfo.logoutLink=Log out
login.userInfo.editProfileLink=Edit profile
login.userInfo.changePasswordLink=Change password
login.userRegistrationForm.title=Log in
login.userRegistrationForm.email=Your email address:
login.userRegistrationForm.screenName=Your screen name:
login.userRegistrationForm.password=Your password:
login.userRegistrationForm.cookieOption=Remember this login?
login.userRegistrationForm.explainCookieLink=(help)
login.userRegistrationForm.forgotPasswordLink=Forgot your password?
login.userRegistrationForm.newUserRegister=New users register here
login.userNewForm.title=Register
login.userNewForm.aboutYouSectionHeader=<h3>About You</h3>
login.userNewForm.securitySectionHeader=<h3>Security</h3>
login.userNewForm.securityBlurb=We need a password from you to protect your identity as you contribute to the Q&A, discussion forums, and other community activities on this site.
login.userNewForm.passwordBlurb=Choose a password that contains a mix of uppercase letters, lowercase letters, digits, and other symbols. If you forget your password, our server will help you change it to a new one.
login.userNewForm.questionBlurb=We need a customized question and answer so we can make sure only you can change your password.
login.changePasswordForm.oldPasswordLabel=Old Password:
login.changePasswordForm.newPasswordLabel=New Password (at least {0} characters, no whitespace):
login.changePasswordForm.confirmPasswordLabel=Confirm Password:
login.changePasswordForm.submit=Submit
login.changePasswordForm.noUserError=User is not logged in
login.changePasswordForm.badPasswordError=Incorrect Password
login.changePasswordForm.mustDifferError=New password must differ from old
login.changePasswordForm.mustMatchError=New passwords must match
login.changePasswordForm.mailSubject=Your password has been changed
login.changePasswordForm.mailBody=Dear {0},\n\nYour password has been changed successfully.\nIf you did not intend to change your password,\nplease reply to this mail and report this problem.
login.changePasswordPage.title=Change Password
login.recoverPassword.mailSubject=Change your password
login.recoverPassword.mailBody=Dear {0},\n\nClick on this URL or paste it into your browser to change your password:\n{1}
login.recoverPasswordPage.title=Recover Password
login.loginExpiredPage.title=Login Expired
login.loginExpiredPage.before=The login page has expired. Please\u0020
login.loginExpiredPage.link=login
login.loginExpiredPage.after=\u0020again.
login.passwordValidation.minLengthError=Password must be at least {0} characters long
login.passwordValidation.whitespaceError=Password must not contain whitespace
login.passwordValidation.minTypesError=Password must contain {0} of these 4 character types: uppercase letters, lowercase letters, digits, and other symbols
login.submit=Submit
login.primaryEmail=Email Address:
login.additionalEmail=Additional Email:
login.firstName=First (Given) Name:
login.lastName=Last (Family) Name:
login.password=Password (at least {0} characters, no whitespace):
login.passwordConfirm=Confirm Password:
login.passwordQuestion=Question:
login.passwordAnswer=Answer:
login.url=Personal Home Page URL:
login.screenName=Screen Name:
login.bio=Biography:
login.error.duplicateScreenName=Some other user has this screen name
login.error.duplicateEmail=Some other user has this email address
login.error.mismatchPassword=New passwords must match
login.error.badPassword=Incorrect password
login.error.badAnswer=Incorrect answer
login.error.badEmail=Unrecognized email address {0}
login.error.bannedEmail=User cannot currently access system
login.error.loginFail=Login failed
login.changePasswortForm.greeting=Welcome {0}
login.changePasswortForm.introText=To change your passwort please fill out this form.
login.userForm.couldnt_load_user=Could not load User
login.userLoginForm.couldnt_create_timestamp=Could not create timestamp

View File

@ -0,0 +1,66 @@
login.userEditPage.title=Modifier ce profil
login.userEditPage.changePasswordLink=Modifier le mot de passe
login.workspacePage.title=Votre espace de travail
login.explainCookiesPage.title=Enregistrement de l'adresse de messagerie et du mot de passe
login.userInfo.logoutLink=D\u00e9connexion
login.userInfo.editProfileLink=Modifier ce profil
login.userInfo.changePasswordLink=Modifier le mot de passe
login.userRegistrationForm.title=Se connecter
login.userRegistrationForm.email=Votre adresse de messagerie
login.userRegistrationForm.screenName=Votre pseudonyme
login.userRegistrationForm.password=Votre mot de passe
login.userRegistrationForm.cookieOption=Retenir ce mot de passe?
login.userRegistrationForm.explainCookieLink=(aide)
login.userRegistrationForm.forgotPasswordLink=Vous avez oubli\u00e9 votre mot de passe?
login.userNewForm.title=Cr\u00e9er votre compte
login.userNewForm.aboutYouSectionHeader=<h3>A propos de vous</h3>
login.userNewForm.securitySectionHeader=<h3>Securit\u00e9</h3>
login.userNewForm.securityBlurb=Merci de nous fournir un mot de passe afin que nous puissions prot\u00e9ger votre indentit\u00e9 lorsque vous participez aux Quiz, aux forum de discussions et aux autres activit\u00e9s communes sur notre site.
login.userNewForm.passwordBlurb=Choisissez un mot de passe qui contienne un m\u00e9lange de majuscules, de minuscules, de chiffres et d'autres caract\u00e8res. Si vous oubliez votre mot de passe, notre serveur vous aidera \u00e0 le remplacer par un nouveau
login.userNewForm.questionBlurb=Merci de nous indiquer une question (et sa r\u00e9ponse) \u00e0 laquelle vous seul pouvez r\u00e9pondre pour que nous puission nous assurer que vous serez le seul \u00e0 pouvoir changer votre mot de passe
login.changePasswordForm.oldPasswordLabel=Ancien mot de passe :
login.changePasswordForm.newPasswordLabel=Nouveau mot de passe (au moins {0} caract\u00e8re et pas d'espace):
login.changePasswordForm.confirmPasswordLabel=Confirmation du nouveau mot de passe
login.changePasswordForm.submit=Soumettre
login.changePasswordForm.noUserError=L'utilisateur n'est pas connect\u00e9
login.changePasswordForm.badPasswordError=Mot de passe erron\u00e9
login.changePasswordForm.mustDifferError=Le nouveau mot de passe doit \u00eatre diff\u00e9rent de l'ancien
login.changePasswordForm.mustMatchError=Le nouveau mot de passe doit \u00eatre identique dans la zone de confirmation
login.changePasswordForm.mailSubject=Votre mot de passe a \u00e9t\u00e9 modifi\u00e9
login.changePasswordForm.mailBody=Cher {0}, \n\n Votre mot de passe a \u00e9t\u00e9 modifi\u00e9 avec succ\u00e8s.\nSi vous n'avez pas souhait\u00e9 changer votre mot de passe,\nmerci de r\u00e9pondre \u00e0 ce message en faisant part de ce probl\u00e8me.
login.changePasswordPage.title=Modifier le mot de passe
login.recoverPassword.mailSubject=Modifier votre mot de passe
login.recoverPassword.mailBody=Cher {0},\n\nCliquer sur cet URL ou recopiez le dans la barre d'adresse de votre navigateur pour modifier votre mot de passe:\n{1}
login.recoverPasswordPage.title=R\u00e9cup\u00e9rer le mot de passe
login.loginExpiredPage.title=Votre connexion a expir\u00e9
login.loginExpiredPage.before=La page de connexion a expir\u00e9. Merci\u0020
login.loginExpiredPage.link=de vous connecter
login.loginExpiredPage.after=\u0020\u00e0 nouveau
login.passwordValidation.minLengthError=Le mot de passe doit faire au minimum {0} caract\u00e8res de long
login.passwordValidation.whitespaceError=Le mot de passe ne doit pas contenir d'espace
login.passwordValidation.minTypesError=Le mot de passe doit contenir {0} de ces 4 types de caract\u00e8res : majuscule, minuscule, chiffre ou autre symbole
login.submit=Soumettre
login.primaryEmail=Adresse de messagerie:
login.additionalEmail=Adresse de messagerie suppl\u00e9mentaire
login.firstName=Pr\u00e9nom:
login.lastName=Nom:
login.password=Mot de passe (au moins {0} caract\u00e8re et pas d'espace):
login.passwordConfirm=Confirmation du mot de passe
login.passwordQuestion=Question:
login.passwordAnswer=R\u00e9ponse:
login.url=URL de votre site web personnel
login.screenName=Votre pseudonyme:
login.bio=Biographie:
login.error.duplicateScreenName=Un autre utilisateur utilise d\u00e9j\u00e0 ce pseudonyme
login.error.duplicateEmail=Un autre utilisateur nous a d\u00e9j\u00e0 donner cette adresse de messagerie
login.error.mismatchPassword=Le nouveau mot de passe doit \u00eatre identique dans la zone de confirmation
login.error.badPassword=Mot de passe erron\u00e9
login.error.badAnswer=R\u00e9ponse erron\u00e9e
login.error.badEmail=Cette adresse de messagerie est inconnue
login.changePasswortForm.greeting=Welcome {0}
login.changePasswortForm.introText=To change your passwort please fill out this form.
login.userRegistrationForm.newUserRegister=New users register here
login.error.bannedEmail=User cannot currently access system
login.error.loginFail=User cannot currently access system
login.userForm.couldnt_load_user=Impossible de charger l'utilisateur
login.userLoginForm.couldnt_create_timestamp=Impossible de cr\u00e9er timestamp

View File

@ -1,11 +1,3 @@
create table ccm_core.application_types (
resource_type_id bigint not null,
container_group_id bigint,
provider_app_type_id bigint,
primary key (resource_type_id)
);
create table ccm_core.applications (
primary_url varchar(1024) not null,
object_id bigint not null,
@ -604,21 +596,6 @@
alter table ccm_core.workflow_user_task_assigned_users
add constraint UK_h62r6cqjp2tdnhscfkgwfupwj unique (assigned_user_id);
alter table ccm_core.application_types
add constraint FK_r9rd4iekfy3m8r1a1gto4t39
foreign key (container_group_id)
references ccm_core.ccm_groups;
alter table ccm_core.application_types
add constraint FK_i44k6al7mr4u1c76iudglds39
foreign key (provider_app_type_id)
references ccm_core.application_types;
alter table ccm_core.application_types
add constraint FK_41e4vrshljdkymnhb4cbkroa1
foreign key (resource_type_id)
references ccm_core.resource_types;
alter table ccm_core.applications
add constraint FK_kr3wur06hmironiamv0rn38nu
foreign key (container_group_id)
@ -679,11 +656,6 @@
foreign key (subject_id)
references ccm_core.subjects;
alter table ccm_core.ccm_privileges
add constraint FK_g06a7mpltqti17tvibm2j7ti8
foreign key (relevant_privilege_id)
references ccm_core.application_types;
alter table ccm_core.ccm_roles
add constraint FK_ice2oswni34d2xx80cf81v2cv
foreign key (implicit_group_id)

View File

@ -1,11 +1,3 @@
create table ccm_core.application_types (
resource_type_id int8 not null,
container_group_id int8,
provider_app_type_id int8,
primary key (resource_type_id)
);
create table ccm_core.applications (
primary_url varchar(1024) not null,
object_id int8 not null,
@ -603,21 +595,6 @@
alter table ccm_core.workflow_user_task_assigned_users
add constraint UK_h62r6cqjp2tdnhscfkgwfupwj unique (assigned_user_id);
alter table ccm_core.application_types
add constraint FK_r9rd4iekfy3m8r1a1gto4t39
foreign key (container_group_id)
references ccm_core.ccm_groups;
alter table ccm_core.application_types
add constraint FK_i44k6al7mr4u1c76iudglds39
foreign key (provider_app_type_id)
references ccm_core.application_types;
alter table ccm_core.application_types
add constraint FK_41e4vrshljdkymnhb4cbkroa1
foreign key (resource_type_id)
references ccm_core.resource_types;
alter table ccm_core.applications
add constraint FK_kr3wur06hmironiamv0rn38nu
foreign key (container_group_id)
@ -678,11 +655,6 @@
foreign key (subject_id)
references ccm_core.subjects;
alter table ccm_core.ccm_privileges
add constraint FK_g06a7mpltqti17tvibm2j7ti8
foreign key (relevant_privilege_id)
references ccm_core.application_types;
alter table ccm_core.ccm_roles
add constraint FK_ice2oswni34d2xx80cf81v2cv
foreign key (implicit_group_id)

View File

@ -24,7 +24,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.libreccm.tests.categories.UnitTest;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
import java.net.URI;
import java.net.URISyntaxException;
@ -68,11 +68,11 @@ public class EqualsAndHashCodeTest {
final Domain domain2 = new Domain();
domain2.setDomainKey("Domain Two");
final Application application1 = new Application();
application1.setPrimaryUrl(new URI("http://application-one.exampl.org"));
final CcmApplication application1 = new CcmApplication();
application1.setPrimaryUrl("http://application-one.exampl.org");
final Application application2 = new Application();
application2.setPrimaryUrl(new URI("http://application-two.exampl.org"));
final CcmApplication application2 = new CcmApplication();
application2.setPrimaryUrl("http://application-two.exampl.org");
EqualsVerifier
.forClass(entityClass)
@ -81,7 +81,7 @@ public class EqualsAndHashCodeTest {
.withRedefinedSuperclass()
.withPrefabValues(Category.class, category1, category2)
.withPrefabValues(Domain.class, domain1, domain2)
.withPrefabValues(Application.class, application1, application2)
.withPrefabValues(CcmApplication.class, application1, application2)
.verify();
}

View File

@ -107,7 +107,7 @@ public class CcmObjectRepositoryTest {
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.CcmObjectRepositoryTest.war")
.addPackage(CcmObject.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).

View File

@ -26,7 +26,6 @@ import org.libreccm.tests.categories.UnitTest;
import java.util.Arrays;
import java.util.Collection;
import org.libreccm.web.ApplicationType;
/**
*

View File

@ -108,7 +108,7 @@ public class GroupManagerTest {
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.GroupManagerTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).

View File

@ -102,7 +102,7 @@ public class GroupRepositoryTest {
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).

View File

@ -130,7 +130,7 @@ public class PermissionManagerTest {
String.format("LibreCCM-%s.war",
PermissionManagerTest.class.getName()))
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).

View File

@ -123,7 +123,7 @@ public class PermissionRepositoryTest {
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).

View File

@ -101,7 +101,7 @@ public class PrivilegeRepositoryTest {
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).

View File

@ -103,7 +103,7 @@ public class RoleRepositoryTest {
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.RoleRepositoryTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).

View File

@ -26,7 +26,6 @@ import org.libreccm.tests.categories.UnitTest;
import java.util.Arrays;
import java.util.Collection;
import org.libreccm.web.ApplicationType;
/**
*
@ -39,7 +38,6 @@ public class ToStringTest extends ToStringVerifier {
@Parameterized.Parameters(name = "{0}")
public static Collection<Class<?>> data() {
return Arrays.asList(new Class<?>[]{
ApplicationType.class,
CcmObject.class,
EmailAddress.class,
GroupMembership.class,

View File

@ -115,7 +115,7 @@ public class UserManagerTest {
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.UserManagerTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).

View File

@ -116,7 +116,7 @@ public class UserRepositoryTest {
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
.addPackage(User.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).

View File

@ -116,7 +116,7 @@ public class LoginManagerTest {
.create(WebArchive.class,
"LibreCCM-org.libreccm.core.authentication.LoginManagerTest.war")
.addPackage(CcmObject.class.getPackage())
.addPackage(org.libreccm.web.Application.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.categorization.Category.class.
getPackage())
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage())

View File

@ -1,71 +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.web;
import nl.jqno.equalsverifier.EqualsVerifier;
import nl.jqno.equalsverifier.Warning;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ApplicationTypeTest {
public ApplicationTypeTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void verifyEqualsAndHashCod() {
final ApplicationType appType1 = new ApplicationType();
appType1.setTitle("app-type-1");
final ApplicationType appType2 = new ApplicationType();
appType2.setTitle("app-type-2");
EqualsVerifier
.forClass(ApplicationType.class)
.suppress(Warning.STRICT_INHERITANCE)
.suppress(Warning.NONFINAL_FIELDS)
.withPrefabValues(ApplicationType.class, appType1, appType2)
.withRedefinedSuperclass()
.verify();
}
}

View File

@ -43,7 +43,7 @@ public class EqualsAndHashCodeTest {
@Parameterized.Parameters(name = "{0}")
public static Collection<Class<?>> data() {
return Arrays.asList(new Class<?>[]{
Application.class,
CcmApplication.class,
Host.class
});
}

View File

@ -38,7 +38,7 @@ public class ToStringTest extends ToStringVerifier {
@Parameterized.Parameters(name = "{0}")
public static Collection<Class<?>> data() {
return Arrays.asList(new Class<?>[]{
Application.class,
CcmApplication.class,
Host.class
});
}

View File

@ -18,7 +18,7 @@
*/
package org.libreccm.docrepo;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
import javax.persistence.Column;
import javax.persistence.Entity;
@ -26,14 +26,14 @@ import javax.persistence.Table;
/**
* Entity class of a repository for documents. Instances will be persisted into the
* database. Instance variables are inherited from {@link Application}.
* database. Instance variables are inherited from {@link CcmApplication}.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 01/10/2015
*/
@Entity
@Table(schema = "CCM_DOCREPO", name = "REPOSITORIES")
public class Repository extends Application {
public class Repository extends CcmApplication {
private static final long serialVersionUID = 6673243021462798036L;
@ -50,7 +50,7 @@ public class Repository extends Application {
private long ownerId;
/**
* Constructor calls the super-class-constructor of {@link Application}.
* Constructor calls the super-class-constructor of {@link CcmApplication}.
*/
public Repository() {
super();

View File

@ -20,7 +20,8 @@ package org.libreccm.shortcuts;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.libreccm.web.Application;
import org.libreccm.web.CcmApplication;
/**
*
@ -28,7 +29,7 @@ import org.libreccm.web.Application;
*/
@Entity
@Table(schema ="CCM_SHORTCUTS", name = "SHORTCUTS_APP")
public class Shortcuts extends Application {
public class Shortcuts extends CcmApplication {
private static final long serialVersionUID = -6793265996161649637L;
// private String shortcutAppName;