com.github.jeromeroucou.javasignedurl.utils.SignedUrlUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.github.jeromeroucou.javasignedurl.utils.SignedUrlUtils.java

Source

/*******************************************************************************
 * This software is a computer program whose purpose is to test signed URL functionality.
 *
 * This software is governed by the CeCILL-C license under French law and
 * abiding by the rules of distribution of free software.  You can  use, 
 * modify and/ or redistribute the software under the terms of the CeCILL-C
 * license as circulated by CEA, CNRS and INRIA at the following URL
 * "http://www.cecill.info". 
 *
 * As a counterpart to the access to the source code and  rights to copy,
 * modify and redistribute granted by the license, users are provided only
 * with a limited warranty  and the software's author,  the holder of the
 * economic rights,  and the successive licensors  have only  limited
 * liability. 
 *
 * In this respect, the user's attention is drawn to the risks associated
 * with loading,  using,  modifying and/or developing or reproducing the
 * software by the user in light of its specific status of free software,
 * that may mean  that it is complicated to manipulate,  and  that  also
 * therefore means  that it is reserved for developers  and  experienced
 * professionals having in-depth computer knowledge. Users are therefore
 * encouraged to load and test the software's suitability as regards their
 * requirements in conditions enabling the security of their systems and/or 
 * data to be ensured and,  more generally, to use and operate it in the 
 * same conditions as regards security. 
 *
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL-C license and that you accept its terms.
 *******************************************************************************/
package com.github.jeromeroucou.javasignedurl.utils;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.jeromeroucou.javasignedurl.exceptions.SignedUrlException;

/**
 * Provide utilities methods
 * 
 * @author Jrme ROUCOU <java-signed-url@roucou.org>
 * @since 1.0
 */
public final class SignedUrlUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(SignedUrlUtils.class);

    private static String salt;

    /** Utility class : private constructor */
    private SignedUrlUtils() {
        // Utility class : private constructor
    }

    /**
     * @return A random number to add some salt in hash encoding
     * @since 1.0
     */
    private static String getSomeSalt() {
        synchronized (SignedUrlUtils.class) {
            if (salt == null) {
                salt = String.valueOf(Math.random()).substring(2);
            }
        }
        return salt;
    }

    /**
     * Get SHA256 hash from text passed in parameter.
     * 
     * @param textToBeHashed the text to be hashed
     * @return the hash from the text passed in parameter's method
     * @since 1.0
     */
    public static String hashSha256WithSalt(final String textToBeHashed) {
        String hash;
        synchronized (textToBeHashed) {
            hash = DigestUtils.sha256Hex(textToBeHashed + getSomeSalt()).toUpperCase();
        }
        LOGGER.debug("{} -> SHA256 -> {}", new Object[] { textToBeHashed, hash, });
        return hash;
    }

    /**
     * Get the queryString and signature's parameter (HASH key) separately.
     * 
     * @param queryString URL parameters with signature (parameter "data").
     * @return query string without signature parameter (parameter "data") and signature separately
     * @throws SignedUrlException if URL parameter of signature is not unique
     * @since 1.0
     */
    public static Map<SignedUrlType, String> separateQueryStringAndSignature(final String queryString)
            throws SignedUrlException {
        return separateQueryStringAndSignature(queryString, "data");
    }

    /**
     * Get the queryString and signature's parameter (HASH key) separately.
     * 
     * @param queryString URL parameters with signature.
     * @param signatureParamName the signature parameter name.
     * @return query string without signature parameter and signature separately
     * @throws SignedUrlException if URL parameter of signature is not unique
     * @since 1.0
     */
    public static Map<SignedUrlType, String> separateQueryStringAndSignature(final String queryString,
            final String signatureParamName) throws SignedUrlException {
        final Map<SignedUrlType, String> map = new HashMap<SignedUrlType, String>();
        boolean isUniqueSignatureMethod = true;
        final StringBuilder queryStringTemp = new StringBuilder();
        final String[] parameters = queryString.split("&");
        for (int i = 0; i < parameters.length; i++) {
            final String param = parameters[i];
            if (param.startsWith(signatureParamName)) {
                // The signature parameter (hash key) must be unique
                if (!isUniqueSignatureMethod) {
                    throw new SignedUrlException("The signature parameter is not unique : " + queryString);
                }
                isUniqueSignatureMethod = false;
                map.put(SignedUrlType.signature, param.substring(param.indexOf('=') + 1));
            } else {
                if (i > 0) {
                    queryStringTemp.append('&');
                }
                queryStringTemp.append(param);
            }
        }
        map.put(SignedUrlType.queryString, queryStringTemp.toString());
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("queryStringWithoutSignature : {}", map.get(SignedUrlType.queryString));
            LOGGER.debug("signature : {}", map.get(SignedUrlType.signature));
        }
        return map;
    }

}