blob: e1a50062734f874bcd71f01374b65098f6042d95 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.lenya.ac.impl;
import java.io.InputStream;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.lenya.ac.AccessControlException;
import org.apache.lenya.ac.AccessController;
import org.apache.lenya.ac.Accreditable;
import org.apache.lenya.ac.AccreditableManager;
import org.apache.lenya.ac.Credential;
import org.apache.lenya.ac.ModifiablePolicy;
import org.apache.lenya.ac.Policy;
import org.apache.lenya.ac.Role;
import org.apache.lenya.ac.User;
import org.apache.lenya.ac.World;
import org.apache.lenya.ac.cache.BuildException;
import org.apache.lenya.ac.cache.InputStreamBuilder;
import org.apache.lenya.xml.DocumentHelper;
import org.apache.lenya.xml.NamespaceHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Builds policies from input streams.
* @version $Id$
*/
public class PolicyBuilder implements InputStreamBuilder {
/**
* Ctor.
* @param _accreditableManager An accreditable manager.
*/
public PolicyBuilder(AccreditableManager _accreditableManager) {
assert _accreditableManager != null;
this.accreditableManager = _accreditableManager;
}
/**
* Returns the accreditable manager.
* @return An accreditable manager.
*/
public AccreditableManager getAccreditableManager() {
return this.accreditableManager;
}
private AccreditableManager accreditableManager;
protected static final String POLICY_ELEMENT = "policy";
protected static final String GROUP_ELEMENT = "group";
protected static final String USER_ELEMENT = "user";
protected static final String ROLE_ELEMENT = "role";
protected static final String WORLD_ELEMENT = "world";
protected static final String IP_RANGE_ELEMENT = "ip-range";
protected static final String ID_ATTRIBUTE = "id";
protected static final String SSL_ATTRIBUTE = "ssl";
protected static final String METHOD_ATTRIBUTE = "method";
/**
* Builds a policy from an input stream.
* @param stream The input stream to read the policy from.
* @return A policy.
* @throws AccessControlException when something went wrong.
*/
public ModifiablePolicy buildPolicy(InputStream stream)
throws AccessControlException {
Document document;
try {
document = DocumentHelper.readDocument(stream);
} catch (Exception e) {
throw new AccessControlException(e);
}
return buildPolicy(document);
}
/**
* Builds a policy from an XML document.
* @param document The XML document.
* @return A policy.
* @throws AccessControlException when something went wrong.
*/
public ModifiablePolicy buildPolicy(Document document)
throws AccessControlException {
DefaultPolicy policy = new DefaultPolicy();
Element policyElement = document.getDocumentElement();
assert policyElement.getLocalName().equals(POLICY_ELEMENT);
NamespaceHelper helper =
new NamespaceHelper(
AccessController.NAMESPACE,
AccessController.DEFAULT_PREFIX,
document);
Element[] credentialElements = helper.getChildren(policyElement);
for (int i = 0; i < credentialElements.length; i++) {
Accreditable accreditable = null;
String id = credentialElements[i].getAttribute(ID_ATTRIBUTE);
accreditable = getAccreditable(credentialElements[i].getLocalName(), id);
Element[] roleElements = helper.getChildren(credentialElements[i], ROLE_ELEMENT);
for (int j = 0; j < roleElements.length; j++) {
String roleId = roleElements[j].getAttribute(ID_ATTRIBUTE);
Role role = getAccreditableManager().getRoleManager().getRole(roleId);
CredentialImpl credential = new CredentialImpl(accreditable, role);
String method = roleElements[j].getAttribute(METHOD_ATTRIBUTE);
// If method is not set, we assume DENY
if (method.length() == 0) method = CredentialImpl.DENY;
credential.setMethod(method);
policy.addCredential(credential);
}
}
boolean ssl = false;
String sslString = policyElement.getAttribute(SSL_ATTRIBUTE);
if (sslString != null) {
ssl = Boolean.valueOf(sslString).booleanValue();
}
policy.setSSL(ssl);
return policy;
}
/**
* Creates an accredtiable for an element.
* @param elementName The elment name.
* @param id The ID of the accreditable.
* @return An accreditable.
* @throws AccessControlException when something went wrong.
*/
protected Accreditable getAccreditable(
String elementName,
String id)
throws AccessControlException {
Accreditable accreditable = null;
if (elementName.equals(USER_ELEMENT)) {
accreditable = getAccreditableManager().getUserManager().getUser(id);
} else if (elementName.equals(GROUP_ELEMENT)) {
accreditable = getAccreditableManager().getGroupManager().getGroup(id);
} else if (elementName.equals(WORLD_ELEMENT)) {
accreditable = World.getInstance();
} else if (elementName.equals(IP_RANGE_ELEMENT)) {
accreditable = getAccreditableManager().getIPRangeManager().getIPRange(id);
}
if (accreditable == null) {
throw new AccessControlException(
"Unknown accreditable [" + elementName + "] with ID [" + id + "]");
}
return accreditable;
}
/**
* Saves a policy to an XML document.
* @param policy The policy to save.
* @return A DOM document.
* @throws AccessControlException when something went wrong.
*/
public static Document savePolicy(Policy policy) throws AccessControlException {
NamespaceHelper helper;
try {
helper =
new NamespaceHelper(
AccessController.NAMESPACE,
AccessController.DEFAULT_PREFIX,
POLICY_ELEMENT);
} catch (ParserConfigurationException e) {
throw new AccessControlException(e);
}
Credential[] credentials = ((DefaultPolicy) policy).getCredentials();
Element policyElement = helper.getDocument().getDocumentElement();
for (int i = 0; i < credentials.length; i++) {
Accreditable accreditable = credentials[i].getAccreditable();
Element accreditableElement = save(accreditable, helper);
Role role = credentials[i].getRole();
Element roleElement = helper.createElement(ROLE_ELEMENT);
roleElement.setAttribute(ID_ATTRIBUTE, role.getId());
roleElement.setAttribute(METHOD_ATTRIBUTE, credentials[i].getMethod());
accreditableElement.appendChild(roleElement);
policyElement.appendChild(accreditableElement);
}
policyElement.setAttribute(SSL_ATTRIBUTE, Boolean.toString(policy.isSSLProtected()));
return helper.getDocument();
}
/**
* Saves an accreditable to an XML element.
* @param accreditable The accreditable.
* @param helper The namespace helper to be used.
* @return An XML element.
* @throws AccessControlException when something went wrong.
*/
protected static Element save(Accreditable accreditable, NamespaceHelper helper)
throws AccessControlException {
String localName = null;
String id = null;
if (accreditable instanceof User) {
localName = USER_ELEMENT;
id = ((User) accreditable).getId();
} else if (accreditable instanceof AbstractGroup) {
localName = GROUP_ELEMENT;
id = ((AbstractGroup) accreditable).getId();
} else if (accreditable instanceof World) {
localName = WORLD_ELEMENT;
} else if (accreditable instanceof AbstractIPRange) {
localName = IP_RANGE_ELEMENT;
id = ((AbstractIPRange) accreditable).getId();
}
if (localName == null) {
throw new AccessControlException("Could not save accreditable [" + accreditable + "]");
}
Element element = helper.createElement(localName);
if (id != null) {
element.setAttribute(ID_ATTRIBUTE, id);
}
return element;
}
/**
* @see org.apache.lenya.ac.cache.InputStreamBuilder#build(java.io.InputStream)
*/
public Object build(InputStream stream) throws BuildException {
Object value = null;
try {
value = buildPolicy(stream);
} catch (AccessControlException e) {
throw new BuildException(e);
}
return value;
}
}