blob: 0658bc511e75650f49041f39f5913fb86bd6ab51 [file] [log] [blame]
/*
* 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();
}
}