/* * File: FieldSearchResultHandler.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.ws.operations; import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.ws.handler.soap.SOAPMessageContext; import org.fcrepo.common.Constants; import org.fcrepo.server.security.RequestCtx; import org.fcrepo.server.security.xacml.pep.ContextHandler; import org.fcrepo.server.security.xacml.pep.PEPException; import org.fcrepo.server.security.xacml.pep.ResourceAttributes; import org.fcrepo.server.types.gen.FieldSearchResult; import org.fcrepo.server.types.gen.ObjectFields; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.jboss.security.xacml.sunxacml.attr.AttributeValue; import org.jboss.security.xacml.sunxacml.attr.StringAttribute; import org.jboss.security.xacml.sunxacml.ctx.ResponseCtx; import org.jboss.security.xacml.sunxacml.ctx.Result; import org.jboss.security.xacml.sunxacml.ctx.Status; /** * This class handles the filtering of search results for both the findObjects * and resumeFindObjects operations and is called by each of them. * * @author nishen@melcoe.mq.edu.au */ public class FieldSearchResultHandler extends AbstractOperationHandler { private static final Logger logger = LoggerFactory.getLogger(FieldSearchResultHandler.class); /** * Default constructor. * * @throws PEPException */ public FieldSearchResultHandler(ContextHandler contextHandler) throws PEPException { super(contextHandler); } /** * Removes non-permissable objects from the result list. * * @param context * the message context * @param result * the search result object * @return the new search result object without non-permissable items * @throws PEPException */ public FieldSearchResult filter(SOAPMessageContext context, FieldSearchResult result) throws PEPException { if (result == null || result.getResultList() == null || result.getResultList().getObjectFields() == null || result.getResultList().getObjectFields().isEmpty()) { return result; } List<ObjectFields> objs = result.getResultList().getObjectFields(); RequestCtx[] requests = new RequestCtx[objs.size()]; int ix = 0; Map<String, ObjectFields> objects = new HashMap<String, ObjectFields>(); for (ObjectFields o : objs) { logger.debug("Checking: {}", o.getPid()); Map<URI, AttributeValue> actions = new HashMap<URI, AttributeValue>(); Map<URI, AttributeValue> resAttr; String pid = o.getPid() != null ? o.getPid().getValue() : null; if (pid != null && !pid.isEmpty()) { objects.put(pid, o); try { actions .put(Constants.ACTION.ID.getURI(), new StringAttribute(Constants.ACTION.LIST_OBJECT_IN_FIELD_SEARCH_RESULTS .getURI().toASCIIString())); actions.put(Constants.ACTION.API.getURI(), new StringAttribute(Constants.ACTION.APIA.getURI() .toASCIIString())); resAttr = ResourceAttributes.getResources(pid); RequestCtx req = getContextHandler() .buildRequest(getSubjects(context), actions, resAttr, getEnvironment(context)); requests[ix++] = req; } catch (Exception e) { logger.error(e.getMessage(), e); throw new OperationHandlerException(e.getMessage(), e); } } } ResponseCtx resCtx = getContextHandler().evaluateBatch(requests); @SuppressWarnings("unchecked") Set<Result> results = resCtx.getResults(); List<ObjectFields> resultObjects = new ArrayList<ObjectFields>(); for (Result r : results) { String resource = r.getResource(); if (resource == null || resource.isEmpty()) { logger.warn("This resource has no resource identifier in the xacml response results!"); } else { logger.debug("Checking: {}", resource); } int lastSlash = resource.lastIndexOf('/'); String rid = resource.substring(lastSlash + 1); if (r.getStatus().getCode().contains(Status.STATUS_OK) && r.getDecision() == Result.DECISION_PERMIT) { ObjectFields tmp = objects.get(rid); if (tmp != null) { resultObjects.add(tmp); logger.debug("Adding: {}[{}]", resource, rid); } else { logger.warn("Not adding this object as no object found for this key: {}[{}]", resource, rid); } } } FieldSearchResult.ResultList rl = new FieldSearchResult.ResultList(); rl.getObjectFields().addAll(resultObjects); result.setResultList(rl); return result; } /* * (non-Javadoc) * @see * org.fcrepo.server.security.xacml.pep.ws.operations.OperationHandler#handleRequest(SOAPMessageContext) */ @Override public RequestCtx handleRequest(SOAPMessageContext context) throws OperationHandlerException { RequestCtx req = null; Map<URI, AttributeValue> resAttr; Map<URI, AttributeValue> actions = new HashMap<URI, AttributeValue>(); try { resAttr = ResourceAttributes.getRepositoryResources(); actions.put(Constants.ACTION.ID.getURI(), new StringAttribute(Constants.ACTION.FIND_OBJECTS .getURI().toASCIIString())); actions.put(Constants.ACTION.API.getURI(), new StringAttribute(Constants.ACTION.APIA.getURI() .toASCIIString())); req = getContextHandler().buildRequest(getSubjects(context), actions, resAttr, getEnvironment(context)); } catch (Exception e) { logger.error(e.getMessage(), e); throw new OperationHandlerException(e.getMessage(), e); } return req; } /* * (non-Javadoc) * @see * org.fcrepo.server.security.xacml.pep.ws.operations.OperationHandler#handleResponse(SOAPMessageContext) */ @Override public RequestCtx handleResponse(SOAPMessageContext context) throws OperationHandlerException { try { Object response = getSOAPResponseObject(context); org.fcrepo.server.types.gen.FieldSearchResult result = (org.fcrepo.server.types.gen.FieldSearchResult) callGetter("getResult",response); result = filter(context, result); Method setter = response.getClass().getDeclaredMethod("setResult", org.fcrepo.server.types.gen.FieldSearchResult.class); setter.invoke(response, result); setSOAPResponseObject(context, response); } catch (Exception e) { logger.error("Error filtering Objects", e); throw new OperationHandlerException("Error filtering Objects", e); } return null; } }