Projet

Général

Profil

Télécharger (7,23 ko) Statistiques
| Branche: | Tag: | Révision:
/*
* This program is a part of the IoTa Project.
*
* Copyright © 2011-2012 Université de Caen Basse-Normandie, GREYC
* Copyright © 2011 Orange Labs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* <http://www.gnu.org/licenses/>
*
* See AUTHORS for a list of contributors.
*/
package fr.unicaen.iota.xacml;

import com.sun.xacml.BasicEvaluationCtx;
import com.sun.xacml.EvaluationCtx;
import com.sun.xacml.PDPConfig;
import com.sun.xacml.ParsingException;
import com.sun.xacml.attr.AttributeValue;
import com.sun.xacml.ctx.RequestCtx;
import com.sun.xacml.ctx.ResponseCtx;
import com.sun.xacml.ctx.Result;
import com.sun.xacml.ctx.Status;
import com.sun.xacml.finder.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class EPCISPDP {

// the single attribute finder that can be used to find external values
private AttributeFinder attributeFinder;
// the single policy finder that will be used to resolve policies
private PolicyFinder policyFinder;
// the single resource finder that will be used to resolve resources
private ResourceFinder resourceFinder;
// the logger we'll use for all messages
private static final Log log = LogFactory.getLog(EPCISPDP.class);

public EPCISPDP(PDPConfig pDPConfig) {
log.trace("Instanciate EPCISPDP");
this.attributeFinder = pDPConfig.getAttributeFinder();
this.policyFinder = pDPConfig.getPolicyFinder();
this.policyFinder.init();
this.resourceFinder = pDPConfig.getResourceFinder();
}

public AttributeFinder getAttributeFinder() {
return attributeFinder;
}

public void setAttributeFinder(AttributeFinder attributeFinder) {
this.attributeFinder = attributeFinder;
}

public PolicyFinder getPolicyFinder() {
return policyFinder;
}

public void setPolicyFinder(PolicyFinder policyFinder) {
this.policyFinder = policyFinder;
}

public ResourceFinder getResourceFinder() {
return resourceFinder;
}

public void setResourceFinder(ResourceFinder resourceFinder) {
this.resourceFinder = resourceFinder;
}

//@Override
public ResponseCtx evaluate(RequestCtx request) {
// try to create the EvaluationCtx out of the request
try {
return evaluate(new BasicEvaluationCtx(request, attributeFinder));
} catch (ParsingException pe) {
log.info("the PDP receieved an invalid request", pe);

// there was something wrong with the request, so we return
// Indeterminate with a status of syntax error...though this
// may change if a more appropriate status type exists
ArrayList code = new ArrayList();
code.add(Status.STATUS_SYNTAX_ERROR);
Status status = new Status(code, pe.getMessage());
return new ResponseCtx(new Result(Result.DECISION_INDETERMINATE, status));
}
}

//@Override
public ResponseCtx evaluate(EvaluationCtx context) {
// see if we need to call the resource finder
if (context.getScope() != EvaluationCtx.SCOPE_IMMEDIATE) {
AttributeValue parent = context.getResourceId();
ResourceFinderResult resourceResult;

if (context.getScope() == EvaluationCtx.SCOPE_CHILDREN) {
resourceResult = resourceFinder.findChildResources(parent, context);
} else {
resourceResult = resourceFinder.findDescendantResources(parent, context);
}

// see if we actually found anything
if (resourceResult.isEmpty()) {
// this is a problem, since we couldn't find any resources
// to work on...the spec is not explicit about what kind of
// error this is, so we're treating it as a processing error
ArrayList code = new ArrayList();
code.add(Status.STATUS_PROCESSING_ERROR);
String msg = "Couldn't find any resources to work on.";

return new ResponseCtx(new Result(Result.DECISION_INDETERMINATE,
new Status(code, msg),
context.getResourceId().encode()));
}

// setup a set to keep track of the results
HashSet results = new HashSet();

// at this point, we need to go through all the resources we
// successfully found and start collecting results
Iterator it = resourceResult.getResources().iterator();
while (it.hasNext()) {
// get the next resource, and set it in the EvaluationCtx
AttributeValue resource = (AttributeValue) (it.next());
context.setResourceId(resource);

// do the evaluation, and set the resource in the result
Result result = evaluateContext(context);
log.trace("EPCISPDP evaluate: " + result.getDecision());
result.setResource(resource.encode());

// add the result
results.add(result);
}

// now that we've done all the successes, we add all the failures
// from the finder result
Map failureMap = resourceResult.getFailures();
it = failureMap.keySet().iterator();
while (it.hasNext()) {
// get the next resource, and use it to get its Status data
AttributeValue resource = (AttributeValue) (it.next());
Status status = (Status) (failureMap.get(resource));

// add a new result
results.add(new Result(Result.DECISION_INDETERMINATE,
status, resource.encode()));
}

// return the set of results
return new ResponseCtx(results);
} else {
// the scope was IMMEDIATE (or missing), so we can just evaluate
// the request and return whatever we get back
return new ResponseCtx(evaluateContext(context));
}
}

private Result evaluateContext(EvaluationCtx context) {
// first off, try to find a policy
PolicyFinderResult finderResult = policyFinder.findPolicy(context);

// see if there weren't any applicable policies
if (finderResult.notApplicable()) {
return new Result(Result.DECISION_DENY,
context.getResourceId().encode());
}

if (finderResult.indeterminate()) {
return new Result(Result.DECISION_DENY,
finderResult.getStatus(),
context.getResourceId().encode());
}
Result result = finderResult.getPolicy().evaluate(context);
return result;
}
}
(3-3/5)