001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.lenya.ac.impl;
020:
021: import java.io.InputStream;
022:
023: import javax.xml.parsers.ParserConfigurationException;
024:
025: import org.apache.lenya.ac.AccessControlException;
026: import org.apache.lenya.ac.AccessController;
027: import org.apache.lenya.ac.Accreditable;
028: import org.apache.lenya.ac.AccreditableManager;
029: import org.apache.lenya.ac.Credential;
030: import org.apache.lenya.ac.ModifiablePolicy;
031: import org.apache.lenya.ac.Policy;
032: import org.apache.lenya.ac.Role;
033: import org.apache.lenya.ac.User;
034: import org.apache.lenya.ac.World;
035: import org.apache.lenya.ac.cache.BuildException;
036: import org.apache.lenya.ac.cache.InputStreamBuilder;
037: import org.apache.lenya.xml.DocumentHelper;
038: import org.apache.lenya.xml.NamespaceHelper;
039: import org.w3c.dom.Document;
040: import org.w3c.dom.Element;
041:
042: /**
043: * Builds policies from input streams.
044: * @version $Id: PolicyBuilder.java 603883 2007-12-13 11:01:32Z andreas $
045: */
046: public class PolicyBuilder implements InputStreamBuilder {
047:
048: /**
049: * Ctor.
050: * @param _accreditableManager An accreditable manager.
051: */
052: public PolicyBuilder(AccreditableManager _accreditableManager) {
053: assert _accreditableManager != null;
054: this .accreditableManager = _accreditableManager;
055: }
056:
057: /**
058: * Returns the accreditable manager.
059: * @return An accreditable manager.
060: */
061: public AccreditableManager getAccreditableManager() {
062: return this .accreditableManager;
063: }
064:
065: private AccreditableManager accreditableManager;
066:
067: protected static final String POLICY_ELEMENT = "policy";
068: protected static final String GROUP_ELEMENT = "group";
069: protected static final String USER_ELEMENT = "user";
070: protected static final String ROLE_ELEMENT = "role";
071: protected static final String WORLD_ELEMENT = "world";
072: protected static final String IP_RANGE_ELEMENT = "ip-range";
073: protected static final String ID_ATTRIBUTE = "id";
074: protected static final String SSL_ATTRIBUTE = "ssl";
075: protected static final String METHOD_ATTRIBUTE = "method";
076:
077: /**
078: * Builds a policy from an input stream.
079: * @param stream The input stream to read the policy from.
080: * @return A policy.
081: * @throws AccessControlException when something went wrong.
082: */
083: public ModifiablePolicy buildPolicy(InputStream stream)
084: throws AccessControlException {
085:
086: Document document;
087:
088: try {
089: document = DocumentHelper.readDocument(stream);
090: } catch (Exception e) {
091: throw new AccessControlException(e);
092: }
093:
094: return buildPolicy(document);
095: }
096:
097: /**
098: * Builds a policy from an XML document.
099: * @param document The XML document.
100: * @return A policy.
101: * @throws AccessControlException when something went wrong.
102: */
103: public ModifiablePolicy buildPolicy(Document document)
104: throws AccessControlException {
105:
106: DefaultPolicy policy = new DefaultPolicy();
107: Element policyElement = document.getDocumentElement();
108: assert policyElement.getLocalName().equals(POLICY_ELEMENT);
109:
110: NamespaceHelper helper = new NamespaceHelper(
111: AccessController.NAMESPACE,
112: AccessController.DEFAULT_PREFIX, document);
113:
114: Element[] credentialElements = helper
115: .getChildren(policyElement);
116:
117: for (int i = 0; i < credentialElements.length; i++) {
118: Accreditable accreditable = null;
119:
120: String id = credentialElements[i]
121: .getAttribute(ID_ATTRIBUTE);
122: accreditable = getAccreditable(credentialElements[i]
123: .getLocalName(), id);
124:
125: Element[] roleElements = helper.getChildren(
126: credentialElements[i], ROLE_ELEMENT);
127:
128: for (int j = 0; j < roleElements.length; j++) {
129: String roleId = roleElements[j]
130: .getAttribute(ID_ATTRIBUTE);
131: Role role = getAccreditableManager().getRoleManager()
132: .getRole(roleId);
133: if (role == null) {
134: throw new AccessControlException("The role '"
135: + roleId + "' does not exist.");
136: }
137: CredentialImpl credential = new CredentialImpl(
138: accreditable, role);
139: String method = roleElements[j]
140: .getAttribute(METHOD_ATTRIBUTE);
141: // If method is not set, we assume DENY
142: if (method.length() == 0)
143: method = CredentialImpl.DENY;
144: credential.setMethod(method);
145: policy.addCredential(credential);
146: }
147:
148: }
149:
150: boolean ssl = false;
151: String sslString = policyElement.getAttribute(SSL_ATTRIBUTE);
152: if (sslString != null) {
153: ssl = Boolean.valueOf(sslString).booleanValue();
154: }
155: policy.setSSL(ssl);
156:
157: return policy;
158: }
159:
160: /**
161: * Creates an accredtiable for an element.
162: * @param elementName The elment name.
163: * @param id The ID of the accreditable.
164: * @return An accreditable.
165: * @throws AccessControlException when something went wrong.
166: */
167: protected Accreditable getAccreditable(String elementName, String id)
168: throws AccessControlException {
169: Accreditable accreditable = null;
170:
171: if (elementName.equals(USER_ELEMENT)) {
172: accreditable = getAccreditableManager().getUserManager()
173: .getUser(id);
174: } else if (elementName.equals(GROUP_ELEMENT)) {
175: accreditable = getAccreditableManager().getGroupManager()
176: .getGroup(id);
177: } else if (elementName.equals(WORLD_ELEMENT)) {
178: accreditable = World.getInstance();
179: } else if (elementName.equals(IP_RANGE_ELEMENT)) {
180: accreditable = getAccreditableManager().getIPRangeManager()
181: .getIPRange(id);
182: }
183:
184: if (accreditable == null) {
185: throw new AccessControlException("Unknown accreditable ["
186: + elementName + "] with ID [" + id + "]");
187: }
188:
189: return accreditable;
190: }
191:
192: /**
193: * Saves a policy to an XML document.
194: * @param policy The policy to save.
195: * @return A DOM document.
196: * @throws AccessControlException when something went wrong.
197: */
198: public static Document savePolicy(Policy policy)
199: throws AccessControlException {
200: NamespaceHelper helper;
201:
202: try {
203: helper = new NamespaceHelper(AccessController.NAMESPACE,
204: AccessController.DEFAULT_PREFIX, POLICY_ELEMENT);
205: } catch (ParserConfigurationException e) {
206: throw new AccessControlException(e);
207: }
208:
209: Credential[] credentials = ((DefaultPolicy) policy)
210: .getCredentials();
211: Element policyElement = helper.getDocument()
212: .getDocumentElement();
213:
214: for (int i = 0; i < credentials.length; i++) {
215: Accreditable accreditable = credentials[i]
216: .getAccreditable();
217: Element accreditableElement = save(accreditable, helper);
218:
219: Role role = credentials[i].getRole();
220: Element roleElement = helper.createElement(ROLE_ELEMENT);
221: roleElement.setAttribute(ID_ATTRIBUTE, role.getId());
222: roleElement.setAttribute(METHOD_ATTRIBUTE, credentials[i]
223: .getMethod());
224: accreditableElement.appendChild(roleElement);
225:
226: policyElement.appendChild(accreditableElement);
227: }
228:
229: policyElement.setAttribute(SSL_ATTRIBUTE, Boolean
230: .toString(policy.isSSLProtected()));
231:
232: return helper.getDocument();
233: }
234:
235: /**
236: * Saves an accreditable to an XML element.
237: * @param accreditable The accreditable.
238: * @param helper The namespace helper to be used.
239: * @return An XML element.
240: * @throws AccessControlException when something went wrong.
241: */
242: protected static Element save(Accreditable accreditable,
243: NamespaceHelper helper) throws AccessControlException {
244: String localName = null;
245: String id = null;
246:
247: if (accreditable instanceof User) {
248: localName = USER_ELEMENT;
249: id = ((User) accreditable).getId();
250: } else if (accreditable instanceof AbstractGroup) {
251: localName = GROUP_ELEMENT;
252: id = ((AbstractGroup) accreditable).getId();
253: } else if (accreditable instanceof World) {
254: localName = WORLD_ELEMENT;
255: } else if (accreditable instanceof AbstractIPRange) {
256: localName = IP_RANGE_ELEMENT;
257: id = ((AbstractIPRange) accreditable).getId();
258: }
259:
260: if (localName == null) {
261: throw new AccessControlException(
262: "Could not save accreditable [" + accreditable
263: + "]");
264: }
265:
266: Element element = helper.createElement(localName);
267:
268: if (id != null) {
269: element.setAttribute(ID_ATTRIBUTE, id);
270: }
271:
272: return element;
273: }
274:
275: /**
276: * @see org.apache.lenya.ac.cache.InputStreamBuilder#build(java.io.InputStream)
277: */
278: public Object build(InputStream stream) throws BuildException {
279: Object value = null;
280: try {
281: value = buildPolicy(stream);
282: } catch (AccessControlException e) {
283: throw new BuildException(e);
284: }
285: return value;
286: }
287:
288: }
|