/**
* Copyright (C) 2011 JTalks.org Team
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.jtalks.jcommune.service.security.acl;
import org.apache.commons.lang.Validate;
import org.springframework.security.acls.model.*;
import javax.annotation.Nonnull;
import java.io.Serializable;
import java.util.List;
/**
* This implementations of {@link MutableAcl} adds additional handy methods like {@link #delete(AccessControlEntry)}.
* It's actually a wrapper that delegates all the implemented methods to the internal {@link MutableAcl} that is
* accepted in the constructor.
*
* @author stanislav bashkirtsev
*/
public class ExtendedMutableAcl implements MutableAcl {
/**
* This is a mock instance that is used usually just for testing purposes, most of its methods will throw {@link
* NullPointerException} if you invoke them.
*/
public final static ExtendedMutableAcl NULL_ACL = new ExtendedMutableAcl();
private final MutableAcl acl;
/**
* Use factory methods like {@link #create(MutableAcl)} to instantiate the objects.
*
* @param acl the internal delegate-instance
*/
private ExtendedMutableAcl(@Nonnull MutableAcl acl) {
Validate.notNull(acl, "Acl can't be null while creating ExtendedMutableAcl!");
this.acl = acl;
}
/**
* An empty construct that shouldn't be ever used :) It's purpose is only to serve for {@link #NULL_ACL}.
*/
private ExtendedMutableAcl() {
acl = null;
}
/**
* Finds the specified {@link AccessControlEntry} and removes it from the entry list of the {@link Acl}.
*
* @param entryToDelete the entry to remove from the {@link Acl}
* @return the id of the removed entry or {@code -1} if no such entry was found
*/
public int delete(@Nonnull AccessControlEntry entryToDelete) {
List<AccessControlEntry> aclEntries = acl.getEntries();
for (int i = 0; i < aclEntries.size(); i++) {
if (aclEntries.get(i).equals(entryToDelete)) {
acl.deleteAce(i);
return i;
}
}
return -1;
}
/**
* Deletes all the specified entries from the {@link Acl#getEntries()} list. If some or all entries were not found
* in the list, those elements are not removed and nothing happens.
*
* @param entriesToDelete the list of entries to remove from the {@link Acl#getEntries()}
*/
public void delete(@Nonnull List<AccessControlEntry> entriesToDelete) {
for (AccessControlEntry next : entriesToDelete) {
delete(next);
}
}
/**
* Adds all the permissions to the specified sid. Note, that it doesn't check whether there is already such Sid with
* such Permission in the ACL, so you should ensures this on your own.
*
* @param sid sid to grant the permissions to
* @param permissions the list of permissions that should be granted to the Sid
* @param granting specify {@code true} if you want to grant the permission or {@code false} if you want to
* restrict all the permissions
* @see #addPermissions(List, List, boolean)
*/
public void addPermissions(@Nonnull Sid sid, @Nonnull List<Permission> permissions, boolean granting) {
int entriesAmount = acl.getEntries().size();
for (Permission permission : permissions) {
acl.insertAce(entriesAmount++, permission, sid, granting);
}
}
/**
* Adds all the permissions to all the specified sids. Note, that it doesn't check whether there are already such
* Sids with such Permission in the ACL, so you should check it on your own.
*
* @param sids the sids to grant the permissions to
* @param permissions the list of permissions that should be granted to the Sid
* @param granting specify {@code true} if you want to grant the permission or {@code false} if you want to
* restrict all the permissions
* @see #addPermissions(Sid, List, boolean)
*/
public void addPermissions(@Nonnull List<? extends Sid> sids, @Nonnull List<Permission> permissions, boolean granting) {
for (Sid recipient : sids) {
addPermissions(recipient, permissions, granting);
}
}
/**
* Wraps the specified {@link MutableAcl} with the instance of {@link ExtendedMutableAcl} and returns the latter.
*
* @param acl the acl to be wrapped with the {@link ExtendedMutableAcl}
* @return a new instance of {@link ExtendedMutableAcl} that wraps the specified {@code acl}
*/
public static ExtendedMutableAcl create(@Nonnull MutableAcl acl) {
return new ExtendedMutableAcl(acl);
}
/**
* Wraps the specified {@link MutableAcl} with the instance of {@link ExtendedMutableAcl} and returns the latter.
* Throws exception if the specified parameter is not an instance of {@link MutableAcl}.
*
* @param acl the acl to be wrapped with the {@link ExtendedMutableAcl}
* @return a new instance of {@link ExtendedMutableAcl} that wraps the specified {@code acl}
* @throws ClassCastException if the specified parameter is not an instance of {@link MutableAcl}
*/
public static ExtendedMutableAcl castAndCreate(@Nonnull Acl acl) {
return new ExtendedMutableAcl((MutableAcl) acl);
}
/**
* Gets the wrapped instance that was specified into the factory methods.
*
* @return the wrapped instance that was specified into the factory methods
*/
public MutableAcl getAcl() {
return acl;
}
/**
* {@inheritDoc}
*/
@Override
public void deleteAce(int aceIndex) throws NotFoundException {
acl.deleteAce(aceIndex);
}
/**
* {@inheritDoc}
*/
@Override
public void insertAce(
int atIndexLocation, Permission permission, Sid sid, boolean granting) throws NotFoundException {
acl.insertAce(atIndexLocation, permission, sid, granting);
}
/**
* {@inheritDoc}
*/
@Override
public List<AccessControlEntry> getEntries() {
return acl.getEntries();
}
/**
* {@inheritDoc}
*/
@Override
public Serializable getId() {
return acl.getId();
}
/**
* {@inheritDoc}
*/
@Override
public ObjectIdentity getObjectIdentity() {
return acl.getObjectIdentity();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isEntriesInheriting() {
return acl.isEntriesInheriting();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isGranted(List<Permission> permission, List<Sid> sids,
boolean administrativeMode) throws NotFoundException, UnloadedSidException {
return acl.isGranted(permission, sids, administrativeMode);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isSidLoaded(List<Sid> sids) {
return acl.isSidLoaded(sids);
}
/**
* {@inheritDoc}
*/
@Override
public void setEntriesInheriting(boolean entriesInheriting) {
acl.setEntriesInheriting(entriesInheriting);
}
/**
* {@inheritDoc}
*/
@Override
public void setOwner(Sid newOwner) {
acl.setOwner(newOwner);
}
/**
* {@inheritDoc}
*/
@Override
public Sid getOwner() {
return acl.getOwner();
}
/**
* {@inheritDoc}
*/
@Override
public void setParent(Acl newParent) {
acl.setParent(newParent);
}
/**
* {@inheritDoc}
*/
@Override
public Acl getParentAcl() {
return acl.getParentAcl();
}
/**
* {@inheritDoc}
*/
@Override
public void updateAce(int aceIndex, Permission permission) throws NotFoundException {
acl.updateAce(aceIndex, permission);
}
}