Projects >> fcrepo >>9d1dcaab7c8d6747d0347175453edd32f48ba4ef

Chunk
Conflicting content
package org.fcrepo.server.security.xacml.pep.rest;

import java.io.IOException;
<<<<<<< HEAD
=======
import java.io.InputStream;
import java.util.HashMap;
>>>>>>> 547638622e4425f9db12d41c8aa7862c1b4926c9
import java.util.Map;
import java.util.Set;
Solution content
package org.fcrepo.server.security.xacml.pep.rest;

import java.io.IOException;

import java.util.Map;
import java.util.Set;
File
PEP.java
Developer's decision
Version 1
Kind of conflict
Import
Chunk
Conflicting content
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
<<<<<<< HEAD
=======
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import com.sun.xacml.ctx.RequestCtx;
import com.sun.xacml.ctx.ResponseCtx;
import com.sun.xacml.ctx.Result;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.fcrepo.common.Constants;
>>>>>>> 547638622e4425f9db12d41c8aa7862c1b4926c9

import org.fcrepo.server.security.xacml.pep.AuthzDeniedException;
import org.fcrepo.server.security.xacml.pep.ContextHandler;
Solution content
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.xacml.ctx.RequestCtx;
import com.sun.xacml.ctx.ResponseCtx;
import com.sun.xacml.ctx.Result;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.fcrepo.server.security.xacml.pep.AuthzDeniedException;
import org.fcrepo.server.security.xacml.pep.ContextHandler;
File
PEP.java
Developer's decision
Combination
Kind of conflict
Import
Chunk
Conflicting content
import org.fcrepo.server.security.xacml.pep.rest.filters.ObjectsRESTFilterMatcher;
import org.fcrepo.server.security.xacml.pep.rest.filters.ParameterRequestWrapper;
import org.fcrepo.server.security.xacml.pep.rest.filters.RESTFilter;
<<<<<<< HEAD
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.xacml.ctx.RequestCtx;
import com.sun.xacml.ctx.ResponseCtx;
import com.sun.xacml.ctx.Result;
=======
import org.fcrepo.server.security.xacml.pep.rest.filters.ResponseHandlingRESTFilter;
>>>>>>> 547638622e4425f9db12d41c8aa7862c1b4926c9


/**
Solution content
import org.fcrepo.server.security.xacml.pep.rest.filters.ObjectsRESTFilterMatcher;
import org.fcrepo.server.security.xacml.pep.rest.filters.ParameterRequestWrapper;
import org.fcrepo.server.security.xacml.pep.rest.filters.RESTFilter;
import org.fcrepo.server.security.xacml.pep.rest.filters.ResponseHandlingRESTFilter;


/**
File
PEP.java
Developer's decision
Version 2
Kind of conflict
Import
Chunk
Conflicting content
    private static final Logger logger =
            LoggerFactory.getLogger(PEP.class);

<<<<<<< HEAD
    private Map m_filters = null;
=======
    private Map filters = null;
    private ObjectsRESTFilterMatcher objectsRESTFilterMatcher = null;
>>>>>>> 547638622e4425f9db12d41c8aa7862c1b4926c9

    private ContextHandler m_ctxHandler = null;
Solution content
    private static final Logger logger =
            LoggerFactory.getLogger(PEP.class);

    private Map m_filters;
    private ObjectsRESTFilterMatcher m_objectsRESTFilterMatcher;

    private ContextHandler m_ctxHandler = null;
    
    public PEP(ObjectsRESTFilterMatcher objectsRESTFilterMatcher, Map filters ) throws PEPException {
        m_objectsRESTFilterMatcher = objectsRESTFilterMatcher;
        m_filters = filters;
    }
File
PEP.java
Developer's decision
Manual
Kind of conflict
Attribute
Chunk
Conflicting content
                throw new PEPException("No FeSL REST filter found for " + servletPath);
            }

<<<<<<< HEAD
            // handle the response if we have a filter
            if (filter != null) {
                reqCtx = filter.handleResponse(req, res);
                if (reqCtx != null) {
                    resCtx = m_ctxHandler.evaluate(reqCtx);
                    enforce(resCtx);
                }

                out.write(res.getData());
                out.flush();
                out.close();
=======
            if(ResponseHandlingRESTFilter.class.isInstance(filter)) {
            	// handle the response if we have a non-null response handling filter
            	reqCtx = ((ResponseHandlingRESTFilter)filter).handleResponse(req, res);
            	if (reqCtx != null) {
            		resCtx = ctxHandler.evaluate(reqCtx);
            		enforce(resCtx);
            	}

            	out.write(((DataResponseWrapper)res).getData());
            	out.flush();
            	out.close();
>>>>>>> 547638622e4425f9db12d41c8aa7862c1b4926c9
            }
        } catch (AuthzDeniedException ae) {
            if (!res.isCommitted()
Solution content
                throw new PEPException("No FeSL REST filter found for " + servletPath);
            }

            if(ResponseHandlingRESTFilter.class.isInstance(filter)) {
            	// handle the response if we have a non-null response handling filter
            	reqCtx = ((ResponseHandlingRESTFilter)filter).handleResponse(req, res);
            	if (reqCtx != null) {
            		resCtx = m_ctxHandler.evaluate(reqCtx);
            		enforce(resCtx);
            	}

            	out.write(((DataResponseWrapper)res).getData());
            	out.flush();
            	out.close();
            }
        } catch (AuthzDeniedException ae) {
            if (!res.isCommitted()
File
PEP.java
Developer's decision
Combination
Kind of conflict
Comment
If statement
Method invocation
Variable
Chunk
Conflicting content
        logger.info("Initialising Servlet Filter: " + PEP.class);

<<<<<<< HEAD
=======
        try {
           objectsRESTFilterMatcher = new ObjectsRESTFilterMatcher();
       } catch (PEPException pe) {
           logger.error("Error obtaining ObjectsRESTFilterMatcher", pe);
           throw new ServletException("Error obtaining ObjectsRESTFilterMatcher", pe);
       }

        loadFilters();
>>>>>>> 547638622e4425f9db12d41c8aa7862c1b4926c9
    }

    @Override
Solution content
/*
 * File: PEP.java
 *
 * Copyright 2007 Macquarie E-Learning Centre Of Excellence
 *
 * 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.fcrepo.server.security.xacml.pep.rest;

import java.io.IOException;

import java.util.Map;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.xacml.ctx.RequestCtx;
import com.sun.xacml.ctx.ResponseCtx;
import com.sun.xacml.ctx.Result;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.fcrepo.server.security.xacml.pep.AuthzDeniedException;
import org.fcrepo.server.security.xacml.pep.ContextHandler;
import org.fcrepo.server.security.xacml.pep.PEPException;
import org.fcrepo.server.security.xacml.pep.rest.filters.DataResponseWrapper;
import org.fcrepo.server.security.xacml.pep.rest.filters.ObjectsFilter;
import org.fcrepo.server.security.xacml.pep.rest.filters.ObjectsRESTFilterMatcher;
import org.fcrepo.server.security.xacml.pep.rest.filters.ParameterRequestWrapper;
import org.fcrepo.server.security.xacml.pep.rest.filters.RESTFilter;
import org.fcrepo.server.security.xacml.pep.rest.filters.ResponseHandlingRESTFilter;


/**
 * This is the PEP for the REST interface.
 *
 * @author nishen@melcoe.mq.edu.au
 */
public final class PEP
        implements Filter {

    private static final Logger logger =
            LoggerFactory.getLogger(PEP.class);

    private Map m_filters;
    private ObjectsRESTFilterMatcher m_objectsRESTFilterMatcher;

    private ContextHandler m_ctxHandler = null;
    
    public PEP(ObjectsRESTFilterMatcher objectsRESTFilterMatcher, Map filters ) throws PEPException {
        m_objectsRESTFilterMatcher = objectsRESTFilterMatcher;
        m_filters = filters;
    }

    /*
     * (non-Javadoc)
     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
     * javax.servlet.ServletResponse, javax.servlet.FilterChain)
     */
    @Override
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain) throws IOException,
            ServletException {
        // if a response has already been committed, bypass this filter...
        if (response.isCommitted()) {
            if (logger.isDebugEnabled()) {
                logger.debug("Response has already been committed. Bypassing PEP.");
            }
            // continuing the chain once auth has failed causes errors. Short
            // circuiting the path here.
            // remove this if it causes problems
            // chain.doFilter(request, response);
            return;
        }

        // Need to make sure we are dealing with HttpServlets
        if (!(request instanceof HttpServletRequest)
                || !(response instanceof HttpServletResponse)) {
            logger.error("Servlets are not HttpServlets!");
            throw new ServletException("Servlets are not HttpServlets!");
        }

        ServletOutputStream out = null;
        ParameterRequestWrapper req = null;
        HttpServletResponse res = (HttpServletResponse)response;

        // the request and response context
        RequestCtx reqCtx = null;
        ResponseCtx resCtx = null;

        String uri = ((HttpServletRequest) request).getRequestURI();
        String servletPath = ((HttpServletRequest) request).getServletPath();
        if (logger.isDebugEnabled()) {
            logger.debug("Incoming URI: " + uri);
            logger.debug("Incoming servletPath: " + servletPath);
        }

        // Fix-up for direct web.xml servlet mappings for:
        // /objects/nextPID and /objects/nextPID.xml
        // (so servlet path will be different in these cases)
        // FIXME: we don't support .xml any more? but included as the servlet mapping is still specified
        if (uri.endsWith("/nextPID") || uri.endsWith("/nextPID.xml")) {
            servletPath = "/objects";
        }


        // get the filter (or null if no filter)
        RESTFilter filter = m_filters.get(servletPath);

        if (filter != null && logger.isDebugEnabled())
            logger.debug("obtaining filter: {}", filter.getClass().getName());

        if(ObjectsFilter.class.isInstance(filter)) { // go find the ObjectHandler
            HttpServletRequest httpRequest = (HttpServletRequest)request;
      	  filter = this.m_objectsRESTFilterMatcher.getObjectsHandler(httpRequest);
      	  if (filter == null) {
            logger.error("No FeSL REST objects handler found for \"{}\"", httpRequest.getPathInfo());
            throw new ServletException(new PEPException("No FeSL REST objects handler found for " + servletPath));
      	  }
        }
        try {
            // handle the request if we have a filter
            if (filter != null) {
                // substitute our own request object that manages parameters
                try {
                    req =
                            new ParameterRequestWrapper((HttpServletRequest) request);
                } catch (Exception e) {
                    throw new PEPException(e);
                }

                if (logger.isDebugEnabled()) {
                   logger.debug("Filtering URI: [" + req.getRequestURI()
                           + "] with: [" + filter.getClass().getName() + "]");
                }

                if(ResponseHandlingRESTFilter.class.isInstance(filter)) {
               	 // substitute our own response object that captures the data
               	 res = new DataResponseWrapper(((HttpServletResponse) response));
                   // get a handle for the original OutputStream
                   out = response.getOutputStream();
                   if (logger.isDebugEnabled()) {
                      logger.debug("Filtering will include post-processing the response");
                   }
                }

                reqCtx = filter.handleRequest(req, res);
                if (reqCtx != null) {
                    resCtx = m_ctxHandler.evaluate(reqCtx);
                    enforce(resCtx);
                }

                // pass the request along to the next chain...
                chain.doFilter(req, res);
            } else {
                // there must always be a filter, even if it is a NOOP
                logger.error("No FeSL REST filter found for \"{}\"", servletPath);
                throw new PEPException("No FeSL REST filter found for " + servletPath);
            }

            if(ResponseHandlingRESTFilter.class.isInstance(filter)) {
            	// handle the response if we have a non-null response handling filter
            	reqCtx = ((ResponseHandlingRESTFilter)filter).handleResponse(req, res);
            	if (reqCtx != null) {
            		resCtx = m_ctxHandler.evaluate(reqCtx);
            		enforce(resCtx);
            	}

            	out.write(((DataResponseWrapper)res).getData());
            	out.flush();
            	out.close();
            }
        } catch (AuthzDeniedException ae) {
            if (!res.isCommitted()
                    && (req.getRemoteUser() == null || "".equals(req
                            .getRemoteUser().trim()))) {
                loginForm(res);
            } else {
                denyAccess((HttpServletResponse) response, ae.getMessage());
            }
        } catch (PEPException pe) {
            throw new ServletException("Error evaluating request", pe);
        }
    }

    /*
     * (non-Javadoc)
     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
     */
    public void init() throws ServletException {
        logger.info("Initialising Servlet Filter: " + PEP.class);
        if (m_ctxHandler == null) {
            throw new ServletException("Error obtaining ContextHandler");
        }
    }

    @Override
File
PEP.java
Developer's decision
Manual
Kind of conflict
Method invocation
Try statement
Chunk
Conflicting content


}

import com.sun.xacml.ctx.RequestCtx;

<<<<<<< HEAD
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.fcrepo.common.Constants;

import org.fcrepo.server.security.xacml.pep.PEPException;
import org.fcrepo.server.security.xacml.pep.rest.objectshandlers.Handlers;

/**
 * Handles the get operations.
 *
 * @author nish.naidoo@gmail.com
 */
public class ObjectsFilter
        extends AbstractFilter {

    private static final Logger logger =
            LoggerFactory.getLogger(ObjectsFilter.class);

    private Map m_objectsHandlers = null;

    /**
     * Default constructor.
     *
     * @throws PEPException
     */
    public ObjectsFilter(Map objectsHandlers)
            throws PEPException {
        super();
        m_objectsHandlers = objectsHandlers;
    }

    /*
     * (non-Javadoc)
     * @see
     * org.fcrepo.server.security.xacml.pep.rest.filters.RESTFilter#handleRequest(javax.servlet
     * .http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public RequestCtx handleRequest(HttpServletRequest request,
                                    HttpServletResponse response)
            throws IOException, ServletException {
        RESTFilter objectsHandler = getObjectsHandler(request);

        if (objectsHandler == null) {
            return null;
        }

        return objectsHandler.handleRequest(request, response);
    }

    /*
     * (non-Javadoc)
     * @see
     * org.fcrepo.server.security.xacml.pep.rest.filters.RESTFilter#handleResponse(javax.servlet
     * .http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public RequestCtx handleResponse(HttpServletRequest request,
                                     HttpServletResponse response)
            throws IOException, ServletException {
        RESTFilter objectsHandler = getObjectsHandler(request);

        if (objectsHandler == null) {
            return null;
        }

        return objectsHandler.handleResponse(request, response);
    }

    protected RESTFilter getObjectsHandler(HttpServletRequest request)
            throws ServletException {

        // IMPORTANT:
        // Do not return null unless you are sure that the endpoint
        // requires no authorisation.  The only current case for this
        // is returning the WADL.  All other REST endpoints MUST have handlers.
        String uri = request.getRequestURI();
        String path = request.getPathInfo();


        // need to handle this special case due to the way the RestServlet is mapped
        // directly to /objects/nextPID and /objects/nextPID.xml
        if (uri.endsWith("/nextPID")) {
            path = "/nextPID";
        } else if (path == null) {
            path = "";
        }

        if (logger.isDebugEnabled()) {
            logger.debug("objectsHandler path: " + path);
        }

        // The method override header. Takes precedence over the HTTP method
        String method = request.getHeader("X-HTTP-Method-Override");
        if (method == null || "".equals(method)) {
            method = request.getMethod();
        }

        if (method == null) {
            throw new ServletException("Request Method was NULL");
        }

        method = method.toUpperCase();

        if (logger.isDebugEnabled()) {
            logger.debug("objectsHandler method: " + method);
        }

        String[] parts = path.split("/");
        if (logger.isDebugEnabled()) {
            for (String p : parts) {
                logger.debug("objectsHandler part: " + p);
            }
        }

        if (parts.length < 1) {
            logger.info("Not enough components on the URI.");
            throw new ServletException("Not enough components on the URI.");
        }

        // IMPORTANT:
        // this is the only case we return null.  No authz on the WADL.
        // Every other endpoint MUST have a handler.
        if (parts.length == 2 && "application.wadl".equals(parts[1])) {
            return null;
        }

        // FIXME: tests below could do with tidying up
        // particularly wrt checking for valid pid and ds IDs.
        // if the tests are done in the correct order this should not be necessary
        // (and the REST API mappings/annotations do not use this form of syntax checking,
        // so they will allow pass-through of invalid PIDs and DSIDs, which will be checked later in the code -
        // the stuff below will actually result in not finding a handler if a bogus PID/DSID is found)

        String handlerName = "no-handler-name-determined-from-request-path";
        // ascertain the correct handler based on uri pattern.

        // - /objects
        if (parts.length < 2) {
            if ("GET".equals(method)) {
                if (request.getParameterMap().containsKey("sessionToken")) {
                    handlerName = Handlers.RESUMEFINDOBJECTS;
                } else {
                    handlerName = Handlers.FINDOBJECTS;
                }
            } else if ("POST".equals(method)) {
                handlerName = Handlers.INGEST;
            }
            // - /objects/nextPID
        } else if (parts.length == 2 && parts[1].equals("nextPID")) {
            handlerName = Handlers.GETNEXTPID;
            // - /objects/[pid]
        } else if (parts.length == 2) {
            if ("GET".equals(method)) {
                handlerName = Handlers.GETOBJECTPROFILE;
            } else if ("PUT".equals(method)) {
                handlerName = Handlers.MODIFYOBJECT;
            } else if ("DELETE".equals(method)) {
                handlerName = Handlers.PURGEOBJECT;
            } else if ("POST".equals(method)) {
                handlerName = Handlers.INGEST;
            }
            // - /objects/[pid]/...  (except relationships - handled later)
        } else if (parts.length == 3 && isPID(parts[1]) && "GET".equals(method)  && !"relationships".equals(parts[2])) {
            if ("datastreams".equals(parts[2])) {
                handlerName = Handlers.LISTDATASTREAMS;
            } else if ("export".equals(parts[2])) {
                handlerName = Handlers.EXPORT;
            } else if ("methods".equals(parts[2])) {
                handlerName = Handlers.LISTMETHODS;
            } else if ("objectXML".equals(parts[2])) {
                handlerName = Handlers.GETOBJECTXML;
            } else if ("versions".equals(parts[2])) {
                handlerName = Handlers.GETOBJECTHISTORY;
            } else if ("validate".equals(parts[2])) {
                handlerName = Handlers.VALIDATE;
            }

            // - /objects/[pid]/datastreams/[dsid]
        } else if (parts.length == 4 && isPID(parts[1])
                && "datastreams".equals(parts[2]) && isDatastream(parts[3])) {
            if ("PUT".equals(method)
                    && request.getParameterMap().containsKey("dsState")) {
                handlerName = Handlers.SETDATASTREAMSTATE;
            } else if ("PUT".equals(method)
                    && request.getParameterMap().containsKey("versionable")) {
                handlerName = Handlers.SETDATASTREAMVERSIONABLE;
            } else if ("PUT".equals(method)) {
                handlerName = Handlers.MODIFYDATASTREAM;
            } else if ("POST".equals(method)) {
                handlerName = Handlers.ADDDATASTREAM;
            } else if ("GET".equals(method)) {
                handlerName = Handlers.GETDATASTREAM;
            } else if ("DELETE".equals(method)) {
                handlerName = Handlers.PURGEDATASTREAM;
            }
            // - /objects/[pid]/datastreams/[dsid]/content
        } else if (parts.length == 5 && isPID(parts[1])
                && "datastreams".equals(parts[2]) && isDatastream(parts[3])
                && "content".equals(parts[4])) {
            handlerName = Handlers.GETDATASTREAMDISSEMINATION;

            // - /objects/[pid]/datastreams/[dsid]/history
        } else if (parts.length == 5 && isPID(parts[1]) && "datastreams".equals(parts[2]) && isDatastream(parts[3]) && "history".equals(parts[4])) {
            handlerName = Handlers.GETDATASTREAMHISTORY;

            // - /objects/[pid]/methods/[sdef]/method
        } else if (parts.length == 5 && isPID(parts[1])
                && "methods".equals(parts[2]) && isPID(parts[3]) && "GET".equals(method)) {
            handlerName = Handlers.GETDISSEMINATION;

            // - /objects/[pid]/methods/[sdef]
        } else if (parts.length == 4 && isPID(parts[1]) && "GET".equals(method) && "methods".equals(parts[2]) && isPID(parts[3])) {
            handlerName = Handlers.LISTMETHODS;

            // - /objects/[pid/relationships[/...]
        } else if (isPID(parts[1]) && "relationships".equals(parts[2])) {
            // add
            if ("POST".equals(method)) {
                handlerName = Handlers.ADDRELATIONSHIP;
                // get
            } else if ("GET".equals(method)) {
                handlerName = Handlers.GETRELATIONSHIPS;
                // purge
            } else if ("DELETE".equals(method)) {
                handlerName = Handlers.PURGERELATIONSHIP;
            }
        }


        RESTFilter handler = m_objectsHandlers.get(handlerName);
        if (handler != null) {
            if (logger.isDebugEnabled()) {
                logger.debug("activating handler: " + handlerName);
            }
            return handler;
        } else {
            // there must always be a handler
            throw new ServletException("No REST handler defined for method " + method + "(handler name: " + handlerName + ") path=" + path);
        }

    }

}
=======
public class ObjectsFilter implements RESTFilter {

	/* (non-Javadoc)
	 * @see org.fcrepo.server.security.xacml.pep.rest.filters.RESTFilter#handleRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public RequestCtx handleRequest(HttpServletRequest request, HttpServletResponse response) throws IOException,
			ServletException {
		// TODO Auto-generated method stub
		return null;
	}
>>>>>>> 547638622e4425f9db12d41c8aa7862c1b4926c9
Solution content
import com.sun.xacml.ctx.RequestCtx;

/**
 * Handles the get operations.
 *
 * @author nish.naidoo@gmail.com
 */
public class ObjectsFilter
        implements RESTFilter {

    /*
     * (non-Javadoc)
     * @see
     * org.fcrepo.server.security.xacml.pep.rest.filters.RESTFilter#handleRequest(javax.servlet
     * .http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public RequestCtx handleRequest(HttpServletRequest request,
                                    HttpServletResponse response)
            throws IOException, ServletException {
        return null;
    }
}
File
ObjectsFilter.java
Developer's decision
Manual
Kind of conflict
Attribute
Class declaration
Comment
Import
Method declaration
Method invocation