diff options
| author | wbauer <wbauer@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2008-09-04 14:56:54 +0000 | 
|---|---|---|
| committer | wbauer <wbauer@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2008-09-04 14:56:54 +0000 | 
| commit | e0f2c64ad6360e2ecec983cb5e0a60f812672106 (patch) | |
| tree | 75040ef0d3424c8722d81163570c6770125b4d8c /bkucommon/src | |
| parent | ea5a30db385d2859cc45c889877954bda00ac560 (diff) | |
| download | mocca-e0f2c64ad6360e2ecec983cb5e0a60f812672106.tar.gz mocca-e0f2c64ad6360e2ecec983cb5e0a60f812672106.tar.bz2 mocca-e0f2c64ad6360e2ecec983cb5e0a60f812672106.zip | |
finished access controller, accessed it from command invoker and 
configured everything within onlinebku 
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@14 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
Diffstat (limited to 'bkucommon/src')
28 files changed, 1465 insertions, 1012 deletions
| diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java index 3b75a5f2..cd837cd7 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AccessControllerFactory.java @@ -15,8 +15,9 @@ import at.gv.egiz.bku.accesscontrol.config.AccessControl;  import at.gv.egiz.bku.accesscontrol.config.Chain;
  import at.gv.egiz.bku.accesscontrol.config.Command;
  import at.gv.egiz.bku.accesscontrol.config.ObjectFactory;
 +import at.gv.egiz.bku.accesscontrol.config.Param;
  import at.gv.egiz.bku.accesscontrol.config.Rule;
 -import at.gv.egiz.bku.slcommands.impl.InfoboxReadCommandImpl;
 +import at.gv.egiz.bku.accesscontroller.RuleChecker.PEER_TYPE;
  import at.gv.egiz.bku.slexceptions.SLRuntimeException;
  public class AccessControllerFactory {
 @@ -24,6 +25,8 @@ public class AccessControllerFactory {  	private static AccessControllerFactory instance = new AccessControllerFactory();
  	private static Log log = LogFactory.getLog(AccessControllerFactory.class);
  	private static JAXBContext jaxbContext;
 +	public static String INPUT_CHAIN = "InputChain";
 +	public static String OUTPUT_CHAIN = "OutputChain";
  	static {
  		try {
 @@ -63,43 +66,72 @@ public class AccessControllerFactory {  	public void registerChainChecker(ChainChecker cc) {
  		chainTable.put(cc.getId(), cc);
  	}
 -	
 +
 +	public CommandParamChecker createParamChecker(String cmd) {
 +		if ((cmd != null) && (cmd.startsWith("Infobox"))) {
 +			return new InfoboxParamChecker();
 +		} else {
 +			return null;
 +		}
 +	}
 +
  	public RuleChecker createRuleChecker(Rule rule) {
  		RuleChecker rc;
 +		rc = new RuleChecker(rule.getId());
  		Command cmd = rule.getCommand();
  		if (cmd != null) {
 -			if ((cmd.getParam() != null) && (cmd.getParam().size()>0)) {
 -				if (cmd.getName().startsWith("Infobox")) {
 -					rc = new InfoboxRuleChecker(rule.getId());
 -				} else {
 -					throw new SLRuntimeException("Cannot handle parameters for command "+cmd.getName());
 -				}
 -			} else {
 -				rc = new RuleChecker(rule.getId());
 +			rc.setCommandName(cmd.getName());
 +			for (Param p : cmd.getParam()) {
 +				rc.addParameter(p.getName(), p.getValue());
  			}
 -		} else {
 -			rc = new RuleChecker(rule.getId());
  		}
 -		// FIXME TODO cont. here
 -		
 -		
 -	return  rc;	
 +		rc.setAuthenticationClass(rule.getAuthClass());
 +		if (rule.getIPv4Address() != null) {
 +			rc.setPeerId(rule.getIPv4Address(), PEER_TYPE.IP);
 +		} else if (rule.getDomainName() != null) {
 +			rc.setPeerId(rule.getDomainName(), PEER_TYPE.HOST);
 +		} else if (rule.getURL() != null) {
 +			rc.setPeerId(rule.getURL(), PEER_TYPE.URL);
 +		}
 +		rc.setAction(rule.getAction().getRuleAction());
 +		rc.setChainId(rule.getAction().getChainRef());
 +		rc.setUserAction(rule.getUserInteraction());
 +		return rc;
  	}
 -	
 -	
 +
  	public void init(InputStream is) throws JAXBException {
 +		chainTable.clear();
  		Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
  		AccessControl ac = (AccessControl) unmarshaller.unmarshal(is);
  		List<Chain> chainList = ac.getChains().getChain();
 -		log.debug("Found "+chainList.size()+" chains in config");
 +		log.debug("Found " + chainList.size() + " chains in config");
  		for (Chain chain : chainList) {
 +			log.trace("Creating chain: " + chain.getId());
 +			ChainChecker cc = createChainChecker(chain.getId(), false);
  			List<Rule> ruleList = chain.getRules().getRule();
 -			log.debug("Found "+ruleList.size()+" rules in chain "+chain.getId());
 +			log
 +					.debug("Found " + ruleList.size() + " rules in chain "
 +							+ chain.getId());
  			for (Rule rule : ruleList) {
 -				//rule.g
 +				log.trace("Creating rule: " + rule.getId());
 +				cc.addRule(createRuleChecker(rule));
 +			}
 +			registerChainChecker(cc);
 +		}
 +		validate();
 +	}
 +	
 +	private void validate() {
 +		for (ChainChecker chain : chainTable.values()) {
 +			for (RuleChecker rule : chain.getRules()) {
 +				if (rule.getChainId() != null) {
 +					log.trace("Checking reference to chain: "+rule.getChainId());
 +					if (getChainChecker(rule.getChainId()) == null) {
 +						throw new SLRuntimeException("Invalid reference to unknown chain: "+rule.getChainId());
 +					}
 +				}
  			}
  		}
 -		
  	}
  }
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java index 242d9b02..a290fe8d 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/ChainChecker.java @@ -1,5 +1,6 @@  package at.gv.egiz.bku.accesscontroller;
 +import java.util.Collections;
  import java.util.LinkedList;
  import java.util.List;
 @@ -35,6 +36,10 @@ public class ChainChecker implements AccessChecker {  			rules.add(rule);
  		}
  	}
 +	
 +	public List<RuleChecker> getRules() {
 +		return Collections.unmodifiableList(rules);
 +	}
  	@Override
  	public ChainResult check(AccessCheckerContext checkCtx) throws SLException {
 @@ -43,7 +48,6 @@ public class ChainChecker implements AccessChecker {  			log.trace("Checking rule: "+rule.getId());
  			RuleResult result = rule.check(checkCtx);
  			if (result.matchFound()) {
 -				log.debug("Found matching rule: "+rule.getId());
  				if (result.getDelegateChainId() != null) {
  					// process chain
  					ChainChecker cc = AccessControllerFactory.getInstance().getChainChecker(result.getDelegateChainId());
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/CommandParamChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/CommandParamChecker.java new file mode 100644 index 00000000..3927c3c9 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/CommandParamChecker.java @@ -0,0 +1,52 @@ +package at.gv.egiz.bku.accesscontroller;
 +
 +import java.util.LinkedList;
 +import java.util.List;
 +
 +import at.gv.egiz.bku.slcommands.SLCommand;
 +
 +public abstract class CommandParamChecker {
 +
 +	protected List<Tupel<String, String>> paramList = new LinkedList<Tupel<String, String>>();
 +
 +	public static class Tupel<T, Q> {
 +		private T key;
 +		private Q val;
 +
 +		public Tupel(T key, Q val) {
 +			if ((key == null) || (val == null)) {
 +				throw new NullPointerException("Tupel key and value must not be null");
 +			}
 +			this.key = key;
 +			this.val = val;
 +		}
 +
 +		public T getKey() {
 +			return key;
 +		}
 +
 +		public Q getVal() {
 +			return val;
 +		}
 +
 +		@SuppressWarnings("unchecked")
 +		public boolean equals(Object other) {
 +			if (other instanceof Tupel) {
 +				Tupel ot = (Tupel) other;
 +				return (key.equals(ot.key) && val.equals(ot.val));
 +			}
 +			return false;
 +		}
 +
 +		public int hashCode() {
 +			return key.hashCode();
 +		}
 +	}
 +
 +	public void addParameter(String key, String value) {
 +		paramList.add(new Tupel<String, String>(key, value));
 +	}
 +
 +	public abstract boolean checkParameter(SLCommand cmd);
 +
 +}
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java new file mode 100644 index 00000000..33689ae0 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxParamChecker.java @@ -0,0 +1,58 @@ +package at.gv.egiz.bku.accesscontroller;
 +
 +import java.util.regex.Matcher;
 +import java.util.regex.Pattern;
 +
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +
 +import at.gv.egiz.bku.slcommands.InfoboxReadCommand;
 +import at.gv.egiz.bku.slcommands.SLCommand;
 +import at.gv.egiz.bku.slexceptions.SLRuntimeException;
 +
 +public class InfoboxParamChecker extends CommandParamChecker {
 +	private static Log log = LogFactory.getLog(InfoboxParamChecker.class);
 +
 +	public final static String INFOBOX_ID = "InfoboxIdentifier";
 +	public final static String PERSON_ID = "PersonIdentifier";
 +	public final static String DERIVED = "derived";
 +
 +	@Override
 +	public boolean checkParameter(SLCommand cmd) {
 +		if (paramList.size() == 0) {
 +			return true;
 +		}
 +
 +		if (cmd instanceof InfoboxReadCommand) {
 +			InfoboxReadCommand irc = (InfoboxReadCommand) cmd;
 +			for (Tupel<String, String> param : paramList) {
 +				if (param.getKey().equals(INFOBOX_ID)) {
 +					if (!param.getVal().equals(irc.getInfoboxIdentifier())) {
 +						return false;
 +					}
 +				} else if (param.getKey().equals(PERSON_ID)) {
 +					if (param.getVal().equals(DERIVED)) {
 +						if (irc.getIdentityLinkDomainId() == null) {
 +							return false;
 +						}
 +					} else {
 +						Pattern p = Pattern.compile(param.getVal());
 +						Matcher m = p.matcher(irc.getIdentityLinkDomainId());
 +						if (!m.matches()) {
 +							return false;
 +						}
 +					}
 +
 +				} else {
 +					throw new SLRuntimeException("Cannot handle parameter "
 +							+ param.getKey());
 +				}
 +			}
 +			return true;
 +		} else {
 +			log.error("Cannot handle parameter for command: " + cmd.getName());
 +			throw new SLRuntimeException("Cannot handle parameters for command: "
 +					+ cmd.getName());
 +		}
 +	}
 +}
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxRuleChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxRuleChecker.java deleted file mode 100644 index 2981d24e..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/InfoboxRuleChecker.java +++ /dev/null @@ -1,14 +0,0 @@ -package at.gv.egiz.bku.accesscontroller;
 -
 -/**
 - * Adds infobox parameter checks
 - * @author wbauer
 - *
 - */
 -public class InfoboxRuleChecker extends RuleChecker {
 -
 -	public InfoboxRuleChecker(String id) {
 -		super(id);
 -	}
 -
 -}
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java index c59f5b70..b0bf7fac 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/RuleChecker.java @@ -31,6 +31,7 @@ public class RuleChecker implements AccessChecker {  	protected Action action;
  	protected UserAction userAction;
  	protected String chainId;
 +	protected CommandParamChecker paramChecker;
  	public RuleChecker(String id) {
  		if (id == null) {
 @@ -40,27 +41,33 @@ public class RuleChecker implements AccessChecker {  	}
  	public void setAuthenticationClass(String ac) {
 -		AuthenticationClass tmp = AuthenticationClass.fromString(ac);
 -		if (tmp == null) {
 -			throw new SLRuntimeException("Unknown authentication class " + ac);
 +		if (ac != null) {
 +			AuthenticationClass tmp = AuthenticationClass.fromString(ac);
 +			if (tmp == null) {
 +				throw new SLRuntimeException("Unknown authentication class " + ac);
 +			}
 +			authenticationClass = tmp;
  		}
 -		authenticationClass = tmp;
  	}
  	public void setAction(String ac) {
 -		Action tmp = Action.fromString(ac);
 -		if (tmp == null) {
 -			throw new SLRuntimeException("Unknown action " + ac);
 +		if (ac != null) {
 +			Action tmp = Action.fromString(ac);
 +			if (tmp == null) {
 +				throw new SLRuntimeException("Unknown action " + ac);
 +			}
 +			action = tmp;
  		}
 -		action = tmp;
  	}
  	public void setUserAction(String uac) {
 -		UserAction tmp = UserAction.fromString(uac);
 -		if (tmp == null) {
 -			throw new SLRuntimeException("Unknown user action " + uac);
 +		if (uac != null) {
 +			UserAction tmp = UserAction.fromString(uac);
 +			if (tmp == null) {
 +				throw new SLRuntimeException("Unknown user action " + uac);
 +			}
 +			userAction = tmp;
  		}
 -		userAction = tmp;
  	}
  	public void setChainId(String chainId) {
 @@ -76,6 +83,22 @@ public class RuleChecker implements AccessChecker {  	public void setCommandName(String commandName) {
  		this.commandName = commandName;
  		commandNamePattern = Pattern.compile(commandName);
 +		paramChecker = AccessControllerFactory.getInstance().createParamChecker(
 +				commandName);
 +	}
 +
 +	/**
 +	 * Make sure to set the commandName first
 +	 * 
 +	 * @param key
 +	 * @param value
 +	 */
 +	public void addParameter(String key, String value) {
 +		if (paramChecker == null) {
 +			throw new IllegalArgumentException("Cannot set parameters for command "
 +					+ commandName);
 +		}
 +		paramChecker.addParameter(key, value);
  	}
  	public String getId() {
 @@ -83,22 +106,30 @@ public class RuleChecker implements AccessChecker {  	}
  	protected boolean matchAuthenticationClass(AuthenticationClass cls) {
 -		if (this.authenticationClass == null) {
 +		if ((this.authenticationClass == null) || (cls == null)) {
  			return true;
  		}
  		return this.authenticationClass.compareTo(cls) <= 0;
  	}
  	protected boolean matchCommandName(SLCommand cmd) {
 -		if (commandName == null) {
 +		if ((commandName == null) || (cmd == null)) {
  			return true;
  		}
  		Matcher matcher = commandNamePattern.matcher(cmd.getName());
 -		return matcher.matches();
 +		if (matcher.matches()) {
 +			if (paramChecker != null) {
 +				return paramChecker.checkParameter(cmd);
 +			} else {
 +				return true;
 +			}
 +		} else {
 +			return false;
 +		}
  	}
  	protected boolean matchPeerId(String peerUrl) {
 -		if (peerId == null) {
 +		if ((peerId == null) || (peerUrl == null)) {
  			return true;
  		}
  		if (peerType == PEER_TYPE.URL) {
 @@ -110,7 +141,8 @@ public class RuleChecker implements AccessChecker {  				if (peerType == PEER_TYPE.HOST) {
  					try {
  						String host = url.getHost();
 -						String hostName = InetAddress.getByName(host).getCanonicalHostName();
 +						String hostName = InetAddress.getByName(host)
 +								.getCanonicalHostName();
  						Matcher matcher = peerIdPattern.matcher(hostName);
  						return matcher.matches();
  					} catch (UnknownHostException e) {
 @@ -143,9 +175,13 @@ public class RuleChecker implements AccessChecker {  				&& matchPeerId(checkCtx.getPeerUrl())) {
  			log.debug("Match found for rule: " + id);
  			return new RuleResult(action, userAction, true, chainId);
 -		} 
 +		}
  		log.debug("No match found for rule: " + id);
  		return new RuleResult(action, userAction, false, chainId);
  	}
 +	public String getChainId() {
 +		return chainId;
 +	}
 +
  }
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java new file mode 100644 index 00000000..32242772 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/SecurityManagerFacade.java @@ -0,0 +1,102 @@ +package at.gv.egiz.bku.accesscontroller;
 +
 +import java.io.InputStream;
 +
 +import javax.xml.bind.JAXBException;
 +
 +import org.apache.commons.logging.Log;
 +import org.apache.commons.logging.LogFactory;
 +
 +import at.gv.egiz.bku.slcommands.SLCommand;
 +import at.gv.egiz.bku.slcommands.SLSourceContext;
 +import at.gv.egiz.bku.slcommands.SLTargetContext;
 +
 +/**
 + * Facade for the access controller
 + */
 +public class SecurityManagerFacade {
 +
 +	private static Log log = LogFactory.getLog(SecurityManagerFacade.class);
 +
 +	private boolean allowUnmatched = false;
 +	private ChainChecker inputFilter = null;
 +	private ChainChecker outputFilter = null;
 +	
 +	public boolean mayInvokeCommand(SLCommand cmd, SLSourceContext ctx) {
 +		if (inputFilter != null) {
 +			AuthenticationClass ac = AuthenticationClassifier.getAuthenticationClass(
 +					ctx.isSourceIsDataURL(), ctx.getSourceUrl(), ctx
 +							.getSourceCertificate());
 +			AccessCheckerContext acc = new AccessCheckerContext(cmd, ac, ctx
 +					.getSourceUrl().toString());
 +			try {
 +				ChainResult cr = inputFilter.check(acc);
 +				if (cr.matchFound()) {
 +					if (cr.getAction() == Action.ALLOW) {
 +						return true;
 +					} else {
 +						return false;
 +					}
 +				} else {
 +					return allowUnmatched;
 +				}
 +			} catch (Exception e) {
 +				log.error(e);
 +				return false;
 +			}
 +		} else {
 +			log.warn("No input chain defined");
 +			return allowUnmatched;
 +		}
 +	}
 +
 +	public boolean maySendResult(SLCommand cmd, SLTargetContext ctx) {
 +		if (outputFilter != null) {
 +			AuthenticationClass ac = AuthenticationClassifier.getAuthenticationClass(
 +					ctx.isTargetIsDataURL(), ctx.getTargetUrl(), ctx
 +							.getTargetCertificate());
 +			AccessCheckerContext acc = new AccessCheckerContext(cmd, ac, ctx
 +					.getTargetUrl().toString());
 +			try {
 +				ChainResult cr = outputFilter.check(acc);
 +				if (cr.matchFound()) {
 +					if (cr.getAction() == Action.ALLOW) {
 +						return true;
 +					} else {
 +						return false;
 +					}
 +				} else {
 +					return allowUnmatched;
 +				}
 +			} catch (Exception e) {
 +				log.error(e);
 +				return false;
 +			}
 +		} else {
 +			log.warn("No output chain defined");
 +			return allowUnmatched;
 +		}
 +	}
 +
 +	/**
 +	 * Default policy if not match was found
 +	 * 
 +	 * @param allow
 +	 */
 +	public void setAllowUnmatched(boolean allow) {
 +		this.allowUnmatched = allow;
 +	}
 +
 +	public void init(InputStream is) {
 +		inputFilter = null;
 +		outputFilter = null;
 +		AccessControllerFactory fab = AccessControllerFactory.getInstance();
 +		try {
 +			fab.init(is);
 +		} catch (JAXBException e) {
 +			log.error(e);
 +		}
 +		inputFilter = fab.getChainChecker(AccessControllerFactory.INPUT_CHAIN);
 +		outputFilter = fab.getChainChecker(AccessControllerFactory.OUTPUT_CHAIN);
 +	}
 +}
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java index a4e5bd90..ed37f08f 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManager.java @@ -16,6 +16,7 @@  */  package at.gv.egiz.bku.binding;
 +import java.net.MalformedURLException;  import java.util.Locale;
  import java.util.Set;
 @@ -34,28 +35,28 @@ public interface BindingProcessorManager {     * FactoryMethod creating a new BindingProcessor object.
     * The created binding processor must be passed to the process method to execute.
     * 
 -   * @param protcol
 -   *          the transport binding protocol
 +   * @param urlString
 +   *          the source url
     * @param aSessionId
     *          optional an external sessionId (e.g. http session) could be
     *          provided. This parameter may be null.
     * @param locale the locale used for user interaction, may be null
     */
 -  public BindingProcessor createBindingProcessor(String protcol,
 -      String aSessionId, Locale locale);
 +  public BindingProcessor createBindingProcessor(String urlString,
 +      String aSessionId, Locale locale) throws MalformedURLException;
    /**
     * FactoryMethod creating a new BindingProcessor object.
     * The created binding processor must be passed to the process method to execute.
     * 
     * @param protcol
 -   *          the transport binding protocol
 +   *          the source url
     * @param aSessionId
     *          optional an external sessionId (e.g. http session) could be
     *          provided. This parameter may be null.
     */
 -  public BindingProcessor createBindingProcessor(String protcol,
 -      String aSessionId);
 +  public BindingProcessor createBindingProcessor(String urlString,
 +      String aSessionId) throws MalformedURLException;
    /**
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java index 7a3b1bb9..6f5ca2d2 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessorManagerImpl.java @@ -16,6 +16,8 @@  */  package at.gv.egiz.bku.binding;
 +import java.net.MalformedURLException; +import java.net.URL;  import java.util.Collections;
  import java.util.HashMap;
  import java.util.HashSet;
 @@ -152,20 +154,22 @@ public class BindingProcessorManagerImpl implements BindingProcessorManager {    /**
     * Uses the default locale
     */
 -  public BindingProcessor createBindingProcessor(String protocol,
 -      String aSessionId) {
 -    return createBindingProcessor(protocol, aSessionId, null);
 +  public BindingProcessor createBindingProcessor(String srcUrl,
 +      String aSessionId) throws MalformedURLException  {
 +    return createBindingProcessor(srcUrl, aSessionId, null);
    }
    /**
     * FactoryMethod creating a new BindingProcessor object.
     * 
     * @param protocol
 -   *          must not be null
 +   *          must not be null +   * @throws MalformedURLException 
     */
 -  public BindingProcessor createBindingProcessor(String protocol,
 -      String aSessionId, Locale locale) {
 -    String low = protocol.toLowerCase();
 +  public BindingProcessor createBindingProcessor(String srcUrl,
 +      String aSessionId, Locale locale) throws MalformedURLException { +  	URL url = new URL(srcUrl);
 +    String low = url.getProtocol().toLowerCase();
      Protocol proto = null;
      for (int i = 0; i < SUPPORTED_PROTOCOLS.length; i++) {
        if (SUPPORTED_PROTOCOLS[i].toString().equals(low)) {
 @@ -177,7 +181,7 @@ public class BindingProcessorManagerImpl implements BindingProcessorManager {        throw new UnsupportedOperationException();
      }
      BindingProcessor bindingProcessor = new HTTPBindingProcessor(aSessionId,
 -        commandInvokerClass.newInstance(), proto);
 +        commandInvokerClass.newInstance(), url);
      STAL stal = stalFactory.createSTAL();
      bindingProcessor.init(stal, commandInvokerClass.newInstance());
      if (locale != null) {
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java index e6d5e075..6d654639 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java @@ -16,12 +16,13 @@  */  package at.gv.egiz.bku.binding;
 -import java.io.IOException;
 -import java.io.InputStream;
 -import java.net.SocketTimeoutException;
 -import java.security.cert.X509Certificate;
 -
 -import at.gv.egiz.bku.slcommands.SLResult;
 +import java.io.IOException; +import java.io.InputStream; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.security.cert.X509Certificate; + +import at.gv.egiz.bku.slcommands.SLResult;  /**
   * Transmit a security layer result to DataURL via HTTP POST, encoded as multipart/form-data. 
 @@ -41,7 +42,9 @@ public interface DataUrlConnection {      public static final String XML_RESPONSE_ENCODING = "UTF-8";
 -    public String getProtocol();
 +    public String getProtocol(); +     +    public URL getUrl();
      /**
       * Set a HTTP Header.
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java index 134d765e..9f5d70cb 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java @@ -212,5 +212,10 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI {    @Override
    public DataUrlConnectionSPI newInstance() {
      return new DataUrlConnectionImpl();
 -  }
 +  } + +	@Override +	public URL getUrl() { +		return url; +	}
  }
\ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java index b79f7d55..19f22126 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java @@ -1,820 +1,818 @@  /* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* 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 at.gv.egiz.bku.binding;
 -
 -import java.io.IOException;
 -import java.io.InputStream;
 -import java.io.InputStreamReader;
 -import java.io.OutputStream;
 -import java.io.OutputStreamWriter;
 -import java.io.Reader;
 -import java.security.cert.X509Certificate;
 -import java.util.ArrayList;
 -import java.util.Arrays;
 -import java.util.Collection;
 -import java.util.Collections;
 -import java.util.HashMap;
 -import java.util.Iterator;
 -import java.util.List;
 -import java.util.Locale;
 -import java.util.Map;
 -
 -import javax.net.ssl.SSLHandshakeException;
 -import javax.xml.transform.Transformer;
 -import javax.xml.transform.TransformerException;
 -import javax.xml.transform.TransformerFactory;
 -import javax.xml.transform.URIResolver;
 -import javax.xml.transform.stream.StreamResult;
 -import javax.xml.transform.stream.StreamSource;
 -
 -import org.apache.commons.logging.Log;
 -import org.apache.commons.logging.LogFactory;
 -
 -import at.gv.egiz.bku.slcommands.SLCommand;
 -import at.gv.egiz.bku.slcommands.SLCommandContext;
 -import at.gv.egiz.bku.slcommands.SLCommandFactory;
 -import at.gv.egiz.bku.slcommands.SLCommandInvoker;
 -import at.gv.egiz.bku.slcommands.SLResult;
 -import at.gv.egiz.bku.slcommands.SLSourceContext;
 -import at.gv.egiz.bku.slcommands.SLTargetContext;
 -import at.gv.egiz.bku.slcommands.impl.ErrorResultImpl;
 -import at.gv.egiz.bku.slexceptions.SLBindingException;
 -import at.gv.egiz.bku.slexceptions.SLCanceledException;
 -import at.gv.egiz.bku.slexceptions.SLException;
 -import at.gv.egiz.bku.slexceptions.SLRuntimeException;
 -import at.gv.egiz.bku.utils.StreamUtil;
 -import at.gv.egiz.bku.utils.binding.Protocol;
 -import at.gv.egiz.bku.utils.urldereferencer.FormDataURLSupplier;
 -import at.gv.egiz.bku.utils.urldereferencer.SimpleFormDataContextImpl;
 -import at.gv.egiz.bku.utils.urldereferencer.StreamData;
 -import at.gv.egiz.bku.utils.urldereferencer.URIResolverAdapter;
 -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
 -import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
 -import at.gv.egiz.stal.QuitRequest;
 -import at.gv.egiz.stal.STALRequest;
 -
 -/**
 - * Class performing the HTTP binding as defined by the CCE specification.
 - * Currently a huge monolithic class. 
 - * @TODO refactor 
 - */
 -@SuppressWarnings("unchecked")
 -public class HTTPBindingProcessor extends AbstractBindingProcessor implements
 -    FormDataURLSupplier {
 -
 -  private static Log log = LogFactory.getLog(HTTPBindingProcessor.class);
 -
 -  private static enum State {
 -    INIT, PROCESS, DATAURL, TRANSFORM, FINISHED
 -  };
 -
 -  public final static Collection<String> XML_REQ_TRANSFER_ENCODING = Arrays
 -      .asList(new String[] { "binary" });
 -
 -  /**
 -   * Defines the maximum number of dataurl connects that are allowed within a
 -   * single SL Request processing.
 -   */
 -  protected static int MAX_DATAURL_HOPS = 10;
 -
 -  protected static String XML_MIME_TYPE = "text/xml";
 -  protected static String BINARY_MIME_TYPE = "application/octet-stream";
 -
 -  /**
 -   * If null everything is ok and the result is taken from the command invoker.
 -   */
 -  protected SLException bindingProcessorError;
 -  protected SLCommandInvoker commandInvoker;
 -  protected DataUrlResponse dataUrlResponse;
 -  protected Map<String, String> headerMap = Collections.EMPTY_MAP;
 -  protected SLCommand slCommand;
 -  protected Map<String, FormParameter> formParameterMap = new HashMap<String, FormParameter>();
 -  protected SLSourceContext srcContex = new SLSourceContext();
 -  protected SLTargetContext targetContext = new SLTargetContext();
 -  protected Protocol protocol;
 -  protected State currentState = State.INIT;
 -  protected Transformer transformer = null;
 -  protected String resultContentType = null;
 -  protected SLResult slResult = null;
 -  protected int responseCode = 200;
 -  protected Map<String, String> responseHeaders = Collections.EMPTY_MAP;
 -  protected Locale locale = Locale.getDefault();
 -
 -  /**
 -   * 
 -   * @param id
 -   *          may be null. In this case a new session id will be created.
 -   * @param cmdInvoker
 -   *          must not be null;
 -   */
 -  public HTTPBindingProcessor(String id, SLCommandInvoker cmdInvoker,
 -      Protocol protocol) {
 -    super(id);
 -    if ((protocol != Protocol.HTTP) && (protocol != Protocol.HTTPS)) {
 -      throw new SLRuntimeException("Protocol not supported: " + protocol);
 -    }
 -    if (cmdInvoker == null) {
 -      throw new NullPointerException("Commandinvoker cannot be set to null");
 -    }
 -    commandInvoker = cmdInvoker;
 -    this.protocol = protocol;
 -    srcContex.setSourceProtocol(protocol);
 -    srcContex.setSourceIsDataURL(false);
 -  }
 -
 -  //----------------------------------------------------------------------------
 -  // ----------- BEGIN CONVENIENCE METHODS -----------
 -
 -  protected void sendSTALQuit() {
 -    log.info("Sending QUIT command to STAL");
 -    List<STALRequest> quit = new ArrayList<STALRequest>(1);
 -    quit.add(new QuitRequest());
 -    getSTAL().handleRequest(quit);
 -  }
 -
 -  protected String getFormParameterAsString(String formParameterName) {
 -    FormParameter fp = formParameterMap.get(formParameterName);
 -    return getFormParameterAsString(fp);
 -  }
 -
 -  protected String getFormParameterAsString(FormParameter fp) {
 -    if (fp == null) {
 -      return null;
 -    }
 -    try {
 -      return StreamUtil.asString(fp.getFormParameterValue(), HttpUtil
 -          .getCharset(fp.getFormParameterContentType(), true));
 -    } catch (IOException e) {
 -      return null;
 -    }
 -  }
 -
 -  protected String getDataUrl() {
 -    return getFormParameterAsString(FixedFormParameters.DATAURL);
 -  }
 -
 -  protected String getStyleSheetUrl() {
 -    return getFormParameterAsString(FixedFormParameters.STYLESHEETURL);
 -  }
 -
 -  protected List<FormParameter> getFormParameters(String parameterNamePostfix) {
 -    List<FormParameter> resultList = new ArrayList<FormParameter>();
 -    for (Iterator<String> fpi = formParameterMap.keySet().iterator(); fpi
 -        .hasNext();) {
 -      String paramName = fpi.next();
 -      if (paramName.endsWith(parameterNamePostfix)) {
 -        resultList.add(formParameterMap.get(paramName));
 -      }
 -    }
 -    return resultList;
 -  }
 -
 -  protected List<FormParameter> getTransferHeaders() {
 -    return getFormParameters("__");
 -  }
 -
 -  protected List<FormParameter> getTransferForms() {
 -    List<FormParameter> resultList = new ArrayList<FormParameter>();
 -    for (Iterator<String> fpi = formParameterMap.keySet().iterator(); fpi
 -        .hasNext();) {
 -      String paramName = fpi.next();
 -      if ((paramName.endsWith("_")) && (!paramName.endsWith("__"))) {
 -        resultList.add(formParameterMap.get(paramName));
 -      }
 -    }
 -    return resultList;
 -  }
 -
 -  protected void closeDataUrlConnection() {
 -    log.debug("Closing data url input stream");
 -    if (dataUrlResponse == null) {
 -      return;
 -    }
 -    InputStream is = dataUrlResponse.getStream();
 -    if (is != null) {
 -      try {
 -        is.close();
 -      } catch (IOException e) {
 -        log.info("Error closing input stream to dataurl server:" + e);
 -      }
 -    }
 -  }
 -
 -  //----------------------------------------------------------------------------
 -  // ----------- END CONVENIENCE METHODS -----------
 -
 -  //----------------------------------------------------------------------------
 -  // -- BEGIN Methods that handle the http binding activities as defined in the
 -  // activity diagram --
 -
 -  protected void init() {
 -    log.info("Starting Bindingprocessor in Thread: "
 -        + Thread.currentThread().getId());
 -    if (bindingProcessorError != null) {
 -      log.debug("Detected binding processor error, sending quit command");
 -      // sendSTALQuit();
 -      currentState = State.FINISHED;
 -    } else if (slCommand == null) {
 -      log.error("SLCommand not set (consumeRequest not called ??)");
 -      bindingProcessorError = new SLException(2000);
 -      // sendSTALQuit();
 -      currentState = State.FINISHED;
 -    } else {
 -      currentState = State.PROCESS;
 -    }
 -  }
 -
 -  protected void processRequest() {
 -    log.debug("Entered State: " + State.PROCESS);
 -    log.debug("Processing command: " + slCommand);
 -    commandInvoker.setCommand(slCommand);
 -    responseCode = 200;
 -    responseHeaders = Collections.EMPTY_MAP;
 -    try {
 -      commandInvoker.invoke(srcContex);
 -    } catch (SLCanceledException e) {
 -      log.info("Caught exception: " + e);
 -      bindingProcessorError = e;
 -      currentState = State.TRANSFORM;
 -    }
 -    dataUrlResponse = null;
 -    if (getDataUrl() != null) {
 -      log.debug("Data Url set to: " + getDataUrl());
 -      currentState = State.DATAURL;
 -    } else {
 -      log.debug("No data url set");
 -      currentState = State.TRANSFORM;
 -    }
 -  }
 -
 -  protected void handleDataUrl() {
 -    log.debug("Entered State: " + State.DATAURL);
 -    try {
 -      DataUrl dataUrl = new DataUrl(getDataUrl());
 -      DataUrlConnection conn = dataUrl.openConnection();
 -
 -      // set transfer headers
 -      for (FormParameter fp : getTransferHeaders()) {
 -        String paramString = getFormParameterAsString(fp);
 -        if (paramString == null) {
 -          log.error("Got empty transfer header, ignoring this");
 -        } else {
 -          String[] keyVal = paramString.split(":", 2);
 -          String key = keyVal[0];
 -          String val = null;
 -          if (keyVal.length == 2) {
 -            val = keyVal[1];
 -          }
 -          val = val.trim();
 -          log.debug("Setting header " + key + " to value " + val);
 -          conn.setHTTPHeader(key, val);
 -        }
 -      }
 -
 -      // set transfer form parameters
 -      for (FormParameter fp : getTransferForms()) {
 -        String contentTransferEncoding = null;
 -        String contentType = fp.getFormParameterContentType();
 -        String charSet = HttpUtil.getCharset(contentType, false);
 -        if (charSet != null) {
 -          contentType = contentType.substring(0, contentType
 -              .lastIndexOf(HttpUtil.SEPERATOR[0]));
 -        }
 -        for (Iterator<String> header = fp.getHeaderNames(); header.hasNext();) {
 -          if (HttpUtil.CONTENT_TRANSFER_ENCODING
 -              .equalsIgnoreCase(header.next())) {
 -            contentTransferEncoding = getFormParameterAsString(fp);
 -          }
 -        }
 -        log.debug("Setting form: " + fp.getFormParameterName()
 -            + " contentType: " + contentType + " charset: " + charSet
 -            + " contentTransferEncoding: " + contentTransferEncoding);
 -        conn.setHTTPFormParameter(fp.getFormParameterName(), fp
 -            .getFormParameterValue(), contentType, charSet,
 -            contentTransferEncoding);
 -      }
 -
 -      // connect
 -      conn.connect();
 -      // fetch and set SL result
 -      targetContext.setTargetIsDataURL(true);
 -      targetContext.setTargetCertificate(conn.getServerCertificate());
 -      targetContext.setTargetProtocol(conn.getProtocol());
 -      SLResult result = commandInvoker.getResult(targetContext);
 -
 -      // transfer result
 -      conn.transmit(result);
 -
 -      // process Dataurl response
 -      dataUrlResponse = conn.getResponse();
 -      log.debug("Received data url response code: "
 -          + dataUrlResponse.getResponseCode());
 -      protocol = Protocol.fromString(conn.getProtocol());
 -
 -      switch (dataUrlResponse.getResponseCode()) {
 -      case 200:
 -        String contentType = dataUrlResponse.getContentType();
 -        log.debug("Got dataurl response content type: " + contentType);
 -        if (contentType != null) {
 -          if ((contentType.startsWith(HttpUtil.APPLICATION_URL_ENCODED))
 -              || (contentType.startsWith(HttpUtil.MULTIPART_FOTMDATA))) {
 -            log.debug("Detected SL Request in dataurl response");
 -            // process headers and request
 -            setHTTPHeaders(dataUrlResponse.getResponseHeaders());
 -            consumeRequestStream(dataUrlResponse.getStream());
 -            closeDataUrlConnection();
 -            srcContex.setSourceCertificate(conn.getServerCertificate());
 -            srcContex.setSourceIsDataURL(true);
 -            srcContex
 -                .setSourceProtocol(Protocol.fromString(conn.getProtocol()));
 -            currentState = State.PROCESS;
 -          } else if (((contentType.startsWith(HttpUtil.TXT_HTML))
 -              || (contentType.startsWith(HttpUtil.TXT_PLAIN)) || (contentType
 -              .startsWith(HttpUtil.TXT_XML)))
 -              && (dataUrlResponse.isHttpResponseXMLOK())) {
 -            log.info("Dataurl response matches <ok/> with content type: "
 -                + contentType);
 -            currentState = State.TRANSFORM;
 -
 -          } else if ((contentType.startsWith(HttpUtil.TXT_XML))
 -              && (!dataUrlResponse.isHttpResponseXMLOK())) {
 -            log
 -                .debug("Detected text/xml  dataurl response with content != <ok/>");
 -            headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType);
 -            assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset(
 -                contentType, true));
 -            closeDataUrlConnection();
 -            srcContex.setSourceCertificate(conn.getServerCertificate());
 -            srcContex.setSourceIsDataURL(true);
 -            srcContex
 -                .setSourceProtocol(Protocol.fromString(conn.getProtocol()));
 -            currentState = State.PROCESS;
 -            // just to be complete, actually not used
 -            srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders()
 -                .get(HttpUtil.HTTP_HEADER_REFERER));
 -          } else {
 -            resultContentType = contentType;
 -            responseHeaders = dataUrlResponse.getResponseHeaders();
 -            responseCode = dataUrlResponse.getResponseCode();
 -            currentState = State.FINISHED;
 -          }
 -        } else {
 -          log.debug("Content type not set in dataurl response");
 -          closeDataUrlConnection();
 -          throw new SLBindingException(2007);
 -        }
 -
 -        break;
 -      case 307:
 -        contentType = dataUrlResponse.getContentType();
 -        if ((contentType != null) && (contentType.startsWith(HttpUtil.TXT_XML))) {
 -          log.debug("Received dataurl response code 307 with XML content");
 -          String location = dataUrlResponse.getResponseHeaders().get(
 -              HttpUtil.HTTP_HEADER_LOCATION);
 -          if (location == null) {
 -            log
 -                .error("Did not get a location header for a 307 data url response");
 -            throw new SLBindingException(2003);
 -          }
 -          // consumeRequestStream(dataUrlResponse.getStream());
 -          FormParameterStore fp = new FormParameterStore();
 -          fp.init(location.getBytes(HttpUtil.DEFAULT_CHARSET),
 -              FixedFormParameters.DATAURL, null, null);
 -          formParameterMap.put(FixedFormParameters.DATAURL, fp);
 -          headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType);
 -          assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset(
 -              dataUrlResponse.getContentType(), true));
 -          closeDataUrlConnection();
 -          srcContex.setSourceCertificate(conn.getServerCertificate());
 -          srcContex.setSourceIsDataURL(true);
 -          srcContex.setSourceProtocol(Protocol.fromString(conn.getProtocol()));
 -          currentState = State.PROCESS;
 -          // just to be complete, actually not used
 -          srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders()
 -              .get(HttpUtil.HTTP_HEADER_REFERER));
 -
 -        } else {
 -          log.debug("Received dataurl response code 307 non XML content: "
 -              + dataUrlResponse.getContentType());
 -          resultContentType = dataUrlResponse.getContentType();
 -          currentState = State.FINISHED;
 -        }
 -        responseHeaders = dataUrlResponse.getResponseHeaders();
 -        responseCode = dataUrlResponse.getResponseCode();
 -        break;
 -
 -      case 301:
 -      case 302:
 -      case 303:
 -        responseHeaders = dataUrlResponse.getResponseHeaders();
 -        responseCode = dataUrlResponse.getResponseCode();
 -        resultContentType = dataUrlResponse.getContentType();
 -        currentState = State.FINISHED;
 -        break;
 -
 -      default:
 -        // issue error
 -        log.info("Unexpected response code from dataurl server: "
 -            + dataUrlResponse.getResponseCode());
 -        throw new SLBindingException(2007);
 -      }
 -
 -    } catch (SLException slx) {
 -      bindingProcessorError = slx;
 -      log.error("Error during dataurl communication");
 -      resultContentType = HttpUtil.TXT_XML;
 -      currentState = State.TRANSFORM;
 -    } catch (SSLHandshakeException hx) {
 -      bindingProcessorError = new SLException(2010);
 -      log.info("Error during dataurl communication", hx);
 -      resultContentType = HttpUtil.TXT_XML;
 -      currentState = State.TRANSFORM;
 -    } catch (IOException e) {
 -      bindingProcessorError = new SLBindingException(2001);
 -      log.error("Error while data url handling", e);
 -      resultContentType = HttpUtil.TXT_XML;
 -      currentState = State.TRANSFORM;
 -      return;
 -    }
 -  }
 -
 -  protected void transformResult() {
 -    log.debug("Entered State: " + State.TRANSFORM);
 -    if (bindingProcessorError != null) {
 -      resultContentType = HttpUtil.TXT_XML;
 -    } else if (dataUrlResponse != null) {
 -      resultContentType = dataUrlResponse.getContentType();
 -    } else {
 -      targetContext.setTargetIsDataURL(false);
 -      targetContext.setTargetProtocol(protocol.toString());
 -      try {
 -        slResult = commandInvoker.getResult(targetContext);
 -        resultContentType = slResult.getMimeType();
 -        log
 -            .debug("Successfully got SLResult from commandinvoker, setting mimetype to: "
 -                + resultContentType);
 -      } catch (SLCanceledException e) {
 -        log.info("Cannot get result from invoker:", e);
 -        bindingProcessorError = new SLException(6002);
 -        resultContentType = HttpUtil.TXT_XML;
 -      }
 -    }
 -    transformer = getTransformer(getStyleSheetUrl());
 -    if (transformer != null) {
 -      log.debug("Output transformation required");
 -      resultContentType = transformer.getOutputProperty("media-type");
 -      log.debug("Got media type from stylesheet: " + resultContentType);
 -      if (resultContentType == null) {
 -        log.debug("Setting to default text/xml result conent type");
 -        resultContentType = "text/xml";
 -      }
 -      log.debug("Deferring sytylesheet processing");
 -    }
 -    currentState = State.FINISHED;
 -  }
 -
 -  protected void finished() {
 -    log.debug("Entered State: " + State.FINISHED);
 -    if (bindingProcessorError != null) {
 -      log.debug("Binding processor error, sending quit command");
 -      resultContentType = HttpUtil.TXT_XML;
 -    }
 -    sendSTALQuit();
 -    log.info("Terminating Bindingprocessor; Thread: "
 -        + Thread.currentThread().getId());
 -  }
 -
 -  // -- END Methods that handle the http binding activities as defined in the
 -  // activity diagram --
 -  //----------------------------------------------------------------------------
 -
 -  /**
 -   * Sets the headers of the SL Request. IMPORTANT: make sure to set all headers
 -   * before invoking {@link #consumeRequestStream(InputStream)}
 -   * 
 -   * @param aHeaderMap
 -   *          if null all header will be cleared.
 -   */
 -  public void setHTTPHeaders(Map<String, String> aHeaderMap) {
 -    headerMap = new HashMap<String, String>();
 -    // ensure lowercase keys
 -    if (aHeaderMap != null) {
 -      for (String s : aHeaderMap.keySet()) {
 -        if (s != null) {
 -          headerMap.put(s.toLowerCase(), aHeaderMap.get(s));
 -          if (s.equalsIgnoreCase(HttpUtil.HTTP_HEADER_REFERER)) {
 -            String referer = aHeaderMap.get(s);
 -            log.debug("Got referer header: " + referer);
 -            srcContex.setSourceHTTPReferer(referer);
 -          }
 -        }
 -      }
 -    }
 -  }
 -
 -  public void setSourceCertificate(X509Certificate aCert) {
 -    srcContex.setSourceCertificate(aCert);
 -  }
 -
 -  /**
 -   * The HTTPBindingProcessor does not handle redirect URLs. It only provides
 -   * the parameter.
 -   * 
 -   * @return null if redirect url is not set.
 -   */
 -  public String getRedirectURL() {
 -    return getFormParameterAsString(FixedFormParameters.REDIRECTURL);
 -  }
 -
 -  public String getFormDataContentType(String aParameterName) {
 -    FormParameter fp = formParameterMap.get(aParameterName);
 -    if (fp != null) {
 -      return fp.getFormParameterContentType();
 -    }
 -    return null;
 -  }
 -
 -  public InputStream getFormData(String aParameterName) {
 -    FormParameter fp = formParameterMap.get(aParameterName);
 -    if (fp != null) {
 -      return fp.getFormParameterValue();
 -    }
 -    return null;
 -  }
 -
 -  protected void assignXMLRequest(InputStream is, String charset)
 -      throws IOException, SLException {
 -    Reader r = new InputStreamReader(is, charset);
 -    StreamSource source = new StreamSource(r);
 -    SLCommandContext commandCtx = new SLCommandContext();
 -    commandCtx.setSTAL(getSTAL());
 -    commandCtx.setURLDereferencerContext(new SimpleFormDataContextImpl(this));
 -    slCommand = SLCommandFactory.getInstance().createSLCommand(source,
 -        commandCtx);
 -    log.debug("Created new command: " + slCommand);
 -  }
 -
 -  @Override
 -  public void run() {
 -    boolean done = false;
 -    int hopcounter = 0;
 -    if (bindingProcessorError != null) {
 -      currentState = State.FINISHED;
 -    }
 -    try {
 -      while (!done) {
 -        try {
 -          switch (currentState) {
 -          case INIT:
 -            init();
 -            break;
 -          case PROCESS:
 -            processRequest();
 -            break;
 -          case DATAURL:
 -            handleDataUrl();
 -            if (++hopcounter > MAX_DATAURL_HOPS) {
 -              log.error("Maximum number of dataurl hops reached");
 -              bindingProcessorError = new SLBindingException(2000);
 -              currentState = State.FINISHED;
 -            }
 -            break;
 -          case TRANSFORM:
 -            transformResult();
 -            break;
 -          case FINISHED:
 -            done = true;
 -            finished();
 -            break;
 -          }
 -        } catch (RuntimeException rte) {
 -          throw rte;
 -        } catch (Exception t) {
 -          log.error("Caught unexpected exception", t);
 -          responseCode = 200;
 -          resultContentType = HttpUtil.TXT_XML;
 -          responseHeaders = Collections.EMPTY_MAP;
 -          bindingProcessorError = new SLException(2000);
 -          currentState = State.FINISHED;
 -        }
 -      }
 -    } catch (Throwable t) {
 -      log.error("Caught unexpected exception", t);
 -      responseCode = 200;
 -      resultContentType = HttpUtil.TXT_XML;
 -      responseHeaders = Collections.EMPTY_MAP;
 -      bindingProcessorError = new SLException(2000);
 -      currentState = State.FINISHED;
 -    }
 -    log.debug("Terminated http binding processor");
 -  }
 -
 -  @Override
 -  public void consumeRequestStream(InputStream is) {
 -    try {
 -      log.debug("Start consuming request stream");
 -      formParameterMap.clear();
 -      String cl = headerMap
 -          .get(HttpUtil.HTTP_HEADER_CONTENT_TYPE.toLowerCase());
 -      if (cl == null) {
 -        log.info("No content type set in http header");
 -        throw new SLBindingException(2006);
 -      }
 -      InputDecoder id = InputDecoderFactory.getDecoder(cl, is);
 -      id.setContentType(cl);
 -      if (id == null) {
 -        log.error("Cannot get inputdecoder for is");
 -        throw new SLException(2006);
 -      }
 -      for (Iterator<FormParameter> fpi = id.getFormParameterIterator(); fpi
 -          .hasNext();) {
 -        FormParameter fp = fpi.next();
 -        log.debug("Got request parameter with name: "
 -            + fp.getFormParameterName());
 -        if (fp.getFormParameterName().equals(FixedFormParameters.XMLREQUEST)) {
 -          log.debug("Creating XML Request");
 -          for (Iterator<String> headerIterator = fp.getHeaderNames(); headerIterator
 -              .hasNext();) {
 -            String headerName = headerIterator.next();
 -            if (HttpUtil.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(headerName)) {
 -              String transferEncoding = fp.getHeaderValue(headerName);
 -              log.debug("Got transfer encoding for xmlrequest: "
 -                  + transferEncoding);
 -              if (XML_REQ_TRANSFER_ENCODING.contains(transferEncoding)) {
 -                log.debug("Supported transfer encoding: " + transferEncoding);
 -              } else {
 -                log
 -                    .error("Transferencoding not supported: "
 -                        + transferEncoding);
 -                throw new SLBindingException(2005);
 -              }
 -            }
 -          }
 -          String charset = HttpUtil.getCharset(cl, true);
 -          assignXMLRequest(fp.getFormParameterValue(), charset);
 -        } else {
 -          FormParameterStore fps = new FormParameterStore();
 -          fps.init(fp);
 -          if (!fps.isEmpty()) {
 -            log.debug("Setting from parameter: " + fps.getFormParameterName());
 -            formParameterMap.put(fps.getFormParameterName(), fps);
 -          }
 -        }
 -      }
 -      if (slCommand == null) {
 -        throw new SLBindingException(2004);
 -      }
 -      if (is.read() != -1) {
 -        log.error("Request input stream not completely read");
 -        // consume rest of stream, should never occur
 -        throw new SLRuntimeException(
 -            "request input stream not consumed till end");
 -      }
 -    } catch (SLException slx) {
 -      log.info("Error while consuming input stream " + slx);
 -      bindingProcessorError = slx;
 -    } catch (Throwable t) {
 -      log.info("Error while consuming input stream " + t, t);
 -      bindingProcessorError = new SLException(2000);
 -    } finally {
 -      try {
 -        while (is.read() != -1)
 -          ;
 -      } catch (IOException e) {
 -        log.error(e);
 -      }
 -    }
 -  }
 -
 -  @Override
 -  public String getResultContentType() {
 -    return resultContentType;
 -  }
 -
 -  protected Transformer getTransformer(String styleSheetURL) {
 -    if (styleSheetURL == null) {
 -      log.debug("Stylesheet URL not set");
 -      return null;
 -    }
 -    try {
 -      URLDereferencerContext urlCtx = new SimpleFormDataContextImpl(this);
 -      URIResolver resolver = new URIResolverAdapter(URLDereferencer
 -          .getInstance(), urlCtx);
 -      TransformerFactory factory = TransformerFactory.newInstance();
 -      StreamData sd = URLDereferencer.getInstance().dereference(styleSheetURL,
 -          urlCtx);
 -      Transformer t = factory.newTransformer(new StreamSource(sd.getStream()));
 -      t.setURIResolver(resolver);
 -      return t;
 -    } catch (Exception ex) {
 -      log.info("Cannot instantiate transformer", ex);
 -      bindingProcessorError = new SLException(2002);
 -      return null;
 -    }
 -  }
 -
 -  protected void handleBindingProcessorError(OutputStream os, String encoding,
 -      Transformer transformer) throws IOException {
 -    log.debug("Writing error as result");
 -    ErrorResultImpl error = new ErrorResultImpl(bindingProcessorError);
 -    try {
 -      error.writeTo(new StreamResult(new OutputStreamWriter(os, encoding)),
 -          transformer);
 -    } catch (TransformerException e) {
 -      log.fatal("Cannot write error result to stream", e);
 -    }
 -  }
 -
 -  @Override
 -  public void writeResultTo(OutputStream os, String encoding)
 -      throws IOException {
 -    if (encoding == null) {
 -      encoding = HttpUtil.DEFAULT_CHARSET;
 -    }
 -    if (bindingProcessorError != null) {
 -      log.debug("Detected error in binding processor, writing error as result");
 -      handleBindingProcessorError(os, encoding, transformer);
 -      return;
 -    } else if (dataUrlResponse != null) {
 -      log.debug("Writing data url response  as result");
 -      String charEnc = HttpUtil.getCharset(dataUrlResponse.getContentType(),
 -          true);
 -      InputStreamReader isr = new InputStreamReader(
 -          dataUrlResponse.getStream(), charEnc);
 -      OutputStreamWriter osw = new OutputStreamWriter(os, encoding);
 -      if (transformer == null) {
 -        StreamUtil.copyStream(isr, osw);
 -      } else {
 -        try {
 -          transformer.transform(new StreamSource(isr), new StreamResult(osw));
 -        } catch (TransformerException e) {
 -          log.fatal("Exception occured during result transformation", e);
 -          // bindingProcessorError = new SLException(2008);
 -          // handleBindingProcessorError(os, encoding, null);
 -          return;
 -        }
 -      }
 -      osw.flush();
 -      isr.close();
 -    } else if (slResult == null) {
 -      // result not yet assigned -> must be a cancel
 -      bindingProcessorError = new SLException(6001);
 -      handleBindingProcessorError(os, encoding, transformer);
 -      return;
 -    } else {
 -      log.debug("Getting result from invoker");
 -      OutputStreamWriter osw = new OutputStreamWriter(os, encoding);
 -      try {
 -        slResult.writeTo(new StreamResult(osw), transformer);
 -      } catch (TransformerException e) {
 -        log.fatal("Cannot write result to stream", e);
 -        // bindingProcessorError = new SLException(2008);
 -        // handleBindingProcessorError(os, encoding, transformer);
 -      }
 -      osw.flush();
 -    }
 -  }
 -
 -  /**
 -   * The response code from the dataurl server or 200 if no dataurl server
 -   * created the result
 -   * 
 -   * @return
 -   */
 -  public int getResponseCode() {
 -    return responseCode;
 -  }
 -
 -  /**
 -   * All headers from the data url server in case of a direct forward from the
 -   * dataurl server.
 -   * 
 -   * @return
 -   */
 -  public Map<String, String> getResponseHeaders() {
 -    return responseHeaders;
 -  }
 -
 -  @Override
 -  public void setLocale(Locale locale) {
 -    if (locale == null) {
 -      throw new NullPointerException("Locale must not be set to null");
 -    }
 -    this.locale = locale;
 -  }
 -
 + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * 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 at.gv.egiz.bku.binding; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.net.URL; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import javax.net.ssl.SSLHandshakeException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.URIResolver; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slcommands.SLCommandFactory; +import at.gv.egiz.bku.slcommands.SLCommandInvoker; +import at.gv.egiz.bku.slcommands.SLResult; +import at.gv.egiz.bku.slcommands.SLSourceContext; +import at.gv.egiz.bku.slcommands.SLTargetContext; +import at.gv.egiz.bku.slcommands.impl.ErrorResultImpl; +import at.gv.egiz.bku.slexceptions.SLBindingException; +import at.gv.egiz.bku.slexceptions.SLException; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.utils.StreamUtil; +import at.gv.egiz.bku.utils.binding.Protocol; +import at.gv.egiz.bku.utils.urldereferencer.FormDataURLSupplier; +import at.gv.egiz.bku.utils.urldereferencer.SimpleFormDataContextImpl; +import at.gv.egiz.bku.utils.urldereferencer.StreamData; +import at.gv.egiz.bku.utils.urldereferencer.URIResolverAdapter; +import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; +import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext; +import at.gv.egiz.stal.QuitRequest; +import at.gv.egiz.stal.STALRequest; + +/** + * Class performing the HTTP binding as defined by the CCE specification. + * Currently a huge monolithic class. + *  + * @TODO refactor + */ +@SuppressWarnings("unchecked") +public class HTTPBindingProcessor extends AbstractBindingProcessor implements +		FormDataURLSupplier { + +	private static Log log = LogFactory.getLog(HTTPBindingProcessor.class); + +	private static enum State { +		INIT, PROCESS, DATAURL, TRANSFORM, FINISHED +	}; + +	public final static Collection<String> XML_REQ_TRANSFER_ENCODING = Arrays +			.asList(new String[] { "binary" }); + +	/** +	 * Defines the maximum number of dataurl connects that are allowed within a +	 * single SL Request processing. +	 */ +	protected static int MAX_DATAURL_HOPS = 10; + +	protected static String XML_MIME_TYPE = "text/xml"; +	protected static String BINARY_MIME_TYPE = "application/octet-stream"; + +	/** +	 * If null everything is ok and the result is taken from the command invoker. +	 */ +	protected SLException bindingProcessorError; +	protected SLCommandInvoker commandInvoker; +	protected DataUrlResponse dataUrlResponse; +	protected Map<String, String> headerMap = Collections.EMPTY_MAP; +	protected SLCommand slCommand; +	protected Map<String, FormParameter> formParameterMap = new HashMap<String, FormParameter>(); +	protected SLSourceContext srcContex = new SLSourceContext(); +	protected SLTargetContext targetContext = new SLTargetContext(); +	protected URL srcUrl; +	protected State currentState = State.INIT; +	protected Transformer transformer = null; +	protected String resultContentType = null; +	protected SLResult slResult = null; +	protected int responseCode = 200; +	protected Map<String, String> responseHeaders = Collections.EMPTY_MAP; +	protected Locale locale = Locale.getDefault(); + +	/** +	 *  +	 * @param id +	 *          may be null. In this case a new session id will be created. +	 * @param cmdInvoker +	 *          must not be null; +	 */ +	public HTTPBindingProcessor(String id, SLCommandInvoker cmdInvoker, URL source) { +		super(id); +		this.srcUrl = source; +		Protocol protocol = Protocol.fromString(source.getProtocol()); +		if ((protocol != Protocol.HTTP) && (protocol != Protocol.HTTPS)) { +			throw new SLRuntimeException("Protocol not supported: " + protocol); +		} +		if (cmdInvoker == null) { +			throw new NullPointerException("Commandinvoker cannot be set to null"); +		} +		commandInvoker = cmdInvoker; +		srcContex.setSourceUrl(source); +		srcContex.setSourceIsDataURL(false); +	} + +	//----------------------------------------------------------------------------
 +	// ----------- BEGIN CONVENIENCE METHODS -----------
 + +	protected void sendSTALQuit() { +		log.info("Sending QUIT command to STAL"); +		List<STALRequest> quit = new ArrayList<STALRequest>(1); +		quit.add(new QuitRequest()); +		getSTAL().handleRequest(quit); +	} + +	protected String getFormParameterAsString(String formParameterName) { +		FormParameter fp = formParameterMap.get(formParameterName); +		return getFormParameterAsString(fp); +	} + +	protected String getFormParameterAsString(FormParameter fp) { +		if (fp == null) { +			return null; +		} +		try { +			return StreamUtil.asString(fp.getFormParameterValue(), HttpUtil +					.getCharset(fp.getFormParameterContentType(), true)); +		} catch (IOException e) { +			return null; +		} +	} + +	protected String getDataUrl() { +		return getFormParameterAsString(FixedFormParameters.DATAURL); +	} + +	protected String getStyleSheetUrl() { +		return getFormParameterAsString(FixedFormParameters.STYLESHEETURL); +	} + +	protected List<FormParameter> getFormParameters(String parameterNamePostfix) { +		List<FormParameter> resultList = new ArrayList<FormParameter>(); +		for (Iterator<String> fpi = formParameterMap.keySet().iterator(); fpi +				.hasNext();) { +			String paramName = fpi.next(); +			if (paramName.endsWith(parameterNamePostfix)) { +				resultList.add(formParameterMap.get(paramName)); +			} +		} +		return resultList; +	} + +	protected List<FormParameter> getTransferHeaders() { +		return getFormParameters("__"); +	} + +	protected List<FormParameter> getTransferForms() { +		List<FormParameter> resultList = new ArrayList<FormParameter>(); +		for (Iterator<String> fpi = formParameterMap.keySet().iterator(); fpi +				.hasNext();) { +			String paramName = fpi.next(); +			if ((paramName.endsWith("_")) && (!paramName.endsWith("__"))) { +				resultList.add(formParameterMap.get(paramName)); +			} +		} +		return resultList; +	} + +	protected void closeDataUrlConnection() { +		log.debug("Closing data url input stream"); +		if (dataUrlResponse == null) { +			return; +		} +		InputStream is = dataUrlResponse.getStream(); +		if (is != null) { +			try { +				is.close(); +			} catch (IOException e) { +				log.info("Error closing input stream to dataurl server:" + e); +			} +		} +	} + +	//----------------------------------------------------------------------------
 +	// ----------- END CONVENIENCE METHODS -----------
 + +	//----------------------------------------------------------------------------
 +	// -- BEGIN Methods that handle the http binding activities as defined in the
 +	// activity diagram --
 + +	protected void init() { +		log.info("Starting Bindingprocessor in Thread: " +				+ Thread.currentThread().getId()); +		if (bindingProcessorError != null) { +			log.debug("Detected binding processor error, sending quit command"); +			// sendSTALQuit();
 +			currentState = State.FINISHED; +		} else if (slCommand == null) { +			log.error("SLCommand not set (consumeRequest not called ??)"); +			bindingProcessorError = new SLException(2000); +			// sendSTALQuit();
 +			currentState = State.FINISHED; +		} else { +			currentState = State.PROCESS; +		} +	} + +	protected void processRequest() { +		log.debug("Entered State: " + State.PROCESS); +		log.debug("Processing command: " + slCommand); +		commandInvoker.setCommand(slCommand); +		responseCode = 200; +		responseHeaders = Collections.EMPTY_MAP; +		try { +			commandInvoker.invoke(srcContex); +		} catch (SLException e) { +			log.info("Caught exception: " + e); +			bindingProcessorError = e; +			currentState = State.TRANSFORM; +		} +		dataUrlResponse = null; +		if (getDataUrl() != null) { +			log.debug("Data Url set to: " + getDataUrl()); +			currentState = State.DATAURL; +		} else { +			log.debug("No data url set"); +			currentState = State.TRANSFORM; +		} +	} + +	protected void handleDataUrl() { +		log.debug("Entered State: " + State.DATAURL); +		try { +			DataUrl dataUrl = new DataUrl(getDataUrl()); +			DataUrlConnection conn = dataUrl.openConnection(); + +			// set transfer headers
 +			for (FormParameter fp : getTransferHeaders()) { +				String paramString = getFormParameterAsString(fp); +				if (paramString == null) { +					log.error("Got empty transfer header, ignoring this"); +				} else { +					String[] keyVal = paramString.split(":", 2); +					String key = keyVal[0]; +					String val = null; +					if (keyVal.length == 2) { +						val = keyVal[1]; +					} +					val = val.trim(); +					log.debug("Setting header " + key + " to value " + val); +					conn.setHTTPHeader(key, val); +				} +			} + +			// set transfer form parameters
 +			for (FormParameter fp : getTransferForms()) { +				String contentTransferEncoding = null; +				String contentType = fp.getFormParameterContentType(); +				String charSet = HttpUtil.getCharset(contentType, false); +				if (charSet != null) { +					contentType = contentType.substring(0, contentType +							.lastIndexOf(HttpUtil.SEPERATOR[0])); +				} +				for (Iterator<String> header = fp.getHeaderNames(); header.hasNext();) { +					if (HttpUtil.CONTENT_TRANSFER_ENCODING +							.equalsIgnoreCase(header.next())) { +						contentTransferEncoding = getFormParameterAsString(fp); +					} +				} +				log.debug("Setting form: " + fp.getFormParameterName() +						+ " contentType: " + contentType + " charset: " + charSet +						+ " contentTransferEncoding: " + contentTransferEncoding); +				conn.setHTTPFormParameter(fp.getFormParameterName(), fp +						.getFormParameterValue(), contentType, charSet, +						contentTransferEncoding); +			} + +			// connect
 +			conn.connect(); +			// fetch and set SL result
 +			targetContext.setTargetIsDataURL(true); +			targetContext.setTargetCertificate(conn.getServerCertificate()); +			targetContext.setTargetUrl(conn.getUrl()); +			SLResult result = commandInvoker.getResult(targetContext); + +			// transfer result
 +			conn.transmit(result); + +			// process Dataurl response
 +			dataUrlResponse = conn.getResponse(); +			log.debug("Received data url response code: " +					+ dataUrlResponse.getResponseCode()); + +			switch (dataUrlResponse.getResponseCode()) { +			case 200: +				String contentType = dataUrlResponse.getContentType(); +				log.debug("Got dataurl response content type: " + contentType); +				if (contentType != null) { +					if ((contentType.startsWith(HttpUtil.APPLICATION_URL_ENCODED)) +							|| (contentType.startsWith(HttpUtil.MULTIPART_FOTMDATA))) { +						log.debug("Detected SL Request in dataurl response"); +						// process headers and request
 +						setHTTPHeaders(dataUrlResponse.getResponseHeaders()); +						consumeRequestStream(dataUrlResponse.getStream()); +						closeDataUrlConnection(); +						srcContex.setSourceCertificate(conn.getServerCertificate()); +						srcContex.setSourceIsDataURL(true); +						srcContex.setSourceUrl(conn.getUrl()); +						currentState = State.PROCESS; +					} else if (((contentType.startsWith(HttpUtil.TXT_HTML)) +							|| (contentType.startsWith(HttpUtil.TXT_PLAIN)) || (contentType +							.startsWith(HttpUtil.TXT_XML))) +							&& (dataUrlResponse.isHttpResponseXMLOK())) { +						log.info("Dataurl response matches <ok/> with content type: " +								+ contentType); +						currentState = State.TRANSFORM; + +					} else if ((contentType.startsWith(HttpUtil.TXT_XML)) +							&& (!dataUrlResponse.isHttpResponseXMLOK())) { +						log +								.debug("Detected text/xml  dataurl response with content != <ok/>"); +						headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType); +						assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset( +								contentType, true)); +						closeDataUrlConnection(); +						srcContex.setSourceCertificate(conn.getServerCertificate()); +						srcContex.setSourceIsDataURL(true); +						srcContex.setSourceUrl(conn.getUrl()); +						currentState = State.PROCESS; +						// just to be complete, actually not used
 +						srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders() +								.get(HttpUtil.HTTP_HEADER_REFERER)); +					} else { +						resultContentType = contentType; +						responseHeaders = dataUrlResponse.getResponseHeaders(); +						responseCode = dataUrlResponse.getResponseCode(); +						currentState = State.FINISHED; +					} +				} else { +					log.debug("Content type not set in dataurl response"); +					closeDataUrlConnection(); +					throw new SLBindingException(2007); +				} + +				break; +			case 307: +				contentType = dataUrlResponse.getContentType(); +				if ((contentType != null) && (contentType.startsWith(HttpUtil.TXT_XML))) { +					log.debug("Received dataurl response code 307 with XML content"); +					String location = dataUrlResponse.getResponseHeaders().get( +							HttpUtil.HTTP_HEADER_LOCATION); +					if (location == null) { +						log +								.error("Did not get a location header for a 307 data url response"); +						throw new SLBindingException(2003); +					} +					// consumeRequestStream(dataUrlResponse.getStream());
 +					FormParameterStore fp = new FormParameterStore(); +					fp.init(location.getBytes(HttpUtil.DEFAULT_CHARSET), +							FixedFormParameters.DATAURL, null, null); +					formParameterMap.put(FixedFormParameters.DATAURL, fp); +					headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType); +					assignXMLRequest(dataUrlResponse.getStream(), HttpUtil.getCharset( +							dataUrlResponse.getContentType(), true)); +					closeDataUrlConnection(); +					srcContex.setSourceCertificate(conn.getServerCertificate()); +					srcContex.setSourceIsDataURL(true); +					srcContex.setSourceUrl(conn.getUrl()); +					currentState = State.PROCESS; +					// just to be complete, actually not used
 +					srcContex.setSourceHTTPReferer(dataUrlResponse.getResponseHeaders() +							.get(HttpUtil.HTTP_HEADER_REFERER)); + +				} else { +					log.debug("Received dataurl response code 307 non XML content: " +							+ dataUrlResponse.getContentType()); +					resultContentType = dataUrlResponse.getContentType(); +					currentState = State.FINISHED; +				} +				responseHeaders = dataUrlResponse.getResponseHeaders(); +				responseCode = dataUrlResponse.getResponseCode(); +				break; + +			case 301: +			case 302: +			case 303: +				responseHeaders = dataUrlResponse.getResponseHeaders(); +				responseCode = dataUrlResponse.getResponseCode(); +				resultContentType = dataUrlResponse.getContentType(); +				currentState = State.FINISHED; +				break; + +			default: +				// issue error
 +				log.info("Unexpected response code from dataurl server: " +						+ dataUrlResponse.getResponseCode()); +				throw new SLBindingException(2007); +			} + +		} catch (SLException slx) { +			bindingProcessorError = slx; +			log.error("Error during dataurl communication"); +			resultContentType = HttpUtil.TXT_XML; +			currentState = State.TRANSFORM; +		} catch (SSLHandshakeException hx) { +			bindingProcessorError = new SLException(2010); +			log.info("Error during dataurl communication", hx); +			resultContentType = HttpUtil.TXT_XML; +			currentState = State.TRANSFORM; +		} catch (IOException e) { +			bindingProcessorError = new SLBindingException(2001); +			log.error("Error while data url handling", e); +			resultContentType = HttpUtil.TXT_XML; +			currentState = State.TRANSFORM; +			return; +		} +	} + +	protected void transformResult() { +		log.debug("Entered State: " + State.TRANSFORM); +		if (bindingProcessorError != null) { +			resultContentType = HttpUtil.TXT_XML; +		} else if (dataUrlResponse != null) { +			resultContentType = dataUrlResponse.getContentType(); +		} else { +			targetContext.setTargetIsDataURL(false); +			targetContext.setTargetUrl(srcUrl); +			try { +				slResult = commandInvoker.getResult(targetContext); +				resultContentType = slResult.getMimeType(); +				log +						.debug("Successfully got SLResult from commandinvoker, setting mimetype to: " +								+ resultContentType); +			} catch (SLException e) { +				log.info("Cannot get result from invoker:", e); +				bindingProcessorError = new SLException(6002); +				resultContentType = HttpUtil.TXT_XML; +			} +		} +		transformer = getTransformer(getStyleSheetUrl()); +		if (transformer != null) { +			log.debug("Output transformation required"); +			resultContentType = transformer.getOutputProperty("media-type"); +			log.debug("Got media type from stylesheet: " + resultContentType); +			if (resultContentType == null) { +				log.debug("Setting to default text/xml result conent type"); +				resultContentType = "text/xml"; +			} +			log.debug("Deferring sytylesheet processing"); +		} +		currentState = State.FINISHED; +	} + +	protected void finished() { +		log.debug("Entered State: " + State.FINISHED); +		if (bindingProcessorError != null) { +			log.debug("Binding processor error, sending quit command"); +			resultContentType = HttpUtil.TXT_XML; +		} +		sendSTALQuit(); +		log.info("Terminating Bindingprocessor; Thread: " +				+ Thread.currentThread().getId()); +	} + +	// -- END Methods that handle the http binding activities as defined in the
 +	// activity diagram --
 +	//----------------------------------------------------------------------------
 + +	/** +	 * Sets the headers of the SL Request. IMPORTANT: make sure to set all headers +	 * before invoking {@link #consumeRequestStream(InputStream)} +	 *  +	 * @param aHeaderMap +	 *          if null all header will be cleared. +	 */ +	public void setHTTPHeaders(Map<String, String> aHeaderMap) { +		headerMap = new HashMap<String, String>(); +		// ensure lowercase keys
 +		if (aHeaderMap != null) { +			for (String s : aHeaderMap.keySet()) { +				if (s != null) { +					headerMap.put(s.toLowerCase(), aHeaderMap.get(s)); +					if (s.equalsIgnoreCase(HttpUtil.HTTP_HEADER_REFERER)) { +						String referer = aHeaderMap.get(s); +						log.debug("Got referer header: " + referer); +						srcContex.setSourceHTTPReferer(referer); +					} +				} +			} +		} +	} + +	public void setSourceCertificate(X509Certificate aCert) { +		srcContex.setSourceCertificate(aCert); +	} + +	/** +	 * The HTTPBindingProcessor does not handle redirect URLs. It only provides +	 * the parameter. +	 *  +	 * @return null if redirect url is not set. +	 */ +	public String getRedirectURL() { +		return getFormParameterAsString(FixedFormParameters.REDIRECTURL); +	} + +	public String getFormDataContentType(String aParameterName) { +		FormParameter fp = formParameterMap.get(aParameterName); +		if (fp != null) { +			return fp.getFormParameterContentType(); +		} +		return null; +	} + +	public InputStream getFormData(String aParameterName) { +		FormParameter fp = formParameterMap.get(aParameterName); +		if (fp != null) { +			return fp.getFormParameterValue(); +		} +		return null; +	} + +	protected void assignXMLRequest(InputStream is, String charset) +			throws IOException, SLException { +		Reader r = new InputStreamReader(is, charset); +		StreamSource source = new StreamSource(r); +		SLCommandContext commandCtx = new SLCommandContext(); +		commandCtx.setSTAL(getSTAL()); +		commandCtx.setURLDereferencerContext(new SimpleFormDataContextImpl(this)); +		slCommand = SLCommandFactory.getInstance().createSLCommand(source, +				commandCtx); +		log.debug("Created new command: " + slCommand); +	} + +	@Override +	public void run() { +		boolean done = false; +		int hopcounter = 0; +		if (bindingProcessorError != null) { +			currentState = State.FINISHED; +		} +		try { +			while (!done) { +				try { +					switch (currentState) { +					case INIT: +						init(); +						break; +					case PROCESS: +						processRequest(); +						break; +					case DATAURL: +						handleDataUrl(); +						if (++hopcounter > MAX_DATAURL_HOPS) { +							log.error("Maximum number of dataurl hops reached"); +							bindingProcessorError = new SLBindingException(2000); +							currentState = State.FINISHED; +						} +						break; +					case TRANSFORM: +						transformResult(); +						break; +					case FINISHED: +						done = true; +						finished(); +						break; +					} +				} catch (RuntimeException rte) { +					throw rte; +				} catch (Exception t) { +					log.error("Caught unexpected exception", t); +					responseCode = 200; +					resultContentType = HttpUtil.TXT_XML; +					responseHeaders = Collections.EMPTY_MAP; +					bindingProcessorError = new SLException(2000); +					currentState = State.FINISHED; +				} +			} +		} catch (Throwable t) { +			log.error("Caught unexpected exception", t); +			responseCode = 200; +			resultContentType = HttpUtil.TXT_XML; +			responseHeaders = Collections.EMPTY_MAP; +			bindingProcessorError = new SLException(2000); +			currentState = State.FINISHED; +		} +		log.debug("Terminated http binding processor"); +	} + +	@Override +	public void consumeRequestStream(InputStream is) { +		try { +			log.debug("Start consuming request stream"); +			formParameterMap.clear(); +			String cl = headerMap +					.get(HttpUtil.HTTP_HEADER_CONTENT_TYPE.toLowerCase()); +			if (cl == null) { +				log.info("No content type set in http header"); +				throw new SLBindingException(2006); +			} +			InputDecoder id = InputDecoderFactory.getDecoder(cl, is); +			id.setContentType(cl); +			if (id == null) { +				log.error("Cannot get inputdecoder for is"); +				throw new SLException(2006); +			} +			for (Iterator<FormParameter> fpi = id.getFormParameterIterator(); fpi +					.hasNext();) { +				FormParameter fp = fpi.next(); +				log.debug("Got request parameter with name: " +						+ fp.getFormParameterName()); +				if (fp.getFormParameterName().equals(FixedFormParameters.XMLREQUEST)) { +					log.debug("Creating XML Request"); +					for (Iterator<String> headerIterator = fp.getHeaderNames(); headerIterator +							.hasNext();) { +						String headerName = headerIterator.next(); +						if (HttpUtil.CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(headerName)) { +							String transferEncoding = fp.getHeaderValue(headerName); +							log.debug("Got transfer encoding for xmlrequest: " +									+ transferEncoding); +							if (XML_REQ_TRANSFER_ENCODING.contains(transferEncoding)) { +								log.debug("Supported transfer encoding: " + transferEncoding); +							} else { +								log +										.error("Transferencoding not supported: " +												+ transferEncoding); +								throw new SLBindingException(2005); +							} +						} +					} +					String charset = HttpUtil.getCharset(cl, true); +					assignXMLRequest(fp.getFormParameterValue(), charset); +				} else { +					FormParameterStore fps = new FormParameterStore(); +					fps.init(fp); +					if (!fps.isEmpty()) { +						log.debug("Setting from parameter: " + fps.getFormParameterName()); +						formParameterMap.put(fps.getFormParameterName(), fps); +					} +				} +			} +			if (slCommand == null) { +				throw new SLBindingException(2004); +			} +			if (is.read() != -1) { +				log.error("Request input stream not completely read"); +				// consume rest of stream, should never occur
 +				throw new SLRuntimeException( +						"request input stream not consumed till end"); +			} +		} catch (SLException slx) { +			log.info("Error while consuming input stream " + slx); +			bindingProcessorError = slx; +		} catch (Throwable t) { +			log.info("Error while consuming input stream " + t, t); +			bindingProcessorError = new SLException(2000); +		} finally { +			try { +				while (is.read() != -1) +					; +			} catch (IOException e) { +				log.error(e); +			} +		} +	} + +	@Override +	public String getResultContentType() { +		return resultContentType; +	} + +	protected Transformer getTransformer(String styleSheetURL) { +		if (styleSheetURL == null) { +			log.debug("Stylesheet URL not set"); +			return null; +		} +		try { +			URLDereferencerContext urlCtx = new SimpleFormDataContextImpl(this); +			URIResolver resolver = new URIResolverAdapter(URLDereferencer +					.getInstance(), urlCtx); +			TransformerFactory factory = TransformerFactory.newInstance(); +			StreamData sd = URLDereferencer.getInstance().dereference(styleSheetURL, +					urlCtx); +			Transformer t = factory.newTransformer(new StreamSource(sd.getStream())); +			t.setURIResolver(resolver); +			return t; +		} catch (Exception ex) { +			log.info("Cannot instantiate transformer", ex); +			bindingProcessorError = new SLException(2002); +			return null; +		} +	} + +	protected void handleBindingProcessorError(OutputStream os, String encoding, +			Transformer transformer) throws IOException { +		log.debug("Writing error as result"); +		ErrorResultImpl error = new ErrorResultImpl(bindingProcessorError); +		try { +			error.writeTo(new StreamResult(new OutputStreamWriter(os, encoding)), +					transformer); +		} catch (TransformerException e) { +			log.fatal("Cannot write error result to stream", e); +		} +	} + +	@Override +	public void writeResultTo(OutputStream os, String encoding) +			throws IOException { +		if (encoding == null) { +			encoding = HttpUtil.DEFAULT_CHARSET; +		} +		if (bindingProcessorError != null) { +			log.debug("Detected error in binding processor, writing error as result"); +			handleBindingProcessorError(os, encoding, transformer); +			return; +		} else if (dataUrlResponse != null) { +			log.debug("Writing data url response  as result"); +			String charEnc = HttpUtil.getCharset(dataUrlResponse.getContentType(), +					true); +			InputStreamReader isr = new InputStreamReader( +					dataUrlResponse.getStream(), charEnc); +			OutputStreamWriter osw = new OutputStreamWriter(os, encoding); +			if (transformer == null) { +				StreamUtil.copyStream(isr, osw); +			} else { +				try { +					transformer.transform(new StreamSource(isr), new StreamResult(osw)); +				} catch (TransformerException e) { +					log.fatal("Exception occured during result transformation", e); +					// bindingProcessorError = new SLException(2008);
 +					// handleBindingProcessorError(os, encoding, null);
 +					return; +				} +			} +			osw.flush(); +			isr.close(); +		} else if (slResult == null) { +			// result not yet assigned -> must be a cancel
 +			bindingProcessorError = new SLException(6001); +			handleBindingProcessorError(os, encoding, transformer); +			return; +		} else { +			log.debug("Getting result from invoker"); +			OutputStreamWriter osw = new OutputStreamWriter(os, encoding); +			try { +				slResult.writeTo(new StreamResult(osw), transformer); +			} catch (TransformerException e) { +				log.fatal("Cannot write result to stream", e); +				// bindingProcessorError = new SLException(2008);
 +				// handleBindingProcessorError(os, encoding, transformer);
 +			} +			osw.flush(); +		} +	} + +	/** +	 * The response code from the dataurl server or 200 if no dataurl server +	 * created the result +	 *  +	 * @return +	 */ +	public int getResponseCode() { +		return responseCode; +	} + +	/** +	 * All headers from the data url server in case of a direct forward from the +	 * dataurl server. +	 *  +	 * @return +	 */ +	public Map<String, String> getResponseHeaders() { +		return responseHeaders; +	} + +	@Override +	public void setLocale(Locale locale) { +		if (locale == null) { +			throw new NullPointerException("Locale must not be set to null"); +		} +		this.locale = locale; +	} +  }
\ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java index ef2affd1..a23d96e8 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/SLCommandInvokerImpl.java @@ -1,66 +1,95 @@  /* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* 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 at.gv.egiz.bku.binding;
 -
 -import org.apache.commons.logging.Log;
 -import org.apache.commons.logging.LogFactory;
 -
 -import at.gv.egiz.bku.slcommands.SLCommand;
 -import at.gv.egiz.bku.slcommands.SLCommandInvoker;
 -import at.gv.egiz.bku.slcommands.SLResult;
 -import at.gv.egiz.bku.slcommands.SLSourceContext;
 -import at.gv.egiz.bku.slcommands.SLTargetContext;
 -
 -/**
 - * This class implements the entry point for the CCEs security management.
 - * 
 - * TODO the secuirty management is currently not implemented.
 - */
 -public class SLCommandInvokerImpl implements SLCommandInvoker {
 -  
 -  private static Log log = LogFactory.getLog(SLCommandInvokerImpl.class);
 -
 -  protected SLCommand command;
 -  protected SLResult result;
 -
 -  /**
 -   * Invokes a sl command. 
 -   */
 -  public void invoke(SLSourceContext aContext) {
 -    // FIXXME add security policy here.
 -    log.warn("Security policy not implemented yet, invoking command: "+command);
 -    result = command.execute();
 -  }
 -
 -  public SLResult getResult(SLTargetContext aContext) {
 -    // FIXXME
 -    log.warn("Security policy not implemented yet, getting result of command: "+command);
 -    return result;
 -  }
 -
 -  public void setCommand(SLCommand aCmd) {
 -    command = aCmd;
 -  }
 -
 -  @Override
 -  public SLCommandInvoker newInstance() {
 -    SLCommandInvokerImpl cmdInv = new SLCommandInvokerImpl();
 -    return cmdInv;
 -  }
 -  
 -  
 + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * 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 at.gv.egiz.bku.binding; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.accesscontroller.SecurityManagerFacade; +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slcommands.SLCommandInvoker; +import at.gv.egiz.bku.slcommands.SLResult; +import at.gv.egiz.bku.slcommands.SLSourceContext; +import at.gv.egiz.bku.slcommands.SLTargetContext; +import at.gv.egiz.bku.slexceptions.SLException; + +/** + * This class implements the entry point for the CCEs security management. + *  + */ +public class SLCommandInvokerImpl implements SLCommandInvoker { + +	private static Log log = LogFactory.getLog(SLCommandInvokerImpl.class); + +	protected SLCommand command; +	protected SLResult result; +	protected SecurityManagerFacade securityManager; + +	/** +	 * Invokes a sl command. +	 *  +	 * @throws SLException +	 */ +	public void invoke(SLSourceContext aContext) throws SLException { +		if (securityManager == null) { +			log.warn("Security policy not implemented yet, invoking command: " +					+ command); +			result = command.execute(); +		} else { +			if (securityManager.mayInvokeCommand(command, aContext)) { +				result = command.execute(); +			} else { +				throw new SLException(6002); +			} +		} +	} + +	public SLResult getResult(SLTargetContext aContext) throws SLException { +		if (securityManager == null) { +			log +					.warn("Security policy not implemented yet, getting result of command: " +							+ command); +			return result; +		} else { +			if (securityManager.maySendResult(command, aContext)) { +				return result; +			} else { +				throw new SLException(6002); +			} +		} +	} + +	public void setCommand(SLCommand aCmd) { +		command = aCmd; +	} + +	@Override +	public SLCommandInvoker newInstance() { +		SLCommandInvokerImpl cmdInv = new SLCommandInvokerImpl(); +		cmdInv.setSecurityManager(securityManager); +		return cmdInv; +	} + +	public SecurityManagerFacade getSecurityManager() { +		return securityManager; +	} + +	public void setSecurityManager(SecurityManagerFacade securityManager) { +		this.securityManager = securityManager; +	} +  }
\ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadCommand.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadCommand.java index 77529a36..73fddf1f 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadCommand.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxReadCommand.java @@ -16,5 +16,13 @@  */  package at.gv.egiz.bku.slcommands;
 -public interface InfoboxReadCommand extends SLCommand {
 +public interface InfoboxReadCommand extends SLCommand { +	 public String getInfoboxIdentifier(); +	  +	 /** +	  * Convenience method to get the domain identifier if the infobox  +	  * referes to a Identitylink.  +	  * @return the domain id or null if the Infobox is not of type Identitylink or no domain parameter was specified +	  */ +	 public String getIdentityLinkDomainId();
  }
\ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java index 30c6b68f..c28288c9 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandInvoker.java @@ -16,7 +16,8 @@  */  package at.gv.egiz.bku.slcommands;
 -import at.gv.egiz.bku.slexceptions.SLCanceledException;
 +import at.gv.egiz.bku.slexceptions.SLCanceledException; +import at.gv.egiz.bku.slexceptions.SLException;  public interface SLCommandInvoker {
 @@ -25,7 +26,7 @@ public interface SLCommandInvoker {     * @param aContext
     * @throws SLCanceledException if the security management prevents execution of this command
     */
 -  public void invoke(SLSourceContext aContext) throws SLCanceledException;
 +  public void invoke(SLSourceContext aContext) throws SLException;
    /**
     * 
 @@ -33,7 +34,7 @@ public interface SLCommandInvoker {     * @return
     * @throws SLCanceledException if the security management prevents execution of this command
     */
 -  public SLResult getResult(SLTargetContext aContext) throws SLCanceledException;
 +  public SLResult getResult(SLTargetContext aContext) throws SLException;
    public void setCommand(at.gv.egiz.bku.slcommands.SLCommand aCmd);
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java index ded55b2a..f25a0ea4 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLSourceContext.java @@ -16,6 +16,7 @@  */  package at.gv.egiz.bku.slcommands;
 +import java.net.URL;  import java.security.cert.X509Certificate;
  import at.gv.egiz.bku.utils.binding.Protocol;
 @@ -23,17 +24,17 @@ import at.gv.egiz.bku.utils.binding.Protocol;  public class SLSourceContext {
 -  private Protocol sourceProtocol;
 +  private URL sourceUrl;
    private boolean sourceIsDataURL;
    private X509Certificate sourceCertificate;
    private String sourceHTTPReferer;
 -  public Protocol getSourceProtocol() {
 -    return sourceProtocol;
 +  public URL getSourceUrl() {
 +    return sourceUrl;
    }
 -  public void setSourceProtocol(Protocol sourceProtocol) {
 -    this.sourceProtocol = sourceProtocol;
 +  public void setSourceUrl(URL sourceProtocol) {
 +    this.sourceUrl = sourceProtocol;
    }
    public boolean isSourceIsDataURL() {
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLTargetContext.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLTargetContext.java index cf800406..f9df3ced 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLTargetContext.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLTargetContext.java @@ -16,19 +16,20 @@  */  package at.gv.egiz.bku.slcommands;
 -import java.security.cert.X509Certificate;
 +import java.net.URL; +import java.security.cert.X509Certificate;  public class SLTargetContext {
 -  private String targetProtocol;
 +  private URL targetUrl;
    private boolean targetIsDataURL;
    private X509Certificate targetCertificate;
 -  public String getTargetProtocol() {
 -    return targetProtocol;
 +  public URL getTargetUrl() {
 +    return targetUrl;
    }
 -  public void setTargetProtocol(String targetProtocol) {
 -    this.targetProtocol = targetProtocol;
 +  public void setTargetUrl(URL targetUrl) {
 +    this.targetUrl = targetUrl;
    }
    public boolean isTargetIsDataURL() {
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java index 93131cf4..b6745e1f 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java @@ -405,5 +405,10 @@ public class InfoboxReadCommandImpl extends SLCommandImpl<InfoboxReadRequestType      return result;
 -  }
 +  } + +	@Override +	public String getIdentityLinkDomainId() { +		return identityLinkDomainIdentifier; +	}
  }
 diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/accesscontroller/ConfigTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/accesscontroller/ConfigTest.java index b53db264..bce3cdd9 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/accesscontroller/ConfigTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/accesscontroller/ConfigTest.java @@ -4,14 +4,101 @@ import javax.xml.bind.JAXBException;  import org.junit.Test;
 +import at.gv.egiz.bku.slcommands.InfoboxReadCommand;
 +import at.gv.egiz.bku.slcommands.SLCommandContext;
 +import at.gv.egiz.bku.slcommands.SLResult;
 +import at.gv.egiz.bku.slcommands.impl.InfoboxReadCommandImpl;
 +import at.gv.egiz.bku.slexceptions.SLCommandException;
 +import at.gv.egiz.bku.slexceptions.SLException;
 +import static org.junit.Assert.*;
 +
  public class ConfigTest {
 -	public final static String RESOURCE = "at/gv/egiz/bku/accesscontroller/AccessControlConfig.xml";
 +	public final static String RESOURCE1 = "at/gv/egiz/bku/accesscontroller/AccessControlConfig.xml";
 +	public final static String RESOURCE2 = "at/gv/egiz/bku/accesscontroller/SimpleChainTest.xml";
 +
 +	static class MyInfoBox implements InfoboxReadCommand {
 +		private String domainId;
 +		private String boxId;
 +		private String name;
 +
 +		public MyInfoBox(String identifier, String domainId) {
 +			this.boxId = identifier;
 +			this.domainId = domainId;
 +		}
 +
 +		@Override
 +		public String getIdentityLinkDomainId() {
 +			return domainId;
 +		}
 +
 +		@Override
 +		public String getInfoboxIdentifier() {
 +			return boxId;
 +		}
 +
 +		@Override
 +		public SLResult execute() {
 +			return null;
 +		}
 +		
 +		public void setName(String name) {
 +			this.name = name;
 +		}
 +
 +		@Override
 +		public String getName() {
 +			return "InfoboxReadRequest";
 +		}
 +
 +		@Override
 +		public void init(SLCommandContext ctx, Object unmarshalledRequest)
 +				throws SLCommandException {
 +		}
 +	}
  	@Test
  	public void testUnmarshall() throws JAXBException {
  		AccessControllerFactory.getInstance().init(
 -				getClass().getClassLoader().getResourceAsStream(RESOURCE));
 +				getClass().getClassLoader().getResourceAsStream(RESOURCE1));
 +	}
 +
 +	@Test
 +	public void testBasicFunction() throws JAXBException, SLException {
 +		AccessControllerFactory.getInstance().init(
 +				getClass().getClassLoader().getResourceAsStream(RESOURCE2));
 +		ChainChecker cc = AccessControllerFactory.getInstance().getChainChecker(
 +				"InputFilter");
 +		assertNotNull(cc);
 +
 +		AccessCheckerContext ctx = new AccessCheckerContext(null,
 +				AuthenticationClass.ANONYMOUS, null);
 +		ChainResult cr = cc.check(ctx);
 +		assertFalse(cr.matchFound());
 +
 +		ctx = new AccessCheckerContext(new MyInfoBox("IdentityLink", "hansi"),
 +				AuthenticationClass.CERTIFIED, null);
 +		cr = cc.check(ctx);
 +		assertTrue(cr.matchFound());
 +
 +		ctx = new AccessCheckerContext(new MyInfoBox("Something", "hansi"),
 +				AuthenticationClass.CERTIFIED, null);
 +		cr = cc.check(ctx);
 +		assertFalse(cr.matchFound());
 +		
 +		MyInfoBox mib = new MyInfoBox("IdentityLink", "seppl");
 +		mib.setName("ReadInfoboxSchickSchnack");
 +		ctx = new AccessCheckerContext(mib,	AuthenticationClass.CERTIFIED, null);
 +		cr = cc.check(ctx);
 +		assertTrue(cr.matchFound());
 +		assertTrue(cr.getAction()==Action.ALLOW);
 +		
 +		mib = new MyInfoBox("IdentityLink", null);
 +		mib.setName("ReadInfoboxSchickSchnack");
 +		ctx = new AccessCheckerContext(mib,	AuthenticationClass.CERTIFIED, null);
 +		cr = cc.check(ctx);
 +		assertTrue(cr.matchFound());
 +		assertTrue(cr.getAction()==Action.DENY);
  	}
  }
 diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/binding/BindingProcessorManagerTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/binding/BindingProcessorManagerTest.java index 16d5451a..9481f0bc 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/binding/BindingProcessorManagerTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/binding/BindingProcessorManagerTest.java @@ -17,6 +17,8 @@  package at.gv.egiz.bku.binding;
  import static org.junit.Assert.*;
 + +import java.net.MalformedURLException;  import org.junit.Before;
  import org.junit.Test;
 @@ -29,16 +31,16 @@ public class BindingProcessorManagerTest {    }
 -  @Test(expected = UnsupportedOperationException.class)
 -  public void basicCreationTest() {
 +  @Test(expected = MalformedURLException.class)
 +  public void basicCreationTest() throws MalformedURLException {
     BindingProcessorManager manager = new BindingProcessorManagerImpl(new DummyStalFactory(), new SLCommandInvokerImpl());
 -   BindingProcessor bp = manager.createBindingProcessor("http", null);
 +   BindingProcessor bp = manager.createBindingProcessor("http://www.at/", null);
     assertNotNull(bp.getId().toString());
     assertEquals(40, bp.getId().toString().length());
     String hansi = "Hansi";
 -   bp = manager.createBindingProcessor("http",hansi);
 +   bp = manager.createBindingProcessor("http://www.iaik.at",hansi);
     assertEquals(hansi, bp.getId().toString()); 
 -   bp = manager.createBindingProcessor("HtTp", null);
 +   bp = manager.createBindingProcessor("HtTp://www.iaik.at", null);
     assertNotNull(bp);
     manager.createBindingProcessor("seppl", null);
    }
 diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/binding/DataUrlConnectionTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/binding/DataUrlConnectionTest.java index d9995fdd..87726c49 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/binding/DataUrlConnectionTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/binding/DataUrlConnectionTest.java @@ -20,41 +20,31 @@   */  package at.gv.egiz.bku.binding; -import at.gv.egiz.bku.slcommands.SLCommandFactory; -import at.gv.egiz.bku.slcommands.SLResult; - -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; -import java.io.BufferedReader;  import java.io.ByteArrayInputStream;  import java.io.IOException;  import java.io.InputStream; -import java.io.InputStreamReader;  import java.io.OutputStream; -import java.io.OutputStreamWriter;  import java.net.InetSocketAddress;  import java.net.URL; -import java.net.URLConnection;  import java.util.Date;  import java.util.HashMap;  import java.util.Iterator; -import java.util.LinkedList;  import java.util.List;  import java.util.Map;  import java.util.Set;  import org.apache.commons.logging.Log;  import org.apache.commons.logging.LogFactory; -import org.junit.After; -import static org.junit.Assert.*; -  import org.junit.AfterClass;  import org.junit.Before;  import org.junit.BeforeClass;  import org.junit.Test; +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +  /**   *    * @author clemens @@ -83,7 +73,7 @@ public class DataUrlConnectionTest {      manager = new BindingProcessorManagerImpl(new DummyStalFactory(),          new SLCommandInvokerImpl());      bindingProcessor = (HTTPBindingProcessor) manager.createBindingProcessor( -        "http", null); +        "http://www.iaik.at", null);      Map<String, String> headers = new HashMap<String, String>();      headers.put("Content-Type", InputDecoderFactory.MULTIPART_FORMDATA          + ";boundary=---------------------------2330864292941"); diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/binding/ExpiryRemoverTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/binding/ExpiryRemoverTest.java index 41c69a1d..61729567 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/binding/ExpiryRemoverTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/binding/ExpiryRemoverTest.java @@ -16,16 +16,18 @@  */  package at.gv.egiz.bku.binding;
 +import java.net.MalformedURLException; +  import org.junit.Test;
  import static org.junit.Assert.*;
  public class ExpiryRemoverTest {
    @Test
 -  public void testMe() throws InterruptedException {
 +  public void testMe() throws InterruptedException, MalformedURLException {
      BindingProcessorManager manager = new BindingProcessorManagerImpl(new DummyStalFactory(),
          new SLCommandInvokerImpl());
 -    BindingProcessor bp = manager.createBindingProcessor("http", null);
 +    BindingProcessor bp = manager.createBindingProcessor("http://www.at", null);
      ExpiryRemover remover = new ExpiryRemover();
      remover.setBindingProcessorManager(manager);
      remover.execute();
 @@ -42,10 +44,10 @@ public class ExpiryRemoverTest {    }
    @Test
 -  public void testMe2() throws InterruptedException {
 +  public void testMe2() throws InterruptedException, MalformedURLException {
      BindingProcessorManager manager = new BindingProcessorManagerImpl(new DummyStalFactory(),
          new SLCommandInvokerImpl());
 -    BindingProcessor bp = manager.createBindingProcessor("http", null);
 +    BindingProcessor bp = manager.createBindingProcessor("http://www.iaik.at", null);
      ExpiryRemover remover = new ExpiryRemover();
      remover.setBindingProcessorManager(manager);
      remover.execute();
 diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/binding/HttpBindingProcessorTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/binding/HttpBindingProcessorTest.java index 38f61aa2..6a0792d5 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/binding/HttpBindingProcessorTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/binding/HttpBindingProcessorTest.java @@ -93,7 +93,7 @@ public class HttpBindingProcessorTest {      manager = new BindingProcessorManagerImpl(new DummyStalFactory(),
          new SLCommandInvokerImpl());
      bindingProcessor = (HTTPBindingProcessor) manager.createBindingProcessor(
 -        "http", null);
 +        "http://www.iaik.at", null);
      clientHeaderMap = new HashMap<String, String>();
      clientHeaderMap.put("Content-Type",
          "application/x-www-form-urlencoded;charset=utf8");
 diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/binding/MultipartSLRequestTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/binding/MultipartSLRequestTest.java index 7ef1a9bf..2c48bf4e 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/binding/MultipartSLRequestTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/binding/MultipartSLRequestTest.java @@ -17,6 +17,7 @@  package at.gv.egiz.bku.binding;
  import java.io.InputStream;
 +import java.net.MalformedURLException;  import java.util.HashMap;
  import java.util.LinkedList;
  import java.util.List;
 @@ -34,11 +35,11 @@ public class MultipartSLRequestTest {    protected BindingProcessorManager manager;
    @Before
 -  public void setUp() {
 +  public void setUp() throws MalformedURLException {
      manager = new BindingProcessorManagerImpl(new DummyStalFactory(),
          new SLCommandInvokerImpl());
      HTTPBindingProcessor http = (HTTPBindingProcessor) manager
 -        .createBindingProcessor("http", null);
 +        .createBindingProcessor("http://www.at/", null);
      Map<String, String> headers = new HashMap<String, String>();
      headers.put("Content-Type", InputDecoderFactory.MULTIPART_FORMDATA
          + ";boundary=---------------------------2330864292941");
 diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/binding/NullOperationTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/binding/NullOperationTest.java index 66b9dffb..b2a7d387 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/binding/NullOperationTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/binding/NullOperationTest.java @@ -17,6 +17,7 @@  package at.gv.egiz.bku.binding;
  import java.io.InputStream;
 +import java.net.MalformedURLException;  import java.util.HashMap;
  import java.util.Map;
 @@ -32,9 +33,9 @@ public class NullOperationTest {    protected BindingProcessorManager manager;
    @Before
 -  public void setUp() {
 +  public void setUp() throws MalformedURLException {
      manager = new BindingProcessorManagerImpl(new DummyStalFactory(), new SLCommandInvokerImpl());
 -    HTTPBindingProcessor http =   (HTTPBindingProcessor) manager.createBindingProcessor("http", null);
 +    HTTPBindingProcessor http =   (HTTPBindingProcessor) manager.createBindingProcessor("http://www.at/", null);
      Map<String, String> headers = new HashMap<String, String>();
      headers.put("Content-Type", "application/x-www-form-urlencoded");
      http.setHTTPHeaders(headers);
 diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/binding/TestDataUrlConnection.java b/bkucommon/src/test/java/at/gv/egiz/bku/binding/TestDataUrlConnection.java index e644f964..45e38674 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/binding/TestDataUrlConnection.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/binding/TestDataUrlConnection.java @@ -119,5 +119,10 @@ public class TestDataUrlConnection implements DataUrlConnectionSPI {    @Override
    public DataUrlConnectionSPI newInstance() {
      return this;
 -  }
 +  } + +	@Override +	public URL getUrl() { +		return url; +	}
   }
 diff --git a/bkucommon/src/test/resources/at/gv/egiz/bku/accesscontroller/AccessControlConfig.xml b/bkucommon/src/test/resources/at/gv/egiz/bku/accesscontroller/AccessControlConfig.xml index 2455d68d..22f9e4a5 100644 --- a/bkucommon/src/test/resources/at/gv/egiz/bku/accesscontroller/AccessControlConfig.xml +++ b/bkucommon/src/test/resources/at/gv/egiz/bku/accesscontroller/AccessControlConfig.xml @@ -29,7 +29,7 @@  				</Rule>
  				<Rule Id="rule-4">
  					<AuthClass>anonymous</AuthClass>
 -					<DomainName>*.gv.at</DomainName>
 +					<DomainName>$.gv.at</DomainName>
  					<Action>
  						<RuleAction>allow</RuleAction>
  					</Action>
 @@ -44,7 +44,7 @@  					<AnyPeer />
  					<Command Name="Infobox*">
  						<Param Name="InfoboxIdentifier">IdentityLink</Param>
 -						<Param Name="PersonIdentifier">*</Param>
 +						<Param Name="PersonIdentifier">.*</Param>
  					</Command>
  					<Action>
  						<RuleAction>allow</RuleAction>
 @@ -56,7 +56,7 @@  					<URL>https://finanzonline.bmf.gv.at/*</URL>
  					<Command Name="InfoboxReadRequest">
  						<Param Name="InfoboxIdentifier">Mandates</Param>
 -						<Param Name="PersonIdentifier">*</Param>
 +						<Param Name="PersonIdentifier">.*</Param>
  					</Command>
  					<Action>
  						<RuleAction>allow</RuleAction>
 diff --git a/bkucommon/src/test/resources/at/gv/egiz/bku/accesscontroller/SimpleChainTest.xml b/bkucommon/src/test/resources/at/gv/egiz/bku/accesscontroller/SimpleChainTest.xml new file mode 100644 index 00000000..92490fb2 --- /dev/null +++ b/bkucommon/src/test/resources/at/gv/egiz/bku/accesscontroller/SimpleChainTest.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?>
 +<AccessControl>
 +	<Chains>
 +		<Chain Id="InputFilter">
 +			<Rules>
 +				<Rule Id="rule-IF1">
 +					<AuthClass>pseudoanonymous</AuthClass>
 +					<Action>
 +						<ChainRef>DelegateFilter</ChainRef>
 +					</Action>
 +				</Rule>
 +			</Rules>
 +		</Chain>
 +
 +		<Chain Id="DelegateFilter">
 +			<Rules>
 +				<Rule Id="rule-DF1">
 +					<AuthClass>certified</AuthClass>
 +					<Command Name="Infobox.*">
 +						<Param Name="InfoboxIdentifier">IdentityLink</Param>
 +						<Param Name="PersonIdentifier">derived</Param>
 +					</Command>
 +					<Action>
 +						<RuleAction>allow</RuleAction>
 +					</Action>
 +				</Rule>
 +				<Rule Id="rule-DF2">
 +          <AuthClass>certified</AuthClass>
 +          <Command Name="Infobox.*">
 +            <Param Name="InfoboxIdentifier">IdentityLink</Param>
 +          </Command>
 +          <Action>
 +            <RuleAction>deny</RuleAction>
 +          </Action>
 +        </Rule>
 +			</Rules>
 +		</Chain>
 +	</Chains>
 +</AccessControl>
\ No newline at end of file | 
