001/* 002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * bstefanescu 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.webengine.security; 021 022import java.text.ParseException; 023import java.util.HashMap; 024import java.util.Map; 025 026import org.apache.commons.logging.Log; 027import org.apache.commons.logging.LogFactory; 028import org.nuxeo.common.xmap.annotation.XContent; 029import org.nuxeo.common.xmap.annotation.XNode; 030import org.nuxeo.common.xmap.annotation.XObject; 031import org.nuxeo.ecm.webengine.security.guards.And; 032import org.nuxeo.ecm.webengine.security.guards.FacetGuard; 033import org.nuxeo.ecm.webengine.security.guards.GroupGuard; 034import org.nuxeo.ecm.webengine.security.guards.IsAdministratorGuard; 035import org.nuxeo.ecm.webengine.security.guards.PermissionGuard; 036import org.nuxeo.ecm.webengine.security.guards.SchemaGuard; 037import org.nuxeo.ecm.webengine.security.guards.ScriptGuard; 038import org.nuxeo.ecm.webengine.security.guards.TypeGuard; 039import org.nuxeo.ecm.webengine.security.guards.UserGuard; 040import org.w3c.dom.DocumentFragment; 041import org.w3c.dom.NamedNodeMap; 042import org.w3c.dom.Node; 043 044/** 045 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 046 */ 047@XObject("permission") 048public class GuardDescriptor { 049 050 private static final Log log = LogFactory.getLog(GuardDescriptor.class); 051 052 @XNode("@id") 053 protected String id; 054 055 @XNode("@expression") 056 protected String expression; 057 058 protected Map<String, Guard> guards; 059 060 public GuardDescriptor() { 061 this(null); 062 } 063 064 public GuardDescriptor(String name) { 065 id = name; 066 guards = new HashMap<String, Guard>(); 067 } 068 069 public Map<String, Guard> getGuards() { 070 return guards; 071 } 072 073 /** 074 * @param expression the expression to set. 075 */ 076 public void setExpression(String expression) { 077 this.expression = expression; 078 } 079 080 /** 081 * @return the expression. 082 */ 083 public String getExpression() { 084 return expression; 085 } 086 087 @XContent 088 protected void setGuards(DocumentFragment content) { 089 Node node = content.getFirstChild(); 090 while (node != null) { 091 if (node.getNodeType() == Node.ELEMENT_NODE) { 092 String name = node.getNodeName(); 093 if ("guard".equals(name)) { 094 NamedNodeMap map = node.getAttributes(); 095 Node aId = map.getNamedItem("id"); 096 Node aType = map.getNamedItem("type"); 097 if (aId == null) { 098 throw new IllegalArgumentException("id is required"); 099 } 100 String id = aId.getNodeValue(); 101 if (aType == null) { 102 throw new IllegalArgumentException("type is required"); 103 } else { 104 // String value = node.getTextContent().trim(); 105 // guards.put(id, new ScriptGuard(value)); 106 // TODO: compound guard 107 } 108 String type = aType.getNodeValue(); 109 if ("permission".equals(type)) { 110 String value = node.getTextContent().trim(); 111 guards.put(id, new PermissionGuard(value)); 112 } else if ("isAdministrator".equals(type)) { 113 String value = node.getTextContent().trim(); 114 guards.put(id, new IsAdministratorGuard(value)); 115 } else if ("facet".equals(type)) { 116 String value = node.getTextContent().trim(); 117 guards.put(id, new FacetGuard(value)); 118 } else if ("type".equals(type)) { 119 String value = node.getTextContent().trim(); 120 guards.put(id, new TypeGuard(value)); 121 } else if ("schema".equals(type)) { 122 String value = node.getTextContent().trim(); 123 guards.put(id, new SchemaGuard(value)); 124 } else if ("user".equals(type)) { 125 String value = node.getTextContent().trim(); 126 guards.put(id, new UserGuard(value)); 127 } else if ("group".equals(type)) { 128 String value = node.getTextContent().trim(); 129 guards.put(id, new GroupGuard(value)); 130 } else if ("script".equals(type)) { 131 Node engineNode = map.getNamedItem("engine"); 132 if (engineNode == null) { 133 throw new IllegalArgumentException("Must specify an engine attribute on script guards"); 134 } 135 String value = node.getTextContent().trim(); 136 guards.put(id, new ScriptGuard(engineNode.getNodeValue(), value)); 137 } else if ("expression".equals(type)) { 138 String value = node.getTextContent().trim(); 139 try { 140 guards.put(id, PermissionService.getInstance().parse(value, guards)); 141 } catch (ParseException e) { 142 log.error(e, e); 143 } 144 } else { // the type should be a guard factory 145 String value = node.getTextContent().trim(); 146 try { 147 Class<?> factory = Class.forName(type); 148 Guard guard = ((GuardFactory) factory.newInstance()).newGuard(value); 149 guards.put(id, guard); 150 } catch (ReflectiveOperationException e) { 151 log.error(e, e); // TODO should throw a DeployException 152 } 153 } 154 } 155 } 156 node = node.getNextSibling(); 157 } 158 } 159 160 public Guard getGuard() throws ParseException { 161 if (expression == null || expression.length() == 0) { 162 return new And(guards.values()); 163 } 164 return PermissionService.getInstance().parse(expression, guards); 165 } 166 167 public String getId() { 168 return id; 169 } 170 171 public Permission getPermission() throws ParseException { 172 return new DefaultPermission(id, getGuard()); 173 } 174 175}