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 * Nuxeo - initial API and implementation 011 * 012 * $Id$ 013 */ 014 015package org.nuxeo.ecm.core.api.security.impl; 016 017import java.util.ArrayList; 018import java.util.Arrays; 019import java.util.Iterator; 020import java.util.List; 021 022import org.nuxeo.ecm.core.api.security.ACE; 023import org.nuxeo.ecm.core.api.security.ACL; 024import org.nuxeo.ecm.core.api.security.AdministratorGroupsProvider; 025import org.nuxeo.ecm.core.api.security.SecurityConstants; 026import org.nuxeo.runtime.api.Framework; 027 028import com.google.common.collect.Lists; 029 030/** 031 * An ACL implementation. 032 * 033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 034 */ 035public class ACLImpl extends ArrayList<ACE>implements ACL { 036 037 private static final long serialVersionUID = 5332101749929771434L; 038 039 private final String name; 040 041 private final boolean isReadOnly; 042 043 public ACLImpl(String name, boolean isReadOnly) { 044 this.name = name; 045 this.isReadOnly = isReadOnly; 046 } 047 048 public ACLImpl() { 049 this(LOCAL_ACL, false); 050 } 051 052 public ACLImpl(String name) { 053 this(name, false); 054 } 055 056 @Override 057 public String getName() { 058 return name; 059 } 060 061 @Override 062 public ACE[] getACEs() { 063 return toArray(new ACE[size()]); 064 } 065 066 @Override 067 public void setACEs(ACE[] aces) { 068 clear(); 069 addAll(Arrays.asList(aces)); 070 } 071 072 public boolean isReadOnly() { 073 return isReadOnly; 074 } 075 076 @Override 077 public boolean blockInheritance(String username) { 078 boolean aclChanged = false; 079 List<ACE> aces = Lists.newArrayList(getACEs()); 080 if (!aces.contains(ACE.BLOCK)) { 081 aces.add(ACE.builder(username, SecurityConstants.EVERYTHING).creator(username).build()); 082 aces.addAll(getAdminEverythingACES()); 083 aces.add(ACE.BLOCK); 084 aclChanged = true; 085 setACEs(aces.toArray(new ACE[aces.size()])); 086 } 087 return aclChanged; 088 } 089 090 @Override 091 public boolean unblockInheritance() { 092 boolean aclChanged = false; 093 List<ACE> aces = Lists.newArrayList(getACEs()); 094 if (aces.contains(ACE.BLOCK)) { 095 aces.remove(ACE.BLOCK); 096 aclChanged = true; 097 setACEs(aces.toArray(new ACE[aces.size()])); 098 } 099 return aclChanged; 100 } 101 102 @Override 103 public boolean add(ACE ace) { 104 boolean aclChanged = false; 105 List<ACE> aces = Lists.newArrayList(getACEs()); 106 if (!aces.contains(ace)) { 107 int pos = aces.indexOf(ACE.BLOCK); 108 if (pos >= 0) { 109 aces.add(pos, ace); 110 } else { 111 aces.add(ace); 112 } 113 aclChanged = true; 114 setACEs(aces.toArray(new ACE[aces.size()])); 115 } 116 117 return aclChanged; 118 } 119 120 protected List<ACE> getAdminEverythingACES() { 121 List<ACE> aces = new ArrayList<>(); 122 AdministratorGroupsProvider provider = Framework.getLocalService(AdministratorGroupsProvider.class); 123 List<String> administratorsGroups = provider.getAdministratorsGroups(); 124 for (String adminGroup : administratorsGroups) { 125 aces.add(new ACE(adminGroup, SecurityConstants.EVERYTHING, true)); 126 } 127 return aces; 128 } 129 130 @Override 131 public boolean replace(ACE oldACE, ACE newACE) { 132 boolean aclChanged = false; 133 int index = indexOf(oldACE); 134 if (index != -1) { 135 remove(oldACE); 136 add(index, newACE); 137 aclChanged = true; 138 } 139 140 return aclChanged; 141 } 142 143 @Override 144 public boolean removeByUsername(String username) { 145 boolean aclChanged = false; 146 147 List<ACE> aces = Lists.newArrayList(getACEs()); 148 for (Iterator<ACE> it = aces.iterator(); it.hasNext();) { 149 ACE ace = it.next(); 150 if (ace.getUsername().equals(username)) { 151 it.remove(); 152 aclChanged = true; 153 } 154 } 155 setACEs(aces.toArray(new ACE[aces.size()])); 156 157 return aclChanged; 158 } 159 160 @Override 161 public Object clone() { 162 ACLImpl copy = new ACLImpl(name, isReadOnly); 163 ACE[] aces = new ACE[size()]; 164 for (int i = 0; i < size(); i++) { 165 aces[i] = (ACE) get(i).clone(); 166 } 167 copy.setACEs(aces); 168 return copy; 169 } 170 171}