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.Map; 024import java.util.concurrent.ConcurrentHashMap; 025import java.util.concurrent.ConcurrentMap; 026 027import org.nuxeo.ecm.webengine.security.PostfixExpression.Token; 028import org.nuxeo.ecm.webengine.security.guards.And; 029import org.nuxeo.ecm.webengine.security.guards.FacetGuard; 030import org.nuxeo.ecm.webengine.security.guards.GroupGuard; 031import org.nuxeo.ecm.webengine.security.guards.IsAdministratorGuard; 032import org.nuxeo.ecm.webengine.security.guards.Not; 033import org.nuxeo.ecm.webengine.security.guards.Or; 034import org.nuxeo.ecm.webengine.security.guards.PermissionGuard; 035import org.nuxeo.ecm.webengine.security.guards.SchemaGuard; 036import org.nuxeo.ecm.webengine.security.guards.TypeGuard; 037import org.nuxeo.ecm.webengine.security.guards.UserGuard; 038 039/** 040 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 041 */ 042public class PermissionService implements PostfixExpression.Visitor { 043 044 private static final PermissionService instance = new PermissionService(); 045 046 protected final ConcurrentMap<String, Guard> guards; // global guards 047 048 public static PermissionService getInstance() { 049 return instance; 050 } 051 052 protected PermissionService() { 053 guards = new ConcurrentHashMap<String, Guard>(); 054 } 055 056 public void registerGuard(String name, Guard guard) { 057 guards.put(name, guard); 058 } 059 060 public Guard unregisterGuard(String name) { 061 return guards.remove(name); 062 } 063 064 public Guard getGuard(String name) { 065 return guards.get(name); 066 } 067 068 public static Guard parse(String expr) throws ParseException { 069 return (Guard) new PostfixExpression(expr).visit(instance); 070 } 071 072 public Guard parse(String expr, final Map<String, Guard> localGuards) throws ParseException { 073 PostfixExpression.Visitor visitor = new PostfixExpression.Visitor() { 074 public Object createOperation(Token token, Object lparam, Object rparam) { 075 return PermissionService.this.createOperation(token, lparam, rparam); 076 } 077 078 public Object createParameter(Token token) { 079 Guard guard = localGuards.get(token.name); 080 if (guard == null) { // assume a built-in permission name 081 return PermissionService.this.createParameter(token); 082 } 083 return guard; 084 } 085 }; 086 return (Guard) new PostfixExpression(expr).visit(visitor); 087 } 088 089 public Object createOperation(Token token, Object lparam, Object rparam) { 090 switch (token.type) { 091 case PostfixExpression.AND: 092 return new And((Guard) lparam, (Guard) rparam); 093 case PostfixExpression.OR: 094 return new Or((Guard) lparam, (Guard) rparam); 095 case PostfixExpression.NOT: 096 return new Not((Guard) lparam); 097 } 098 throw new IllegalStateException("Supported ops are: AND, OR and NOT"); 099 } 100 101 public Object createParameter(Token token) { 102 String name = token.name; 103 int p = name.indexOf('='); 104 if (p > -1) { 105 String key = name.substring(0, p).trim(); 106 String value = name.substring(p + 1).trim(); 107 if ("user".equals(key)) { 108 return new UserGuard(value); 109 } else if ("group".equals(key)) { 110 return new GroupGuard(value); 111 } else if ("isAdministrator".equals(key)) { 112 return new IsAdministratorGuard(value); 113 } else if ("type".equals(key)) { 114 return new TypeGuard(value); 115 } else if ("facet".equals(key)) { 116 return new FacetGuard(value); 117 } else if ("schema".equals(key)) { 118 return new SchemaGuard(value); 119 } else if ("permission".equals(key)) { 120 return new PermissionGuard(value); 121 } 122 throw new IllegalArgumentException("Invalid argument: " + name); 123 } else { 124 Guard guard = guards.get(token.name); 125 if (guard == null) { // assume a built-in permission name 126 guard = new PermissionGuard(token.name); 127 } 128 return guard; 129 } 130 } 131 132}