org.xlcloud.iam.EntitlementInterceptor.java Source code

Java tutorial

Introduction

Here is the source code for org.xlcloud.iam.EntitlementInterceptor.java

Source

/*
 * Copyright 2012 AMG.lab, a Bull Group Company
 * 
 * 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 org.xlcloud.iam;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.xlcloud.rest.AuthorizationTokenResolver;
import org.xlcloud.rest.RequestAwareResource;
import org.xlcloud.rest.ResourceInterceptorBinding;
import org.xlcloud.rest.exception.ForbiddenException;

/**
 * Interceptor for authorizing resource requests. Uses
 * {@link EntitlementValidator} to validate the request.
 * 
 * @author Andrzej Stasiak, AMG.net
 * @author Piotr Kulasek-Szwed, AMG.net
 */
@Interceptor
@ResourceInterceptorBinding
public class EntitlementInterceptor implements Serializable {

    private static final long serialVersionUID = 6278017503199479842L;

    private static Logger LOG = Logger.getLogger(EntitlementInterceptor.class);

    @Inject
    protected EntitlementContext entitlementCtx;

    @Inject
    protected EntitlementValidator entitlementValidator;

    @Inject
    private AuthorizationTokenResolver authTokenResolver;

    private Map<String, String> predefinedPaths;

    public EntitlementInterceptor() {
        // FIXME (by Tomek Adamczewski): find a better solution!
        predefinedPaths = new HashMap<String, String>();
        predefinedPaths.put("stacks", "stacks");
        predefinedPaths.put("accounts", "accounts");
        predefinedPaths.put("users", "users");
        predefinedPaths.put("projects", "projects");
    }

    /**
     * It authorizes request, if the request is kind of
     * {@link RequestAwareResource}. See:
     * {@link #authorizeRequest(InvocationContext)}
     * 
     * @param invocationContext
     *            invocation context
     * @return original invocation value
     * @throws Exception
     */
    @AroundInvoke
    public Object setupEntitlement(InvocationContext invocationContext) throws Exception {
        if (invocationContext.getTarget() instanceof RequestAwareResource) {
            authorizeRequest(invocationContext);
        }
        return invocationContext.proceed();
    }

    /**
     * It authorizes the request within entitlement context. This method
     * retrieves following options from the session: - access token - action
     * name - resource path. Then it verifies if the user is allowed to access
     * the resource described by the retrieved options using:
     * {@link EntitlementValidator#validate()}.
     * 
     * @param invocationContext
     *            invocation context
     */
    private void authorizeRequest(InvocationContext invocationContext) {
        LOG.debug("Intercepted request on resource - request will be authorized.");

        RequestAwareResource target = (RequestAwareResource) invocationContext.getTarget();

        // set Auth Token if no header, throws exception
        entitlementCtx.setAccessToken(authTokenResolver.get(target));

        String relativeRequestPath = target.getRelativeRequestPath();
        if (relativeRequestPath.endsWith("/")) {
            relativeRequestPath = relativeRequestPath.substring(0, relativeRequestPath.length() - 1);
        }

        // set HTTP method
        String method = target.getHttpMethod();
        entitlementCtx.setAction(method);

        // set Resource
        String predefinedPath = predefinedPaths.get(relativeRequestPath);
        if (StringUtils.isNotBlank(predefinedPath)) {
            entitlementCtx.setResource(predefinedPath);
        } else {
            entitlementCtx.setResource(target.normalizePath());
        }

        try {
            // authorize the request within entitlement context
            entitlementValidator.validate();
        } catch (ForbiddenException e) {
            // we don't want to expose the entitlement path
            // TODO ((ExceptionDetails) e.getResponse().getEntity()).setResource(target.getRelativeRequestPath());
            throw e;
        }
    }
}