You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2012/08/22 17:25:36 UTC

svn commit: r1376099 [1/2] - in /chemistry/opencmis/trunk: chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/ chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/o...

Author: fmui
Date: Wed Aug 22 15:25:35 2012
New Revision: 1376099

URL: http://svn.apache.org/viewvc?rev=1376099&view=rev
Log:
Added Browser Binding token support

Added:
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/AbstractSimpleTokenHandler.java   (with props)
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandler.java   (with props)
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandlerSessionHelper.java   (with props)
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenCallContextHandler.java   (with props)
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenHandler.java   (with props)
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/package.html   (with props)
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/cmis.js.jsp   (with props)
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/login.jsp   (with props)
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/repository.jsp   (with props)
Removed:
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/web/createdocument.html
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/web/createfolder.html
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/web/demo.html
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/web/opencmis.js
Modified:
    chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Constants.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/BrowserBindingUtils.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/CmisBrowserBindingServlet.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ObjectService.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/shared/HttpUtils.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/web.xml
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/web/index.html

Modified: chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Constants.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Constants.java?rev=1376099&r1=1376098&r2=1376099&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Constants.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Constants.java Wed Aug 22 15:25:35 2012
@@ -166,6 +166,7 @@ public final class Constants {
     public static final String PARAM_CHILD_TYPES = "childTypes";
     public static final String PARAM_CONTINUE_ON_FAILURE = "continueOnFailure";
     public static final String PARAM_DEPTH = "depth";
+    public static final String PARAM_DOWNLOAD = "download";
     public static final String PARAM_FILTER = "filter";
     public static final String PARAM_SUCCINCT = "succinct";
     public static final String PARAM_FOLDER_ID = "folderId";

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/BrowserBindingUtils.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/BrowserBindingUtils.java?rev=1376099&r1=1376098&r2=1376099&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/BrowserBindingUtils.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/BrowserBindingUtils.java Wed Aug 22 15:25:35 2012
@@ -480,7 +480,10 @@ public class BrowserBindingUtils {
             throws IOException {
         String token = getStringParameter(request, Constants.PARAM_TOKEN);
 
-        if (token == null) {
+        if (token != null && "POST".equals(request.getMethod())) {
+            response.setContentType(HTML_MIME_TYPE);
+            response.setContentLength(0);
+        } else {
             response.setContentType(JSON_MIME_TYPE);
             response.setCharacterEncoding("UTF-8");
 
@@ -497,9 +500,6 @@ public class BrowserBindingUtils {
             if (callback != null) {
                 response.getWriter().print(");");
             }
-        } else {
-            response.setContentType(HTML_MIME_TYPE);
-            response.setContentLength(0);
         }
 
         response.getWriter().flush();

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/CmisBrowserBindingServlet.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/CmisBrowserBindingServlet.java?rev=1376099&r1=1376098&r2=1376099&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/CmisBrowserBindingServlet.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/CmisBrowserBindingServlet.java Wed Aug 22 15:25:35 2012
@@ -109,6 +109,7 @@ import org.apache.chemistry.opencmis.com
 import org.apache.chemistry.opencmis.server.impl.CmisRepositoryContextListener;
 import org.apache.chemistry.opencmis.server.impl.ServerVersion;
 import org.apache.chemistry.opencmis.server.impl.browser.BrowserBindingUtils.CallUrl;
+import org.apache.chemistry.opencmis.server.impl.browser.token.TokenHandler;
 import org.apache.chemistry.opencmis.server.shared.CallContextHandler;
 import org.apache.chemistry.opencmis.server.shared.Dispatcher;
 import org.apache.chemistry.opencmis.server.shared.ExceptionHelper;
@@ -246,6 +247,22 @@ public class CmisBrowserBindingServlet e
         // create a context object, dispatch and handle exceptions
         CallContext context = null;
         try {
+            String method = request.getMethod();
+
+            if (METHOD_GET.equals(method)) {
+                request = new QueryStringHttpServletRequestWrapper(request);
+            } else if (METHOD_POST.equals(method)) {
+                request = new POSTHttpServletRequestWrapper(request, tempDir, memoryThreshold, maxContentSize);
+            } else {
+                throw new CmisNotSupportedException("Unsupported method");
+            }
+
+            // invoke token handler, if necessary
+            if (request.getParameter("login") != null && callContextHandler instanceof TokenHandler) {
+                ((TokenHandler) callContextHandler).service(getServletContext(), request, response);
+                return;
+            }
+
             context = HttpUtils.createContext(request, response, getServletContext(), CallContext.BINDING_BROWSER,
                     callContextHandler, tempDir, memoryThreshold, maxContentSize);
             dispatch(context, request, response);
@@ -310,13 +327,11 @@ public class CmisBrowserBindingServlet e
             boolean methodFound = false;
 
             if (METHOD_GET.equals(method)) {
-                QueryStringHttpServletRequestWrapper getRequest = new QueryStringHttpServletRequestWrapper(request);
-
-                String selector = getStringParameter(getRequest, Constants.PARAM_SELECTOR);
-                String objectId = getStringParameter(getRequest, PARAM_OBJECT_ID);
+                String selector = getStringParameter(request, Constants.PARAM_SELECTOR);
+                String objectId = getStringParameter(request, PARAM_OBJECT_ID);
 
                 // add object id and object base type id to context
-                prepareContext(context, callUrl, service, repositoryId, objectId, null, getRequest);
+                prepareContext(context, callUrl, service, repositoryId, objectId, null, request);
 
                 // dispatch
                 if (callUrl == CallUrl.REPOSITORY) {
@@ -325,7 +340,7 @@ public class CmisBrowserBindingServlet e
                     }
 
                     methodFound = repositoryDispatcher.dispatch(selector, method, context, service, repositoryId,
-                            getRequest, response);
+                            request, response);
                 } else if (callUrl == CallUrl.ROOT) {
                     // set default method if necessary
                     if (selector == null) {
@@ -347,31 +362,28 @@ public class CmisBrowserBindingServlet e
                         }
                     }
 
-                    methodFound = rootDispatcher.dispatch(selector, method, context, service, repositoryId, getRequest,
+                    methodFound = rootDispatcher.dispatch(selector, method, context, service, repositoryId, request,
                             response);
                 }
             } else if (METHOD_POST.equals(method)) {
-                POSTHttpServletRequestWrapper postRequest = new POSTHttpServletRequestWrapper(request, tempDir,
-                        memoryThreshold, maxContentSize);
-
-                String cmisaction = getStringParameter(postRequest, Constants.CONTROL_CMISACTION);
-                String objectId = getStringParameter(postRequest, Constants.CONTROL_OBJECT_ID);
-                String token = getStringParameter(postRequest, Constants.CONTROL_TOKEN);
+                String cmisaction = getStringParameter(request, Constants.CONTROL_CMISACTION);
+                String objectId = getStringParameter(request, Constants.CONTROL_OBJECT_ID);
+                String token = getStringParameter(request, Constants.CONTROL_TOKEN);
 
                 if (cmisaction == null || cmisaction.length() == 0) {
                     throw new CmisNotSupportedException("Unknown action");
                 }
 
                 // add object id and object base type id to context
-                prepareContext(context, callUrl, service, repositoryId, objectId, token, postRequest);
+                prepareContext(context, callUrl, service, repositoryId, objectId, token, request);
 
                 // dispatch
                 if (callUrl == CallUrl.REPOSITORY) {
                     methodFound = repositoryDispatcher.dispatch(cmisaction, method, context, service, repositoryId,
-                            postRequest, response);
+                            request, response);
                 } else if (callUrl == CallUrl.ROOT) {
-                    methodFound = rootDispatcher.dispatch(cmisaction, method, context, service, repositoryId,
-                            postRequest, response);
+                    methodFound = rootDispatcher.dispatch(cmisaction, method, context, service, repositoryId, request,
+                            response);
                 }
             }
 

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ObjectService.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ObjectService.java?rev=1376099&r1=1376098&r2=1376099&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ObjectService.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/ObjectService.java Wed Aug 22 15:25:35 2012
@@ -21,6 +21,7 @@ package org.apache.chemistry.opencmis.se
 import static org.apache.chemistry.opencmis.commons.impl.Constants.MEDIATYPE_OCTETSTREAM;
 import static org.apache.chemistry.opencmis.commons.impl.Constants.PARAM_ACL;
 import static org.apache.chemistry.opencmis.commons.impl.Constants.PARAM_ALLOWABLE_ACTIONS;
+import static org.apache.chemistry.opencmis.commons.impl.Constants.PARAM_DOWNLOAD;
 import static org.apache.chemistry.opencmis.commons.impl.Constants.PARAM_FILTER;
 import static org.apache.chemistry.opencmis.commons.impl.Constants.PARAM_POLICY_IDS;
 import static org.apache.chemistry.opencmis.commons.impl.Constants.PARAM_RELATIONSHIPS;
@@ -432,6 +433,7 @@ public final class ObjectService {
         // get parameters
         String objectId = (String) context.get(CONTEXT_OBJECT_ID);
         String streamId = getStringParameter(request, PARAM_STREAM_ID);
+        boolean download = getBooleanParameter(request, PARAM_DOWNLOAD, false);
 
         BigInteger offset = context.getOffset();
         BigInteger length = context.getLength();
@@ -455,9 +457,18 @@ public final class ObjectService {
             setStatus(request, response, HttpServletResponse.SC_PARTIAL_CONTENT);
         }
         response.setContentType(contentType);
-        if (content.getFileName() != null) {
+
+        String contentFilename = content.getFileName();
+        if (contentFilename == null) {
+            contentFilename = "content";
+        }
+
+        if (download) {
+            response.setHeader(MimeHelper.CONTENT_DISPOSITION,
+                    MimeHelper.encodeContentDisposition(MimeHelper.DISPOSITION_ATTACHMENT, contentFilename));
+        } else {
             response.setHeader(MimeHelper.CONTENT_DISPOSITION,
-                    MimeHelper.encodeContentDisposition(MimeHelper.DISPOSITION_INLINE, content.getFileName()));
+                    MimeHelper.encodeContentDisposition(MimeHelper.DISPOSITION_INLINE, contentFilename));
         }
 
         // send content

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/AbstractSimpleTokenHandler.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/AbstractSimpleTokenHandler.java?rev=1376099&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/AbstractSimpleTokenHandler.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/AbstractSimpleTokenHandler.java Wed Aug 22 15:25:35 2012
@@ -0,0 +1,396 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser.token;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.net.URL;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
+import org.apache.chemistry.opencmis.commons.impl.json.JSONArray;
+import org.apache.chemistry.opencmis.commons.impl.json.JSONObject;
+import org.apache.chemistry.opencmis.commons.impl.json.JSONStreamAware;
+import org.apache.chemistry.opencmis.commons.server.CmisServiceFactory;
+import org.apache.chemistry.opencmis.server.impl.CmisRepositoryContextListener;
+import org.apache.chemistry.opencmis.server.impl.browser.BrowserBindingUtils;
+
+public abstract class AbstractSimpleTokenHandler implements TokenHandler, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    // return 10 tokens per batch
+    private static final int TOKEN_BATCH_SIZE = 10;
+
+    private static final String ATTR_PREFIX = "org.apache.chemistry.opencmis.";
+
+    private static final String JSP_PATH = "/WEB-INF/token/";
+    private static final String JSP_SCRIPT = "cmis.js.jsp";
+    private static final String JSP_IFRAME = "repository.jsp";
+    private static final String JSP_LOGIN = "login.jsp";
+
+    private static final String PARAM_LOGIN = "login";
+
+    private static final String LOGIN_SCRIPT = "script";
+    private static final String LOGIN_CONTROLLER = "controller";
+    private static final String LOGIN_LOGIN = "login";
+    private static final String LOGIN_LOGOUT = "logout";
+    private static final String LOGIN_TOKEN = "token";
+
+    public void service(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response) {
+
+        String login = request.getParameter(PARAM_LOGIN);
+        try {
+            if (LOGIN_TOKEN.equals(login)) {
+                sendTokens(servletContext, request, response);
+            } else if (LOGIN_SCRIPT.equals(login)) {
+                sendJavaScript(servletContext, request, response);
+            } else if (LOGIN_CONTROLLER.equals(login)) {
+                sendControllerContent(servletContext, request, response);
+            } else if (LOGIN_LOGIN.equals(login)) {
+                login(servletContext, request, response);
+            } else if (LOGIN_LOGOUT.equals(login)) {
+                logout(servletContext, request, response);
+            } else {
+                throw new CmisObjectNotFoundException();
+            }
+        } catch (Exception e) {
+            if (e instanceof CmisBaseException) {
+                throw (CmisBaseException) e;
+            } else {
+                throw new CmisRuntimeException("Internal Error!", e);
+            }
+        }
+    }
+
+    /**
+     * Sends a batch of new tokens.
+     */
+    protected void sendTokens(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response)
+            throws IOException {
+        JSONArray result = new JSONArray();
+
+        if (!SimpleTokenHandlerSessionHelper.checkApplicationKey(request)) {
+            // PARANOIA: remove the application key if the presented key is
+            // wrong, don't allow a second attempt
+            String appId = SimpleTokenHandlerSessionHelper.getApplicationIdFromKey(SimpleTokenHandlerSessionHelper
+                    .getKey(request));
+            if (appId != null) {
+                SimpleTokenHandlerSessionHelper.removeApplicationKey(request, appId);
+            }
+        } else {
+            // generate a batch of tokens
+            String appId = SimpleTokenHandlerSessionHelper.getApplicationIdFromKey(SimpleTokenHandlerSessionHelper
+                    .getKey(request));
+
+            for (int i = 0; i < TOKEN_BATCH_SIZE; i++) {
+                // create token
+                String token = SimpleTokenHandlerSessionHelper.generateKey(appId);
+
+                // put token into session and it to the response
+                SimpleTokenHandlerSessionHelper.addToken(request, token);
+                result.add(token);
+            }
+        }
+
+        printJSON(response, result);
+    }
+
+    /**
+     * Sends the JavaScript file for web clients.
+     */
+    protected void sendJavaScript(ServletContext servletContext, HttpServletRequest request,
+            HttpServletResponse response) throws IOException {
+
+        UrlBuilder baseUrl = BrowserBindingUtils.compileBaseUrl(request);
+        URL url = new URL(baseUrl.toString());
+
+        request.setAttribute(ATTR_PREFIX + "domain", encodeJavaScriptString(url.getProtocol() + "://" + url.getHost()
+                + (url.getPort() > -1 ? ":" + url.getPort() : "")));
+        request.setAttribute(ATTR_PREFIX + "serviceUrl", encodeJavaScriptString(baseUrl.toString()));
+        request.setAttribute(ATTR_PREFIX + "iframeUrl",
+                encodeJavaScriptString(baseUrl.addParameter(PARAM_LOGIN, LOGIN_CONTROLLER).toString()));
+
+        response.setContentType("application/json; charset=UTF-8");
+
+        RequestDispatcher dispatcher = servletContext.getRequestDispatcher(JSP_PATH + JSP_SCRIPT);
+        try {
+            dispatcher.include(request, response);
+        } catch (Exception e) {
+            throw new CmisRuntimeException("Internal error!", e);
+        }
+    }
+
+    /**
+     * Sends the IFrame content.
+     */
+    protected void sendControllerContent(ServletContext servletContext, HttpServletRequest request,
+            HttpServletResponse response) throws IOException {
+
+        response.setContentType("text/html; charset=UTF-8");
+
+        request.setAttribute(ATTR_PREFIX + "loginUrl",
+                encodeJavaScriptString(BrowserBindingUtils.compileBaseUrl(request).addParameter(PARAM_LOGIN, "")
+                        .toString()));
+
+        RequestDispatcher dispatcher = servletContext.getRequestDispatcher(JSP_PATH + JSP_IFRAME);
+        try {
+            dispatcher.include(request, response);
+        } catch (Exception e) {
+            throw new CmisRuntimeException("Internal error!", e);
+        }
+    }
+
+    /**
+     * Handles logins.
+     */
+    protected void login(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response)
+            throws IOException {
+        if ("GET".equals(request.getMethod())) {
+            showLoginForm(servletContext, request, response, null);
+        } else if ("POST".equals(request.getMethod())) {
+            authenticate(servletContext, request, response);
+        } else {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+        }
+    }
+
+    protected void showLoginForm(ServletContext servletContext, HttpServletRequest request,
+            HttpServletResponse response, String errorMessage) throws IOException {
+
+        String formKey = SimpleTokenHandlerSessionHelper.getKey(request);
+        String appId = SimpleTokenHandlerSessionHelper.getApplicationIdFromKey(formKey);
+        URL appUrl = SimpleTokenHandlerSessionHelper.getApplicationURL(request, appId);
+
+        request.setAttribute(ATTR_PREFIX + "formkey", formKey);
+        request.setAttribute(ATTR_PREFIX + "error", errorMessage);
+        request.setAttribute(ATTR_PREFIX + "appurl", encodeHTMLString(appUrl.toString()));
+
+        response.setContentType("text/html; charset=UTF-8");
+
+        RequestDispatcher dispatcher = servletContext.getRequestDispatcher(JSP_PATH + JSP_LOGIN);
+        try {
+            dispatcher.include(request, response);
+        } catch (Exception e) {
+            throw new CmisRuntimeException("Internal error!", e);
+        }
+    }
+
+    protected void authenticate(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response)
+            throws IOException {
+        if (SimpleTokenHandlerSessionHelper.checkFormKey(request)) {
+            // login form returns
+
+            String trustapp = request.getParameter(SimpleTokenHandlerSessionHelper.PARAM_TRUSTAPP);
+            String user = request.getParameter(SimpleTokenHandlerSessionHelper.PARAM_USER);
+            String password = request.getParameter(SimpleTokenHandlerSessionHelper.PARAM_PASSWORD);
+
+            if (!"1".equals(trustapp)) {
+                String error = "Please confirm that you trust the application!";
+                showLoginForm(servletContext, request, response, error);
+                return;
+            }
+
+            if (!authenticate(servletContext, request, response, user, password)) {
+                String error = "Invalid credentials!";
+                showLoginForm(servletContext, request, response, error);
+                return;
+            }
+
+            // authentication successful -> create application key and
+            // forward to application
+            String appId = SimpleTokenHandlerSessionHelper.getApplicationIdFromKey(SimpleTokenHandlerSessionHelper
+                    .getKey(request));
+            String appKey = SimpleTokenHandlerSessionHelper.generateKey(appId);
+            SimpleTokenHandlerSessionHelper.setApplicationKey(request, appKey);
+            SimpleTokenHandlerSessionHelper.setUser(request, appId, user);
+            SimpleTokenHandlerSessionHelper.removeFormKey(request, appId);
+
+            URL appURL = SimpleTokenHandlerSessionHelper.getApplicationURL(request, appId);
+
+            response.sendRedirect(response.encodeRedirectURL(appURL.toString()));
+
+            return;
+        }
+
+        // check URL
+        String url = request.getParameter(SimpleTokenHandlerSessionHelper.PARAM_URL);
+
+        if (url == null || url.trim().length() < 8 || !url.toLowerCase().startsWith("http")) {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return;
+        }
+
+        URL appURL = null;
+        try {
+            appURL = new URL(url);
+        } catch (Exception e) {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return;
+        }
+
+        // check login key
+        String loginKey = request.getParameter(SimpleTokenHandlerSessionHelper.PARAM_KEY);
+
+        if (loginKey == null || loginKey.trim().length() == 0) {
+            // no login key set -> generate one and return it
+
+            String appId = SimpleTokenHandlerSessionHelper.generateAppId();
+            loginKey = SimpleTokenHandlerSessionHelper.generateKey(appId);
+            String formKey = SimpleTokenHandlerSessionHelper.generateKey(appId);
+
+            SimpleTokenHandlerSessionHelper.setLoginKey(request, loginKey, formKey, appURL);
+
+            String formURL = encodeJavaScriptString(BrowserBindingUtils.compileBaseUrl(request)
+                    .addParameter(PARAM_LOGIN, LOGIN_LOGIN)
+                    .addParameter(SimpleTokenHandlerSessionHelper.PARAM_KEY, formKey).toString());
+
+            JSONObject result = new JSONObject();
+            result.put("ok", 0);
+            result.put("key", loginKey);
+            result.put("url", formURL);
+
+            printJSON(response, result);
+
+            return;
+        }
+
+        String appId = SimpleTokenHandlerSessionHelper.getApplicationIdFromKey(SimpleTokenHandlerSessionHelper
+                .getKey(request));
+        String appKey = SimpleTokenHandlerSessionHelper.getApplicationKey(request, appId);
+
+        // check if login key fits
+        if (appKey == null || !SimpleTokenHandlerSessionHelper.checkLoginKey(request)) {
+            // PARANOIA: remove keys, don't allow a second attempt
+            SimpleTokenHandlerSessionHelper.removeLoginKey(request, appId);
+            SimpleTokenHandlerSessionHelper.removeApplicationKey(request, appId);
+            response.sendError(400);
+            return;
+        }
+
+        // remove login key - it should not be reused
+        SimpleTokenHandlerSessionHelper.removeLoginKey(request, appId);
+
+        // return application key
+        JSONObject result = new JSONObject();
+        result.put("ok", 1);
+        result.put("key", appKey);
+
+        printJSON(response, result);
+    }
+
+    protected abstract boolean authenticate(final ServletContext servletContext, final HttpServletRequest request,
+            final HttpServletResponse response, String user, String password);
+
+    /**
+     * Handles logouts.
+     */
+    protected void logout(final ServletContext servletContext, final HttpServletRequest request,
+            final HttpServletResponse response) throws IOException {
+        String appId = SimpleTokenHandlerSessionHelper.getApplicationIdFromKey(SimpleTokenHandlerSessionHelper
+                .getKey(request));
+        if (appId != null) {
+            SimpleTokenHandlerSessionHelper.removeApplicationKey(request, appId);
+        }
+
+        JSONObject result = new JSONObject();
+        result.put("ok", 1);
+
+        printJSON(response, result);
+    }
+
+    protected CmisServiceFactory getCmisServiceFactory(final ServletContext servletContext) {
+        CmisServiceFactory factory = (CmisServiceFactory) servletContext
+                .getAttribute(CmisRepositoryContextListener.SERVICES_FACTORY);
+
+        if (factory == null) {
+            throw new CmisRuntimeException("Service factory not available! Configuration problem?");
+        }
+
+        return factory;
+    }
+
+    protected void printJSON(final HttpServletResponse response, final JSONStreamAware json) throws IOException {
+        response.setStatus(HttpServletResponse.SC_OK);
+        response.setContentType("application/json; charset=utf-8");
+        response.addHeader("Cache-Control", "private, max-age=0");
+
+        PrintWriter pw = response.getWriter();
+        json.writeJSONString(pw);
+        pw.flush();
+    }
+
+    protected String encodeJavaScriptString(final String s) {
+        if (s == null) {
+            return null;
+        }
+
+        StringBuilder sb = new StringBuilder();
+
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            if (c == '\'') {
+                sb.append("\\'");
+            } else {
+                sb.append(c);
+            }
+        }
+
+        return sb.toString();
+    }
+
+    protected String encodeHTMLString(final String s) {
+        if (s == null) {
+            return null;
+        }
+
+        StringBuilder sb = new StringBuilder();
+
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+
+            if (c == '\t' || c == '\n' || c == '\r' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+                    || (c >= '0' && c <= '9') || c == ' ' || c == '.' || c == ',' || c == '-' || c == '_') {
+                sb.append(c);
+            } else if (c <= 0x1f || (c >= 0x7f && c <= 0x9f)) {
+                sb.append(' ');
+            } else if (c == '&') {
+                sb.append("&amp;");
+            } else if (c == '"') {
+                sb.append("&quot;");
+            } else if (c == '<') {
+                sb.append("&lt;");
+            } else if (c == '>') {
+                sb.append("&gt;");
+            } else {
+                sb.append("&#x" + Integer.toHexString(c) + ";");
+            }
+        }
+
+        return sb.toString();
+    }
+}

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/AbstractSimpleTokenHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandler.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandler.java?rev=1376099&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandler.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandler.java Wed Aug 22 15:25:35 2012
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser.token;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
+import org.apache.chemistry.opencmis.commons.server.CmisServiceFactory;
+import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
+
+public class SimpleTokenHandler extends AbstractSimpleTokenHandler {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    protected boolean authenticate(final ServletContext servletContext, final HttpServletRequest request,
+            final HttpServletResponse response, final String user, final String password) {
+
+        // get the service factory
+        CmisServiceFactory factory = getCmisServiceFactory(servletContext);
+
+        // build a call context
+        CallContextImpl context = new CallContextImpl(CallContext.BINDING_BROWSER, null, false);
+        context.put(CallContext.USERNAME, user);
+        context.put(CallContext.PASSWORD, password);
+
+        // call getRepositoryInfos() method
+        CmisService service = null;
+        try {
+            // get the service
+            service = factory.getService(context);
+
+            try {
+                service.getRepositoryInfos(null);
+            } catch (Exception e) {
+                // we interpret all exceptions as a login failure
+                return false;
+            }
+        } finally {
+            if (service != null) {
+                service.close();
+            }
+        }
+
+        return true;
+    }
+}

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandlerSessionHelper.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandlerSessionHelper.java?rev=1376099&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandlerSessionHelper.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandlerSessionHelper.java Wed Aug 22 15:25:35 2012
@@ -0,0 +1,326 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser.token;
+
+import java.net.URL;
+import java.security.SecureRandom;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+public class SimpleTokenHandlerSessionHelper {
+
+    public static final String ATTR_CMIS_USER = "cmis-token.user";
+    public static final String ATTR_CMIS_AUTH_TIMESTAMP = "cmis-token.timestamp";
+    public static final String ATTR_CMIS_TOKEN = "cmis-token.token";
+    public static final String ATTR_CMIS_LOGIN_KEY = "cmis-token.token.loginkey";
+    public static final String ATTR_CMIS_FORM_KEY = "cmis-token.formkey";
+    public static final String ATTR_CMIS_APP_URL = "cmis-token.appurl";
+    public static final String ATTR_CMIS_APP_KEY = "cmis-token.appkey";
+
+    public static final String ATTR_SEPARATOR = "\n";
+
+    public static final String PARAM_KEY = "key";
+    public static final String PARAM_TOKEN = "token";
+    public static final String PARAM_URL = "url";
+    public static final String PARAM_USER = "user";
+    public static final String PARAM_PASSWORD = "password";
+    public static final String PARAM_TRUSTAPP = "trustapp";
+
+    public static final int APP_ID_BYTES = 10;
+    public static final int APP_ID_LENGTH = APP_ID_BYTES * 2;
+    public static final int KEY_BYTES = 20;
+    public static final int KEY_LENGTH = KEY_BYTES * 2;
+
+    public static String getApplicationIdFromKey(String key) {
+        if (key == null || key.length() != APP_ID_LENGTH + KEY_LENGTH) {
+            return null;
+        }
+
+        return key.substring(0, APP_ID_LENGTH);
+    }
+
+    public static String getLoginKey(HttpServletRequest request, String appId) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return null;
+        }
+
+        return (String) hs.getAttribute(ATTR_CMIS_LOGIN_KEY + appId);
+    }
+
+    public static void setLoginKey(HttpServletRequest request, String loginKey, String formKey, URL appURL) {
+        HttpSession hs = request.getSession();
+
+        String appId = getApplicationIdFromKey(loginKey);
+
+        hs.setAttribute(ATTR_CMIS_LOGIN_KEY + appId, loginKey);
+        hs.setAttribute(ATTR_CMIS_FORM_KEY + appId, formKey);
+        hs.setAttribute(ATTR_CMIS_APP_URL + appId, appURL);
+    }
+
+    public static boolean checkLoginKey(HttpServletRequest request) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return false;
+        }
+
+        String key = getKey(request);
+
+        if (key == null) {
+            return false;
+        }
+
+        String appId = getApplicationIdFromKey(key);
+        if (appId == null) {
+            return false;
+        }
+
+        return key.equals(hs.getAttribute(ATTR_CMIS_LOGIN_KEY + appId));
+    }
+
+    public static void removeLoginKey(HttpServletRequest request, String appId) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return;
+        }
+
+        hs.removeAttribute(ATTR_CMIS_LOGIN_KEY + appId);
+    }
+
+    public static boolean checkFormKey(HttpServletRequest request) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return false;
+        }
+
+        String formKey = getKey(request);
+
+        if (formKey == null) {
+            return false;
+        }
+
+        String appId = getApplicationIdFromKey(formKey);
+        if (appId == null) {
+            return false;
+        }
+
+        return formKey.equals(hs.getAttribute(ATTR_CMIS_FORM_KEY + appId));
+    }
+
+    public static void removeFormKey(HttpServletRequest request, String appId) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return;
+        }
+
+        hs.removeAttribute(ATTR_CMIS_FORM_KEY + appId);
+    }
+
+    public static String getUser(HttpServletRequest request, String appId) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return null;
+        }
+
+        return (String) hs.getAttribute(ATTR_CMIS_USER + appId);
+    }
+
+    public static void setUser(HttpServletRequest request, String appId, String user) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return;
+        }
+
+        hs.setAttribute(ATTR_CMIS_USER + appId, user);
+        hs.setAttribute(ATTR_CMIS_AUTH_TIMESTAMP + appId, System.currentTimeMillis());
+    }
+
+    public static String getApplicationKey(HttpServletRequest request, String appId) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return null;
+        }
+
+        return (String) hs.getAttribute(ATTR_CMIS_APP_KEY + appId);
+    }
+
+    public static void setApplicationKey(HttpServletRequest request, String key) {
+        HttpSession hs = request.getSession();
+
+        String appId = getApplicationIdFromKey(key);
+
+        hs.setAttribute(ATTR_CMIS_APP_KEY + appId, key);
+    }
+
+    public static boolean checkApplicationKey(HttpServletRequest request) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return false;
+        }
+
+        String key = getKey(request);
+
+        if (key == null) {
+            return false;
+        }
+
+        String appId = getApplicationIdFromKey(key);
+        if (appId == null) {
+            return false;
+        }
+
+        return key.equals(hs.getAttribute(ATTR_CMIS_APP_KEY + appId));
+    }
+
+    public static void removeApplicationKey(HttpServletRequest request, String appId) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return;
+        }
+
+        hs.removeAttribute(ATTR_CMIS_APP_KEY + appId);
+        hs.removeAttribute(ATTR_CMIS_APP_URL + appId);
+        hs.removeAttribute(ATTR_CMIS_USER + appId);
+        hs.removeAttribute(ATTR_CMIS_AUTH_TIMESTAMP + appId);
+    }
+
+    public static URL getApplicationURL(HttpServletRequest request, String appId) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return null;
+        }
+
+        return (URL) hs.getAttribute(ATTR_CMIS_APP_URL + appId);
+    }
+
+    /**
+     * Retrieves the token from the requests and tests if this token belongs to
+     * the current session. If the token is associated with the session, the
+     * token will be removed from the session and cannot be reused again.
+     * 
+     * @return <code>true</code> if the request contains a token and this token
+     *         belongs to the session, <code>false</code> otherwise
+     */
+    public static boolean testAndInvalidateToken(HttpServletRequest request) {
+        HttpSession hs = request.getSession(false);
+        if (hs == null) {
+            return false;
+        }
+
+        String token = getToken(request);
+
+        if (token == null) {
+            return false;
+        }
+
+        String tokenKey = ATTR_CMIS_TOKEN + token;
+
+        Long tokenCreationTimestamp = (Long) hs.getAttribute(tokenKey);
+        if (tokenCreationTimestamp != null) {
+            // if the token exists, remove it
+            hs.removeAttribute(tokenKey);
+
+            // PARANOIA: don't accept tokens that are older than 8 hours
+            return System.currentTimeMillis() - tokenCreationTimestamp < 8 * 60 * 60 * 1000;
+        }
+
+        return false;
+    }
+
+    /**
+     * Adds a token to the session.
+     */
+    public static void addToken(HttpServletRequest request, String token) {
+        HttpSession hs = request.getSession();
+
+        String tokenKey = ATTR_CMIS_TOKEN + token;
+
+        // set the token and retain creation timestamp
+        hs.setAttribute(tokenKey, System.currentTimeMillis());
+    }
+
+    /**
+     * Gets the key parameter from the request and checks its validity.
+     */
+    public static String getKey(HttpServletRequest request) {
+        String key = request.getParameter(PARAM_KEY);
+        return normalizeKey(key);
+    }
+
+    /**
+     * Gets the domain parameter from the request and checks its validity.
+     */
+    public static String getToken(HttpServletRequest request) {
+        String token = request.getParameter(PARAM_TOKEN);
+        return normalizeKey(token);
+    }
+
+    public static String normalizeKey(String key) {
+        if (key == null) {
+            return null;
+        }
+
+        key = key.trim();
+
+        if (key.length() != APP_ID_LENGTH + KEY_LENGTH || !key.matches("^[0-9a-f]+$")) {
+            return null;
+        }
+
+        return key;
+    }
+
+    public static String generateAppId() {
+        SecureRandom random = new SecureRandom();
+
+        byte[] bytes = new byte[APP_ID_BYTES];
+        random.nextBytes(bytes);
+
+        StringBuilder sb = new StringBuilder();
+
+        for (byte b : bytes) {
+            String s = Integer.toHexString(b & 0xff);
+            if (s.length() < 2) {
+                sb.append('0');
+            }
+            sb.append(s);
+        }
+
+        return sb.toString();
+    }
+
+    public static String generateKey(String appId) {
+        SecureRandom random = new SecureRandom();
+
+        byte[] bytes = new byte[KEY_BYTES];
+        random.nextBytes(bytes);
+
+        StringBuilder sb = new StringBuilder(appId);
+
+        for (byte b : bytes) {
+            String s = Integer.toHexString(b & 0xff);
+            if (s.length() < 2) {
+                sb.append('0');
+            }
+            sb.append(s);
+        }
+
+        return sb.toString();
+    }
+}

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/SimpleTokenHandlerSessionHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenCallContextHandler.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenCallContextHandler.java?rev=1376099&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenCallContextHandler.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenCallContextHandler.java Wed Aug 22 15:25:35 2012
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser.token;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.server.shared.BasicAuthCallContextHandler;
+import org.apache.chemistry.opencmis.server.shared.HttpUtils;
+
+public class TokenCallContextHandler extends BasicAuthCallContextHandler implements TokenHandler {
+
+    private static final long serialVersionUID = 1L;
+
+    private final TokenHandler tokenHandler;
+
+    /**
+     * Constructor.
+     */
+    public TokenCallContextHandler() {
+        tokenHandler = new SimpleTokenHandler();
+    }
+
+    public Map<String, String> getCallContextMap(HttpServletRequest request) {
+        Map<String, String> result = new HashMap<String, String>();
+
+        Map<String, String> basicAuthMap = super.getCallContextMap(request);
+        if (basicAuthMap != null && !basicAuthMap.isEmpty()) {
+            result.putAll(basicAuthMap);
+        }
+
+        // lastResult must always provide an old token
+        // -> don't check the token
+        boolean isLastResultRequest = "lastresult".equalsIgnoreCase(HttpUtils.getStringParameter(request,
+                Constants.PARAM_SELECTOR));
+
+        if (!isLastResultRequest) {
+            // if a token is provided, check it
+            if (request.getParameter(Constants.PARAM_TOKEN) != null) {
+                if (SimpleTokenHandlerSessionHelper.testAndInvalidateToken(request)) {
+                    String token = SimpleTokenHandlerSessionHelper.getToken(request);
+                    String appId = SimpleTokenHandlerSessionHelper.getApplicationIdFromKey(token);
+                    result.put(CallContext.USERNAME, SimpleTokenHandlerSessionHelper.getUser(request, appId));
+                    result.put(CallContext.PASSWORD, null);
+                } else {
+                    throw new CmisPermissionDeniedException("Invalid token!");
+                }
+            }
+
+            if (!result.containsKey(CallContext.USERNAME)) {
+                // neither basic authentication nor token authentication have
+                // returned a username -> reject request
+                throw new CmisPermissionDeniedException("No authentication!");
+            }
+        }
+
+        return result;
+    }
+
+    public void service(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response) {
+        tokenHandler.service(servletContext, request, response);
+    }
+}

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenCallContextHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenHandler.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenHandler.java?rev=1376099&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenHandler.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenHandler.java Wed Aug 22 15:25:35 2012
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.server.impl.browser.token;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public interface TokenHandler {
+
+    void service(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response);
+}

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/TokenHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/package.html
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/package.html?rev=1376099&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/package.html (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/package.html Wed Aug 22 15:25:35 2012
@@ -0,0 +1,38 @@
+<!-- 
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+ -->
+<html>
+<head>
+<!--
+ JavaDoc package.html
+-->
+</head>
+<body>
+CMIS 1.1 Browser Binding Token Sample Implementation.
+
+<p>
+This package contains a sample implementation of the token handling
+described in the CMIS 1.1 specification. This is sample code and not
+indented for productive use. It has to be adapted or to be replaced
+by repository specific code.
+</p>
+
+</body>
+</html>
\ No newline at end of file

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/token/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/shared/HttpUtils.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/shared/HttpUtils.java?rev=1376099&r1=1376098&r2=1376099&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/shared/HttpUtils.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/shared/HttpUtils.java Wed Aug 22 15:25:35 2012
@@ -20,6 +20,7 @@ package org.apache.chemistry.opencmis.se
 
 import java.io.File;
 import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.math.BigInteger;
 import java.net.URLDecoder;
@@ -252,7 +253,7 @@ public class HttpUtils {
             Method m = clazz.getMethod("fromValue", new Class[] { String.class });
             return (T) m.invoke(null, new Object[] { value });
         } catch (Exception e) {
-            if (e instanceof IllegalArgumentException) {
+            if (e instanceof InvocationTargetException && e.getCause() instanceof IllegalArgumentException) {
                 throw new CmisInvalidArgumentException("Invalid parameter '" + name + "'!");
             }
 

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/cmis.js.jsp
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/cmis.js.jsp?rev=1376099&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/cmis.js.jsp (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/cmis.js.jsp Wed Aug 22 15:25:35 2012
@@ -0,0 +1,204 @@
+<%@ page language="java" contentType="application/json; charset=UTF-8" pageEncoding="UTF-8"%>
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+function OpenCMISConnector()  {
+	this.repositoryDomain  = '<%= request.getAttribute("org.apache.chemistry.opencmis.domain") %>';
+	this.serviceUrl        = '<%= request.getAttribute("org.apache.chemistry.opencmis.serviceUrl") %>';
+	this.iframeUrl         = '<%= request.getAttribute("org.apache.chemistry.opencmis.iframeUrl") %>';
+	this.applicationDomain = '';
+	this.iframe   = null;
+	this.init     = false;
+	this.appKey   = '';
+	this.loginKey = '';
+	this.loginCallback  = null;
+	this.logoutCallback = null;
+	this.tokenCallbacks = new Array();
+}
+
+OpenCMISConnector.prototype.cmisInit = function() {
+	// get login key cookie
+	var ca = document.cookie.split(';');
+	for (var i = 0; i < ca.length; i++) {
+		var c = ca[i].replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+		if (c.indexOf('opencmis_loginkey=') == 0) {
+			this.loginKey = unescape(c.substring(18));
+			break;
+		}
+	}
+
+	if (this.loginKey != '') {
+		// remove the cookie
+		document.cookie = 'opencmis_loginkey=_; Max-Age=0; expires=Thu, 01-Jan-70 00:00:01 GMT; Version="1"';
+	}
+
+	// app domain and path
+	this.applicationDomain = window.location.protocol + '//' + window.location.host;
+	var appDomainEncoded = encodeURIComponent(this.applicationDomain);
+	var appPathEncoded = encodeURIComponent(window.location.pathname + window.location.search);
+
+	var self = this;
+
+	// register message event listener
+	window.addEventListener('message', function(event) { self.cmisReceiver(event) }, false);
+
+	// set up iframe
+	var repositoryIframe = document.createElement('iframe');
+	repositoryIframe.src = this.iframeUrl + (this.iframeUrl.indexOf('?') == -1 ? '?' : '&') + 'domain=' + appDomainEncoded + '&path=' + appPathEncoded;
+	repositoryIframe.style.display = 'none';
+
+	//var frameLoginKey = this.loginKey;
+	//var frameRepositoryDomain = this.repositoryDomain;
+	repositoryIframe.onload = function() { self.sendLoginMessage(); };
+
+	this.iframe = document.getElementsByTagName('body').item(0).appendChild(repositoryIframe);
+
+	this.init = true;
+};
+
+OpenCMISConnector.prototype.cmisReceiver = function(e) {
+	if (e.origin != this.repositoryDomain) {
+		// ignore messages that have not been sent from the repository domain
+		return;
+	}
+
+	if (e.data.substring(0, 6) == 'token:') {
+		// response of a token request, repository sends token
+
+		if (this.tokenCallbacks.length > 0) {
+			// at least one callback is waiting for a token
+
+			// extract token
+			var token = e.data.substring(6);
+
+			// trigger callback
+			this.tokenCallbacks.pop()(token);
+		}
+	} else if (e.data.substring(0, 7) == 'appkey:') {
+		if (this.loginCallback != null) {
+			var callback = this.loginCallback;
+			this.loginCallback = null;
+
+			this.appKey = e.data.substring(7, 67);
+			this.loginKey = '';
+
+			callback(true);
+		}
+	} else if (e.data.substring(0, 9) == 'loginkey:') {
+		if (this.loginCallback != null) {
+			var callback = this.loginCallback;
+			this.loginCallback = null;
+
+			this.loginKey = e.data.substring(9, 69);
+
+			var loginUrl = e.data.substring(70);
+
+			var expires = new Date();
+			expires.setTime(expires.getTime() + 3600);
+
+			document.cookie = 'opencmis_loginkey=' + escape(this.loginKey)
+			+ '; Max-Age=3600; expires=' + expires.toGMTString()
+			+ '; Version="1"; Discard';
+
+			window.location.href = loginUrl;
+		}
+	} else if (e.data.substring(0, 7) == 'logout:') {
+		if (this.logoutCallback != null) {
+			var callback = this.logoutCallback;
+			this.logoutCallback = null;
+
+			var success = ('ok' == e.data.substring(7));
+
+			callback(success);
+		}
+	}
+};
+
+OpenCMISConnector.prototype.sendLoginMessage = function() {
+	this.iframe.contentWindow.postMessage('login:' + this.loginKey, this.repositoryDomain);
+};
+
+OpenCMISConnector.prototype.cmisServiceURL = function() {
+	return this.serviceUrl;
+};
+
+OpenCMISConnector.prototype.cmisLogin = function(callback) {
+	if (this.loginCallback != null) {
+		// there is already a login in progress
+		callback(false);
+		return;
+	}
+
+	this.loginCallback = callback;
+
+	if (!this.init) {
+		this.cmisInit();
+	} else {
+		sendLoginMessage();
+	}
+};
+
+OpenCMISConnector.prototype.cmisLogout = function(callback) {
+	if (this.logoutCallback != null) {
+		// there is already a logout in progress
+		callback(false);
+		return;
+	}
+
+	if (!this.init) {
+		// there hasn't been a login before
+		callback(false);
+		return;
+	}
+
+	this.logoutCallback = callback;
+	this.iframe.contentWindow.postMessage('logout:' + this.appKey, this.repositoryDomain);
+};
+
+OpenCMISConnector.prototype.cmisNextToken = function(callback) {
+	if (!this.init) {
+		// not logged in
+		callback('');
+		return;
+	}
+
+	this.tokenCallbacks.unshift(callback);
+	this.iframe.contentWindow.postMessage('token:' + this.appKey, this.repositoryDomain);
+};
+
+var openCMISConnector = new OpenCMISConnector();
+
+
+// Functions defined by the CMIS 1.1 specification
+
+function cmisServiceURL() {
+	return openCMISConnector.cmisServiceURL();
+}
+
+function cmisLogin(callback) {
+	openCMISConnector.cmisLogin(callback);
+}
+
+function cmisLogout(callback) {
+	openCMISConnector.cmisLogout(callback);
+}
+
+function cmisNextToken(callback) {
+	openCMISConnector.cmisNextToken(callback);
+}
\ No newline at end of file

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/cmis.js.jsp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/login.jsp
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/login.jsp?rev=1376099&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/login.jsp (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/login.jsp Wed Aug 22 15:25:35 2012
@@ -0,0 +1,76 @@
+<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%>
+<!DOCTYPE html>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<html>
+<head>
+<meta charset="UTF-8">
+<title>Login</title>
+<style type="text/css">
+<!--
+body {
+  font-family: Verdana, arial, sans-serif;
+  color: black;
+  font-size: 12px;
+}
+-->
+</style>
+</head>
+<body>
+	<h1>OpenCMIS Repository Login</h1>
+
+	<div>
+	<p>Please provide your credentials for this CMIS repository.</p>
+	<p>
+		<% if (request.getAttribute("org.apache.chemistry.opencmis.error") != null) { %>
+		<span style="color: red"><%= request.getAttribute("org.apache.chemistry.opencmis.error") %></span>
+		<% } %>
+	</p>
+	</div>
+
+	<div>
+	<form method="POST">
+		<table>
+			<tr>
+				<td>Username:</td>
+				<td><input type="text" name="user" size="20"></td>
+			</tr>
+			<tr>
+				<td>Password:</td>
+				<td><input type="password" name="password" size="20"></td>
+			</tr>
+			<tr>
+				<td></td>
+				<td><input type="checkbox" name="trustapp" value="1">
+				    I'm trusting this application:<br>
+				    <span style="font-weight: bold"><%= request.getAttribute("org.apache.chemistry.opencmis.appurl") %></span>
+				</td>
+			</tr>
+			<tr>
+				<td></td>
+				<td><input type="submit" value="Login"> <input type="button" value="Cancel" onClick="window.history.back()"></td>
+			</tr>
+
+		</table>
+		<input type="hidden" name="key" value="<%= request.getAttribute("org.apache.chemistry.opencmis.formkey") %>">
+	</form>
+	</div>
+	
+</body>
+</html>
\ No newline at end of file

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/login.jsp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/repository.jsp
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/repository.jsp?rev=1376099&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/repository.jsp (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/repository.jsp Wed Aug 22 15:25:35 2012
@@ -0,0 +1,163 @@
+<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%>
+<!DOCTYPE html>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<html>
+<head>
+<meta charset="UTF-8">
+<title>Repository</title>
+</head>
+<body>
+	<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
+	<script type="text/javascript">
+		var appInfo = getAppInfo();
+		var appDomain = appInfo[0];
+		var appPath = appInfo[1]
+
+		// tokens in stock, initially empty
+		var tokens = new Array();
+
+		if (window.top != window.self && appDomain != null && appPath != null) {
+			// add message event listener
+			window.addEventListener('message', receiver, false);
+		}
+
+		//////////////////////////////////////////////////////////
+		// Event listener callback.
+		//////////////////////////////////////////////////////////
+		function receiver(e) {
+			if (e.origin != appDomain) {
+				// ignore messages that have not been sent from the application domain
+				return;
+			}
+
+			if (e.data.substring(0, 5) == 'token') {
+				var appKey = e.data.substring(6);
+
+				if (tokens.length > 0) {
+					// we have a least one token in stock -> remove one and send it
+					e.source.postMessage('token:' + tokens.pop(), e.origin);
+				} else {
+					// we are out of tokens -> ask the server for another batch
+					requestTokens(e, appKey);
+				}
+			} else if (e.data.substring(0, 5) == 'login') {
+				var loginKey = e.data.substring(6);
+				login(e, loginKey);
+			} else if (e.data.substring(0, 6) == 'logout') {
+				var appKey = e.data.substring(7);
+				logout(e, appKey);
+			}
+		}
+
+		function login(e, loginKey) {
+			$.ajax({
+				url : '<%= request.getAttribute("org.apache.chemistry.opencmis.loginUrl") %>login',
+				type : 'POST',
+				data : {
+					url : appDomain + appPath,
+					key : loginKey
+				},
+				success : function(data) {
+					if (data.ok == 1) {
+						e.source.postMessage('appkey:' + data.key, e.origin);
+					} else {
+						e.source.postMessage('loginkey:' + data.key + ":"
+								+ data.url, e.origin);
+					}
+				},
+				error : function(msg) {
+					alert("Error: " + msg);
+				}
+			});
+		}
+
+		function logout(e, appKey) {
+			$.ajax({
+				url : '<%= request.getAttribute("org.apache.chemistry.opencmis.loginUrl") %>logout',
+				type : 'POST',
+				data : {
+					key : appKey
+				},
+				success : function(data) {
+					if (data.ok == 1) {
+						e.source.postMessage('logout:ok', e.origin);
+					} else {
+						e.source.postMessage('logout:failure', e.origin);
+					}
+				},
+				error : function(msg) {
+					alert("Error: " + msg);
+				}
+			});
+		}
+
+		//////////////////////////////////////////////////////////
+		// Requests new tokens from the server.
+		//////////////////////////////////////////////////////////
+		function requestTokens(e, appKey) {
+			$.ajax({
+				url : '<%= request.getAttribute("org.apache.chemistry.opencmis.loginUrl") %>token',
+				type : 'POST',
+				data : {
+					key : appKey
+				},
+				success : function(data) {
+
+					// sanity check: we expect an array
+					if ($.isArray(data)) {
+
+						// if we received more than one token, put them in stock except for the first one
+						if (data.length > 1) {
+							for ( var i = 1; i < data.length; i++) {
+								var token = data[i];
+								tokens.push(token);
+							}
+						}
+
+						// if the array wasn't empty, send the first token to the applictaion
+						if (data.length > 0) {
+							e.source.postMessage('token:' + data[0], e.origin);
+						}
+					}
+				}
+			});
+		}
+
+		function getAppInfo() {
+			var domain = null;
+			var path = null;
+			var frameHref = window.location.href;
+
+			var params = frameHref.slice(frameHref.indexOf('?') + 1).split('&');
+			for ( var i = 0; i < params.length; i++) {
+				var keyValue = params[i].split('=');
+				if (keyValue[0] == 'domain') {
+					domain = decodeURIComponent(keyValue[1]);
+				} else if (keyValue[0] == 'path') {
+					path = decodeURIComponent(keyValue[1]);
+				}
+			}
+
+			return [ domain, path ];
+		}
+	</script>
+
+</body>
+</html>
\ No newline at end of file

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/token/repository.jsp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/web.xml?rev=1376099&r1=1376098&r2=1376099&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/web.xml (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/webapp/WEB-INF/web.xml Wed Aug 22 15:25:35 2012
@@ -118,7 +118,7 @@
 		<servlet-class>org.apache.chemistry.opencmis.server.impl.browser.CmisBrowserBindingServlet</servlet-class>
 		<init-param>
 			<param-name>callContextHandler</param-name>
-			<param-value>org.apache.chemistry.opencmis.server.shared.BasicAuthCallContextHandler</param-value>
+			<param-value>org.apache.chemistry.opencmis.server.impl.browser.token.TokenCallContextHandler</param-value>
 		</init-param>
 		<load-on-startup>2</load-on-startup>
 	</servlet>