001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * bstefanescu 011 */ 012package org.nuxeo.ecm.automation.features; 013 014import java.util.HashSet; 015import java.util.Set; 016 017import org.apache.commons.lang.StringUtils; 018import org.nuxeo.ecm.core.api.DocumentModel; 019import org.nuxeo.ecm.core.api.NuxeoGroup; 020import org.nuxeo.ecm.core.api.NuxeoPrincipal; 021import org.nuxeo.ecm.core.api.security.ACE; 022import org.nuxeo.ecm.core.api.security.ACL; 023import org.nuxeo.ecm.core.api.security.ACP; 024import org.nuxeo.ecm.core.api.security.PermissionProvider; 025import org.nuxeo.ecm.core.api.security.SecurityConstants; 026import org.nuxeo.ecm.platform.usermanager.UserManager; 027 028/** 029 * Provides helper methods to find extract permissions/principals info from documents. 030 * 031 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 032 * @author Anahide Tchertchian 033 */ 034public class PrincipalHelper { 035 036 protected UserManager userManager; 037 038 protected PermissionProvider permissionProvider; 039 040 public PrincipalHelper(UserManager userManager, PermissionProvider permissionProvider) { 041 this.userManager = userManager; 042 this.permissionProvider = permissionProvider; 043 } 044 045 @SuppressWarnings("unchecked") 046 public Set<String> getEmailsForPermission(DocumentModel input, String permission, boolean ignoreGroups) 047 { 048 return (Set<String>) collectObjectsMatchingPermission(input, permission, ignoreGroups, true, 049 new EmailCollector(userManager.getUserSchemaName(), userManager.getUserEmailField())); 050 } 051 052 /** 053 * Resolves the list of identifiers for users and groups who have the given permission on given document. 054 * 055 * @param input document model to resolve users and groups on. 056 * @param permission the permission to check 057 * @param ignoreGroups if true, will ignore groups in resolution of ids 058 * @param resolveGroups if true, will resolve user members, iterating in the hierarchy of groups 059 * @param prefixIds if true, will prefix identifiers with {@link NuxeoPrincipal#PREFIX} and 060 * {@link NuxeoGroup#PREFIX} 061 */ 062 @SuppressWarnings("unchecked") 063 public Set<String> getUserAndGroupIdsForPermission(DocumentModel input, String permission, boolean ignoreGroups, 064 boolean resolveGroups, boolean prefixIds) { 065 return (Set<String>) collectObjectsMatchingPermission(input, permission, ignoreGroups, resolveGroups, 066 new IdCollector(prefixIds)); 067 } 068 069 @SuppressWarnings("unchecked") 070 public Set<NuxeoPrincipal> getPrincipalsForPermission(DocumentModel input, String permission, boolean ignoreGroups, 071 boolean resolveGroups) { 072 return (Set<NuxeoPrincipal>) collectObjectsMatchingPermission(input, permission, ignoreGroups, resolveGroups, 073 new PrincipalCollector()); 074 } 075 076 public Set<String> getEmailsFromGroup(String groupId, boolean resolveGroups) { 077 EmailCollector collector = new EmailCollector(userManager.getUserSchemaName(), userManager.getUserEmailField()); 078 collectObjectsFromGroup(groupId, resolveGroups, collector); 079 return collector.getResult(); 080 } 081 082 public Set<NuxeoPrincipal> getPrincipalsFromGroup(String groupId, boolean resolveGroups) { 083 PrincipalCollector collector = new PrincipalCollector(); 084 collectObjectsFromGroup(groupId, resolveGroups, collector); 085 return collector.getResult(); 086 } 087 088 public Set<String> getUserNamesFromGroup(String groupId, boolean resolveGroups, boolean prefixIds) 089 { 090 IdCollector collector = new IdCollector(prefixIds); 091 collectObjectsFromGroup(groupId, resolveGroups, collector); 092 return collector.getResult(); 093 } 094 095 public void collectObjectsFromGroup(String groupId, boolean resolveGroups, Collector<?> collector) 096 { 097 NuxeoGroup group = userManager.getGroup(groupId); 098 if (group == null) { 099 userManager.getPrincipal(groupId); 100 } else { 101 for (String u : group.getMemberUsers()) { 102 NuxeoPrincipal principal = userManager.getPrincipal(u); 103 if (principal != null) { 104 collector.collect(principal); 105 } 106 } 107 if (resolveGroups) { 108 for (String g : group.getMemberGroups()) { 109 collectObjectsFromGroup(g, resolveGroups, collector); 110 } 111 } 112 } 113 } 114 115 public HashSet<?> collectObjectsMatchingPermission(DocumentModel input, String permission, boolean ignoreGroups, 116 boolean resolveGroups, Collector<?> collector) { 117 String[] perms = getPermissionsToCheck(permission); 118 ACP acp = input.getACP(); 119 for (ACL acl : acp.getACLs()) { 120 for (ACE ace : acl.getACEs()) { 121 if (ace.isGranted() && permissionMatch(perms, ace.getPermission())) { 122 NuxeoGroup group = userManager.getGroup(ace.getUsername()); 123 if (group == null) { 124 // this may be a user 125 collector.collect(userManager.getPrincipal(ace.getUsername())); 126 } else if (!ignoreGroups) { 127 if (resolveGroups) { 128 resolveGroups(group, collector); 129 } else { 130 collector.collect(group); 131 } 132 } 133 } 134 } 135 } 136 return collector.getResult(); 137 } 138 139 public void resolveGroups(NuxeoGroup group, Collector<?> collector) { 140 if (group != null) { 141 for (String memberUser : group.getMemberUsers()) { 142 collector.collect(userManager.getPrincipal(memberUser)); 143 } 144 for (String subGroup : group.getMemberGroups()) { 145 resolveGroups(userManager.getGroup(subGroup), collector); 146 } 147 } 148 } 149 150 public String[] getPermissionsToCheck(String permission) { 151 String[] groups = permissionProvider.getPermissionGroups(permission); 152 if (groups == null) { 153 return new String[] { permission, SecurityConstants.EVERYTHING }; 154 } else { 155 String[] perms = new String[groups.length + 2]; 156 perms[0] = permission; 157 System.arraycopy(groups, 0, perms, 1, groups.length); 158 perms[groups.length + 1] = SecurityConstants.EVERYTHING; 159 return perms; 160 } 161 } 162 163 public boolean permissionMatch(String[] perms, String perm) { 164 for (String p : perms) { 165 if (p.equals(perm)) { 166 return true; 167 } 168 } 169 return false; 170 } 171 172 interface Collector<T> { 173 174 void collect(NuxeoPrincipal principal); 175 176 void collect(NuxeoGroup group); 177 178 HashSet<T> getResult(); 179 } 180 181 public static class EmailCollector implements Collector<String> { 182 183 protected final String userSchemaName; 184 185 protected final String userEmailFieldName; 186 187 protected HashSet<String> result = new HashSet<String>(); 188 189 EmailCollector(String userSchemaName, String userEmailFieldName) { 190 this.userSchemaName = userSchemaName; 191 this.userEmailFieldName = userEmailFieldName; 192 } 193 194 @Override 195 public void collect(NuxeoPrincipal principal) { 196 if (principal == null) { 197 return; 198 } 199 DocumentModel userEntry = principal.getModel(); 200 String email = (String) userEntry.getProperty(userSchemaName, userEmailFieldName); 201 if (!StringUtils.isEmpty(email)) { 202 result.add(email); 203 } 204 } 205 206 @Override 207 public void collect(NuxeoGroup group) { 208 // do nothing 209 } 210 211 @Override 212 public HashSet<String> getResult() { 213 return result; 214 } 215 } 216 217 static class PrincipalCollector implements Collector<NuxeoPrincipal> { 218 219 protected HashSet<NuxeoPrincipal> result = new HashSet<NuxeoPrincipal>(); 220 221 @Override 222 public void collect(NuxeoPrincipal principal) { 223 if (principal == null) { 224 return; 225 } 226 result.add(principal); 227 } 228 229 @Override 230 public void collect(NuxeoGroup group) { 231 // do nothing 232 } 233 234 @Override 235 public HashSet<NuxeoPrincipal> getResult() { 236 return result; 237 } 238 } 239 240 static class IdCollector implements Collector<String> { 241 242 protected final boolean prefixIds; 243 244 protected HashSet<String> result = new HashSet<String>(); 245 246 IdCollector(boolean prefixIds) { 247 this.prefixIds = prefixIds; 248 } 249 250 @Override 251 public void collect(NuxeoPrincipal principal) { 252 if (principal != null) { 253 String name = principal.getName(); 254 if (name != null) { 255 if (prefixIds) { 256 result.add(NuxeoPrincipal.PREFIX + name); 257 } else { 258 result.add(name); 259 } 260 } 261 } 262 } 263 264 @Override 265 public void collect(NuxeoGroup group) { 266 if (group != null) { 267 String name = group.getName(); 268 if (name != null) { 269 if (prefixIds) { 270 result.add(NuxeoGroup.PREFIX + name); 271 } else { 272 result.add(name); 273 } 274 } 275 } 276 } 277 278 @Override 279 public HashSet<String> getResult() { 280 return result; 281 } 282 283 } 284 285}