X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=source%2FMir.java;h=3c42ca602678f5adc1f3ccf406daaf4a25ccd7ba;hb=a420f03f20c6f3383f3d7a6eb34bb7812540b80c;hp=ed6825c3a2ecefeb3832ce1a366fc949d065036e;hpb=c1442585c17418ee8c6d96635a180c0a3c55ef07;p=mir.git diff --git a/source/Mir.java b/source/Mir.java index ed6825c3..3c42ca60 100755 --- a/source/Mir.java +++ b/source/Mir.java @@ -18,99 +18,77 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with the com.oreilly.servlet library, any library - * licensed under the Apache Software License, The Sun (tm) Java Advanced - * Imaging library (JAI), The Sun JIMI library (or with modified versions of - * the above that use the same license as the above), and distribute linked - * combinations including the two. You must obey the GNU General Public - * License in all respects for all of the code used other than the above - * mentioned libraries. If you modify this file, you may extend this exception - * to your version of the file, but you are not obligated to do so. If you do - * not wish to do so, delete this exception statement from your version. + * the code of this program with any library licensed under the Apache Software License, + * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library + * (or with modified versions of the above that use the same license as the above), + * and distribute linked combinations including the two. You must obey the + * GNU General Public License in all respects for all of the code used other than + * the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. + * If you do not wish to do so, delete this exception statement from your version. */ import java.io.IOException; -import java.io.PrintWriter; - import java.lang.reflect.Method; - -import java.util.GregorianCalendar; +import java.util.*; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Vector; - +import javax.servlet.*; import javax.servlet.ServletException; import javax.servlet.UnavailableException; -import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.*; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.struts.util.MessageResources; - - -import freemarker.template.SimpleHash; -import freemarker.template.SimpleList; -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateModel; - import mir.config.MirPropertiesConfiguration; -import mir.generator.FreemarkerGenerator; -import mir.log.LoggerWrapper; -import mir.misc.HTMLTemplateProcessor; -import mir.misc.StringUtil; import mir.servlet.AbstractServlet; import mir.servlet.ServletModule; import mir.servlet.ServletModuleDispatch; -import mir.servlet.ServletModuleException; -import mir.servlet.ServletModuleUserException; +import mir.servlet.ServletModuleExc; +import mir.servlet.ServletModuleUserExc; +import mir.util.ExceptionFunctions; import mir.util.StringRoutines; - import mircoders.entity.EntityUsers; import mircoders.global.MirGlobal; import mircoders.module.ModuleMessage; import mircoders.module.ModuleUsers; -import mircoders.storage.DatabaseArticleType; -import mircoders.storage.DatabaseMessages; +import mircoders.servlet.ServletHelper; import mircoders.storage.DatabaseUsers; + /** * Mir.java - main servlet, that dispatches to servletmodules * - * @author $Author: idfx $ - * @version $Id: Mir.java,v 1.30 2003/02/28 18:27:07 idfx Exp $ + * @author $Author: zapata $ + * @version $Id: Mir.java,v 1.49.2.7 2003/09/04 03:11:42 zapata Exp $ * */ public class Mir extends AbstractServlet { private static ModuleUsers usersModule = null; private static ModuleMessage messageModule = null; - private final static HashMap servletModuleInstanceHash = new HashMap(); + private final static Map servletModuleInstanceHash = new HashMap(); + private static Locale fallbackLocale = null; - //I don't know about making this static cause it removes the - //possibility to change the config on the fly.. -mh private static List loginLanguages = null; - public HttpSession session; - public void doGet(HttpServletRequest req, HttpServletResponse res) - throws ServletException, IOException { - doPost(req, res); - } - - protected TemplateModel getLoginLanguages() throws ServletException { + protected List getLoginLanguages() throws ServletException { synchronized (Mir.class) { try { if (loginLanguages == null) { - MessageResources messageResources2 = - MessageResources.getMessageResources("bundles.admin"); MessageResources messageResources = MessageResources.getMessageResources("bundles.adminlocal"); + MessageResources messageResources2 = + MessageResources.getMessageResources("bundles.admin"); + List languages = - StringRoutines.splitString(MirGlobal.getConfigPropertyWithDefault( - "Mir.Login.Languages", "en"), ";"); + StringRoutines.splitString(MirGlobal.config().getString("Mir.Login.Languages", "en"), ";"); loginLanguages = new Vector(); @@ -136,198 +114,158 @@ public class Mir extends AbstractServlet { } } - return FreemarkerGenerator.makeAdapter(loginLanguages); - } catch (Throwable t) { + return loginLanguages; + } + catch (Throwable t) { throw new ServletException(t.getMessage()); } } } - // FIXME: this should probalby go into AbstractServlet so it can be used in - // OpenMir as well -mh - protected String getDefaultLanguage(HttpServletRequest req) { + public void init(ServletConfig config) throws ServletException { + super.init(config); + + usersModule = new ModuleUsers(DatabaseUsers.getInstance()); + } + + protected String getDefaultLanguage(HttpServletRequest aRequest) { String defaultlanguage = - MirGlobal.getConfigPropertyWithDefault("Mir.Login.DefaultLanguage", ""); + MirGlobal.config().getString("Mir.Login.DefaultLanguage", ""); if (defaultlanguage.length() == 0) { - Locale locale = req.getLocale(); + Locale locale = aRequest.getLocale(); defaultlanguage = locale.getLanguage(); } return defaultlanguage; } - public void doPost(HttpServletRequest req, HttpServletResponse res) - throws ServletException, IOException, UnavailableException { - long startTime = System.currentTimeMillis(); - long sessionConnectTime = 0; - EntityUsers userEntity; - String http = ""; - - if ((configuration.getString("RootUri") == null) || - configuration.getString("RootUri").equals("")) { - configuration.setProperty("RootUri", req.getContextPath()); + protected synchronized Locale getFallbackLocale() throws ServletException { + try { + if (fallbackLocale == null) { + fallbackLocale = new Locale(MirPropertiesConfiguration.instance().getString("Mir.Admin.FallbackLanguage", "en"), ""); + } + } + catch (Throwable t) { + throw new ServletException(t.getMessage()); } - configuration.addProperty("ServletName", getServletName()); - - //*** test - // Log.info(this, "blalalala"); - session = req.getSession(true); - userEntity = (EntityUsers) session.getAttribute("login.uid"); + return fallbackLocale; + } - if (req.getServerPort() == 443) { - http = "https"; - } else { - http = "http"; - } + public EntityUsers checkCredentials(HttpServletRequest aRequest) throws ServletException { + try { + EntityUsers user = ServletHelper.getUser(aRequest); - //make sure client browsers don't cache anything - setNoCaching(res); + String username = aRequest.getParameter("login"); + String password = aRequest.getParameter("password"); - //FIXME: this seems kind of hackish and only here because we can have - // default other than the one that the browser is set to. - Locale locale = new Locale(getDefaultLanguage(req), ""); - MessageResources messageResources = - MessageResources.getMessageResources("bundles.admin"); - String htmlcharset = messageResources.getMessage(locale, "htmlcharset"); + if (username != null && password != null) { + user = usersModule.getUserForLogin(username, password); - res.setContentType("text/html; charset=" + htmlcharset); + if (user!=null) { + ServletHelper.setUser(aRequest, user); + aRequest.getSession().setAttribute("sessiontracker", new SessionTracker(username)); + } + } - String moduleName = req.getParameter("module"); - checkLanguage(session, req); + return user; + } + catch (Throwable t) { + t.printStackTrace(); - /** @todo for cleanup and readability this should be moved to - * method loginIfNecessary() */ - if ((moduleName != null) && moduleName.equals("direct")) { - //... + throw new ServletException(t.toString()); } + } - // Authentication - if (((moduleName != null) && moduleName.equals("login")) || - (userEntity == null)) { - String user = req.getParameter("login"); - String passwd = req.getParameter("password"); - logger.debug("--login: evaluating for user: " + user); - userEntity = allowedUser(user, passwd); + public void process(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletException, IOException, UnavailableException { + try { + long startTime = System.currentTimeMillis(); + long sessionConnectTime = 0; - if (userEntity == null) { - // login failed: redirecting to login - logger.warn("--login: failed!"); - _sendLoginPage(res, req, res.getWriter()); - - return; - } else if ((moduleName != null) && moduleName.equals("login")) { - // login successful - logger.info("--login: successful! setting uid: " + userEntity.getId()); - session.setAttribute("login.uid", userEntity); - logger.debug("--login: trying to retrieve login.target"); - - String target = (String) session.getAttribute("login.target"); - - if (target != null) { - logger.debug("Redirect: " + target); - - int serverPort = req.getServerPort(); - String redirect = ""; - String redirectString = ""; - - if (serverPort == 80) { - redirect = - res.encodeURL(http + "://" + req.getServerName() + target); - redirectString = - "going Mir"; - } else { - redirect = - res.encodeURL(http + "://" + req.getServerName() + ":" + - req.getServerPort() + target); - redirectString = - "going Mir"; - } + HttpSession session = aRequest.getSession(true); + setNoCaching(aResponse); + Locale locale = new Locale(getDefaultLanguage(aRequest), ""); + aResponse.setContentType("text/html; charset=" + + configuration. + getString("Mir.DefaultHTMLCharset", "UTF-8")); - res.getWriter().println(redirectString); + EntityUsers userEntity = checkCredentials(aRequest); - //res.sendRedirect(redirect); - } else { - // redirecting to default target - logger.debug("--login: no target - redirecting to default"); - _sendStartPage(res, req, res.getWriter(), userEntity); + if (userEntity == null) { + String queryString = aRequest.getQueryString(); + + if ( (queryString != null) && (queryString.length() != 0) && session.getAttribute("login.target") == null && + (aRequest.getParameter("module")==null || + (!aRequest.getParameter("module").equals("login") && !aRequest.getParameter("module").equals("logout")))) { + session.setAttribute("login.target", queryString); } - return; + _sendLoginPage(aResponse, aRequest); } - // if login succesful - } - // if login + else { + String moduleName = aRequest.getParameter("module"); + checkLanguage(session, aRequest); - if ((moduleName != null) && moduleName.equals("logout")) { - logger.info("--logout"); - session.invalidate(); - - //session = req.getSession(true); - //checkLanguage(session, req); - _sendLoginPage(res, req, res.getWriter()); - - return; - } + if ( ( (moduleName == null) || moduleName.equals(""))) { + moduleName="Admin"; + } - // Check if authed! - if (userEntity == null) { - // redirect to loginpage - String redirectString = req.getRequestURI(); - String queryString = req.getQueryString(); - if ((queryString != null) && !queryString.equals("")) { - redirectString += ("?" + req.getQueryString()); - logger.debug("STORING: " + redirectString); - session.setAttribute("login.target", redirectString); - } + if (moduleName.equals("login")) { + String target = (String) session.getAttribute("login.target"); - _sendLoginPage(res, req, res.getWriter()); + if (target != null) { + ServletHelper.redirect(aResponse, target); + } + else { + ServletHelper.redirect(aResponse, ""); + } + } + else if (moduleName.equals("logout")) { + logger.info(userEntity.getValue("login") + " has logged out"); + session.invalidate(); + _sendLoginPage(aResponse, aRequest); + return; + } + else { + try { + ServletModule servletModule = getServletModuleForName(moduleName); + ServletModuleDispatch.dispatch(servletModule, aRequest, aResponse); - return; - } + sessionConnectTime = System.currentTimeMillis() - startTime; + logger.info("EXECTIME (" + moduleName + "): " + sessionConnectTime + " ms"); + } + catch (Throwable e) { + Throwable cause = ExceptionFunctions.traceCauseException(e); - // If no module is specified goto standard startpage - if ((moduleName == null) || moduleName.equals("")) { - logger.debug("no module: redirect to standardpage"); - _sendStartPage(res, req, res.getWriter(), userEntity); + if (cause instanceof ServletModuleUserExc) + handleUserError(aRequest, aResponse, (ServletModuleUserExc) cause); + else + handleError(aRequest, aResponse, cause); + } - return; + if (aRequest.getParameter("killsession")!=null) + aRequest.getSession().invalidate(); + } + } } + catch (Throwable t) { + t.printStackTrace(); - // end of auth - // From now on regular dispatching... - try { - // get servletmodule by parameter and continue with dispacher - ServletModule smod = getServletModuleForName(moduleName); - ServletModuleDispatch.dispatch(smod, req, res); - } catch (ServletModuleException e) { - handleError(req, res, res.getWriter(), - "ServletException in Module " + moduleName + " -- " + e.getMessage()); - } catch (ServletModuleUserException e) { - handleUserError(req, res, res.getWriter(), e.getMessage()); + throw new ServletException(t.toString()); } - - // timing... - sessionConnectTime = System.currentTimeMillis() - startTime; - logger.info("EXECTIME (" + moduleName + "): " + sessionConnectTime + " ms"); } /** - * Private method getServletModuleForName returns ServletModule - * from Cache - * - * @param moduleName - * @return ServletModule + * caching routine to get a module for a module name * + * @param moduleName the module name + * @return the requested module + * @throws ServletModuleExc */ - private static ServletModule getServletModuleForName(String moduleName) - throws ServletModuleException { + + private static ServletModule getServletModuleForName(String moduleName) throws ServletModuleExc { // Instance in Map ? if (!servletModuleInstanceHash.containsKey(moduleName)) { // was not found in hash... @@ -338,7 +276,8 @@ public class Mir extends AbstractServlet { // first we try to get ServletModule from stern.che3.servlet theServletModuleClass = Class.forName("mircoders.servlet.ServletModule" + moduleName); - } catch (ClassNotFoundException e) { + } + catch (ClassNotFoundException e) { // on failure, we try to get it from lib-layer theServletModuleClass = Class.forName("mir.servlet.ServletModule" + moduleName); @@ -351,123 +290,63 @@ public class Mir extends AbstractServlet { servletModuleInstanceHash.put(moduleName, smod); return smod; - } catch (Exception e) { - throw new ServletModuleException("*** error resolving classname for " + - moduleName + " -- " + e.getMessage()); } - } else { + catch (Exception e) { + throw new ServletModuleExc("*** error resolving classname for " + moduleName + " -- " + e.getMessage()); + } + } + else { return (ServletModule) servletModuleInstanceHash.get(moduleName); } } - private void handleError(HttpServletRequest req, HttpServletResponse res, - PrintWriter out, String errorString) { + private void handleUserError(HttpServletRequest aRequest, HttpServletResponse aResponse, ServletModuleUserExc anException) { try { - logger.error(errorString); - - SimpleHash modelRoot = new SimpleHash(); - modelRoot.put("errorstring", new SimpleScalar(errorString)); - modelRoot.put("date", - new SimpleScalar(StringUtil.date2readableDateTime( - new GregorianCalendar()))); - HTMLTemplateProcessor.process(res, - MirPropertiesConfiguration.instance().getString("Mir.ErrorTemplate"), - modelRoot, out, getLocale(req)); - out.close(); - } - catch (Exception e) { - logger.error("Error in ErrorTemplate: " + e.getMessage()); - e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE)); - } - } + logger.info("user error: " + anException.getMessage()); - private void handleUserError(HttpServletRequest req, HttpServletResponse res, - PrintWriter out, String errorString) { - try { - logger.error(errorString); - - SimpleHash modelRoot = new SimpleHash(); - modelRoot.put("errorstring", new SimpleScalar(errorString)); - modelRoot.put("date", - new SimpleScalar(StringUtil.date2readableDateTime( - new GregorianCalendar()))); - HTMLTemplateProcessor.process(res, - MirPropertiesConfiguration.instance().getString("Mir.UserErrorTemplate"), - modelRoot, out, getLocale(req)); - out.close(); - } - catch (Exception e) { - logger.error("Error in UserErrorTemplate"); - } - } - - /** - * evaluate login for user / password - */ - protected EntityUsers allowedUser(String user, String password) { - try { - if (usersModule == null) { - usersModule = new ModuleUsers(DatabaseUsers.getInstance()); - } + Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()}); - return usersModule.getUserForLogin(user, password); - } catch (Exception e) { - logger.debug(e.getMessage()); - e.printStackTrace(); + MessageResources messages = MessageResources.getMessageResources("bundles.admin"); + responseData.put("errorstring", messages.getMessage(getLocale(aRequest), anException.getMessage(), anException.getParameters())); + responseData.put("date", new GregorianCalendar().getTime()); - return null; + ServletHelper.generateResponse(aResponse.getWriter(), responseData, MirPropertiesConfiguration.instance().getString("Mir.UserErrorTemplate")); + } + catch (Throwable e) { + logger.error("Error handling user error" + e.toString()); } } - // Redirect-methods - private void _sendLoginPage(HttpServletResponse res, HttpServletRequest req, - PrintWriter out) { - String loginTemplate = configuration.getString("Mir.LoginTemplate"); - String sessionUrl = res.encodeURL(""); - + private void handleError(HttpServletRequest aRequest, HttpServletResponse aResponse, Throwable anException) { try { - SimpleHash mergeData = new SimpleHash(); - SimpleList languages = new SimpleList(); + logger.error("error: " + anException); - mergeData.put("session", sessionUrl); + Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()}); - mergeData.put("defaultlanguage", getDefaultLanguage(req)); - mergeData.put("languages", getLoginLanguages()); + responseData.put("errorstring", anException.toString()); + responseData.put("date", new GregorianCalendar().getTime()); - HTMLTemplateProcessor.process(res, loginTemplate, mergeData, out, - getLocale(req)); - } catch (Throwable e) { - handleError(req, res, out, "Error sending login page: " + e.getMessage()); + ServletHelper.generateResponse(aResponse.getWriter(), responseData, MirPropertiesConfiguration.instance().getString("Mir.ErrorTemplate")); + } + catch (Throwable e) { + logger.error("Error handling error: " + e.toString()); } } - private void _sendStartPage(HttpServletResponse res, HttpServletRequest req, - PrintWriter out, EntityUsers userEntity) { - String startTemplate = "templates/admin/start_admin.template"; - String sessionUrl = res.encodeURL(""); + // Redirect-methods + private void _sendLoginPage(HttpServletResponse aResponse, HttpServletRequest aRequest) { + String loginTemplate = configuration.getString("Mir.LoginTemplate"); try { - // merge with logged in user and messages - SimpleHash mergeData = new SimpleHash(); - mergeData.put("session", sessionUrl); - mergeData.put("login_user", userEntity); - - if (messageModule == null) { - messageModule = new ModuleMessage(DatabaseMessages.getInstance()); - } - - mergeData.put("messages", - messageModule.getByWhereClause(null, "webdb_create desc", 0, 10)); + Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()}); - mergeData.put("articletypes", - DatabaseArticleType.getInstance().selectByWhereClause("", "id", 0, 20)); + responseData.put("defaultlanguage", getDefaultLanguage(aRequest)); + responseData.put("languages", getLoginLanguages()); - HTMLTemplateProcessor.process(res, startTemplate, mergeData, out, - getLocale(req)); + ServletHelper.generateResponse(aResponse.getWriter(), responseData, loginTemplate); } - catch (Exception e) { - e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE)); - handleError(req, res, out, "error while trying to send startpage. " + e.getMessage()); + catch (Throwable e) { + handleError(aRequest, aResponse, e); } } @@ -475,20 +354,19 @@ public class Mir extends AbstractServlet { return "Mir " + configuration.getString("Mir.Version"); } - private void checkLanguage(HttpSession session, HttpServletRequest req) { - // a lang parameter always sets the language - String lang = req.getParameter("language"); + private class SessionTracker implements HttpSessionBindingListener { + private String name; - if (lang != null) { - logger.info("selected language " + lang + " overrides accept-language"); - setLanguage(session, lang); - setLocale(session, new Locale(lang, "")); + public SessionTracker(String aUserName) { + name = aUserName; } - // otherwise store language from accept header in session - else if (session.getAttribute("Language") == null) { - logger.info("accept-language is " + req.getLocale().getLanguage()); - setLanguage(session, req.getLocale().getLanguage()); - setLocale(session, req.getLocale()); + + public void valueBound(HttpSessionBindingEvent anEvent) { + MirGlobal.registerLogin(name); + } + + public void valueUnbound(HttpSessionBindingEvent anEvent) { + MirGlobal.registerLogout(name); } } }