You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2009/06/30 01:28:38 UTC

svn commit: r789490 - in /ofbiz/trunk: applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalWorker.java framework/webapp/src/org/ofbiz/webapp/webdav/WebDavUtil.java

Author: adrianc
Date: Mon Jun 29 23:28:37 2009
New Revision: 789490

URL: http://svn.apache.org/viewvc?rev=789490&view=rev
Log:
More iCalendar improvements. Added HTTP challenge/response authentication, enforce SSL.

Modified:
    ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java
    ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalWorker.java
    ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/webdav/WebDavUtil.java

Modified: ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java?rev=789490&r1=789489&r2=789490&view=diff
==============================================================================
--- ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java (original)
+++ ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java Mon Jun 29 23:28:37 2009
@@ -360,8 +360,13 @@
             Debug.logInfo("WorkEffort calendar is not published: " + workEffortId, module);
             return ICalWorker.createNotFoundResponse(null);
         }
-        if (!"WES_PUBLIC".equals(publishProperties.get("scopeEnumId")) && !hasPermission(workEffortId, "VIEW", context)) {
-            return ICalWorker.createNotFoundResponse(null);
+        if (!"WES_PUBLIC".equals(publishProperties.get("scopeEnumId"))) {
+            if (context.get("userLogin") == null) {
+                return ICalWorker.createNotAuthorizedResponse(null);
+            }
+            if (!hasPermission(workEffortId, "VIEW", context)) {
+                return ICalWorker.createForbiddenResponse(null);
+            }
         }
         Calendar calendar = makeCalendar(publishProperties, context);
         ComponentList components = calendar.getComponents();
@@ -677,9 +682,12 @@
             Debug.logInfo("WorkEffort calendar is not published: " + workEffortId, module);
             return ICalWorker.createNotFoundResponse(null);
         }
-        if (!hasPermission(workEffortId, "UPDATE", context)) {
+        if (context.get("userLogin") == null) {
             return ICalWorker.createNotAuthorizedResponse(null);
         }
+        if (!hasPermission(workEffortId, "UPDATE", context)) {
+            return ICalWorker.createForbiddenResponse(null);
+        }
         boolean hasCreatePermission = hasPermission(workEffortId, "CREATE", context);
         List<GenericValue> workEfforts = getRelatedWorkEfforts(publishProperties, context);
         if (workEfforts != null && workEfforts.size() > 0) {
@@ -788,7 +796,7 @@
             return ICalWorker.createNotFoundResponse(null);
         }
         if (!hasPermission(workEffortId, "UPDATE", context)) {
-            return ICalWorker.createNotAuthorizedResponse(null);
+            return null;
         }
         Map<String, Object> serviceMap = FastMap.newInstance();
         serviceMap.put("workEffortId", workEffortId);

Modified: ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalWorker.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalWorker.java?rev=789490&r1=789489&r2=789490&view=diff
==============================================================================
--- ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalWorker.java (original)
+++ ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalWorker.java Mon Jun 29 23:28:37 2009
@@ -41,15 +41,13 @@
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilHttp;
 import org.ofbiz.base.util.UtilJ2eeCompat;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilProperties;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.UtilXml;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.service.ModelService;
+import org.ofbiz.service.ServiceUtil;
 import org.ofbiz.webapp.stats.VisitHandler;
 import org.ofbiz.webapp.webdav.PropFindHelper;
 import org.ofbiz.webapp.webdav.ResponseHelper;
@@ -118,13 +116,10 @@
     }
 
     public static void handleGetRequest(HttpServletRequest request, HttpServletResponse response, ServletContext context) throws ServletException, IOException {
-        setupRequest(request, response);
-        String workEffortId = (String) request.getAttribute("workEffortId");
-        if (workEffortId == null) {
-            Debug.logInfo("[handleGetRequest] workEffortId missing", module);
-            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+        if (!isValidRequest(request, response)) {
             return;
         }
+        String workEffortId = (String) request.getAttribute("workEffortId");
         Debug.logInfo("[handleGetRequest] workEffortId = " + workEffortId, module);
         ResponseProperties responseProps = null;
         try {
@@ -137,17 +132,14 @@
         if (responseProps.statusCode == HttpServletResponse.SC_OK) {
             response.setContentType("text/calendar");
         }
-        writeResponse(responseProps, response, context);
+        writeResponse(responseProps, request, response, context);
     }
 
     public static void handlePropFindRequest(HttpServletRequest request, HttpServletResponse response, ServletContext context) throws ServletException, IOException {
-        setupRequest(request, response);
-        String workEffortId = (String) request.getAttribute("workEffortId");
-        if (workEffortId == null) {
-            Debug.logInfo("[handlePropFindRequest] workEffortId missing", module);
-            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+        if (!isValidRequest(request, response)) {
             return;
         }
+        String workEffortId = (String) request.getAttribute("workEffortId");
         Debug.logInfo("[handlePropFindRequest] workEffortId = " + workEffortId, module);
         try {
             Document requestDocument = WebDavUtil.getDocumentFromRequest(request);
@@ -208,20 +200,16 @@
     }
 
     public static void handlePutRequest(HttpServletRequest request, HttpServletResponse response, ServletContext context) throws ServletException, IOException {
+        if (!isValidRequest(request, response)) {
+            return;
+        }
         String contentType = request.getContentType();
-        Debug.logInfo("[handlePutRequest] content type = " + contentType, module);
         if (contentType != null && !"text/calendar".equals(contentType)) {
             Debug.logInfo("[handlePutRequest] invalid content type", module);
             response.sendError(HttpServletResponse.SC_CONFLICT);
             return;
         }
-        setupRequest(request, response);
         String workEffortId = (String) request.getAttribute("workEffortId");
-        if (workEffortId == null) {
-            Debug.logInfo("[handlePutRequest] workEffortId missing", module);
-            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
-            return;
-        }
         Debug.logInfo("[handlePutRequest] workEffortId = " + workEffortId, module);
         ResponseProperties responseProps = null;
         try {
@@ -231,37 +219,50 @@
             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
             return;
         }
-        writeResponse(responseProps, response, context);
+        writeResponse(responseProps, request, response, context);
     }
 
-    protected static void logInUser(HttpServletRequest request, HttpServletResponse response) throws GenericServiceException, GenericEntityException {
-        GenericValue userLogin = null;
-        String username = request.getParameter("USERNAME");
-        String password = request.getParameter("PASSWORD");
-        if (UtilValidate.isEmpty(username) || UtilValidate.isEmpty(password)) {
-            return;
+    protected static boolean isValidRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        if (!request.isSecure()) {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return false;
         }
-        if ("true".equalsIgnoreCase(UtilProperties.getPropertyValue("security.properties", "username.lowercase"))) {
-            username = username.toLowerCase();
+        setupRequest(request, response);
+        String workEffortId = (String) request.getAttribute("workEffortId");
+        if (workEffortId == null) {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return false;
         }
-        if ("true".equalsIgnoreCase(UtilProperties.getPropertyValue("security.properties", "password.lowercase"))) {
-            password = password.toLowerCase();
+        return true;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected static void logInUser(HttpServletRequest request, HttpServletResponse response) throws GenericServiceException, GenericEntityException {
+        Map<String, Object> serviceMap = (Map<String, Object>) WebDavUtil.getCredentialsFromRequest(request);
+        if (serviceMap == null) {
+            return;
         }
+        serviceMap.put("locale", UtilHttp.getLocale(request));
+        GenericValue userLogin = null;
         HttpSession session = request.getSession();
         LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
-        Map<String, Object> result = dispatcher.runSync("userLogin", UtilMisc.toMap("login.username", username, "login.password", password, "locale", UtilHttp.getLocale(request)));
-        if (ModelService.RESPOND_SUCCESS.equals(result.get(ModelService.RESPONSE_MESSAGE))) {
-            userLogin = (GenericValue) result.get("userLogin");
-            request.setAttribute("userLogin", userLogin);
-            session.setAttribute("userLogin", userLogin);
-            VisitHandler.getVisitor(request, response);
-        } else {
+        Map<String, Object> result = dispatcher.runSync("userLogin", serviceMap);
+        if (ServiceUtil.isError(result) || ServiceUtil.isFailure(result)) {
             return;
         }
+        userLogin = (GenericValue) result.get("userLogin");
+        request.setAttribute("userLogin", userLogin);
+        session.setAttribute("userLogin", userLogin);
+        VisitHandler.getVisitor(request, response);
         GenericValue person = userLogin.getRelatedOne("Person");
-        GenericValue partyGroup = userLogin.getRelatedOne("PartyGroup");
-        if (person != null) request.setAttribute("person", person);
-        if (partyGroup != null) request.setAttribute("partyGroup", partyGroup);
+        if (person != null) {
+            request.setAttribute("person", person);
+        } else {
+            GenericValue partyGroup = userLogin.getRelatedOne("PartyGroup");
+            if (partyGroup != null) {
+                request.setAttribute("partyGroup", partyGroup);
+            }
+        }
     }
 
     protected static void setupRequest(HttpServletRequest request, HttpServletResponse response) {
@@ -284,12 +285,15 @@
         }
     }
 
-    protected static void writeResponse(ResponseProperties responseProps, HttpServletResponse response, ServletContext context) throws IOException {
+    protected static void writeResponse(ResponseProperties responseProps, HttpServletRequest request, HttpServletResponse response, ServletContext context) throws IOException {
         if (Debug.verboseOn()) {
             Debug.logVerbose("Returning response: code = " + responseProps.statusCode +
                     ", message = " + responseProps.statusMessage, module);
         }
         response.setStatus(responseProps.statusCode);
+        if (responseProps.statusCode == HttpServletResponse.SC_UNAUTHORIZED) {
+            response.setHeader("WWW-Authenticate", "Basic realm=\"OFBiz iCalendar " + request.getAttribute("workEffortId") + "\"");
+        }
         if (responseProps.statusMessage != null) {
             Writer writer = getWriter(response, context);
             try {

Modified: ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/webdav/WebDavUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/webdav/WebDavUtil.java?rev=789490&r1=789489&r2=789490&view=diff
==============================================================================
--- ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/webdav/WebDavUtil.java (original)
+++ ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/webdav/WebDavUtil.java Mon Jun 29 23:28:37 2009
@@ -23,11 +23,18 @@
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.Map;
 import java.util.TimeZone;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.xml.parsers.ParserConfigurationException;
 
+import javolution.util.FastMap;
+
+import org.ofbiz.base.util.Base64;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.UtilXml;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
@@ -35,6 +42,7 @@
 /** Utility methods needed to implement a WebDAV servlet. */
 public class WebDavUtil {
 
+    public static final String module = WebDavUtil.class.getName();
     public static final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT");
     public static final String RFC1123_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz";
 
@@ -51,4 +59,44 @@
         return document;
     }
 
+    /** Returns a <code>Map</code> containing user credentials found in the request. Returns
+     * <code>null</code> if no user credentials were found. The returned <code>Map</code> is
+     * intended to be used as parameters for the <code>userLogin</code> service. <p>The method
+     * checks for the request parameters <code>USERNAME</code> and <code>PASSWORD</code>. If
+     * those aren't found, then the request is checked for the HTTP Authorization header.
+     * Currently, only Basic authorization is supported.</p>
+     * 
+     * @param request
+     * @return A <code>Map</code> containing <code>login.username</code> and 
+     * <code>login.password</code> elements.
+     */
+    public static Map<String, Object> getCredentialsFromRequest(HttpServletRequest request) {
+        String username = request.getParameter("USERNAME");
+        String password = request.getParameter("PASSWORD");
+        if (UtilValidate.isEmpty(username) || UtilValidate.isEmpty(password)) {
+            String credentials = request.getHeader("Authorization");
+            if (credentials != null && credentials.startsWith("Basic ")) {
+                credentials = Base64.base64Decode(credentials.replace("Basic ", ""));
+                Debug.logVerbose("Found HTTP Basic credentials", module);
+                String[] parts = credentials.split(":");
+                if (parts.length < 2) {
+                    return null;
+                }
+                username = parts[0];
+                password = parts[1];
+            } else {
+                return null;
+            }
+        }
+        if ("true".equalsIgnoreCase(UtilProperties.getPropertyValue("security.properties", "username.lowercase"))) {
+            username = username.toLowerCase();
+        }
+        if ("true".equalsIgnoreCase(UtilProperties.getPropertyValue("security.properties", "password.lowercase"))) {
+            password = password.toLowerCase();
+        }
+        Map<String, Object> result = FastMap.newInstance();
+        result.put("login.username", username);
+        result.put("login.password", password);
+        return result;        
+    }
 }