package marubinotto.piggydb.ui.page.common; import java.io.UnsupportedEncodingException; import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import marubinotto.piggydb.model.auth.User; import marubinotto.piggydb.service.DomainModelBeans; import marubinotto.piggydb.service.WarSetting; import marubinotto.piggydb.ui.page.HomePage; import marubinotto.piggydb.ui.page.LoginPage; import marubinotto.util.Assert; import marubinotto.util.message.MessageCode; import marubinotto.util.web.WebMessageSource; import marubinotto.util.web.WebUtils; import net.sf.click.Page; import org.apache.commons.codec.net.URLCodec; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.UnhandledException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public abstract class AbstractWebResource extends Page implements ApplicationContextAware, WebMessageSource { public static final String CHAR_ENCODING = "UTF-8"; public static final int ALMOST_UNLIMITED_PAGE_SIZE = 1000000; public PageUrl thisPageUrl; public WebResourcePaths resources; public WebMessageSource messageSource = this; public User user; private Log logger; private ApplicationContext applicationContext; private DomainModelBeans domain; private Session session; public AbstractWebResource() { } protected Log getLogger() { if (this.logger == null) this.logger = LogFactory.getLog(getClass()); return this.logger; } // // WebMessageSource // @Override public String getMessage(String name, Object arg) { return getMessage(name, arg, true); } @Override public String getMessage(String name, Object[] args) { return getMessage(name, args, true); } public String getMessage(MessageCode messageCode) { return getMessage(messageCode, true); } public String getMessage(String name, Object arg, boolean escapeArg) { return getMessage(name, new Object[]{arg}, escapeArg); } public static Object[] escapeArgs(Object[] args) { Object[] escaped = new Object[args.length]; for (int i = 0; i < args.length; i++) escaped[i] = WebUtils.escapeHtml(args[i]); return escaped; } public String getMessage(String name, Object[] args, boolean escapeArgs) { if (escapeArgs) { return super.getMessage(name, escapeArgs(args)); } else { return super.getMessage(name, args); } } public String getMessage(MessageCode messageCode, boolean escapeArgs) { if (messageCode.getArguments() == null) { return getMessage(messageCode.getCode()); } else { return getMessage(messageCode.getCode(), messageCode.getArguments(), escapeArgs); } } // // ApplicationContextAware // public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; this.domain = new DomainModelBeans(this.applicationContext); } public ApplicationContext getApplicationContext() { return this.applicationContext; } protected Object getBean(String beanName) { return this.applicationContext.getBean(beanName); } public DomainModelBeans getDomain() { return this.domain; } protected final WarSetting getWarSetting() { return (WarSetting)getBean("warSetting"); } protected boolean canUploadFile() { return !getWarSetting().isAllowsOnlyOwnerToUploadFile() || (getUser() != null && getUser().isOwner()); } // // Access control // protected boolean needsAuthentication() { return true; } public Session getSession() { return this.session; } public User getUser() { return this.user; } public boolean isAuthenticated() { return this.user != null; } protected String[] getAuthorizedRoles() { return null; } private boolean isAuthorized() { getLogger().info("Authorizing ..."); String[] authorizedRoles = getAuthorizedRoles(); if (authorizedRoles == null) { return true; } for (int i = 0; i < authorizedRoles.length; i++) { if (this.user.isInRole(authorizedRoles[i])) { return true; } } return false; } @Override public final boolean onSecurityCheck() { getLogger().debug("--------------------------------------------------"); logParameters(); this.session = new Session( getContext(), getWarSetting(), getDomain().getAuthentication().isEnableAnonymous()); this.session.log(); // Get a user object if it exists this.user = this.session.getUser(); if (this.user == null) this.user = autoLoginAsAnonymous(); if (this.user != null) { // for marubinotto.util.web.CustomizedSecurityRequestWrapper (for click menu auth) getContext().getRequest().setAttribute(User.KEY, this.user); } // Check security if needed if (needsAuthentication()) { if (this.user == null) { setRedirectToLogin(); return false; } if (!isAuthorized()) { setRedirectWithMessage(HomePage.class, getMessage("no-authority-for-page")); return false; } } // Preparation before init() this.resources = new WebResourcePaths( getContext().getRequest().getContextPath(), getWarSetting().getPiggydbVersion()); try { return onPreInit(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new UnhandledException(e); } } protected void setRedirectToLogin() { String path = getContext().getPagePath(LoginPage.class); setRedirect(path + "?original=" + encodedOriginalPath()); } private String encodedOriginalPath() { HttpServletRequest request = getContext().getRequest(); String path = StringUtils.defaultString(request.getServletPath()) + StringUtils.defaultString(request.getPathInfo()); String queryString = request.getQueryString(); if (StringUtils.isNotBlank(queryString)) { path = path + "?" + queryString; } try { return new URLCodec().encode(path, CHAR_ENCODING); } catch (UnsupportedEncodingException e) { throw new UnhandledException(e); } } protected User autoLoginAsAnonymous() { User user = getDomain().getAuthentication().authenticateAsAnonymous(); if (user == null) return null; getSession().start(user, false); getLogger().debug("Anonymous session created"); return user; } // // Page Processing Flow // /** * A target entity object should be prepared here (if this page is for an entity). */ protected boolean onPreInit() throws Exception { return true; } @Override public void onInit() { super.onInit(); this.thisPageUrl = createThisPageUrl(); // An ID of a target entity object maybe needed } protected PageUrl createThisPageUrl() { return new PageUrl(getClass(), getContext()); } protected String getFullPageUrl() { return WebUtils.makeContextUrl(getContext().getRequest()) + getPath(); } @Override public void onRender() { super.onRender(); try { setModels(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new UnhandledException(e); } } protected void setModels() throws Exception { } // // Utilities // @SuppressWarnings("rawtypes") private void logParameters() { if (!getLogger().isDebugEnabled()) return; getLogger().debug("Parameters {"); for (Enumeration e = getContext().getRequest().getParameterNames(); e.hasMoreElements();) { String name = (String) e.nextElement(); getLogger().debug(" " + name + " = " + ArrayUtils.toString(getContext().getRequest().getParameterValues(name))); } getLogger().debug("}"); } protected void disableClientCaching() { getContext().getResponse().addHeader( "Cache-Control", "no-store, max-age=0, no-cache, must-revalidate"); } protected String modifyIfGarbledByTomcat(String value) { try { return WebUtils.modifyIfGarbledByTomcat(value, getContext().getCharset(), getContext().getRequest(), getContext().getServletContext()); } catch (UnsupportedEncodingException e) { throw new UnhandledException(e); } } public void setRedirectToThisPage() { Assert.Property.requireNotNull(thisPageUrl, "thisPageUrl"); setRedirect(this.thisPageUrl.getPagePath()); } public void setRedirectToThisPage(String message) { Assert.Property.requireNotNull(thisPageUrl, "thisPageUrl"); setRedirectWithMessage(this.thisPageUrl.getPagePath(), message); } public void setRedirectWithMessage(Class<? extends Page> pageClass, String message) { Assert.Arg.notNull(pageClass, "pageClass"); Assert.Arg.notNull(message, "message"); getSession().setFlashMessage(message); setRedirect(pageClass); } public void setRedirectWithMessage(String path, String message) { Assert.Arg.notNull(path, "path"); Assert.Arg.notNull(message, "message"); getSession().setFlashMessage(message); setRedirect(path); } }