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: /* $Id: AccessControlModule.java 535788 2007-05-07 08:52:30Z andreas $ */
020:
021: package org.apache.lenya.cms.cocoon.components.modules.input;
022:
023: import java.util.Arrays;
024: import java.util.Iterator;
025: import java.util.Map;
026:
027: import org.apache.avalon.framework.configuration.Configuration;
028: import org.apache.avalon.framework.configuration.ConfigurationException;
029: import org.apache.avalon.framework.service.ServiceException;
030: import org.apache.avalon.framework.service.ServiceManager;
031: import org.apache.avalon.framework.service.ServiceSelector;
032: import org.apache.avalon.framework.service.Serviceable;
033: import org.apache.cocoon.components.modules.input.AbstractInputModule;
034: import org.apache.cocoon.environment.ObjectModelHelper;
035: import org.apache.cocoon.environment.Request;
036: import org.apache.cocoon.environment.Session;
037: import org.apache.lenya.ac.AccessControlException;
038: import org.apache.lenya.ac.AccessController;
039: import org.apache.lenya.ac.AccessControllerResolver;
040: import org.apache.lenya.ac.AccreditableManager;
041: import org.apache.lenya.ac.Identity;
042: import org.apache.lenya.ac.ItemManager;
043: import org.apache.lenya.ac.Machine;
044: import org.apache.lenya.ac.Policy;
045: import org.apache.lenya.ac.PolicyManager;
046: import org.apache.lenya.ac.Role;
047: import org.apache.lenya.ac.User;
048: import org.apache.lenya.ac.UserManager;
049: import org.apache.lenya.cms.ac.PolicyUtil;
050: import org.apache.lenya.util.ServletHelper;
051:
052: /**
053: * <p>
054: * Input module for access control attributes.
055: * </p>
056: * <p>
057: * Attributes:
058: * </p>
059: * <ul>
060: * <li><strong><code>user-id</code></strong> - the ID of the currently logged-in user</li>
061: * <li><strong><code>user-name</code></strong> - the full name of the currently logged-in user</li>
062: * <li><strong><code>user-name:{user-id}</code></strong> - the full name of a specific user</li>
063: * <li><strong><code>user-email</code></strong> - the e-mail address of the currently logged-in user</li>
064: * <li><strong><code>user-email:{user-id}</code></strong> - the e-mail address of a specific user</li>
065: * <li><strong><code>ip-address</code></strong> - the IP address of the client machine</li>
066: * <li><strong><code>role-ids</code></strong> - the role IDs which are granted to the current identity</li>
067: * <li><strong><code>user-manager</code></strong> - the user manager object</li>
068: * <li><strong><code>group-manager</code></strong> - the group manager object</li>
069: * <li><strong><code>iprange-manager</code></strong> - the IP range manager object</li>
070: * <li><strong><code>role-manager</code></strong> - the role manager object</li>
071: * </ul>
072: *
073: */
074: public class AccessControlModule extends AbstractInputModule implements
075: Serviceable {
076:
077: /**
078: * <code>USER_ID</code> The user id
079: */
080: public static final String USER_ID = "user-id";
081: /**
082: * <code>USER_NAME</code> The user name, optional: provide the user ID after a colon
083: */
084: public static final String USER_NAME = "user-name";
085: /**
086: * <code>USER_EMAIL</code> The user email, optional: provide the user ID after a colon
087: */
088: public static final String USER_EMAIL = "user-email";
089: /**
090: * <code>IP_ADDRESS</code> The IP address
091: */
092: public static final String IP_ADDRESS = "ip-address";
093: /**
094: * <code>ROLE_IDS</code> The role ids
095: */
096: public static final String ROLE_IDS = "role-ids";
097: /**
098: * <code>USER_MANAGER</code> The user manager
099: */
100: public static final String USER_MANAGER = "user-manager";
101: /**
102: * <code>GROUP_MANAGER</code> The group manager
103: */
104: public static final String GROUP_MANAGER = "group-manager";
105: /**
106: * <code>ROLE_MANAGER</code> The role manager
107: */
108: public static final String ROLE_MANAGER = "role-manager";
109: /**
110: * <code>IP_RANGE_MANAGER</code> The IP range manager
111: */
112: public static final String IP_RANGE_MANAGER = "iprange-manager";
113: /**
114: * Returns if the current page is SSL protected (true|false).
115: */
116: public static final String SSL = "ssl";
117:
118: /**
119: * The names of the AccessControlModule parameters.
120: */
121: static final String[] PARAMETER_NAMES = { IP_ADDRESS, USER_ID,
122: USER_NAME, USER_EMAIL, ROLE_IDS, USER_MANAGER,
123: GROUP_MANAGER, ROLE_MANAGER, IP_RANGE_MANAGER, SSL };
124:
125: /**
126: *
127: * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(java.lang.String,
128: * org.apache.avalon.framework.configuration.Configuration, java.util.Map)
129: */
130: public Object getAttribute(String attribute,
131: Configuration modeConf, Map objectModel)
132: throws ConfigurationException {
133:
134: Request request = ObjectModelHelper.getRequest(objectModel);
135: Session session = request.getSession();
136: Object value = null;
137:
138: String[] parameters = attribute.split(":", 2);
139: String name = parameters[0];
140:
141: if (!Arrays.asList(PARAMETER_NAMES).contains(name)) {
142: throw new ConfigurationException("The attribute [" + name
143: + "] is not supported!");
144: }
145:
146: Identity identity = null;
147:
148: if (session != null) {
149: identity = (Identity) session.getAttribute(Identity.class
150: .getName());
151: }
152: User user = getUser(request, parameters, identity);
153:
154: if (user != null) {
155: if (name.equals(USER_NAME)) {
156: value = user.getName();
157: } else if (name.equals(USER_EMAIL)) {
158: value = user.getEmail();
159: }
160: }
161:
162: if (identity != null) {
163: if (name.equals(USER_ID)) {
164: User currentUser = identity.getUser();
165: if (currentUser != null) {
166: value = currentUser.getId();
167: }
168: } else if (name.equals(IP_ADDRESS)) {
169: Machine machine = identity.getMachine();
170: if (machine != null) {
171: value = machine.getIp();
172: }
173: } else if (name.equals(ROLE_IDS)) {
174: try {
175: Role[] roles = PolicyUtil.getRoles(request);
176: StringBuffer buf = new StringBuffer();
177: for (int i = 0; i < roles.length; i++) {
178: if (i > 0) {
179: buf.append(",");
180: }
181: buf.append(roles[i].getId());
182: }
183: value = buf.toString();
184: } catch (AccessControlException e) {
185: throw new ConfigurationException(
186: "Obtaining value for attribute [" + name
187: + "] failed: ", e);
188: }
189: }
190: }
191:
192: if (name.equals(USER_MANAGER) || name.equals(GROUP_MANAGER)
193: || name.equals(ROLE_MANAGER)
194: || name.equals(IP_RANGE_MANAGER)) {
195: value = getItemManager(request, name);
196: }
197:
198: if (name.equals(SSL)) {
199: ServiceSelector selector = null;
200: AccessControllerResolver acResolver = null;
201: AccessController accessController = null;
202: try {
203: selector = (ServiceSelector) this .manager
204: .lookup(AccessControllerResolver.ROLE
205: + "Selector");
206: acResolver = (AccessControllerResolver) selector
207: .select(AccessControllerResolver.DEFAULT_RESOLVER);
208:
209: String url = ServletHelper.getWebappURI(request);
210: accessController = acResolver
211: .resolveAccessController(url);
212: AccreditableManager accreditableManager = accessController
213: .getAccreditableManager();
214: PolicyManager policyManager = accessController
215: .getPolicyManager();
216:
217: Policy policy = policyManager.getPolicy(
218: accreditableManager, url);
219: value = Boolean.toString(policy.isSSLProtected());
220: } catch (Exception e) {
221: throw new ConfigurationException(
222: "Resolving attribute [" + name + "] failed: ",
223: e);
224: } finally {
225: if (selector != null) {
226: if (acResolver != null) {
227: if (accessController != null) {
228: acResolver.release(accessController);
229: }
230: selector.release(acResolver);
231: }
232: this .manager.release(selector);
233: }
234: }
235: }
236:
237: return value;
238: }
239:
240: /**
241: * Returns the user specified with parameter[1], falling back to the currently logged in user.
242: * @param request The request.
243: * @param parameters The parameters.
244: * @param identity The logged in identity.
245: * @return A user or <code>null</code> if no user is specified or logged in.
246: * @throws ConfigurationException if an error occurs.
247: */
248: protected User getUser(Request request, String[] parameters,
249: Identity identity) throws ConfigurationException {
250: User user = null;
251: if (parameters.length == 1) {
252: if (identity != null) {
253: user = identity.getUser();
254: }
255: } else {
256: String userId = parameters[1];
257: if (!userId.equals("")) {
258: UserManager userManager = (UserManager) getItemManager(
259: request, USER_MANAGER);
260: user = userManager.getUser(userId);
261: }
262: }
263: return user;
264: }
265:
266: /**
267: * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeNames(org.apache.avalon.framework.configuration.Configuration,
268: * java.util.Map)
269: */
270: public Iterator getAttributeNames(Configuration modeConf,
271: Map objectModel) throws ConfigurationException {
272: return Arrays.asList(PARAMETER_NAMES).iterator();
273: }
274:
275: /**
276: * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeValues(java.lang.String,
277: * org.apache.avalon.framework.configuration.Configuration, java.util.Map)
278: */
279: public Object[] getAttributeValues(String name,
280: Configuration modeConf, Map objectModel)
281: throws ConfigurationException {
282: Object[] objects = { getAttribute(name, modeConf, objectModel) };
283:
284: return objects;
285: }
286:
287: /**
288: * Returns the item manager for a certain name.
289: * @param request The request.
290: * @param name The name of the manager ({@link #USER_MANAGER}, {@link #ROLE_MANAGER},
291: * {@link #GROUP_MANAGER}, or {@link #IP_RANGE_MANAGER}
292: * @return An item manager.
293: * @throws ConfigurationException when something went wrong.
294: */
295: protected ItemManager getItemManager(Request request, String name)
296: throws ConfigurationException {
297: AccessController accessController = null;
298: ServiceSelector selector = null;
299: AccessControllerResolver resolver = null;
300: ItemManager itemManager = null;
301:
302: try {
303: selector = (ServiceSelector) this .manager
304: .lookup(AccessControllerResolver.ROLE + "Selector");
305: resolver = (AccessControllerResolver) selector
306: .select(AccessControllerResolver.DEFAULT_RESOLVER);
307:
308: String requestURI = request.getRequestURI();
309: String context = request.getContextPath();
310: if (context == null) {
311: context = "";
312: }
313: String url = requestURI.substring(context.length());
314: accessController = resolver.resolveAccessController(url);
315:
316: AccreditableManager accreditableManager = accessController
317: .getAccreditableManager();
318:
319: if (name.equals(USER_MANAGER)) {
320: itemManager = accreditableManager.getUserManager();
321: } else if (name.equals(GROUP_MANAGER)) {
322: itemManager = accreditableManager.getGroupManager();
323: } else if (name.equals(ROLE_MANAGER)) {
324: itemManager = accreditableManager.getRoleManager();
325: } else if (name.equals(IP_RANGE_MANAGER)) {
326: itemManager = accreditableManager.getIPRangeManager();
327: }
328:
329: } catch (Exception e) {
330: throw new ConfigurationException(
331: "Obtaining item manager failed: ", e);
332: } finally {
333: if (selector != null) {
334: if (resolver != null) {
335: if (accessController != null) {
336: resolver.release(accessController);
337: }
338: selector.release(resolver);
339: }
340: this .manager.release(selector);
341: }
342: }
343:
344: return itemManager;
345: }
346:
347: private ServiceManager manager;
348:
349: /**
350: * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
351: */
352: public void service(ServiceManager _manager)
353: throws ServiceException {
354: this.manager = _manager;
355: }
356:
357: }
|