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-94f89814c4dfpull/2/head
parent
33cfd945a3
commit
56d545d175
|
|
@ -101,6 +101,11 @@
|
||||||
<groupId>oro</groupId>
|
<groupId>oro</groupId>
|
||||||
<artifactId>oro</artifactId>
|
<artifactId>oro</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcprov-jdk16</artifactId>
|
||||||
|
<version>1.46</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.sf.jtidy</groupId>
|
<groupId>net.sf.jtidy</groupId>
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 <list>. 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ü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>
|
||||||
|
* <bebop:listPanel>
|
||||||
|
* <bebop:cell> ... cell contents </bebop:cell>
|
||||||
|
* <bebop:cell> ... cell contents </bebop:cell>
|
||||||
|
* ...
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <jross@redhat.com>
|
||||||
|
* @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.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -21,7 +21,7 @@ package com.arsdigita.templating;
|
||||||
|
|
||||||
import com.arsdigita.web.Web;
|
import com.arsdigita.web.Web;
|
||||||
|
|
||||||
import org.libreccm.web.Application;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ public class ApplicationOIDPatternGenerator implements PatternGenerator {
|
||||||
public String[] generateValues(String key,
|
public String[] generateValues(String key,
|
||||||
HttpServletRequest req) {
|
HttpServletRequest req) {
|
||||||
|
|
||||||
final Application application = Web.getWebContext().getApplication();
|
final CcmApplication application = Web.getWebContext().getApplication();
|
||||||
|
|
||||||
if (application != null) {
|
if (application != null) {
|
||||||
String[] oid = new String[1];
|
String[] oid = new String[1];
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,7 @@ import com.arsdigita.web.Web;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.libreccm.web.Application;
|
import org.libreccm.web.CcmApplication;
|
||||||
import org.libreccm.web.ApplicationType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a set of pattern values based on the application key, eg
|
* 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);
|
private static final Logger s_log = Logger.getLogger(PatternGenerator.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation iof the Interface class.
|
* Implementation of the Interface class.
|
||||||
*
|
*
|
||||||
* @param key
|
* @param key
|
||||||
* @param req
|
* @param req
|
||||||
|
|
@ -54,10 +53,9 @@ public class ApplicationPatternGenerator implements PatternGenerator {
|
||||||
|
|
||||||
s_log.debug("Processing Application with key: " + key);
|
s_log.debug("Processing Application with key: " + key);
|
||||||
|
|
||||||
final Application app = Web.getWebContext().getApplication();
|
final CcmApplication app = Web.getWebContext().getApplication();
|
||||||
if (app != null) {
|
if (app != null) {
|
||||||
String[] returnValue = {((ApplicationType) app.getResourceType())
|
String[] returnValue = {app.getApplicationType()};
|
||||||
.getTitle()};
|
|
||||||
s_log.debug("Found application >>" + returnValue
|
s_log.debug("Found application >>" + returnValue
|
||||||
+ "<< in Application.");
|
+ "<< in Application.");
|
||||||
return returnValue;
|
return returnValue;
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import com.arsdigita.web.Web;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
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() {
|
private String getBasePath() {
|
||||||
|
|
||||||
// retrieve the application of the request
|
// retrieve the application of the request
|
||||||
Application app = Web.getWebContext().getApplication();
|
CcmApplication app = Web.getWebContext().getApplication();
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
return "/";
|
return "/";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import com.arsdigita.web.Web;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
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
|
* 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,
|
public String[] generateValues(String key,
|
||||||
HttpServletRequest req) {
|
HttpServletRequest req) {
|
||||||
|
|
||||||
Application app = Web.getWebContext().getApplication();
|
CcmApplication app = Web.getWebContext().getApplication();
|
||||||
String ctx = (app == null) ? null : "";
|
String ctx = (app == null) ? null : "";
|
||||||
|
|
||||||
if (app == null || ctx == null || "".equals(ctx)) {
|
if (app == null || ctx == null || "".equals(ctx)) {
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package com.arsdigita.web;
|
package com.arsdigita.web;
|
||||||
|
|
||||||
import org.libreccm.web.Application;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
@ -45,6 +45,6 @@ public interface ApplicationFileResolver {
|
||||||
RequestDispatcher resolve(String templatePath,
|
RequestDispatcher resolve(String templatePath,
|
||||||
HttpServletRequest sreq,
|
HttpServletRequest sreq,
|
||||||
HttpServletResponse sresp,
|
HttpServletResponse sresp,
|
||||||
Application app);
|
CcmApplication app);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ package com.arsdigita.web;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.libreccm.cdi.utils.CdiLookupException;
|
import org.libreccm.cdi.utils.CdiLookupException;
|
||||||
import org.libreccm.cdi.utils.CdiUtil;
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
import org.libreccm.web.Application;
|
import org.libreccm.web.CcmApplication;
|
||||||
import org.libreccm.web.ApplicationRepository;
|
import org.libreccm.web.ApplicationRepository;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -103,7 +103,7 @@ public abstract class BaseApplicationServlet extends BaseServlet {
|
||||||
final HttpServletResponse response)
|
final HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
|
||||||
final Application app = getApplication(request);
|
final CcmApplication app = getApplication(request);
|
||||||
|
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
response.sendError(404, "Application not found");
|
response.sendError(404, "Application not found");
|
||||||
|
|
@ -141,7 +141,7 @@ public abstract class BaseApplicationServlet extends BaseServlet {
|
||||||
*/
|
*/
|
||||||
protected abstract void doService(final HttpServletRequest sreq,
|
protected abstract void doService(final HttpServletRequest sreq,
|
||||||
final HttpServletResponse sresp,
|
final HttpServletResponse sresp,
|
||||||
final Application app)
|
final CcmApplication app)
|
||||||
throws ServletException, IOException;
|
throws ServletException, IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -150,7 +150,7 @@ public abstract class BaseApplicationServlet extends BaseServlet {
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private Application getApplication(final HttpServletRequest request) {
|
private CcmApplication getApplication(final HttpServletRequest request) {
|
||||||
s_log.debug("Resolving the application that will handle this request");
|
s_log.debug("Resolving the application that will handle this request");
|
||||||
|
|
||||||
Long appId = (Long) request.getAttribute(APPLICATION_ID_ATTRIBUTE);
|
Long appId = (Long) request.getAttribute(APPLICATION_ID_ATTRIBUTE);
|
||||||
|
|
@ -197,7 +197,7 @@ public abstract class BaseApplicationServlet extends BaseServlet {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
// private RequestContext makeLegacyContext(HttpServletRequest sreq,
|
// private RequestContext makeLegacyContext(HttpServletRequest sreq,
|
||||||
// final Application app,
|
// final CcmApplication app,
|
||||||
// final UserContext uc) {
|
// final UserContext uc) {
|
||||||
// s_log.debug("Setting up a legacy context object");
|
// s_log.debug("Setting up a legacy context object");
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import com.arsdigita.util.Assert;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
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.ApplicationRepository;
|
||||||
import org.libreccm.web.ServletPath;
|
import org.libreccm.web.ServletPath;
|
||||||
|
|
||||||
|
|
@ -239,7 +239,7 @@ public class CCMDispatcherServlet extends BaseServlet {
|
||||||
path + "' ***");
|
path + "' ***");
|
||||||
}
|
}
|
||||||
|
|
||||||
final Application application = appRepository
|
final CcmApplication application = appRepository
|
||||||
.retrieveApplicationForPath(path);
|
.retrieveApplicationForPath(path);
|
||||||
|
|
||||||
if (application == null) {
|
if (application == null) {
|
||||||
|
|
@ -278,7 +278,7 @@ public class CCMDispatcherServlet extends BaseServlet {
|
||||||
*
|
*
|
||||||
* @param app
|
* @param app
|
||||||
*/
|
*/
|
||||||
ApplicationSpec(Application app) {
|
ApplicationSpec(CcmApplication app) {
|
||||||
if ( app == null ) { throw new NullPointerException("app"); }
|
if ( app == null ) { throw new NullPointerException("app"); }
|
||||||
|
|
||||||
m_id = app.getObjectId();
|
m_id = app.getObjectId();
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.RequestDispatcher;
|
import javax.servlet.RequestDispatcher;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
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,
|
public RequestDispatcher resolve(String templatePath,
|
||||||
HttpServletRequest sreq,
|
HttpServletRequest sreq,
|
||||||
HttpServletResponse sresp,
|
HttpServletResponse sresp,
|
||||||
Application app) {
|
CcmApplication app) {
|
||||||
|
|
||||||
String pathInfo = sreq.getPathInfo(); // effectively provides an url
|
String pathInfo = sreq.getPathInfo(); // effectively provides an url
|
||||||
if (s_log.isDebugEnabled()) { // with application part stripped
|
if (s_log.isDebugEnabled()) { // with application part stripped
|
||||||
|
|
|
||||||
|
|
@ -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 <jross@redhat.com>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <jross@redhat.com>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.libreccm.web.Application;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -778,7 +778,7 @@ public class URL {
|
||||||
* indicating that the URL has no query string.</p>
|
* indicating that the URL has no query string.</p>
|
||||||
*
|
*
|
||||||
* @param sreq the servlet request
|
* @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
|
* @param pathInfo a <code>String</code> of extra path info for the
|
||||||
* application
|
* application
|
||||||
* @param params a <code>ParameterMap</code> of parameters to use
|
* @param params a <code>ParameterMap</code> of parameters to use
|
||||||
|
|
@ -787,7 +787,7 @@ public class URL {
|
||||||
* <code>pathInfo</code>
|
* <code>pathInfo</code>
|
||||||
*/
|
*/
|
||||||
public static final URL there(final HttpServletRequest sreq,
|
public static final URL there(final HttpServletRequest sreq,
|
||||||
final Application app,
|
final CcmApplication app,
|
||||||
final String pathInfo,
|
final String pathInfo,
|
||||||
final ParameterMap params) {
|
final ParameterMap params) {
|
||||||
if (Assert.isEnabled() && pathInfo != null) {
|
if (Assert.isEnabled() && pathInfo != null) {
|
||||||
|
|
@ -809,7 +809,7 @@ public class URL {
|
||||||
* specified application.
|
* specified application.
|
||||||
*
|
*
|
||||||
* @param sreq the servlet request
|
* @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
|
* @param pathInfo a <code>String</code> of extra path info for the
|
||||||
* application
|
* application
|
||||||
*
|
*
|
||||||
|
|
@ -817,7 +817,7 @@ public class URL {
|
||||||
* <code>pathInfo</code>
|
* <code>pathInfo</code>
|
||||||
*/
|
*/
|
||||||
public static final URL there(final HttpServletRequest sreq,
|
public static final URL there(final HttpServletRequest sreq,
|
||||||
final Application app,
|
final CcmApplication app,
|
||||||
final String pathInfo) {
|
final String pathInfo) {
|
||||||
if (Assert.isEnabled() && pathInfo != null) {
|
if (Assert.isEnabled() && pathInfo != null) {
|
||||||
Assert.isTrue(pathInfo.startsWith("/"),
|
Assert.isTrue(pathInfo.startsWith("/"),
|
||||||
|
|
@ -868,7 +868,7 @@ public class URL {
|
||||||
* <code>HttpServletRequest</code> object as it will ignore any Host header
|
* <code>HttpServletRequest</code> object as it will ignore any Host header
|
||||||
* given by the client.</p>
|
* 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 String pathInfo,
|
||||||
final ParameterMap params) {
|
final ParameterMap params) {
|
||||||
return URL.there(app.getPrimaryUrl() + pathInfo, params);
|
return URL.there(app.getPrimaryUrl() + pathInfo, params);
|
||||||
|
|
@ -877,7 +877,7 @@ public class URL {
|
||||||
public static final URL here(final HttpServletRequest sreq,
|
public static final URL here(final HttpServletRequest sreq,
|
||||||
final String pathInfo,
|
final String pathInfo,
|
||||||
final ParameterMap params) {
|
final ParameterMap params) {
|
||||||
final Application app = Web.getWebContext().getApplication();
|
final CcmApplication app = Web.getWebContext().getApplication();
|
||||||
|
|
||||||
Assert.exists(app, "Application app");
|
Assert.exists(app, "Application app");
|
||||||
|
|
||||||
|
|
@ -886,7 +886,7 @@ public class URL {
|
||||||
|
|
||||||
public static final URL here(final HttpServletRequest sreq,
|
public static final URL here(final HttpServletRequest sreq,
|
||||||
final String pathInfo) {
|
final String pathInfo) {
|
||||||
final Application app = Web.getWebContext().getApplication();
|
final CcmApplication app = Web.getWebContext().getApplication();
|
||||||
|
|
||||||
Assert.exists(app, "Application app");
|
Assert.exists(app, "Application app");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,14 @@
|
||||||
*/
|
*/
|
||||||
package com.arsdigita.web;
|
package com.arsdigita.web;
|
||||||
|
|
||||||
// import com.arsdigita.web.Application;
|
// import com.arsdigita.web.CcmApplication;
|
||||||
import com.arsdigita.util.Assert;
|
import com.arsdigita.util.Assert;
|
||||||
import com.arsdigita.util.Record;
|
import com.arsdigita.util.Record;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.libreccm.core.CcmSessionContext;
|
import org.libreccm.core.CcmSessionContext;
|
||||||
import org.libreccm.core.User;
|
import org.libreccm.core.User;
|
||||||
import org.libreccm.web.Application;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -51,7 +51,7 @@ public final class WebContext extends Record {
|
||||||
*/
|
*/
|
||||||
private static final Logger s_log = Logger.getLogger(WebContext.class);
|
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;
|
private URL m_requestURL = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -90,7 +90,7 @@ public final class WebContext extends Record {
|
||||||
* @param app
|
* @param app
|
||||||
* @param requestURL
|
* @param requestURL
|
||||||
*/
|
*/
|
||||||
final void init(final Application app, final URL requestURL) {
|
final void init(final CcmApplication app, final URL requestURL) {
|
||||||
setApplication(app);
|
setApplication(app);
|
||||||
setRequestURL(requestURL);
|
setRequestURL(requestURL);
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +114,7 @@ public final class WebContext extends Record {
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public final Application getApplication() {
|
public final CcmApplication getApplication() {
|
||||||
return m_application;
|
return m_application;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,7 +122,7 @@ public final class WebContext extends Record {
|
||||||
*
|
*
|
||||||
* @param app
|
* @param app
|
||||||
*/
|
*/
|
||||||
final void setApplication(final Application app) {
|
final void setApplication(final CcmApplication app) {
|
||||||
m_application = app;
|
m_application = app;
|
||||||
|
|
||||||
mutated("Application");
|
mutated("Application");
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import static org.libreccm.core.CoreConstants.*;
|
||||||
|
|
||||||
import org.libreccm.jpa.utils.UriConverter;
|
import org.libreccm.jpa.utils.UriConverter;
|
||||||
import org.libreccm.l10n.LocalizedString;
|
import org.libreccm.l10n.LocalizedString;
|
||||||
import org.libreccm.web.Application;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
@ -65,9 +65,9 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
* as well as the {@code CategoryPurpose} entity from the old
|
* as well as the {@code CategoryPurpose} entity from the old
|
||||||
* {@code ccm-core module}.
|
* {@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
|
* 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.
|
* <em>owners</em> of the domain.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,14 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.categorization;
|
package org.libreccm.categorization;
|
||||||
|
|
||||||
import org.libreccm.web.Application;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides several methods when managing the relations between {@link Domain}s
|
* 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>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
|
|
@ -36,46 +36,46 @@ public class DomainManager {
|
||||||
private transient DomainRepository domainRepo;
|
private transient DomainRepository domainRepo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a {@code Application} to the owners of a {@link Domain}. If the
|
* Adds a {@code CcmApplication} to the owners of a {@link Domain}. If the
|
||||||
* provided {@code Application} is already an owner of the provided
|
* provided {@code CcmApplication} is already an owner of the provided
|
||||||
* {@code Domain} the method does nothing.
|
* {@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}.
|
* {@code Domain}.
|
||||||
* @param domain The {@code Domain} to which owners the
|
* @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) {
|
final Domain domain) {
|
||||||
// TODO implement method
|
// TODO implement method
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a {@code Application} from the owners of a {@code Domain}. If the
|
* Removes a {@code CcmApplication} from the owners of a {@code Domain}. If the
|
||||||
* provided {@code Application} is not an owner of the provided
|
* provided {@code CcmApplication} is not an owner of the provided
|
||||||
* {@code Domain} the method does nothing.
|
* {@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}.
|
* the provided {@code Domain}.
|
||||||
* @param domain The {@code Domain} from which owners the provided
|
* @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) {
|
final Domain domain) {
|
||||||
// TODO implement method
|
// TODO implement method
|
||||||
throw new UnsupportedOperationException();
|
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.
|
* @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.
|
* of the provided {@code Domain}, {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isDomainOwner(final Application application,
|
public boolean isDomainOwner(final CcmApplication application,
|
||||||
final Domain domain) {
|
final Domain domain) {
|
||||||
// TODO implement method
|
// TODO implement method
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import org.libreccm.core.CcmObject;
|
||||||
|
|
||||||
import static org.libreccm.core.CoreConstants.*;
|
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}.
|
* The {@link CcmObject} owning the {@link Domain}.
|
||||||
*/
|
*/
|
||||||
@ManyToOne(optional = false)
|
@ManyToOne(optional = false)
|
||||||
private Application owner;
|
private CcmApplication owner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Domain} owned by the {@link CcmObject}.
|
* The {@link Domain} owned by the {@link CcmObject}.
|
||||||
|
|
@ -98,11 +98,11 @@ public class DomainOwnership implements Serializable {
|
||||||
this.ownershipId = ownershipId;
|
this.ownershipId = ownershipId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Application getOwner() {
|
public CcmApplication getOwner() {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setOwner(final Application owner) {
|
protected void setOwner(final CcmApplication owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,7 @@ import javax.persistence.EntityManager;
|
||||||
org.libreccm.runtime.Initalizer.class,
|
org.libreccm.runtime.Initalizer.class,
|
||||||
org.libreccm.search.lucene.Document.class,
|
org.libreccm.search.lucene.Document.class,
|
||||||
org.libreccm.search.lucene.Index.class,
|
org.libreccm.search.lucene.Index.class,
|
||||||
org.libreccm.web.Application.class,
|
org.libreccm.web.CcmApplication.class,
|
||||||
org.libreccm.web.ApplicationType.class,
|
|
||||||
org.libreccm.web.Host.class,
|
org.libreccm.web.Host.class,
|
||||||
org.libreccm.workflow.Task.class,
|
org.libreccm.workflow.Task.class,
|
||||||
org.libreccm.workflow.UserTask.class,
|
org.libreccm.workflow.UserTask.class,
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import java.io.Serializable;
|
||||||
import javax.enterprise.context.SessionScoped;
|
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.
|
* current party.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ package org.libreccm.core;
|
||||||
import static org.libreccm.core.CoreConstants.*;
|
import static org.libreccm.core.CoreConstants.*;
|
||||||
|
|
||||||
import org.libreccm.l10n.LocalizedString;
|
import org.libreccm.l10n.LocalizedString;
|
||||||
import org.libreccm.web.Application;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collections;
|
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
|
* 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.
|
* Resources can be nested, a resource can have multiple child resources.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,18 @@ import javax.persistence.Table;
|
||||||
import org.libreccm.l10n.LocalizedString;
|
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>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "RESOURCE_TYPES", schema = DB_SCHEMA)
|
@Table(name = "RESOURCE_TYPES", schema = DB_SCHEMA)
|
||||||
@Inheritance(strategy = InheritanceType.JOINED)
|
@Inheritance(strategy = InheritanceType.JOINED)
|
||||||
|
|
|
||||||
|
|
@ -219,11 +219,11 @@ public class User extends Subject implements Serializable {
|
||||||
this.emailAddresses = eMailAddresses;
|
this.emailAddresses = eMailAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addEmailAddress(final EmailAddress emailAddress) {
|
public void addEmailAddress(final EmailAddress emailAddress) {
|
||||||
emailAddresses.add(emailAddress);
|
emailAddresses.add(emailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void removeEmailAddress(final EmailAddress emailAddress) {
|
public void removeEmailAddress(final EmailAddress emailAddress) {
|
||||||
emailAddresses.remove(emailAddress);
|
emailAddresses.remove(emailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,10 @@ public class LoginManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void logout() {
|
||||||
|
sessionContext.setCurrentSubject(null);
|
||||||
|
}
|
||||||
|
|
||||||
private static class LoginCallbackHandler implements CallbackHandler {
|
private static class LoginCallbackHandler implements CallbackHandler {
|
||||||
|
|
||||||
private final transient String username;
|
private final transient String username;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.modules;
|
package org.libreccm.modules;
|
||||||
|
|
||||||
|
import org.libreccm.web.ApplicationType;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
|
@ -67,6 +69,14 @@ public @interface Module {
|
||||||
*/
|
*/
|
||||||
RequiredModule[] requiredModules() default {};
|
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.
|
* The JPA entities provided by the annotated module.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -20,7 +20,10 @@ package org.libreccm.web;
|
||||||
|
|
||||||
import org.libreccm.core.AbstractEntityRepository;
|
import org.libreccm.core.AbstractEntityRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.persistence.NoResultException;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -29,24 +32,52 @@ import javax.persistence.TypedQuery;
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class ApplicationRepository
|
public class ApplicationRepository
|
||||||
extends AbstractEntityRepository<Long, Application> {
|
extends AbstractEntityRepository<Long, CcmApplication> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<Application> getEntityClass() {
|
public Class<CcmApplication> getEntityClass() {
|
||||||
return Application.class;
|
return CcmApplication.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNew(final Application application) {
|
public boolean isNew(final CcmApplication application) {
|
||||||
return application.getObjectId() == 0;
|
return application.getObjectId() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Application retrieveApplicationForPath(final String path) {
|
/**
|
||||||
final TypedQuery<Application> query = getEntityManager()
|
* Retrieve the application mounted at the provided {@code path}.
|
||||||
.createNamedQuery(
|
*
|
||||||
"retrieveApplicationForPath", Application.class);
|
* @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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,165 +18,29 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.web;
|
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 javax.servlet.http.HttpServlet;
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Table(name = "APPLICATION_TYPES", schema = DB_SCHEMA)
|
public @interface ApplicationType {
|
||||||
@SuppressWarnings("PMD.LongVariable")
|
|
||||||
public class ApplicationType extends ResourceType implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -1175728067001112457L;
|
String name();
|
||||||
private static final String PMD_LONG_VARIABLE = "PMD.LongVariable";
|
|
||||||
|
|
||||||
@OneToMany
|
String description();
|
||||||
@JoinColumn(name = "RELEVANT_PRIVILEGE_ID")
|
|
||||||
@SuppressWarnings(PMD_LONG_VARIABLE)
|
|
||||||
private List<Privilege> relevantPrivileges;
|
|
||||||
|
|
||||||
@ManyToOne
|
Class<?> applicationClass() default CcmApplication.class;
|
||||||
@JoinColumn(name = "CONTAINER_GROUP_ID")
|
|
||||||
private Group containerGroup;
|
|
||||||
|
|
||||||
@ManyToOne
|
boolean singleton() default false;
|
||||||
@JoinColumn(name = "PROVIDER_APP_TYPE_ID")
|
|
||||||
@SuppressWarnings(PMD_LONG_VARIABLE)
|
|
||||||
private ApplicationType providerApplicationType;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "providerApplicationType")
|
String servletPath() default "";
|
||||||
@SuppressWarnings(PMD_LONG_VARIABLE)
|
|
||||||
private List<ApplicationType> dependentApplicationTypes;
|
|
||||||
|
|
||||||
public ApplicationType() {
|
Class<? extends HttpServlet> servlet() default HttpServlet.class;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Class<? extends ApplicationCreator> creator();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,17 +58,24 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
@Table(name = "APPLICATIONS", schema = DB_SCHEMA)
|
@Table(name = "APPLICATIONS", schema = DB_SCHEMA)
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name = "retrieveApplicationForPath",
|
@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)
|
@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;
|
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)
|
@Column(name = "PRIMARY_URL", length = 1024, nullable = false)
|
||||||
@Convert(converter = UriConverter.class)
|
|
||||||
@XmlElement(name = "primary-url", namespace = WEB_XML_NS)
|
@XmlElement(name = "primary-url", namespace = WEB_XML_NS)
|
||||||
private URI primaryUrl;
|
private String primaryUrl;
|
||||||
|
|
||||||
@OneToOne
|
@OneToOne
|
||||||
@JoinColumn(name = "CONTAINER_GROUP_ID")
|
@JoinColumn(name = "CONTAINER_GROUP_ID")
|
||||||
|
|
@ -83,16 +90,24 @@ public class Application extends Resource implements Serializable {
|
||||||
@XmlElement(name = "domain", namespace = WEB_XML_NS)
|
@XmlElement(name = "domain", namespace = WEB_XML_NS)
|
||||||
private List<DomainOwnership> domains;
|
private List<DomainOwnership> domains;
|
||||||
|
|
||||||
public Application() {
|
public CcmApplication() {
|
||||||
super();
|
super();
|
||||||
domains = new ArrayList<>();
|
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;
|
return primaryUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrimaryUrl(final URI primaryUrl) {
|
public void setPrimaryUrl(final String primaryUrl) {
|
||||||
this.primaryUrl = 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
|
* 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
|
* @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() {
|
public List<DomainOwnership> getDomains() {
|
||||||
return Collections.unmodifiableList(domains);
|
return Collections.unmodifiableList(domains);
|
||||||
|
|
@ -164,11 +179,11 @@ public class Application extends Resource implements Serializable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(obj instanceof Application)) {
|
if (!(obj instanceof CcmApplication)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Application other = (Application) obj;
|
final CcmApplication other = (CcmApplication) obj;
|
||||||
if (!other.canEqual(this)) {
|
if (!other.canEqual(this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +196,7 @@ public class Application extends Resource implements Serializable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canEqual(final Object obj) {
|
public boolean canEqual(final Object obj) {
|
||||||
return obj instanceof Application;
|
return obj instanceof CcmApplication;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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 (
|
create table ccm_core.applications (
|
||||||
primary_url varchar(1024) not null,
|
primary_url varchar(1024) not null,
|
||||||
object_id bigint not null,
|
object_id bigint not null,
|
||||||
|
|
@ -604,21 +596,6 @@
|
||||||
alter table ccm_core.workflow_user_task_assigned_users
|
alter table ccm_core.workflow_user_task_assigned_users
|
||||||
add constraint UK_h62r6cqjp2tdnhscfkgwfupwj unique (assigned_user_id);
|
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
|
alter table ccm_core.applications
|
||||||
add constraint FK_kr3wur06hmironiamv0rn38nu
|
add constraint FK_kr3wur06hmironiamv0rn38nu
|
||||||
foreign key (container_group_id)
|
foreign key (container_group_id)
|
||||||
|
|
@ -679,11 +656,6 @@
|
||||||
foreign key (subject_id)
|
foreign key (subject_id)
|
||||||
references ccm_core.subjects;
|
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
|
alter table ccm_core.ccm_roles
|
||||||
add constraint FK_ice2oswni34d2xx80cf81v2cv
|
add constraint FK_ice2oswni34d2xx80cf81v2cv
|
||||||
foreign key (implicit_group_id)
|
foreign key (implicit_group_id)
|
||||||
|
|
|
||||||
|
|
@ -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 (
|
create table ccm_core.applications (
|
||||||
primary_url varchar(1024) not null,
|
primary_url varchar(1024) not null,
|
||||||
object_id int8 not null,
|
object_id int8 not null,
|
||||||
|
|
@ -603,21 +595,6 @@
|
||||||
alter table ccm_core.workflow_user_task_assigned_users
|
alter table ccm_core.workflow_user_task_assigned_users
|
||||||
add constraint UK_h62r6cqjp2tdnhscfkgwfupwj unique (assigned_user_id);
|
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
|
alter table ccm_core.applications
|
||||||
add constraint FK_kr3wur06hmironiamv0rn38nu
|
add constraint FK_kr3wur06hmironiamv0rn38nu
|
||||||
foreign key (container_group_id)
|
foreign key (container_group_id)
|
||||||
|
|
@ -678,11 +655,6 @@
|
||||||
foreign key (subject_id)
|
foreign key (subject_id)
|
||||||
references ccm_core.subjects;
|
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
|
alter table ccm_core.ccm_roles
|
||||||
add constraint FK_ice2oswni34d2xx80cf81v2cv
|
add constraint FK_ice2oswni34d2xx80cf81v2cv
|
||||||
foreign key (implicit_group_id)
|
foreign key (implicit_group_id)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
import org.libreccm.tests.categories.UnitTest;
|
import org.libreccm.tests.categories.UnitTest;
|
||||||
import org.libreccm.web.Application;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
@ -68,11 +68,11 @@ public class EqualsAndHashCodeTest {
|
||||||
final Domain domain2 = new Domain();
|
final Domain domain2 = new Domain();
|
||||||
domain2.setDomainKey("Domain Two");
|
domain2.setDomainKey("Domain Two");
|
||||||
|
|
||||||
final Application application1 = new Application();
|
final CcmApplication application1 = new CcmApplication();
|
||||||
application1.setPrimaryUrl(new URI("http://application-one.exampl.org"));
|
application1.setPrimaryUrl("http://application-one.exampl.org");
|
||||||
|
|
||||||
final Application application2 = new Application();
|
final CcmApplication application2 = new CcmApplication();
|
||||||
application2.setPrimaryUrl(new URI("http://application-two.exampl.org"));
|
application2.setPrimaryUrl("http://application-two.exampl.org");
|
||||||
|
|
||||||
EqualsVerifier
|
EqualsVerifier
|
||||||
.forClass(entityClass)
|
.forClass(entityClass)
|
||||||
|
|
@ -81,7 +81,7 @@ public class EqualsAndHashCodeTest {
|
||||||
.withRedefinedSuperclass()
|
.withRedefinedSuperclass()
|
||||||
.withPrefabValues(Category.class, category1, category2)
|
.withPrefabValues(Category.class, category1, category2)
|
||||||
.withPrefabValues(Domain.class, domain1, domain2)
|
.withPrefabValues(Domain.class, domain1, domain2)
|
||||||
.withPrefabValues(Application.class, application1, application2)
|
.withPrefabValues(CcmApplication.class, application1, application2)
|
||||||
.verify();
|
.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ public class CcmObjectRepositoryTest {
|
||||||
.create(WebArchive.class,
|
.create(WebArchive.class,
|
||||||
"LibreCCM-org.libreccm.core.CcmObjectRepositoryTest.war")
|
"LibreCCM-org.libreccm.core.CcmObjectRepositoryTest.war")
|
||||||
.addPackage(CcmObject.class.getPackage())
|
.addPackage(CcmObject.class.getPackage())
|
||||||
.addPackage(org.libreccm.web.Application.class.getPackage())
|
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
|
||||||
.addPackage(org.libreccm.categorization.Category.class.
|
.addPackage(org.libreccm.categorization.Category.class.
|
||||||
getPackage())
|
getPackage())
|
||||||
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import org.libreccm.tests.categories.UnitTest;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import org.libreccm.web.ApplicationType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ public class GroupManagerTest {
|
||||||
.create(WebArchive.class,
|
.create(WebArchive.class,
|
||||||
"LibreCCM-org.libreccm.core.GroupManagerTest.war")
|
"LibreCCM-org.libreccm.core.GroupManagerTest.war")
|
||||||
.addPackage(User.class.getPackage())
|
.addPackage(User.class.getPackage())
|
||||||
.addPackage(org.libreccm.web.Application.class.getPackage())
|
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
|
||||||
.addPackage(org.libreccm.categorization.Category.class.
|
.addPackage(org.libreccm.categorization.Category.class.
|
||||||
getPackage())
|
getPackage())
|
||||||
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ public class GroupRepositoryTest {
|
||||||
.create(WebArchive.class,
|
.create(WebArchive.class,
|
||||||
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
|
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
|
||||||
.addPackage(User.class.getPackage())
|
.addPackage(User.class.getPackage())
|
||||||
.addPackage(org.libreccm.web.Application.class.getPackage())
|
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
|
||||||
.addPackage(org.libreccm.categorization.Category.class.
|
.addPackage(org.libreccm.categorization.Category.class.
|
||||||
getPackage())
|
getPackage())
|
||||||
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ public class PermissionManagerTest {
|
||||||
String.format("LibreCCM-%s.war",
|
String.format("LibreCCM-%s.war",
|
||||||
PermissionManagerTest.class.getName()))
|
PermissionManagerTest.class.getName()))
|
||||||
.addPackage(User.class.getPackage())
|
.addPackage(User.class.getPackage())
|
||||||
.addPackage(org.libreccm.web.Application.class.getPackage())
|
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
|
||||||
.addPackage(org.libreccm.categorization.Category.class.
|
.addPackage(org.libreccm.categorization.Category.class.
|
||||||
getPackage())
|
getPackage())
|
||||||
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ public class PermissionRepositoryTest {
|
||||||
.create(WebArchive.class,
|
.create(WebArchive.class,
|
||||||
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
|
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
|
||||||
.addPackage(User.class.getPackage())
|
.addPackage(User.class.getPackage())
|
||||||
.addPackage(org.libreccm.web.Application.class.getPackage())
|
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
|
||||||
.addPackage(org.libreccm.categorization.Category.class.
|
.addPackage(org.libreccm.categorization.Category.class.
|
||||||
getPackage())
|
getPackage())
|
||||||
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ public class PrivilegeRepositoryTest {
|
||||||
.create(WebArchive.class,
|
.create(WebArchive.class,
|
||||||
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
|
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
|
||||||
.addPackage(User.class.getPackage())
|
.addPackage(User.class.getPackage())
|
||||||
.addPackage(org.libreccm.web.Application.class.getPackage())
|
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
|
||||||
.addPackage(org.libreccm.categorization.Category.class.
|
.addPackage(org.libreccm.categorization.Category.class.
|
||||||
getPackage())
|
getPackage())
|
||||||
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ public class RoleRepositoryTest {
|
||||||
.create(WebArchive.class,
|
.create(WebArchive.class,
|
||||||
"LibreCCM-org.libreccm.core.RoleRepositoryTest.war")
|
"LibreCCM-org.libreccm.core.RoleRepositoryTest.war")
|
||||||
.addPackage(User.class.getPackage())
|
.addPackage(User.class.getPackage())
|
||||||
.addPackage(org.libreccm.web.Application.class.getPackage())
|
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
|
||||||
.addPackage(org.libreccm.categorization.Category.class.
|
.addPackage(org.libreccm.categorization.Category.class.
|
||||||
getPackage())
|
getPackage())
|
||||||
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import org.libreccm.tests.categories.UnitTest;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import org.libreccm.web.ApplicationType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -39,7 +38,6 @@ public class ToStringTest extends ToStringVerifier {
|
||||||
@Parameterized.Parameters(name = "{0}")
|
@Parameterized.Parameters(name = "{0}")
|
||||||
public static Collection<Class<?>> data() {
|
public static Collection<Class<?>> data() {
|
||||||
return Arrays.asList(new Class<?>[]{
|
return Arrays.asList(new Class<?>[]{
|
||||||
ApplicationType.class,
|
|
||||||
CcmObject.class,
|
CcmObject.class,
|
||||||
EmailAddress.class,
|
EmailAddress.class,
|
||||||
GroupMembership.class,
|
GroupMembership.class,
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ public class UserManagerTest {
|
||||||
.create(WebArchive.class,
|
.create(WebArchive.class,
|
||||||
"LibreCCM-org.libreccm.core.UserManagerTest.war")
|
"LibreCCM-org.libreccm.core.UserManagerTest.war")
|
||||||
.addPackage(User.class.getPackage())
|
.addPackage(User.class.getPackage())
|
||||||
.addPackage(org.libreccm.web.Application.class.getPackage())
|
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
|
||||||
.addPackage(org.libreccm.categorization.Category.class.
|
.addPackage(org.libreccm.categorization.Category.class.
|
||||||
getPackage())
|
getPackage())
|
||||||
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ public class UserRepositoryTest {
|
||||||
.create(WebArchive.class,
|
.create(WebArchive.class,
|
||||||
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
|
"LibreCCM-org.libreccm.core.UserRepositoryTest.war")
|
||||||
.addPackage(User.class.getPackage())
|
.addPackage(User.class.getPackage())
|
||||||
.addPackage(org.libreccm.web.Application.class.getPackage())
|
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
|
||||||
.addPackage(org.libreccm.categorization.Category.class.
|
.addPackage(org.libreccm.categorization.Category.class.
|
||||||
getPackage())
|
getPackage())
|
||||||
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ public class LoginManagerTest {
|
||||||
.create(WebArchive.class,
|
.create(WebArchive.class,
|
||||||
"LibreCCM-org.libreccm.core.authentication.LoginManagerTest.war")
|
"LibreCCM-org.libreccm.core.authentication.LoginManagerTest.war")
|
||||||
.addPackage(CcmObject.class.getPackage())
|
.addPackage(CcmObject.class.getPackage())
|
||||||
.addPackage(org.libreccm.web.Application.class.getPackage())
|
.addPackage(org.libreccm.web.CcmApplication.class.getPackage())
|
||||||
.addPackage(org.libreccm.categorization.Category.class.
|
.addPackage(org.libreccm.categorization.Category.class.
|
||||||
getPackage())
|
getPackage())
|
||||||
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage())
|
.addPackage(org.libreccm.l10n.LocalizedString.class.getPackage())
|
||||||
|
|
|
||||||
|
|
@ -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();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -43,7 +43,7 @@ public class EqualsAndHashCodeTest {
|
||||||
@Parameterized.Parameters(name = "{0}")
|
@Parameterized.Parameters(name = "{0}")
|
||||||
public static Collection<Class<?>> data() {
|
public static Collection<Class<?>> data() {
|
||||||
return Arrays.asList(new Class<?>[]{
|
return Arrays.asList(new Class<?>[]{
|
||||||
Application.class,
|
CcmApplication.class,
|
||||||
Host.class
|
Host.class
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ public class ToStringTest extends ToStringVerifier {
|
||||||
@Parameterized.Parameters(name = "{0}")
|
@Parameterized.Parameters(name = "{0}")
|
||||||
public static Collection<Class<?>> data() {
|
public static Collection<Class<?>> data() {
|
||||||
return Arrays.asList(new Class<?>[]{
|
return Arrays.asList(new Class<?>[]{
|
||||||
Application.class,
|
CcmApplication.class,
|
||||||
Host.class
|
Host.class
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.docrepo;
|
package org.libreccm.docrepo;
|
||||||
|
|
||||||
import org.libreccm.web.Application;
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
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
|
* 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>
|
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
|
||||||
* @version 01/10/2015
|
* @version 01/10/2015
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "CCM_DOCREPO", name = "REPOSITORIES")
|
@Table(schema = "CCM_DOCREPO", name = "REPOSITORIES")
|
||||||
public class Repository extends Application {
|
public class Repository extends CcmApplication {
|
||||||
|
|
||||||
private static final long serialVersionUID = 6673243021462798036L;
|
private static final long serialVersionUID = 6673243021462798036L;
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ public class Repository extends Application {
|
||||||
private long ownerId;
|
private long ownerId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor calls the super-class-constructor of {@link Application}.
|
* Constructor calls the super-class-constructor of {@link CcmApplication}.
|
||||||
*/
|
*/
|
||||||
public Repository() {
|
public Repository() {
|
||||||
super();
|
super();
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ package org.libreccm.shortcuts;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import org.libreccm.web.Application;
|
|
||||||
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -28,7 +29,7 @@ import org.libreccm.web.Application;
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema ="CCM_SHORTCUTS", name = "SHORTCUTS_APP")
|
@Table(schema ="CCM_SHORTCUTS", name = "SHORTCUTS_APP")
|
||||||
public class Shortcuts extends Application {
|
public class Shortcuts extends CcmApplication {
|
||||||
private static final long serialVersionUID = -6793265996161649637L;
|
private static final long serialVersionUID = -6793265996161649637L;
|
||||||
|
|
||||||
// private String shortcutAppName;
|
// private String shortcutAppName;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue