com.google.gwt.user.server.Util.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.user.server.Util.java

Source

/*
 * Copyright 2011 Google Inc.
 *
 * Licensed 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 com.google.gwt.user.server;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

/**
 * A bunch of useful methods.
 */
public class Util {

    /**
     * Find an instance of the specified annotation, walking up the inheritance
     * tree if necessary. Copied from {@link
     * com.google.gwt.i18n.rebind.AnnotationUtil}.
     *
     * <p>The super chain is walked first, so if an ancestor superclass has the
     * requested annotation, it will be preferred over a directly implemented
     * interface.
     *
     * @param <T> Annotation type to search for
     * @param clazz root class to search, may be null
     * @param annotationClass class object of Annotation subclass to search for
     * @return the requested annotation or null if none
     */
    public static <T extends Annotation> T getClassAnnotation(Class<?> clazz, Class<T> annotationClass) {
        if (clazz == null) {
            return null;
        }
        T annot = clazz.getAnnotation(annotationClass);
        if (annot == null) {
            annot = getClassAnnotation(clazz.getSuperclass(), annotationClass);
            if (annot != null) {
                return annot;
            }
            for (Class<?> intf : clazz.getInterfaces()) {
                annot = getClassAnnotation(intf, annotationClass);
                if (annot != null) {
                    return annot;
                }
            }
        }
        return annot;
    }

    /**
     * Retrieves named cookie from supplied request. If {@code allowDuplicates} is
     * set to {@code true}, method will throw {@link IllegalStateException} if
     * duplicate cookies are found, which can be a sign of a cookie overwrite
     * attack.
     *
     * @param request HTTP request to retrieve cookie from.
     * @param cookieName Cookie name.
     * @param allowDuplicates if {@code true} duplicate cookies are allowed,
     *        otherwise {@link IllegalStateException} is thrown if duplicate
     *        cookies are detected.
     * @return {@link Cookie} if specified cookie is present, {@code null}
     *         otherwise.
     * @throws IllegalArgumentException if duplicate cookies are detected.
     */
    public static Cookie getCookie(HttpServletRequest request, String cookieName, boolean allowDuplicates) {
        Cookie cookieToReturn = null;
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookieName.equals(cookie.getName())) {
                    // ensure that it's the only one cookie, since duplicate cookies
                    // can be a sign of a cookie overriding attempt.
                    if (cookieToReturn == null) {
                        if (allowDuplicates) {
                            // do not attempt to detect duplicate cookies
                            return cookie;
                        } else {
                            cookieToReturn = cookie;
                        }
                    } else {
                        throw new IllegalArgumentException("Duplicate cookie! " + "Cookie override attack?");
                    }
                }
            }
        }
        return cookieToReturn;
    }

    /**
     * Checks if specified method is XSRF protected based on the following logic:
     *
     * <ul>
     *  <li>Method level annotations override class level annotations.
     *  <li>If method is annotated with {@code xsrfAnnotation} this
     *      method returns {@code true}
     *  <li>If method is annotated with {@code noXsrfAnnotation}, this method
     *      returns {@code false}.
     *  <li>If class is annotated with {@code xsrfAnnotation} and method is not
     *      annotated, this method returns {@code true}.
     *  <li>If class is annotated with {@code noXsrfAnnotation} and method is not
     *      annotated, this method returns {@code false}.
     *  <li>If no annotations are present and class has a method with return value
     *      assignable from {@code xsrfTokenInterface}, this method returns
     *      {@code true}.
     *  <li>If no annotations are present this method returns {@code false}.
     * </ul>
     *
     * @see com.google.gwt.user.server.rpc.AbstractXsrfProtectedServiceServlet
     */
    public static boolean isMethodXsrfProtected(Method method, Class<? extends Annotation> xsrfAnnotation,
            Class<? extends Annotation> noXsrfAnnotation, Class<?> xsrfTokenInterface) {
        Class<?> declaringClass = method.getDeclaringClass();

        if (method.getAnnotation(noXsrfAnnotation) != null
                || (Util.getClassAnnotation(declaringClass, noXsrfAnnotation) != null
                        && method.getAnnotation(xsrfAnnotation) == null)) {
            // XSRF protection is disabled
            return false;
        }

        if (Util.getClassAnnotation(declaringClass, xsrfAnnotation) != null
                || method.getAnnotation(xsrfAnnotation) != null) {
            return true;
        }

        // if no explicit annotation is given no XSRF token verification is done,
        // unless there's a method returning RpcToken in which case XSRF token
        // verification is performed for all methods
        Method[] classMethods = declaringClass.getMethods();
        for (Method classMethod : classMethods) {
            if (xsrfTokenInterface.isAssignableFrom(classMethod.getReturnType()) && !method.equals(classMethod)) {
                return true;
            }
        }
        return false;
    }

    private Util() {
    }
}