NIHVIVO-1296 Integrate login functionality into login widget.
This commit is contained in:
parent
73b881a805
commit
2973ceebf2
14 changed files with 237 additions and 148 deletions
|
@ -233,6 +233,9 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
// We can't use shared variables in the Freemarker configuration to store anything
|
||||
// except theme-specific data, because multiple portals or apps might share the same theme. So instead
|
||||
// we'll get all the shared variables here, and put them in both root and body maps.
|
||||
// If we can eliminate this use case and use shared variables, it would simplify the implementation greatly.
|
||||
// See also directives, where since there are no shared variables we have to manually put elements
|
||||
// of the data model into the directive template model.
|
||||
public Map<String, Object> getSharedVariables(VitroRequest vreq, Map<String, Object> bodyMap) {
|
||||
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.web.widgets;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
@ -11,18 +11,159 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State;
|
||||
import freemarker.core.Environment;
|
||||
import freemarker.template.TemplateModel;
|
||||
|
||||
public class LoginWidget extends Widget {
|
||||
|
||||
private static final Log log = LogFactory.getLog(LoginWidget.class);
|
||||
|
||||
private static enum Macro {
|
||||
LOGIN("loginForm"),
|
||||
FORCE_PASSWORD_CHANGE("forcePasswordChange"),
|
||||
SERVER_ERROR("error");
|
||||
|
||||
private final String macroName;
|
||||
|
||||
Macro(String macroName) {
|
||||
this.macroName = macroName;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return macroName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static enum TemplateVariable {
|
||||
LOGIN_NAME("loginName"),
|
||||
FORM_ACTION("formAction"),
|
||||
INFO_MESSAGE("infoMessage"),
|
||||
ERROR_MESSAGE("errorMessage"),
|
||||
CANCEL_URL("cancelUrl");
|
||||
|
||||
private final String variableName;
|
||||
|
||||
TemplateVariable(String variableName) {
|
||||
this.variableName = variableName;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return variableName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WidgetTemplateValues process(Environment env, Map params,
|
||||
HttpServletRequest request, ServletContext context) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("fruit", "bananas");
|
||||
return new WidgetTemplateValues (getMarkupMacroName(), map);
|
||||
|
||||
WidgetTemplateValues values = null;
|
||||
TemplateModel urls = null;
|
||||
|
||||
try {
|
||||
urls = env.getDataModel().get("urls");
|
||||
State state = getCurrentLoginState(request);
|
||||
log.debug("State on exit: " + state);
|
||||
|
||||
switch (state) {
|
||||
case LOGGED_IN:
|
||||
return null;
|
||||
case FORCED_PASSWORD_CHANGE:
|
||||
values = showPasswordChangeScreen(request);
|
||||
break;
|
||||
default:
|
||||
values = showLoginScreen(request);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
values = showError(e);
|
||||
}
|
||||
values.put("urls", urls);
|
||||
return values;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* User is just starting the login process. Be sure that we have a
|
||||
* {@link LoginProcessBean} with the correct status. Show them the login
|
||||
* screen.
|
||||
*/
|
||||
private WidgetTemplateValues showLoginScreen(HttpServletRequest request)
|
||||
throws IOException {
|
||||
LoginProcessBean bean = LoginProcessBean.getBean(request);
|
||||
bean.setState(State.LOGGING_IN);
|
||||
log.trace("Going to login screen: " + bean);
|
||||
|
||||
WidgetTemplateValues values = new WidgetTemplateValues(Macro.LOGIN.toString());
|
||||
values.put(TemplateVariable.FORM_ACTION.toString(), getAuthenticateUrl(request));
|
||||
values.put(TemplateVariable.LOGIN_NAME.toString(), bean.getUsername());
|
||||
|
||||
String infoMessage = bean.getInfoMessage();
|
||||
if (!infoMessage.isEmpty()) {
|
||||
values.put(TemplateVariable.INFO_MESSAGE.toString(), infoMessage);
|
||||
}
|
||||
String errorMessage = bean.getErrorMessage();
|
||||
if (!errorMessage.isEmpty()) {
|
||||
values.put(TemplateVariable.ERROR_MESSAGE.toString(), errorMessage);
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user has given the correct password, but now they are required to
|
||||
* change it (unless they cancel out).
|
||||
*/
|
||||
private WidgetTemplateValues showPasswordChangeScreen(HttpServletRequest request) {
|
||||
LoginProcessBean bean = LoginProcessBean.getBean(request);
|
||||
bean.setState(State.FORCED_PASSWORD_CHANGE);
|
||||
log.trace("Going to password change screen: " + bean);
|
||||
|
||||
WidgetTemplateValues values = new WidgetTemplateValues(
|
||||
Macro.FORCE_PASSWORD_CHANGE.toString());
|
||||
values.put(TemplateVariable.FORM_ACTION.toString(), getAuthenticateUrl(request));
|
||||
values.put(TemplateVariable.CANCEL_URL.toString(), getCancelUrl(request));
|
||||
|
||||
String errorMessage = bean.getErrorMessage();
|
||||
if (!errorMessage.isEmpty()) {
|
||||
values.put(TemplateVariable.ERROR_MESSAGE.toString(), errorMessage);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private WidgetTemplateValues showError(Exception e) {
|
||||
WidgetTemplateValues values = new WidgetTemplateValues(
|
||||
Macro.SERVER_ERROR.toString());
|
||||
values.put(TemplateVariable.ERROR_MESSAGE.toString(), "Internal server error:<br /> " + e);
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Where are we in the process? Logged in? Not? Somewhere in between?
|
||||
*/
|
||||
private State getCurrentLoginState(HttpServletRequest request) {
|
||||
if (LoginStatusBean.getBean(request).isLoggedIn()) {
|
||||
return State.LOGGED_IN;
|
||||
} else {
|
||||
return LoginProcessBean.getBean(request).getState();
|
||||
}
|
||||
}
|
||||
|
||||
/** What's the URL for this servlet? */
|
||||
private String getAuthenticateUrl(HttpServletRequest request) {
|
||||
String contextPath = request.getContextPath();
|
||||
return contextPath + "/authenticate";
|
||||
}
|
||||
|
||||
/** What's the URL for this servlet, with the cancel parameter added? */
|
||||
private String getCancelUrl(HttpServletRequest request) {
|
||||
String contextPath = request.getContextPath();
|
||||
String urlParams = "?cancel=true";
|
||||
return contextPath + "/authenticate" + urlParams;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,11 @@ public abstract class Widget {
|
|||
ServletContext context = (ServletContext) env.getCustomAttribute("context");
|
||||
|
||||
WidgetTemplateValues values = process(env, params, request, context);
|
||||
// The widget process() method may determine that nothing should display for the widget:
|
||||
// for example, the login widget doesn't display if the user is already logged in.
|
||||
if (values == null) {
|
||||
return "";
|
||||
}
|
||||
String widgetName = params.get("name").toString(); // getWidgetName();
|
||||
return processMacroToString(env, widgetName, values);
|
||||
}
|
||||
|
@ -106,7 +111,9 @@ public abstract class Widget {
|
|||
} catch (Throwable th) {
|
||||
log.error("Could not process widget " + widgetName, th);
|
||||
}
|
||||
return out.toString();
|
||||
String output = out.toString();
|
||||
log.debug("Macro output: " + output);
|
||||
return output;
|
||||
}
|
||||
|
||||
private String processMacroToString(Environment env, String widgetName, String macroName, Map<String, Object> map) {
|
||||
|
@ -134,9 +141,14 @@ public abstract class Widget {
|
|||
protected static class WidgetTemplateValues {
|
||||
private final String macroName;
|
||||
private final Map<String, Object> map;
|
||||
|
||||
public WidgetTemplateValues(String macroName) {
|
||||
this.macroName = macroName;
|
||||
this.map = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
public WidgetTemplateValues(String templateName, Map<String, Object> map) {
|
||||
this.macroName = templateName;
|
||||
public WidgetTemplateValues(String macroName, Map<String, Object> map) {
|
||||
this.macroName = macroName;
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue