001/* 002 * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * bstefanescu 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.webengine.security; 023 024import java.text.ParseException; 025import java.util.HashMap; 026import java.util.Map; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.nuxeo.common.xmap.annotation.XContent; 031import org.nuxeo.common.xmap.annotation.XNode; 032import org.nuxeo.common.xmap.annotation.XObject; 033import org.nuxeo.ecm.webengine.security.guards.And; 034import org.nuxeo.ecm.webengine.security.guards.FacetGuard; 035import org.nuxeo.ecm.webengine.security.guards.GroupGuard; 036import org.nuxeo.ecm.webengine.security.guards.IsAdministratorGuard; 037import org.nuxeo.ecm.webengine.security.guards.PermissionGuard; 038import org.nuxeo.ecm.webengine.security.guards.SchemaGuard; 039import org.nuxeo.ecm.webengine.security.guards.ScriptGuard; 040import org.nuxeo.ecm.webengine.security.guards.TypeGuard; 041import org.nuxeo.ecm.webengine.security.guards.UserGuard; 042import org.w3c.dom.DocumentFragment; 043import org.w3c.dom.NamedNodeMap; 044import org.w3c.dom.Node; 045 046/** 047 * @author <a href="mailto:[email protected]">Bogdan Stefanescu</a> 048 */ 049@XObject("permission") 050public class GuardDescriptor { 051 052 private static final Log log = LogFactory.getLog(GuardDescriptor.class); 053 054 @XNode("@id") 055 protected String id; 056 057 @XNode("@expression") 058 protected String expression; 059 060 protected Map<String, Guard> guards; 061 062 public GuardDescriptor() { 063 this(null); 064 } 065 066 public GuardDescriptor(String name) { 067 id = name; 068 guards = new HashMap<String, Guard>(); 069 } 070 071 public Map<String, Guard> getGuards() { 072 return guards; 073 } 074 075 /** 076 * @param expression the expression to set. 077 */ 078 public void setExpression(String expression) { 079 this.expression = expression; 080 } 081 082 /** 083 * @return the expression. 084 */ 085 public String getExpression() { 086 return expression; 087 } 088 089 @XContent 090 protected void setGuards(DocumentFragment content) { 091 Node node = content.getFirstChild(); 092 while (node != null) { 093 if (node.getNodeType() == Node.ELEMENT_NODE) { 094 String name = node.getNodeName(); 095 if ("guard".equals(name)) { 096 NamedNodeMap map = node.getAttributes(); 097 Node aId = map.getNamedItem("id"); 098 Node aType = map.getNamedItem("type"); 099 if (aId == null) { 100 throw new IllegalArgumentException("id is required"); 101 } 102 String id = aId.getNodeValue(); 103 if (aType == null) { 104 throw new IllegalArgumentException("type is required"); 105 } else { 106 // String value = node.getTextContent().trim(); 107 // guards.put(id, new ScriptGuard(value)); 108 // TODO: compound guard 109 } 110 String type = aType.getNodeValue(); 111 if ("permission".equals(type)) { 112 String value = node.getTextContent().trim(); 113 guards.put(id, new PermissionGuard(value)); 114 } else if ("isAdministrator".equals(type)) { 115 String value = node.getTextContent().trim(); 116 guards.put(id, new IsAdministratorGuard(value)); 117 } else if ("facet".equals(type)) { 118 String value = node.getTextContent().trim(); 119 guards.put(id, new FacetGuard(value)); 120 } else if ("type".equals(type)) { 121 String value = node.getTextContent().trim(); 122 guards.put(id, new TypeGuard(value)); 123 } else if ("schema".equals(type)) { 124 String value = node.getTextContent().trim(); 125 guards.put(id, new SchemaGuard(value)); 126 } else if ("user".equals(type)) { 127 String value = node.getTextContent().trim(); 128 guards.put(id, new UserGuard(value)); 129 } else if ("group".equals(type)) { 130 String value = node.getTextContent().trim(); 131 guards.put(id, new GroupGuard(value)); 132 } else if ("script".equals(type)) { 133 Node engineNode = map.getNamedItem("engine"); 134 if (engineNode == null) { 135 throw new IllegalArgumentException("Must specify an engine attribute on script guards"); 136 } 137 String value = node.getTextContent().trim(); 138 guards.put(id, new ScriptGuard(engineNode.getNodeValue(), value)); 139 } else if ("expression".equals(type)) { 140 String value = node.getTextContent().trim(); 141 try { 142 guards.put(id, PermissionService.getInstance().parse(value, guards)); 143 } catch (ParseException e) { 144 log.error(e, e); 145 } 146 } else { // the type should be a guard factory 147 String value = node.getTextContent().trim(); 148 try { 149 Class<?> factory = Class.forName(type); 150 Guard guard = ((GuardFactory) factory.newInstance()).newGuard(value); 151 guards.put(id, guard); 152 } catch (ReflectiveOperationException e) { 153 log.error(e, e); // TODO should throw a DeployException 154 } 155 } 156 } 157 } 158 node = node.getNextSibling(); 159 } 160 } 161 162 public Guard getGuard() throws ParseException { 163 if (expression == null || expression.length() == 0) { 164 return new And(guards.values()); 165 } 166 return PermissionService.getInstance().parse(expression, guards); 167 } 168 169 public String getId() { 170 return id; 171 } 172 173 public Permission getPermission() throws ParseException { 174 return new DefaultPermission(id, getGuard()); 175 } 176 177}