001/* 002 * (C) Copyright 2006-2007 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 * Nuxeo - initial API and implementation 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.webapp.security; 021 022import java.io.Serializable; 023import java.util.ArrayList; 024import java.util.HashMap; 025import java.util.Iterator; 026import java.util.List; 027import java.util.Map; 028 029import org.apache.commons.logging.Log; 030import org.apache.commons.logging.LogFactory; 031import org.nuxeo.common.utils.i18n.Labeler; 032import org.nuxeo.ecm.core.api.security.SecurityConstants; 033 034/** 035 * Holds the formatted security data, ready to be displayed. Holds the data on each map on the following structure: <br> 036 * <p> 037 * current doc grants: <br> 038 * user 1 - perm1, perm2 <br> 039 * user 2 - perm1, perm2 <br> 040 * user 3 - perm2 <br> 041 * current doc denies:<br> 042 * ... <br> 043 * parent doc grants:<br> 044 * ... <br> 045 * parent doc denies:<br> 046 * ...<br> 047 * <p> 048 * Also has methods that allow manipulation of the contained data, such as add/remove security privileges. The end 049 * result after add/remove has been called will be converted to a backend security DTO and then submitted on backend. 050 * 051 * @author Razvan Caraghin 052 */ 053public class SecurityData implements Serializable { 054 055 protected static final Labeler labeler = new Labeler("label.security.permission"); 056 057 private static final long serialVersionUID = -7958330304227141087L; 058 059 private static final Log log = LogFactory.getLog(SecurityData.class); 060 061 protected Map<String, List<String>> currentDocGrant = new HashMap<String, List<String>>(); 062 063 protected Map<String, List<String>> currentDocDeny = new HashMap<String, List<String>>(); 064 065 protected Map<String, List<String>> parentDocsGrant = new HashMap<String, List<String>>(); 066 067 protected Map<String, List<String>> parentDocsDeny = new HashMap<String, List<String>>(); 068 069 protected final List<String> currentDocumentUsers = new ArrayList<String>(); 070 071 protected final List<String> parentDocumentsUsers = new ArrayList<String>(); 072 073 protected String documentType = ""; 074 075 protected boolean needSave = false; 076 077 public void setNeedSave(boolean needSave) { 078 this.needSave = needSave; 079 } 080 081 public boolean getNeedSave() { 082 return needSave; 083 } 084 085 public Map<String, List<String>> getCurrentDocDeny() { 086 return currentDocDeny; 087 } 088 089 public void setCurrentDocDeny(Map<String, List<String>> deny) { 090 currentDocDeny = deny; 091 } 092 093 public Map<String, List<String>> getCurrentDocGrant() { 094 return currentDocGrant; 095 } 096 097 public void setCurrentDocGrant(Map<String, List<String>> grant) { 098 currentDocGrant = grant; 099 } 100 101 public Map<String, List<String>> getParentDocsDenyLabels() { 102 return buildLabelMap(parentDocsDeny); 103 } 104 105 /** 106 * @since 6.0 107 */ 108 public Map<String, List<String>> getCurrentDocDenyLabels() { 109 return buildLabelMap(currentDocDeny); 110 } 111 112 public Map<String, List<String>> getParentDocsDeny() { 113 return parentDocsDeny; 114 } 115 116 public void setParentDocsDeny(Map<String, List<String>> parentDocsDeny) { 117 this.parentDocsDeny = parentDocsDeny; 118 } 119 120 public Map<String, List<String>> getParentDocsGrant() { 121 return parentDocsGrant; 122 } 123 124 public Map<String, List<String>> getParentDocsGrantLabels() { 125 return buildLabelMap(parentDocsGrant); 126 } 127 128 /** 129 * @since 6.0 130 */ 131 public Map<String, List<String>> getCurrentDocGrantLabels() { 132 return buildLabelMap(currentDocGrant); 133 } 134 135 public void setParentDocsGrant(Map<String, List<String>> parentDocsGrant) { 136 this.parentDocsGrant = parentDocsGrant; 137 } 138 139 public List<String> getCurrentDocumentUsers() { 140 return currentDocumentUsers; 141 } 142 143 public List<String> getParentDocumentsUsers() { 144 return parentDocumentsUsers; 145 } 146 147 protected Map<String, List<String>> buildLabelMap(Map<String, List<String>> permissions) { 148 Map<String, List<String>> labelMap = new HashMap<String, List<String>>(); 149 150 for (String user : permissions.keySet()) { 151 List<String> labels = new ArrayList<String>(); 152 for (String perm : permissions.get(user)) { 153 labels.add(labeler.makeLabel(perm)); 154 } 155 labelMap.put(user, labels); 156 } 157 return labelMap; 158 } 159 160 public void rebuildUserLists() { 161 List<String> users = new ArrayList<String>(); 162 users.addAll(currentDocGrant.keySet()); 163 for (String user : currentDocDeny.keySet()) { 164 if (!users.contains(user)) { 165 users.add(user); 166 } 167 } 168 169 currentDocumentUsers.clear(); 170 currentDocumentUsers.addAll(users); 171 172 users.clear(); 173 users.addAll(parentDocsGrant.keySet()); 174 for (String user : parentDocsDeny.keySet()) { 175 if (!users.contains(user)) { 176 users.add(user); 177 } 178 } 179 180 parentDocumentsUsers.clear(); 181 parentDocumentsUsers.addAll(users); 182 } 183 184 /** 185 * Adds a privilege to the displayed list. This does not submit anything to the backend. 186 */ 187 public void addModifiablePrivilege(String principalName, String permissionName, boolean grant) { 188 if (null == principalName || null == permissionName) { 189 log.error("Null params received, returning..."); 190 return; 191 } 192 193 needSave = true; 194 if (grant) { 195 // if we already have the user stored with rights we dont add the 196 // user again, just update the list if needed 197 if (null != currentDocGrant.get(principalName)) { 198 // we already have the user - add the right to him 199 boolean shouldAddPermission = true; 200 for (String permission : currentDocGrant.get(principalName)) { 201 // only add the right to list if the right is not already 202 // there 203 if (permission.equals(permissionName)) { 204 shouldAddPermission = false; 205 break; 206 } 207 } 208 209 if (shouldAddPermission) { 210 currentDocGrant.get(principalName).add(permissionName); 211 } 212 } else { 213 // add the user and create a new list of rights for him 214 List<String> permissions = new ArrayList<String>(); 215 permissions.add(permissionName); 216 currentDocGrant.put(principalName, permissions); 217 } 218 } else { 219 // if we already have the user stored with rights we dont add the 220 // user again, just update the list if needed 221 if (null != currentDocDeny.get(principalName)) { 222 // we already have the user - add the right to him 223 boolean shouldAddPermission = true; 224 for (String permission : currentDocDeny.get(principalName)) { 225 // only add the right to list if the right is not already 226 // there 227 if (permission.equals(permissionName)) { 228 shouldAddPermission = false; 229 break; 230 } 231 } 232 233 if (shouldAddPermission) { 234 currentDocDeny.get(principalName).add(permissionName); 235 } 236 } else { 237 // add the user and create a new list of rights for him 238 List<String> permissions = new ArrayList<String>(); 239 permissions.add(permissionName); 240 currentDocDeny.put(principalName, permissions); 241 } 242 } 243 244 rebuildUserLists(); 245 } 246 247 /** 248 * Removes a privilege from the displayed list. This does not submit anything to backend. 249 * 250 * @return true if a privilege was indeed removed 251 */ 252 public boolean removeModifiablePrivilege(String principalName, String permissionName, boolean grant) { 253 254 if (null == principalName || null == permissionName) { 255 log.error("Null params received, returning..."); 256 return false; 257 } 258 259 needSave = true; 260 boolean removed = false; 261 if (grant) { 262 if (null != currentDocGrant.get(principalName)) { 263 // we have the specified user, check if we have the right 264 Iterator<String> permissionIterator = currentDocGrant.get(principalName).iterator(); 265 while (permissionIterator.hasNext()) { 266 if (permissionIterator.next().equals(permissionName)) { 267 permissionIterator.remove(); 268 removed = true; 269 break; 270 } 271 } 272 } 273 } else { 274 if (null != currentDocDeny.get(principalName)) { 275 // we have the specified user, check if we have the right 276 Iterator<String> permissionIterator = currentDocDeny.get(principalName).iterator(); 277 while (permissionIterator.hasNext()) { 278 if (permissionIterator.next().equals(permissionName)) { 279 permissionIterator.remove(); 280 removed = true; 281 break; 282 } 283 } 284 } 285 } 286 287 rebuildUserLists(); 288 return removed; 289 } 290 291 /** 292 * Removes all privileges for a given user. This does not edit the backend. 293 */ 294 public void removeModifiablePrivilege(String principalName) { 295 if (null == principalName) { 296 log.error("Null principal received, returning..."); 297 return; 298 } 299 currentDocGrant.remove(principalName); 300 301 // if user everyone had deny everything perm, then we have to 302 // keep this perm 303 if (principalName.equals(SecurityConstants.EVERYONE)) { 304 305 final List<String> deniedPerms = currentDocDeny.get(principalName); 306 boolean keepDenyAll = deniedPerms != null ? deniedPerms.contains(SecurityConstants.EVERYTHING) : false; 307 308 currentDocDeny.remove(principalName); 309 310 if (keepDenyAll) { 311 addModifiablePrivilege(SecurityConstants.EVERYONE, SecurityConstants.EVERYTHING, false); 312 } 313 } else { 314 currentDocDeny.remove(principalName); 315 } 316 317 needSave = true; 318 rebuildUserLists(); 319 } 320 321 /** 322 * Adds an unmodifiable privilege to the displayed list (these are related to the parent documents). 323 */ 324 public void addUnModifiablePrivilege(String principalName, String permissionName, boolean grant) { 325 if (null == principalName || null == permissionName) { 326 log.error("Null params received, returning..."); 327 return; 328 } 329 330 if (grant) { 331 // if we already have the user stored with rights we dont add the 332 // user again, just update the list if needed 333 if (null != parentDocsGrant.get(principalName)) { 334 // we already have the user - add the right to him 335 boolean shouldAddPermission = true; 336 for (String permission : parentDocsGrant.get(principalName)) { 337 // only add the right to list if the right is not already 338 // there 339 if (permission.equals(permissionName)) { 340 shouldAddPermission = false; 341 break; 342 } 343 } 344 345 if (shouldAddPermission) { 346 parentDocsGrant.get(principalName).add(permissionName); 347 } 348 } else { 349 // add the user and create a new list of rights for him 350 List<String> permissions = new ArrayList<String>(); 351 permissions.add(permissionName); 352 parentDocsGrant.put(principalName, permissions); 353 } 354 } else { 355 // if we already have the user stored with rights we dont add the 356 // user again, just update the list if needed 357 if (null != parentDocsDeny.get(principalName)) { 358 // we already have the user - add the right to him 359 boolean shouldAddPermission = true; 360 for (String permission : parentDocsDeny.get(principalName)) { 361 // only add the right to list if the right is not already 362 // there 363 if (permission.equals(permissionName)) { 364 shouldAddPermission = false; 365 break; 366 } 367 } 368 369 if (shouldAddPermission) { 370 parentDocsDeny.get(principalName).add(permissionName); 371 } 372 } else { 373 // add the user and create a new list of rights for him 374 List<String> permissions = new ArrayList<String>(); 375 permissions.add(permissionName); 376 parentDocsDeny.put(principalName, permissions); 377 } 378 379 } 380 381 rebuildUserLists(); 382 } 383 384 public void clear() { 385 currentDocDeny.clear(); 386 currentDocGrant.clear(); 387 parentDocsDeny.clear(); 388 parentDocsGrant.clear(); 389 390 currentDocumentUsers.clear(); 391 parentDocumentsUsers.clear(); 392 393 log.debug("Cleared data..."); 394 needSave = false; 395 } 396 397 public String getDocumentType() { 398 return documentType; 399 } 400 401 public void setDocumentType(String documentType) { 402 this.documentType = documentType; 403 } 404 405}