Java tutorial
/** * This file is part of JEMMA - http://jemma.energy-home.org * (C) Copyright 2013 Telecom Italia (http://www.telecomitalia.it) * * JEMMA is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License (LGPL) version 3 * or later as published by the Free Software Foundation, which accompanies * this distribution and is available at http://www.gnu.org/licenses/lgpl.html * * JEMMA 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 (LGPL) for more details. * */ package org.energy_home.jemma.ah.webui.energyathome.ekitchen; import java.io.IOException; import java.net.URL; import java.util.Map; import java.util.StringTokenizer; import java.util.Enumeration; import javax.security.auth.login.LoginException; import javax.servlet.Servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jabsorb.JSONRPCBridge; import org.jabsorb.JSONRPCServlet; import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext; import org.osgi.service.http.HttpContext; import org.osgi.service.http.HttpService; import org.osgi.service.useradmin.Authorization; import org.osgi.service.useradmin.User; import org.osgi.service.useradmin.UserAdmin; import org.energy_home.jemma.hac.adapter.http.Base64; import org.energy_home.jemma.hac.adapter.http.CustomJsonServlet; import org.energy_home.jemma.hac.adapter.http.HttpImplementor; import org.energy_home.jemma.hac.adapter.http.JsonRPC; /** * Register the url related to the Green@Home web application */ public class EnergyAtHome extends WebApplication implements HttpImplementor, HttpContext { private static class ServletConfigDisableGZIPWrapper implements ServletConfig { private ServletConfig wrapped = null; public ServletConfigDisableGZIPWrapper(ServletConfig wrapped) { this.wrapped = wrapped; } public String getInitParameter(String name) { // Disables gzip compression if (name.equals("gzip_threshold")) { return "-1"; } else { return wrapped.getInitParameter(name); } } public Enumeration getInitParameterNames() { return wrapped.getInitParameterNames(); } public ServletContext getServletContext() { return wrapped.getServletContext(); } public String getServletName() { return wrapped.getServletName(); } } private UserAdmin userAdmin = null; private String applicationWebAlias = "/energyathome"; private String realm = "Energy@Home Login"; private ComponentContext ctxt; private static final Log log = LogFactory.getLog(EnergyAtHome.class); private static final String PROP_ENABLE_AUTH = "it.telecomitalia.ah.energyathome.auth"; private static final String PROP_ENABLE_HTTPS = "it.telecomitalia.ah.energyathome.https"; private static final boolean DEFAULT_ENABLE_AUTH = true; private static final boolean DEFAULT_ENABLE_HTTPS = false; HttpAhBinder ahHttpAdapter = null; private BundleContext bc; JSONRPCBridge jsonRpcBridge; private boolean useBasic = false; private boolean enableSecurity = true; private boolean enableHttps = false; private ServiceRegistryProxy registryProxy; protected void activate(ComponentContext ctxt) { this.ctxt = ctxt; this.bc = ctxt.getBundleContext(); jsonRpcBridge = JSONRPCBridge.getGlobalBridge(); try { registryProxy = new ServiceRegistryProxy(this.bc, jsonRpcBridge); jsonRpcBridge.registerObject("OSGi", registryProxy); } catch (Throwable e) { log.debug(e); } } protected void deactivate(ComponentContext ctxt) { log.debug("deactivated"); if (this.registryProxy != null) { jsonRpcBridge.unregisterObject("OSGi"); this.registryProxy.close(); } } protected synchronized void setHttpService(HttpService s) { ahHttpAdapter = new HttpAhBinder(); this.setRootUrl(applicationWebAlias); Servlet customJsonServlet = new CustomJsonServlet(ahHttpAdapter, ""); Servlet jsonRPC = new JsonRPC(ahHttpAdapter, ""); this.registerResource("/", "webapp/ehdemo"); this.registerResource("/gh", "webapp/gh"); this.registerResource("/post-json", customJsonServlet); this.registerResource("/json-rpc", jsonRPC); this.registerResource("/JSON-RPC", new JSONRPCServlet() { public void init(ServletConfig config) throws ServletException { super.init(new ServletConfigDisableGZIPWrapper(config)); } }); this.setHttpContext(this); this.update(null); super.bindHttpService(s); } protected synchronized void unsetHttpService(HttpService s) { this.unbindHttpService(s); } protected synchronized void setUserAdmin(UserAdmin s) { this.userAdmin = s; } protected synchronized void unsetUserAdmin(UserAdmin s) { if (this.userAdmin == s) this.userAdmin = null; } public Object getObjectByPid(String pid) { return pid; } private boolean failAuthorization(HttpServletRequest request, HttpServletResponse response) { // force a session to be created request.getSession(true); response.setHeader("WWW-Authenticate", "Basic realm=\"" + realm + "\""); try { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } catch (IOException e) { // do nothing } return false; } public String getMimeType(String page) { // TODO addd PNG JPG and GIF files if (page.endsWith(".manifest")) { return "text/cache-manifest"; } else if (page.endsWith(".css")) { return "text/css"; } else if (page.endsWith(".js")) { return "text/javascript"; } else if (page.endsWith(".html")) { return "text/html"; } return null; } public URL getResource(String name) { URL u = this.ctxt.getBundleContext().getBundle().getResource(name); return u; } public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException { // we need http scheme! if (enableHttps && !request.getScheme().equals("https")) { try { response.sendError(HttpServletResponse.SC_FORBIDDEN); } catch (IOException e) { // do nothing } return false; } String queryString = request.getRequestURI(); if (queryString.equals(applicationWebAlias + "/conf") || (queryString.equals(applicationWebAlias + "/conf/"))) { response.sendRedirect(applicationWebAlias + "/conf/index.html"); return true; } else if (queryString.equals(applicationWebAlias) || (queryString.equals(applicationWebAlias + "/"))) { response.sendRedirect(applicationWebAlias + "/index.html"); return true; } if (enableSecurity) { if (useBasic) { String auth = request.getHeader("Authorization"); if (auth == null) return failAuthorization(request, response); StringTokenizer tokens = new StringTokenizer(auth); String authscheme = tokens.nextToken(); if (!authscheme.equals("Basic")) return failAuthorization(request, response); String base64credentials = tokens.nextToken(); String credentials = new String(Base64.decode(base64credentials.getBytes())); int colon = credentials.indexOf(':'); String userid = credentials.substring(0, colon); String password = credentials.substring(colon + 1); Authorization subject = null; try { subject = login(request, userid, password); } catch (LoginException e) { return failAuthorization(request, response); } request.setAttribute(HttpContext.REMOTE_USER, userid); request.setAttribute(HttpContext.AUTHENTICATION_TYPE, authscheme); request.setAttribute(HttpContext.AUTHORIZATION, subject); } else { HttpSession session = request.getSession(true); if (queryString.startsWith(applicationWebAlias + "/conf")) { // this is a restricted area so performs login String a = request.getMethod(); String submit = request.getParameter("submit"); if (submit != null) { String username = request.getParameter("username"); String password = request.getParameter("password"); if (!allowUser(username, password)) { return redirectToLoginPage(request, response); } else { session.putValue("logon.isDone", username); try { String target = (String) session.getValue("login.target"); if (target != null) response.sendRedirect(target); else { response.sendRedirect(applicationWebAlias + "/conf/index.html"); } } catch (Exception ignored) { return false; } } } else { if (queryString.equals(applicationWebAlias + "/conf/login.html")) { return true; } else { // session.putValue("login.target", HttpUtils.getRequestURL(request).toString()); session.putValue("login.target", applicationWebAlias + "/conf/index.html"); Object done = session.getValue("logon.isDone"); if (done == null) { if (request.getMethod().equals("GET")) { return redirectToLoginPage(request, response); } else { response.sendError(HttpServletResponse.SC_FORBIDDEN); return false; } } } } } } } if (request.getRequestURI().endsWith(".png")) { response.setHeader("Cache-Control", "public, max-age=10000"); } /*if (request.getRequestURI().endsWith(".js")) { response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-store"); response.setHeader("Cache-Control", "public, max-age=0"); }*/ // response.addHeader(HttpServletResponse, arg1) return true; } private boolean redirectToLoginPage(HttpServletRequest request, HttpServletResponse response) throws IOException { String redirect = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + applicationWebAlias + "/conf/login.html"; response.sendRedirect(redirect); return true; } private boolean allowUser(String username, String password) { if (userAdmin != null) { User user = userAdmin.getUser("org.energy_home.jemma.username", username); if (user == null) { return false; } if (!user.hasCredential("org.energy_home.jemma.password", password)) { return false; } return true; } return false; } private Authorization login(HttpServletRequest request, final String username, final String password) throws LoginException { Authorization a = (Authorization) request.getAttribute(HttpContext.AUTHORIZATION); if (a != null) { return a; } if (userAdmin != null) { User user = userAdmin.getUser("it.telecomitalia.username", username); if (user == null) { throw new LoginException(); } if (!user.hasCredential("it.telecomitalia.password", password)) { throw new LoginException(); } return userAdmin.getAuthorization(user); } throw new LoginException(); } public void modified(ComponentContext ctxt, Map props) { update(props); } private void update(Map props) { this.enableSecurity = getProperty(props, PROP_ENABLE_AUTH, DEFAULT_ENABLE_AUTH); this.enableHttps = getProperty(props, PROP_ENABLE_HTTPS, DEFAULT_ENABLE_HTTPS); } private boolean getProperty(Map props, String name, boolean value) { if (props == null) { return value; } Object prop = props.get(name); if (prop == null) { return value; } return ((Boolean) prop).booleanValue(); } }