Andrew Hind
2008-05-13 11:54:55 +00:00
parent 344b703a61
commit 1b807e3e77
42 changed files with 2243 additions and 233 deletions

View File

@@ -235,18 +235,18 @@
<value>org.alfresco.repo.security.permissions.impl.PermissionsDaoComponent</value> <value>org.alfresco.repo.security.permissions.impl.PermissionsDaoComponent</value>
</property> </property>
<property name="defaultBinding"> <property name="defaultBinding">
<ref bean="oldPermissionsDaoComponent"></ref> <ref bean="dmPermissionsDaoComponent"></ref>
</property> </property>
<property name="redirectedProtocolBindings"> <property name="redirectedProtocolBindings">
<map> <map>
<entry key="workspace"><ref bean="oldPermissionsDaoComponent"></ref></entry> <entry key="workspace"><ref bean="dmPermissionsDaoComponent"></ref></entry>
<entry key="versionStore"><ref bean="oldPermissionsDaoComponent"></ref></entry> <entry key="versionStore"><ref bean="dmPermissionsDaoComponent"></ref></entry>
<entry key="avm"><ref bean="newPermissionsDaoComponent"/></entry> <entry key="avm"><ref bean="avmPermissionsDaoComponent"/></entry>
</map> </map>
</property> </property>
</bean> </bean>
<bean id="newPermissionsDaoComponent" class="org.alfresco.repo.domain.hibernate.PermissionsDaoComponentImpl"> <bean id="avmPermissionsDaoComponent" class="org.alfresco.repo.domain.hibernate.PermissionsDaoComponentImpl">
<property name="aclDaoComponent"> <property name="aclDaoComponent">
<ref bean="aclDaoComponent" /> <ref bean="aclDaoComponent" />
</property> </property>
@@ -261,7 +261,7 @@
</property> </property>
</bean> </bean>
<bean id="oldPermissionsDaoComponent" class="org.alfresco.repo.domain.hibernate.OldADMPermissionsDaoComponentImpl"> <bean id="dmPermissionsDaoComponent" class="org.alfresco.repo.domain.hibernate.DMPermissionsDaoComponentImpl">
<property name="aclDaoComponent"> <property name="aclDaoComponent">
<ref bean="aclDaoComponent" /> <ref bean="aclDaoComponent" />
</property> </property>
@@ -288,9 +288,18 @@
</property> </property>
</bean> </bean>
<bean id="nodeACLDAO" class="org.alfresco.repo.domain.hibernate.NodeAccessControlListDAO"> <bean id="nodeACLDAO" class="org.alfresco.repo.domain.hibernate.DMAccessControlListDAO">
<property name="nodeDaoService"> <property name="nodeDaoService">
<ref bean="nodeDaoService" /> <ref bean="nodeDaoService" />
</property>
<property name="aclDaoComponent">
<ref bean="aclDaoComponent"/>
</property>
<property name="hibernateSessionHelper">
<ref bean="hibernateSessionHelper"/>
</property>
<property name="nodeService">
<ref bean="nodeService"/>
</property> </property>
</bean> </bean>

View File

@@ -214,9 +214,9 @@ patch.wcmPermissionPatch.result=Updated ACLs: ACLS are moved to the staging area
patch.avmWebProjectInheritPermissions.description=Break inheritance of permissions on wca:webfolder object to hide access by default. patch.avmWebProjectInheritPermissions.description=Break inheritance of permissions on wca:webfolder object to hide access by default.
patch.avmWebProjectInheritPermissions.result=Removed inheritance of permissions on all wca:webfolder objects. patch.avmWebProjectInheritPermissions.result=Removed inheritance of permissions on all wca:webfolder objects.
patch.wcmPostPermissionSnapshotPatch.description=Snapshot stores (after fixing ACLs so they are only set on the staging area store). patch.wcmPostPermissionSnapshotPatch.description=Snapshot stores (after fixing ACLs so they are only set on the staging area store).
patch.wcmPostPermissionSnapshotPatch.result=Snapshot complete after WCM ACL changes. patch.wcmPostPermissionSnapshotPatch.result=Snapshot complete after WCM ACL changes.
patch.updateDmPermissions.description=Update ACLs on all DM node objects to the new 3.0 permission model
patch.updateDmPermissions.result=Updated ACLs. Created {0} defining ACLs.

View File

@@ -179,6 +179,9 @@
</property> </property>
<property name="tenantService"> <property name="tenantService">
<ref bean="tenantService"/> <ref bean="tenantService"/>
</property>
<property name="aclDaoComponent">
<ref bean="aclDaoComponent"/>
</property> </property>
</bean> </bean>
<bean id="sessionSizeResourceInterceptor" class="org.alfresco.repo.transaction.TransactionResourceInterceptor" > <bean id="sessionSizeResourceInterceptor" class="org.alfresco.repo.transaction.TransactionResourceInterceptor" >

View File

@@ -1452,5 +1452,20 @@
</list> </list>
</property> </property>
</bean> </bean>
<bean id="patch.updateDmPermissions" class="org.alfresco.repo.admin.patch.impl.DmPermissionsPatch" parent="basePatch" >
<property name="id"><value>patch.updateDmPermissions</value></property>
<property name="description"><value>patch.updateDmPermissions.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>124</value></property>
<property name="targetSchema"><value>125</value></property>
<!-- helper beans -->
<property name="accessControlListDao">
<ref bean="nodeACLDAO" />
</property>
<property name="aclDaoComponent">
<ref bean="aclDaoComponent" />
</property>
</bean>
</beans> </beans>

View File

@@ -41,7 +41,7 @@
<bean id="permissionServiceImpl" class="org.alfresco.repo.security.permissions.impl.PermissionServiceImpl"> <bean id="permissionServiceImpl" class="org.alfresco.repo.security.permissions.impl.PermissionServiceImpl">
<property name="nodeService"> <property name="nodeService">
<ref bean="nodeService" /> <ref bean="dbNodeService" />
</property> </property>
<property name="tenantService"> <property name="tenantService">
<ref bean="tenantService"/> <ref bean="tenantService"/>
@@ -136,6 +136,16 @@
<property name="nodeService"> <property name="nodeService">
<ref bean="nodeService" /> <ref bean="nodeService" />
</property> </property>
<property name="modelDAO">
<ref bean="permissionsModelDAO" />
</property>
<property name="requiredFor">
<list>
<value>Unlock</value>
<value>CheckIn</value>
<value>CancelCheckOut</value>
</list>
</property>
</bean> </bean>
<!-- ===================== --> <!-- ===================== -->

View File

@@ -19,4 +19,4 @@ version.build=@build-number@
# Schema number # Schema number
version.schema=124 version.schema=125

View File

@@ -0,0 +1,143 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.Map;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.domain.AccessControlListDAO;
import org.alfresco.repo.domain.hibernate.AclDaoComponentImpl;
import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
/**
* Migrate permissions from the OLD format to defining, shared and layered
*/
public class DmPermissionsPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.updateDmPermissions.result";
private AccessControlListDAO accessControlListDao;
private AclDaoComponentImpl aclDaoComponent;
@Override
protected String applyInternal() throws Exception
{
Thread progressThread = null;
if (aclDaoComponent.supportsProgressTracking())
{
Long toDo = aclDaoComponent.getDmNodeCount();
Long maxId = aclDaoComponent.getMaxAclId();
progressThread = new Thread(new ProgressWatcher(toDo, maxId), "DMPatchProgressWatcher");
progressThread.start();
}
Map<ACLType, Integer> summary = accessControlListDao.patchAcls();
if (progressThread != null)
{
progressThread.interrupt();
progressThread.join();
}
// build the result message
String msg = I18NUtil.getMessage(MSG_SUCCESS, summary.get(ACLType.DEFINING));
// done
return msg;
}
/**
* Set the access control list dao
*
* @param accessControlListDao
*/
public void setAccessControlListDao(AccessControlListDAO accessControlListDao)
{
this.accessControlListDao = accessControlListDao;
}
/**
* Set the acl dao component
* @param aclDaoComponent
*/
public void setAclDaoComponent(AclDaoComponentImpl aclDaoComponent)
{
this.aclDaoComponent = aclDaoComponent;
}
private class ProgressWatcher implements Runnable
{
private boolean running = true;
Long toDo;
Long max;
ProgressWatcher(Long toDo, Long max)
{
this.toDo = toDo;
this.max = max;
}
public void run()
{
while (running)
{
try
{
Thread.sleep(60000);
}
catch (InterruptedException e)
{
running = false;
}
if (running)
{
RetryingTransactionHelper txHelper = transactionService.getRetryingTransactionHelper();
txHelper.setMaxRetries(1);
Long done = txHelper.doInTransaction(new RetryingTransactionCallback<Long>()
{
public Long execute() throws Throwable
{
return aclDaoComponent.getDmNodeCountWithNewACLS(max);
}
}, true, true);
reportProgress(toDo, done);
}
}
}
}
}

View File

@@ -83,26 +83,47 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
{ {
} }
/**
* Set the AVM repository
*
* @param repository
*/
public void setAvmRepository(AVMRepository repository) public void setAvmRepository(AVMRepository repository)
{ {
fAVMRepository = repository; fAVMRepository = repository;
} }
/**
* Set the AVM service
*
* @param avmService
*/
public void setAvmService(AVMService avmService) public void setAvmService(AVMService avmService)
{ {
fAVMService = avmService; fAVMService = avmService;
} }
/**
* Set the ACL DAO component
*
* @param aclDaoComponent
*/
public void setAclDaoComponent(AclDaoComponent aclDaoComponent) public void setAclDaoComponent(AclDaoComponent aclDaoComponent)
{ {
this.aclDaoComponent = aclDaoComponent; this.aclDaoComponent = aclDaoComponent;
} }
/**
* @param avmSnapShotTriggeredIndexingMethodInterceptor
*/
public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor) public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor)
{ {
this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor; this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor;
} }
/**
* @param hibernateSessionHelper
*/
public void setHibernateSessionHelper(HibernateSessionHelper hibernateSessionHelper) public void setHibernateSessionHelper(HibernateSessionHelper hibernateSessionHelper)
{ {
this.hibernateSessionHelper = hibernateSessionHelper; this.hibernateSessionHelper = hibernateSessionHelper;
@@ -161,6 +182,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
// to the path stuffed in the NodeRef. // to the path stuffed in the NodeRef.
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
String path = avmVersionPath.getSecond(); String path = avmVersionPath.getSecond();
@SuppressWarnings("unused")
List<ChildAssociationRef> result = new ArrayList<ChildAssociationRef>(); List<ChildAssociationRef> result = new ArrayList<ChildAssociationRef>();
String[] splitPath = AVMNodeConverter.SplitBase(path); String[] splitPath = AVMNodeConverter.SplitBase(path);
if (splitPath[0] == null) if (splitPath[0] == null)
@@ -588,6 +610,16 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
} }
} }
/**
* Set and cascade ACls
*
* @param descriptor
* @param mergeFrom
* @param changes
* @param mode
* @param set
* @param indirections
*/
public void setFixedAcls(AVMNodeDescriptor descriptor, Long mergeFrom, List<AclChange> changes, SetMode mode, boolean set, Map<Long, Set<Long>> indirections) public void setFixedAcls(AVMNodeDescriptor descriptor, Long mergeFrom, List<AclChange> changes, SetMode mode, boolean set, Map<Long, Set<Long>> indirections)
{ {
if (descriptor == null) if (descriptor == null)
@@ -691,9 +723,21 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
} }
} }
/**
* Mode to sue when setting ACLs
* @author andyh
*
*/
private enum SetMode private enum SetMode
{ {
ALL, DIRECT_ONLY; /**
* Set ALL
*/
ALL,
/**
* Set only direct children (not those present by layering)
*/
DIRECT_ONLY;
} }
public Map<ACLType, Integer> patchAcls() public Map<ACLType, Integer> patchAcls()
@@ -893,8 +937,19 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
return result; return result;
} }
private class CounterSet extends HashMap<ACLType, Counter> /**
*
* Counter for each type of ACL change
* @author andyh
*
*/
public static class CounterSet extends HashMap<ACLType, Counter>
{ {
/**
*
*/
private static final long serialVersionUID = -3682278258679211481L;
CounterSet() CounterSet()
{ {
super(); super();
@@ -929,7 +984,12 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
} }
} }
private class Counter /**
* Simple counter
* @author andyh
*
*/
public static class Counter
{ {
int counter; int counter;

View File

@@ -37,6 +37,7 @@ import org.alfresco.repo.security.permissions.ACEType;
import org.alfresco.repo.security.permissions.ACLType; import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.security.permissions.AccessControlEntry; import org.alfresco.repo.security.permissions.AccessControlEntry;
import org.alfresco.repo.security.permissions.AccessControlList; import org.alfresco.repo.security.permissions.AccessControlList;
import org.alfresco.repo.security.permissions.AccessControlListProperties;
import org.alfresco.repo.security.permissions.NodePermissionEntry; import org.alfresco.repo.security.permissions.NodePermissionEntry;
import org.alfresco.repo.security.permissions.PermissionEntry; import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference; import org.alfresco.repo.security.permissions.PermissionReference;
@@ -57,6 +58,16 @@ import org.alfresco.util.GUID;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
/**
* Common suppot for permisisons dao
*
* Sub classes deteremine how ACLs are cascaded to children and how changes may COW/version children as ACLs are pushed down.
*
* TODO: remove the protocol to dao mapping
*
* @author andyh
*
*/
public abstract class AbstractPermissionsDaoComponentImpl implements PermissionsDaoComponent, TransactionalDao public abstract class AbstractPermissionsDaoComponentImpl implements PermissionsDaoComponent, TransactionalDao
{ {
private static Log logger = LogFactory.getLog(AbstractPermissionsDaoComponentImpl.class); private static Log logger = LogFactory.getLog(AbstractPermissionsDaoComponentImpl.class);
@@ -77,11 +88,19 @@ public abstract class AbstractPermissionsDaoComponentImpl implements Permissions
this.uuid = GUID.generate(); this.uuid = GUID.generate();
} }
/**
* Get the ACL DAO component
* @return - the acl dao component
*/
public AclDaoComponent getAclDaoComponent() public AclDaoComponent getAclDaoComponent()
{ {
return aclDaoComponent; return aclDaoComponent;
} }
/**
* Set the ACL DAO component
* @param aclDaoComponent
*/
public void setAclDaoComponent(AclDaoComponent aclDaoComponent) public void setAclDaoComponent(AclDaoComponent aclDaoComponent)
{ {
this.aclDaoComponent = aclDaoComponent; this.aclDaoComponent = aclDaoComponent;
@@ -138,11 +157,19 @@ public abstract class AbstractPermissionsDaoComponentImpl implements Permissions
aclDaoComponent.beforeCommit(); aclDaoComponent.beforeCommit();
} }
/**
* Set the mapping of protocol to DAO
* @param map
*/
public void setProtocolToACLDAO(Map<String, AccessControlListDAO> map) public void setProtocolToACLDAO(Map<String, AccessControlListDAO> map)
{ {
fProtocolToACLDAO = map; fProtocolToACLDAO = map;
} }
/**
* Set the default DAO
* @param defaultACLDAO
*/
public void setDefaultACLDAO(AccessControlListDAO defaultACLDAO) public void setDefaultACLDAO(AccessControlListDAO defaultACLDAO)
{ {
fDefaultACLDAO = defaultACLDAO; fDefaultACLDAO = defaultACLDAO;
@@ -435,6 +462,8 @@ public abstract class AbstractPermissionsDaoComponentImpl implements Permissions
deletePermissions(nodeRef); deletePermissions(nodeRef);
} }
// create the access control list // create the access control list
existing = getAccessControlList(nodeRef);
CreationReport report = createAccessControlList(nodeRef, nodePermissionEntry.inheritPermissions(), existing); CreationReport report = createAccessControlList(nodeRef, nodePermissionEntry.inheritPermissions(), existing);
// add all entries // add all entries
@@ -594,8 +623,26 @@ public abstract class AbstractPermissionsDaoComponentImpl implements Permissions
return npe; return npe;
} }
public AccessControlListProperties getAccessControlListProperties(NodeRef nodeRef)
{
DbAccessControlList acl = getACLDAO(nodeRef).getAccessControlList(nodeRef);
if(acl == null)
{
return null;
}
return aclDaoComponent.getAccessControlListProperties(acl.getId());
}
protected abstract CreationReport createAccessControlList(NodeRef nodeRef, boolean inherit, DbAccessControlList existing); protected abstract CreationReport createAccessControlList(NodeRef nodeRef, boolean inherit, DbAccessControlList existing);
/**
* Internal class used for reporting the collateral damage when creating an new ACL entry
* @author andyh
*
*/
static class CreationReport static class CreationReport
{ {
DbAccessControlList created; DbAccessControlList created;
@@ -608,21 +655,38 @@ public abstract class AbstractPermissionsDaoComponentImpl implements Permissions
this.changes = changes; this.changes = changes;
} }
/**
* Set the change list
*
* @param changes
*/
public void setChanges(List<AclChange> changes) public void setChanges(List<AclChange> changes)
{ {
this.changes = changes; this.changes = changes;
} }
/**
* Set the ACL that was created
* @param created
*/
public void setCreated(DbAccessControlList created) public void setCreated(DbAccessControlList created)
{ {
this.created = created; this.created = created;
} }
/**
* Get the change list
* @return - the change list
*/
public List<AclChange> getChanges() public List<AclChange> getChanges()
{ {
return changes; return changes;
} }
/**
* Get the created ACL
* @return - the acl
*/
public DbAccessControlList getCreated() public DbAccessControlList getCreated()
{ {
return created; return created;

View File

@@ -41,6 +41,7 @@ import org.alfresco.repo.domain.DbAccessControlListChangeSet;
import org.alfresco.repo.domain.DbAccessControlListMember; import org.alfresco.repo.domain.DbAccessControlListMember;
import org.alfresco.repo.domain.DbAuthority; import org.alfresco.repo.domain.DbAuthority;
import org.alfresco.repo.domain.DbPermission; import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.QNameDAO; import org.alfresco.repo.domain.QNameDAO;
import org.alfresco.repo.domain.QNameEntity; import org.alfresco.repo.domain.QNameEntity;
import org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl; import org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl;
@@ -62,10 +63,10 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException; import org.hibernate.Criteria;
import org.hibernate.Query; import org.hibernate.Query;
import org.hibernate.Session; import org.hibernate.Session;
import org.jgroups.tests.DeadlockTest.InRpc; import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
@@ -112,23 +113,59 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
private enum WriteMode private enum WriteMode
{ {
TRUNCATE_INHERITED, ADD_INHERITED, CHANGE_INHERITED, REMOVE_INHERITED, INSERT_INHERITED, COPY_UPDATE_AND_INHERIT, COPY_ONLY; /**
* Remove inherited ACEs after that set
*/
TRUNCATE_INHERITED,
/**
* Add inherited ACEs
*/
ADD_INHERITED,
/**
* The source of inherited ACEs is changing
*/
CHANGE_INHERITED,
/**
* Remove all inherited ACEs
*/
REMOVE_INHERITED,
/**
* Insert inherited ACEs
*/
INSERT_INHERITED,
/**
* Copy ACLs and update ACEs and inheritance
*/
COPY_UPDATE_AND_INHERIT,
/**
* Simlpe copy
*/
COPY_ONLY;
} }
/**
*
*/
public AclDaoComponentImpl() public AclDaoComponentImpl()
{ {
super(); super();
// Wire up for annoying AVM hack to support copy and setting of ACLs as nodes are created
DbAccessControlListImpl.setAclDaoComponent(this); DbAccessControlListImpl.setAclDaoComponent(this);
} }
/** /**
* Set the DAO for accessing QName entities * Set the DAO for accessing QName entities
* @param qnameDAO
*/ */
public void setQnameDAO(QNameDAO qnameDAO) public void setQnameDAO(QNameDAO qnameDAO)
{ {
this.qnameDAO = qnameDAO; this.qnameDAO = qnameDAO;
} }
/**
* Set the ACL cache
* @param aclCache
*/
public void setAclCache(SimpleCache<Long, AccessControlList> aclCache) public void setAclCache(SimpleCache<Long, AccessControlList> aclCache)
{ {
this.aclCache = aclCache; this.aclCache = aclCache;
@@ -344,7 +381,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
* @param toAdd * @param toAdd
* @param inheritsFrom * @param inheritsFrom
* @param depth * @param depth
* @return * @return - an AclChange
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private AclChange getWritable(final Long id, final Long parent, AccessControlEntry exclude, List<DbAccessControlEntry> toAdd, Long inheritsFrom, private AclChange getWritable(final Long id, final Long parent, AccessControlEntry exclude, List<DbAccessControlEntry> toAdd, Long inheritsFrom,
@@ -814,9 +851,26 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<AclChange> deleteAccessControlList(final Long id) public List<AclChange> deleteAccessControlList(final Long id)
{ {
HibernateCallback check = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Criteria criteria = getSession().createCriteria(NodeImpl.class, "node");
criteria.createAlias("node.accessControlList", "acl");
criteria.add(Restrictions.eq("acl.id", id));
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return criteria.list();
}
};
List<Node> nodes = (List<Node>) getHibernateTemplate().execute(check);
for(Node node : nodes)
{
logger.error("Found "+node.getId() +" "+node.getUuid() + " "+node.getAccessControlList() );
}
List<AclChange> acls = new ArrayList<AclChange>(); List<AclChange> acls = new ArrayList<AclChange>();
DbAccessControlList acl = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, id); final DbAccessControlList acl = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, id);
if (!acl.isLatest()) if (!acl.isLatest())
{ {
throw new UnsupportedOperationException("Old ALC versions can not be updated"); throw new UnsupportedOperationException("Old ALC versions can not be updated");
@@ -828,7 +882,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
if ((acl.getAclType() == ACLType.DEFINING) || (acl.getAclType() == ACLType.LAYERED)) if ((acl.getAclType() == ACLType.DEFINING) || (acl.getAclType() == ACLType.LAYERED))
{ {
if (acl.getInheritedAclId() != -1) if ((acl.getInheritedAclId() != null) && (acl.getInheritedAclId() != -1))
{ {
final DbAccessControlList inherited = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, acl.getInheritedAclId()); final DbAccessControlList inherited = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, acl.getInheritedAclId());
// Will remove from the cache // Will remove from the cache
@@ -929,6 +983,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
} }
getHibernateTemplate().delete(acl); getHibernateTemplate().delete(acl);
getSession().flush();
} }
// remove the deleted acl from the cache // remove the deleted acl from the cache
@@ -965,6 +1020,11 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return changes; return changes;
} }
/**
* Search for access control lists
* @param pattern
* @return the ids of the ACLs found
*/
public Long[] findAccessControlList(AccessControlEntry pattern) public Long[] findAccessControlList(AccessControlEntry pattern)
{ {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
@@ -986,6 +1046,10 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return acl; return acl;
} }
/**
* @param id
* @return the access control list
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public AccessControlList getAccessControlListImpl(final Long id) public AccessControlList getAccessControlListImpl(final Long id)
{ {
@@ -1025,7 +1089,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
entry.setContext(context); entry.setContext(context);
} }
DbPermission perm = member.getAccessControlEntry().getPermission(); DbPermission perm = member.getAccessControlEntry().getPermission();
SimplePermissionReference permissionRefernce = new SimplePermissionReference(perm.getTypeQName().getQName(), perm.getName()); SimplePermissionReference permissionRefernce = SimplePermissionReference.getPermissionReference(perm.getTypeQName().getQName(), perm.getName());
entry.setPermission(permissionRefernce); entry.setPermission(permissionRefernce);
entry.setPosition(member.getPosition()); entry.setPosition(member.getPosition());
@@ -1054,6 +1118,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
properties.setInherits(acl.getInherits()); properties.setInherits(acl.getInherits());
properties.setLatest(acl.isLatest()); properties.setLatest(acl.isLatest());
properties.setVersioned(acl.isVersioned()); properties.setVersioned(acl.isVersioned());
properties.setId(id);
return properties; return properties;
} }
@@ -1199,8 +1264,8 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<AclChange> setAccessControlEntry(Long id, final AccessControlEntry ace) public List<AclChange> setAccessControlEntry(final Long id, final AccessControlEntry ace)
{ {
DbAccessControlList target = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, id); DbAccessControlList target = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, id);
if (target.getAclType() == ACLType.SHARED) if (target.getAclType() == ACLType.SHARED)
{ {
@@ -1595,7 +1660,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
entry.setContext(context); entry.setContext(context);
} }
DbPermission perm = member.getAccessControlEntry().getPermission(); DbPermission perm = member.getAccessControlEntry().getPermission();
SimplePermissionReference permissionRefernce = new SimplePermissionReference(perm.getTypeQName().getQName(), perm.getName()); SimplePermissionReference permissionRefernce = SimplePermissionReference.getPermissionReference(perm.getTypeQName().getQName(), perm.getName());
entry.setPermission(permissionRefernce); entry.setPermission(permissionRefernce);
entry.setPosition(Integer.valueOf(0)); entry.setPosition(Integer.valueOf(0));
@@ -1775,11 +1840,17 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return before; return before;
} }
/**
* @param after
*/
public void setAfter(Long after) public void setAfter(Long after)
{ {
this.after = after; this.after = after;
} }
/**
* @param before
*/
public void setBefore(Long before) public void setBefore(Long before)
{ {
this.before = before; this.before = before;
@@ -1790,6 +1861,9 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return typeAfter; return typeAfter;
} }
/**
* @param typeAfter
*/
public void setTypeAfter(ACLType typeAfter) public void setTypeAfter(ACLType typeAfter)
{ {
this.typeAfter = typeAfter; this.typeAfter = typeAfter;
@@ -1800,6 +1874,9 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return typeBefore; return typeBefore;
} }
/**
* @param typeBefore
*/
public void setTypeBefore(ACLType typeBefore) public void setTypeBefore(ACLType typeBefore)
{ {
this.typeBefore = typeBefore; this.typeBefore = typeBefore;
@@ -1820,7 +1897,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
/** /**
* Get the total number of head nodes in the repository * Get the total number of head nodes in the repository
* *
* @return * @return count
*/ */
public Long getAVMHeadNodeCount() public Long getAVMHeadNodeCount()
{ {
@@ -1847,6 +1924,10 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
} }
/**
* Get the max acl id
* @return - max acl id
*/
public Long getMaxAclId() public Long getMaxAclId()
{ {
try try
@@ -1871,6 +1952,11 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
} }
} }
/**
* Does the underlyinf connection support isolation level 1 (dirty read)
*
* @return true if we can do a dirty db read and so track changes (Oracle can not)
*/
public boolean supportsProgressTracking() public boolean supportsProgressTracking()
{ {
try try
@@ -1885,6 +1971,11 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
} }
/**
* Get the acl count canges so far for progress tracking
* @param above
* @return - the count
*/
public Long getAVMNodeCountWithNewACLS(Long above) public Long getAVMNodeCountWithNewACLS(Long above)
{ {
try try
@@ -1910,6 +2001,10 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
} }
} }
/**
* How many nodes are noew in store (approximate)
* @return - the number fo new nodes - approximate
*/
public Long getNewInStore() public Long getNewInStore()
{ {
HibernateCallback callback = new HibernateCallback() HibernateCallback callback = new HibernateCallback()
@@ -1924,6 +2019,13 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return count; return count;
} }
/**
* Find layered directories
* Used to imporove performance during patching and cascading the effect fo permission changes between layers
*
* @return - layered directories
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<Indirection> getLayeredDirectories() public List<Indirection> getLayeredDirectories()
{ {
@@ -1947,6 +2049,13 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return indirections; return indirections;
} }
/**
* Find layered files
*
* Used to imporove performance during patching and cascading the effect fo permission changes between layers
*
* @return - layerd files
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<Indirection> getLayeredFiles() public List<Indirection> getLayeredFiles()
{ {
@@ -1985,6 +2094,11 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
getSession().flush(); getSession().flush();
} }
/**
* Support to describe AVM indirections for permission performance improvements when permissions are set.
* @author andyh
*
*/
public static class Indirection public static class Indirection
{ {
Long from; Long from;
@@ -2000,16 +2114,25 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
this.toVersion = toVersion; this.toVersion = toVersion;
} }
/**
* @return - from id
*/
public Long getFrom() public Long getFrom()
{ {
return from; return from;
} }
/**
* @return - to id
*/
public String getTo() public String getTo()
{ {
return to; return to;
} }
/**
* @return - version
*/
public Integer getToVersion() public Integer getToVersion()
{ {
return toVersion; return toVersion;
@@ -2017,4 +2140,64 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
} }
/**
* Ho many DM nodes are there?
*
* @return - the count
*/
public Long getDmNodeCount()
{
try
{
Session session = getSession();
int isolationLevel = session.connection().getTransactionIsolation();
try
{
session.connection().setTransactionIsolation(1);
Query query = getSession().getNamedQuery("permission.GetDmNodeCount");
Long answer = (Long) query.uniqueResult();
return answer;
}
finally
{
session.connection().setTransactionIsolation(isolationLevel);
}
}
catch (SQLException e)
{
throw new AlfrescoRuntimeException("Failed to set TX isolation level", e);
}
}
/**
* How many DM nodes are three with new ACls (to track patch progress)
* @param above
* @return - the count
*/
public Long getDmNodeCountWithNewACLS(Long above)
{
try
{
Session session = getSession();
int isolationLevel = session.connection().getTransactionIsolation();
try
{
session.connection().setTransactionIsolation(1);
Query query = getSession().getNamedQuery("permission.GetDmNodeCountWherePermissionsHaveChanged");
query.setParameter("above", above);
Long answer = (Long) query.uniqueResult();
return answer;
}
finally
{
session.connection().setTransactionIsolation(isolationLevel);
}
}
catch (SQLException e)
{
throw new AlfrescoRuntimeException("Failed to set TX isolation level", e);
}
}
} }

View File

@@ -0,0 +1,405 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.domain.hibernate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.domain.AccessControlListDAO;
import org.alfresco.repo.domain.ChildAssoc;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.hibernate.AVMAccessControlListDAO.CounterSet;
import org.alfresco.repo.node.db.NodeDaoService;
import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.security.permissions.AccessControlEntry;
import org.alfresco.repo.security.permissions.AccessControlList;
import org.alfresco.repo.security.permissions.SimpleAccessControlListProperties;
import org.alfresco.repo.security.permissions.impl.AclChange;
import org.alfresco.repo.security.permissions.impl.AclDaoComponent;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
/**
* DAO layer for the improved ACL implemtentation.
*
* This layer is responsible for setting ACLs and any cascade behaviour required.
* It also implements the migration from the old implementation to the new.
*
* @author andyh
*
*/
public class DMAccessControlListDAO implements AccessControlListDAO
{
/**
* The DAO for Nodes.
*/
private NodeDaoService nodeDaoService;
private NodeService nodeService;
private AclDaoComponent aclDaoComponent;
private HibernateSessionHelper hibernateSessionHelper;
/**
* Set the node dao service
*
* @param nodeDaoService
*/
public void setNodeDaoService(NodeDaoService nodeDaoService)
{
this.nodeDaoService = nodeDaoService;
}
/**
* Set the ACL DAO components
* @param aclDaoComponent
*/
public void setAclDaoComponent(AclDaoComponent aclDaoComponent)
{
this.aclDaoComponent = aclDaoComponent;
}
/**
* Set the hibernate session helper for session size management
*
* @param hibernateSessionHelper
*/
public void setHibernateSessionHelper(HibernateSessionHelper hibernateSessionHelper)
{
this.hibernateSessionHelper = hibernateSessionHelper;
}
/**
* Set the node service.
* @param nodeService
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void forceCopy(NodeRef nodeRef)
{
// Nothing to do
}
public DbAccessControlList getAccessControlList(NodeRef nodeRef)
{
Node node = nodeDaoService.getNode(nodeRef);
if (node == null)
{
throw new InvalidNodeRefException(nodeRef);
}
return node.getAccessControlList();
}
public DbAccessControlList getAccessControlList(StoreRef storeRef)
{
return null;
}
public Long getIndirectAcl(NodeRef nodeRef)
{
return getAccessControlList(nodeRef).getId();
}
public Long getInheritedAcl(NodeRef nodeRef)
{
Node node = nodeDaoService.getNode(nodeRef);
ChildAssoc ca = nodeDaoService.getPrimaryParentAssoc(node);
if ((ca != null) && (ca.getParent() != null))
{
DbAccessControlList acl = getAccessControlList(ca.getParent().getNodeRef());
if (acl != null)
{
return acl.getId();
}
else
{
return null;
}
}
else
{
return null;
}
}
public Map<ACLType, Integer> patchAcls()
{
CounterSet result = new CounterSet();
List<StoreRef> stores = nodeService.getStores();
for (StoreRef store : stores)
{
@SuppressWarnings("unused")
CounterSet update;
update = fixOldDmAcls(nodeService.getRootNode(store));
}
HashMap<ACLType, Integer> toReturn = new HashMap<ACLType, Integer>();
toReturn.put(ACLType.DEFINING, Integer.valueOf(result.get(ACLType.DEFINING).getCounter()));
toReturn.put(ACLType.FIXED, Integer.valueOf(result.get(ACLType.FIXED).getCounter()));
toReturn.put(ACLType.GLOBAL, Integer.valueOf(result.get(ACLType.GLOBAL).getCounter()));
toReturn.put(ACLType.LAYERED, Integer.valueOf(result.get(ACLType.LAYERED).getCounter()));
toReturn.put(ACLType.OLD, Integer.valueOf(result.get(ACLType.OLD).getCounter()));
toReturn.put(ACLType.SHARED, Integer.valueOf(result.get(ACLType.SHARED).getCounter()));
return toReturn;
}
private CounterSet fixOldDmAcls(NodeRef nodeRef)
{
hibernateSessionHelper.mark();
try
{
return fixOldDmAclsImpl(nodeRef);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
private CounterSet fixOldDmAclsImpl(NodeRef nodeRef)
{
CounterSet result = new CounterSet();
// Do the children first
for (ChildAssociationRef child : nodeService.getChildAssocs(nodeRef))
{
CounterSet update = fixOldDmAcls(child.getChildRef());
result.add(update);
}
DbAccessControlList existingAcl = getAccessControlList(nodeRef);
if (existingAcl != null)
{
if (existingAcl.getAclType() == ACLType.OLD)
{
result.increment(ACLType.DEFINING);
//
SimpleAccessControlListProperties properties = DMPermissionsDaoComponentImpl.getDefaultProperties();
// Accept default versioning
Long id = aclDaoComponent.createAccessControlList(properties);
DbAccessControlList newAcl = aclDaoComponent.getDbAccessControlList(id);
AccessControlList existing = aclDaoComponent.getAccessControlList(existingAcl.getId());
for (AccessControlEntry entry : existing.getEntries())
{
if (entry.getPosition() == 0)
{
aclDaoComponent.setAccessControlEntry(id, entry);
}
}
setAccessControlList(nodeRef, newAcl);
// Cascade to children - changes should all be 1-1 so we do not have to post fix
List<AclChange> changes = new ArrayList<AclChange>();
setFixedAcls(nodeRef, aclDaoComponent.getInheritedAccessControlList(id), changes, false);
}
else
{
// Already fixed up :-)
}
}
return result;
}
public void setAccessControlList(NodeRef nodeRef, DbAccessControlList acl)
{
Node node = nodeDaoService.getNode(nodeRef);
if (node == null)
{
throw new InvalidNodeRefException(nodeRef);
}
node.setAccessControlList(acl);
}
public void setAccessControlList(StoreRef storeRef, DbAccessControlList acl)
{
throw new UnsupportedOperationException();
}
public List<AclChange> setInheritanceForChildren(NodeRef parent, Long mergeFrom)
{
List<AclChange> changes = new ArrayList<AclChange>();
setFixedAcls(parent, mergeFrom, changes, false);
return changes;
}
public void updateChangedAcls(NodeRef startingPoint, List<AclChange> changes)
{
// Nothing to do: no nodes change as a result of ACL changes
}
/**
* Support to set ACLs and cascade fo required
*
* @param nodeRef
* @param mergeFrom
* @param changes
* @param set
*/
public void setFixedAcls(NodeRef nodeRef, Long mergeFrom, List<AclChange> changes, boolean set)
{
if (nodeRef == null)
{
return;
}
else
{
if (set)
{
setAccessControlList(nodeRef, aclDaoComponent.getDbAccessControlList(mergeFrom));
}
List<ChildAssociationRef> children = nodeService.getChildAssocs(nodeRef);
for (ChildAssociationRef child : children)
{
DbAccessControlList acl = getAccessControlList(child.getChildRef());
if (acl == null)
{
hibernateSessionHelper.mark();
try
{
setFixedAcls(child.getChildRef(), mergeFrom, changes, true);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
else if (acl.getAclType() == ACLType.LAYERED)
{
throw new UnsupportedOperationException();
}
else if (acl.getAclType() == ACLType.DEFINING)
{
@SuppressWarnings("unused")
List<AclChange> newChanges = aclDaoComponent.mergeInheritedAccessControlList(mergeFrom, acl.getId());
}
else
{
hibernateSessionHelper.mark();
try
{
setFixedAcls(child.getChildRef(), mergeFrom, changes, true);
}
finally
{
hibernateSessionHelper.resetAndRemoveMark();
}
}
}
}
}
/**
* Static support to set ACLs - required for use by the dbNodeService
*
* @param nodeRef
* @param mergeFrom
* @param set
* @param nodeService
* @param aclDaoComponent
* @param nodeDaoService
*/
public static void setFixedAcls(NodeRef nodeRef, Long mergeFrom, boolean set, NodeService nodeService, AclDaoComponent aclDaoComponent, NodeDaoService nodeDaoService)
{
if (nodeRef == null)
{
return;
}
else
{
if (set)
{
setAccessControlList(nodeRef, aclDaoComponent.getDbAccessControlList(mergeFrom), nodeDaoService);
}
List<ChildAssociationRef> children = nodeService.getChildAssocs(nodeRef);
for (ChildAssociationRef child : children)
{
DbAccessControlList acl = getAccessControlList(child.getChildRef(), nodeDaoService);
if (acl == null)
{
setFixedAcls(child.getChildRef(), mergeFrom, true, nodeService, aclDaoComponent, nodeDaoService);
}
else if (acl.getAclType() == ACLType.LAYERED)
{
throw new UnsupportedOperationException();
}
else if (acl.getAclType() == ACLType.DEFINING)
{
@SuppressWarnings("unused")
List<AclChange> newChanges = aclDaoComponent.mergeInheritedAccessControlList(mergeFrom, acl.getId());
}
else
{
setFixedAcls(child.getChildRef(), mergeFrom, true, nodeService, aclDaoComponent, nodeDaoService);
}
}
}
}
private static DbAccessControlList getAccessControlList(NodeRef nodeRef, NodeDaoService nodeDaoService)
{
Node node = nodeDaoService.getNode(nodeRef);
if (node == null)
{
throw new InvalidNodeRefException(nodeRef);
}
return node.getAccessControlList();
}
private static void setAccessControlList(NodeRef nodeRef, DbAccessControlList acl, NodeDaoService nodeDaoService)
{
Node node = nodeDaoService.getNode(nodeRef);
if (node == null)
{
throw new InvalidNodeRefException(nodeRef);
}
node.setAccessControlList(acl);
}
}

View File

@@ -0,0 +1,167 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.domain.hibernate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.security.permissions.SimpleAccessControlListProperties;
import org.alfresco.repo.security.permissions.impl.AclChange;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Manage creation and deletion of ACL entries for the new DM ACL implementation
*
* @author andyh
*
*/
public class DMPermissionsDaoComponentImpl extends AbstractPermissionsDaoComponentImpl
{
@SuppressWarnings("unused")
private static Log logger = LogFactory.getLog(DMPermissionsDaoComponentImpl.class);
@Override
protected CreationReport createAccessControlList(NodeRef nodeRef, boolean inherit, DbAccessControlList existing)
{
if (existing == null)
{
SimpleAccessControlListProperties properties = new SimpleAccessControlListProperties();
properties.setAclType(ACLType.DEFINING);
properties.setInherits(inherit);
properties.setVersioned(false);
// Accept default versioning
Long id = aclDaoComponent.createAccessControlList(properties);
List<AclChange> changes = new ArrayList<AclChange>();
DbAccessControlList acl = aclDaoComponent.getDbAccessControlList(id);
changes.add(new AclDaoComponentImpl.AclChangeImpl(null, id, null, acl.getAclType()));
changes.addAll(getACLDAO(nodeRef).setInheritanceForChildren(nodeRef, aclDaoComponent.getInheritedAccessControlList(id)));
getACLDAO(nodeRef).setAccessControlList(nodeRef, acl);
return new CreationReport(acl, changes);
}
SimpleAccessControlListProperties properties;
Long id;
List<AclChange> changes;
DbAccessControlList acl;
switch (existing.getAclType())
{
case OLD:
throw new IllegalStateException("Can not mix old and new style permissions");
case DEFINING:
return new CreationReport(existing, Collections.<AclChange> emptyList());
case FIXED:
case GLOBAL:
case SHARED:
// create new defining, wire up and report changes to acl required.
properties = new SimpleAccessControlListProperties();
properties.setAclType(ACLType.DEFINING);
properties.setInherits(existing.getInherits());
properties.setVersioned(false);
id = aclDaoComponent.createAccessControlList(properties);
changes = new ArrayList<AclChange>();
acl = aclDaoComponent.getDbAccessControlList(id);
changes.add(new AclDaoComponentImpl.AclChangeImpl(existing.getId(), id, existing.getAclType(), acl.getAclType()));
changes.addAll(aclDaoComponent.mergeInheritedAccessControlList(existing.getId(), id));
// set this to inherit to children
changes.addAll(getACLDAO(nodeRef).setInheritanceForChildren(nodeRef, aclDaoComponent.getInheritedAccessControlList(id)));
getACLDAO(nodeRef).setAccessControlList(nodeRef, acl);
return new CreationReport(acl, changes);
case LAYERED:
throw new IllegalStateException("Layering is not supported for DM permissions");
default:
throw new IllegalStateException("Unknown type " + existing.getAclType());
}
}
public void deletePermissions(NodeRef nodeRef)
{
DbAccessControlList acl = null;
try
{
acl = getAccessControlList(nodeRef);
}
catch (InvalidNodeRefException e)
{
return;
}
System.out.println("Deleting "+acl+" on "+nodeRef);
if (acl != null)
{
if (acl.getInheritsFrom() != null)
{
@SuppressWarnings("unused")
Long deleted = acl.getId();
Long inheritsFrom = acl.getInheritsFrom();
getACLDAO(nodeRef).setAccessControlList(nodeRef, aclDaoComponent.getDbAccessControlList(inheritsFrom));
List<AclChange> changes = new ArrayList<AclChange>();
changes.addAll(getACLDAO(nodeRef).setInheritanceForChildren(nodeRef, inheritsFrom));
getACLDAO(nodeRef).updateChangedAcls(nodeRef, changes);
aclDaoComponent.deleteAccessControlList(acl.getId());
}
else
{
// TODO: could just cear out existing
@SuppressWarnings("unused")
Long deleted = acl.getId();
SimpleAccessControlListProperties properties = new SimpleAccessControlListProperties();
properties = new SimpleAccessControlListProperties();
properties.setAclType(ACLType.DEFINING);
properties.setInherits(Boolean.FALSE);
properties.setVersioned(false);
Long id = aclDaoComponent.createAccessControlList(properties);
getACLDAO(nodeRef).setAccessControlList(nodeRef, aclDaoComponent.getDbAccessControlList(id));
List<AclChange> changes = new ArrayList<AclChange>();
changes.addAll(getACLDAO(nodeRef).setInheritanceForChildren(nodeRef, aclDaoComponent.getInheritedAccessControlList(id)));
getACLDAO(nodeRef).updateChangedAcls(nodeRef, changes);
aclDaoComponent.deleteAccessControlList(acl.getId());
}
}
}
/**
* Get the default ACL properties
*
* @return the default properties
*/
public static SimpleAccessControlListProperties getDefaultProperties()
{
SimpleAccessControlListProperties properties = new SimpleAccessControlListProperties();
properties.setAclType(ACLType.DEFINING);
properties.setInherits(true);
properties.setVersioned(false);
return properties;
}
}

View File

@@ -62,7 +62,7 @@
fetch="select" fetch="select"
unique="false" unique="false"
not-null="false" not-null="false"
cascade="delete" /> cascade="none" />
<!-- forward assoc to properties --> <!-- forward assoc to properties -->
<map <map
name="properties" name="properties"

View File

@@ -72,10 +72,11 @@ public class OldADMPermissionsDaoComponentImpl extends AbstractPermissionsDaoCom
{ {
logger.debug("Created Access Control List: \n" + " node: " + nodeRef + "\n" + " list: " + acl); logger.debug("Created Access Control List: \n" + " node: " + nodeRef + "\n" + " list: " + acl);
} }
AbstractPermissionsDaoComponentImpl.CreationReport report = new AbstractPermissionsDaoComponentImpl.CreationReport(acl, Collections.<AclChange>singletonList(new AclDaoComponentImpl.AclChangeImpl(null, id, null, acl.getAclType()))); AbstractPermissionsDaoComponentImpl.CreationReport report = new AbstractPermissionsDaoComponentImpl.CreationReport(acl, Collections
.<AclChange> singletonList(new AclDaoComponentImpl.AclChangeImpl(null, id, null, acl.getAclType())));
return report; return report;
} }
public void deletePermissions(NodeRef nodeRef) public void deletePermissions(NodeRef nodeRef)
@@ -96,7 +97,4 @@ public class OldADMPermissionsDaoComponentImpl extends AbstractPermissionsDaoCom
aclDaoComponent.deleteAccessControlList(acl.getId()); aclDaoComponent.deleteAccessControlList(acl.getId());
} }
} }
} }

View File

@@ -433,6 +433,21 @@
</query> </query>
<query name="permission.GetDmNodeCount">
<![CDATA[
select count(*)
from org.alfresco.repo.domain.hibernate.NodeImpl
]]>
</query>
<query name="permission.GetDmNodeCountWherePermissionsHaveChanged">
<![CDATA[
select count(*)
from org.alfresco.repo.domain.hibernate.NodeImpl node
where node.accessControlList.id > :above
]]>
</query>
<!-- <!--
<query name="permission.GetAccessControlEntriesForAuthority"> <query name="permission.GetAccessControlEntriesForAuthority">

View File

@@ -29,7 +29,6 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.hibernate.AbstractPermissionsDaoComponentImpl.CreationReport;
import org.alfresco.repo.security.permissions.ACLType; import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.security.permissions.AccessControlEntry; import org.alfresco.repo.security.permissions.AccessControlEntry;
import org.alfresco.repo.security.permissions.AccessControlList; import org.alfresco.repo.security.permissions.AccessControlList;
@@ -38,6 +37,11 @@ import org.alfresco.repo.security.permissions.impl.AclChange;
import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
/**
* Old permissions dao component impl
* @author andyh
*
*/
public class PermissionsDaoComponentImpl extends AbstractPermissionsDaoComponentImpl public class PermissionsDaoComponentImpl extends AbstractPermissionsDaoComponentImpl
{ {
@@ -142,17 +146,19 @@ public class PermissionsDaoComponentImpl extends AbstractPermissionsDaoComponent
{ {
if (acl.getInheritsFrom() != null) if (acl.getInheritsFrom() != null)
{ {
@SuppressWarnings("unused")
Long deleted = acl.getId(); Long deleted = acl.getId();
Long inheritsFrom = acl.getInheritsFrom(); Long inheritsFrom = acl.getInheritsFrom();
getACLDAO(nodeRef).setAccessControlList(nodeRef, aclDaoComponent.getDbAccessControlList(inheritsFrom)); getACLDAO(nodeRef).setAccessControlList(nodeRef, aclDaoComponent.getDbAccessControlList(inheritsFrom));
aclDaoComponent.deleteAccessControlList(acl.getId());
List<AclChange> changes = new ArrayList<AclChange>(); List<AclChange> changes = new ArrayList<AclChange>();
changes.addAll(getACLDAO(nodeRef).setInheritanceForChildren(nodeRef, inheritsFrom)); changes.addAll(getACLDAO(nodeRef).setInheritanceForChildren(nodeRef, inheritsFrom));
getACLDAO(nodeRef).updateChangedAcls(nodeRef, changes); getACLDAO(nodeRef).updateChangedAcls(nodeRef, changes);
aclDaoComponent.deleteAccessControlList(acl.getId());
} }
else else
{ {
// TODO: could just cear out existing // TODO: could just cear out existing
@SuppressWarnings("unused")
Long deleted = acl.getId(); Long deleted = acl.getId();
SimpleAccessControlListProperties properties = new SimpleAccessControlListProperties(); SimpleAccessControlListProperties properties = new SimpleAccessControlListProperties();
properties.setAclType(ACLType.DEFINING); properties.setAclType(ACLType.DEFINING);
@@ -160,12 +166,11 @@ public class PermissionsDaoComponentImpl extends AbstractPermissionsDaoComponent
// Accept default versioning // Accept default versioning
Long id = aclDaoComponent.createAccessControlList(properties); Long id = aclDaoComponent.createAccessControlList(properties);
getACLDAO(nodeRef).setAccessControlList(nodeRef, aclDaoComponent.getDbAccessControlList(id)); getACLDAO(nodeRef).setAccessControlList(nodeRef, aclDaoComponent.getDbAccessControlList(id));
aclDaoComponent.deleteAccessControlList(acl.getId());
List<AclChange> changes = new ArrayList<AclChange>(); List<AclChange> changes = new ArrayList<AclChange>();
changes.addAll(getACLDAO(nodeRef).setInheritanceForChildren(nodeRef, id)); changes.addAll(getACLDAO(nodeRef).setInheritanceForChildren(nodeRef, aclDaoComponent.getInheritedAccessControlList(id)));
getACLDAO(nodeRef).updateChangedAcls(nodeRef, changes); getACLDAO(nodeRef).updateChangedAcls(nodeRef, changes);
aclDaoComponent.deleteAccessControlList(acl.getId());
} }
} }
} }
} }

View File

@@ -40,6 +40,7 @@ import java.util.Stack;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.ChildAssoc; import org.alfresco.repo.domain.ChildAssoc;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.Node; import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.NodeAssoc; import org.alfresco.repo.domain.NodeAssoc;
import org.alfresco.repo.domain.NodeStatus; import org.alfresco.repo.domain.NodeStatus;
@@ -47,9 +48,16 @@ import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.domain.QNameDAO; import org.alfresco.repo.domain.QNameDAO;
import org.alfresco.repo.domain.QNameEntity; import org.alfresco.repo.domain.QNameEntity;
import org.alfresco.repo.domain.Store; import org.alfresco.repo.domain.Store;
import org.alfresco.repo.domain.hibernate.DMAccessControlListDAO;
import org.alfresco.repo.domain.hibernate.DMPermissionsDaoComponentImpl;
import org.alfresco.repo.node.AbstractNodeServiceImpl; import org.alfresco.repo.node.AbstractNodeServiceImpl;
import org.alfresco.repo.node.StoreArchiveMap; import org.alfresco.repo.node.StoreArchiveMap;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.security.permissions.AccessControlListProperties;
import org.alfresco.repo.security.permissions.SimpleAccessControlListProperties;
import org.alfresco.repo.security.permissions.impl.AclDaoComponent;
import org.alfresco.repo.security.permissions.impl.PermissionsDaoComponent;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.dictionary.AspectDefinition; import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.AssociationDefinition;
@@ -98,6 +106,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
private StoreArchiveMap storeArchiveMap; private StoreArchiveMap storeArchiveMap;
private NodeService avmNodeService; private NodeService avmNodeService;
private TenantService tenantService; private TenantService tenantService;
private AclDaoComponent aclDaoComponent;
public DbNodeServiceImpl() public DbNodeServiceImpl()
{ {
@@ -131,6 +140,11 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
{ {
this.tenantService = tenantService; this.tenantService = tenantService;
} }
public void setAclDaoComponent(AclDaoComponent aclDaoComponent)
{
this.aclDaoComponent = aclDaoComponent;
}
/** /**
* Performs a null-safe get of the node * Performs a null-safe get of the node
@@ -265,9 +279,19 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
ContentModel.ASPECT_ROOT, ContentModel.ASPECT_ROOT,
Collections.<QName, Serializable>emptyMap()); Collections.<QName, Serializable>emptyMap());
// Bind root permission
if(aclDaoComponent != null)
{
SimpleAccessControlListProperties properties = DMPermissionsDaoComponentImpl.getDefaultProperties();
Long id = aclDaoComponent.createAccessControlList(properties);
DbAccessControlList acl = aclDaoComponent.getDbAccessControlList(id);
rootNode.setAccessControlList(acl);
}
// invoke policies // invoke policies
invokeOnCreateStore(rootNodeRef); invokeOnCreateStore(rootNodeRef);
// done // done
if (!store.getStoreRef().equals(storeRef)) if (!store.getStoreRef().equals(storeRef))
{ {
@@ -412,6 +436,20 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
setChildUniqueName(childNode); // ensure uniqueness setChildUniqueName(childNode); // ensure uniqueness
ChildAssociationRef childAssocRef = tenantService.getBaseName(childAssoc.getChildAssocRef()); ChildAssociationRef childAssocRef = tenantService.getBaseName(childAssoc.getChildAssocRef());
// permissions behaviour
if(aclDaoComponent != null)
{
DbAccessControlList inherited = parentNode.getAccessControlList();
if (inherited == null)
{
// not fixde up yet or unset
}
else
{
childNode.setAccessControlList(aclDaoComponent.getDbAccessControlList(aclDaoComponent.getInheritedAccessControlList(inherited.getId())));
}
}
// Invoke policy behaviour // Invoke policy behaviour
invokeOnCreateNode(childAssocRef); invokeOnCreateNode(childAssocRef);
invokeOnCreateChildAssociation(childAssocRef, true); invokeOnCreateChildAssociation(childAssocRef, true);
@@ -519,6 +557,29 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
// check that no cyclic relationships have been created // check that no cyclic relationships have been created
getPaths(nodeToMoveRef, false); getPaths(nodeToMoveRef, false);
// Fix inherited permissions
if(aclDaoComponent != null)
{
Long targetAcl = newAssoc.getChild().getAccessControlList().getId();
AccessControlListProperties aclProperties = aclDaoComponent.getAccessControlListProperties(targetAcl);
Boolean inherits = aclProperties.getInherits();
if((inherits != null) && (inherits.booleanValue()))
{
Long parentAcl = newAssoc.getParent().getAccessControlList().getId();
Long inheritedAcl = aclDaoComponent.getInheritedAccessControlList(parentAcl);
if(aclProperties.getAclType() == ACLType.DEFINING)
{
aclDaoComponent.enableInheritance(targetAcl, parentAcl);
}
else if(aclProperties.getAclType() == ACLType.SHARED)
{
DMAccessControlListDAO.setFixedAcls(newAssoc.getChildAssocRef().getChildRef(), inheritedAcl, true, this, aclDaoComponent, nodeDaoService);
}
}
}
// invoke policy behaviour // invoke policy behaviour
if (movingStore) if (movingStore)
{ {

View File

@@ -26,25 +26,30 @@ package org.alfresco.repo.security.permissions;
import java.io.Serializable; import java.io.Serializable;
/**
* Properties for an access control list
*
* @author andyh
*
*/
public interface AccessControlListProperties extends Serializable public interface AccessControlListProperties extends Serializable
{ {
/** /**
* Get the ACL ID * Get the ACL ID
* @return * @return the acl id
*/ */
public String getAclId(); public String getAclId();
/** /**
* Get the ACL version * Get the ACL version
* @return * @return the acl version
*/ */
public Long getAclVersion(); public Long getAclVersion();
/** /**
* Is this the latest version of the acl identified by the acl id string? * Is this the latest version of the acl identified by the acl id string?
* @return * @return - true if the acl is the latest version
*/ */
public Boolean isLatest(); public Boolean isLatest();
@@ -57,7 +62,7 @@ public interface AccessControlListProperties extends Serializable
/** /**
* Get the type for this ACL * Get the type for this ACL
* *
* @return * @return the acl type
*/ */
public ACLType getAclType(); public ACLType getAclType();
@@ -67,7 +72,14 @@ public interface AccessControlListProperties extends Serializable
* *
* If an acl is versioned it can not be updated - a new copy has to be created, * If an acl is versioned it can not be updated - a new copy has to be created,
* *
* @return * @return if the acl is verioned
*/ */
public Boolean isVersioned(); public Boolean isVersioned();
/**
* The ACL DB id
*
* @return the id
*/
public Long getId();
} }

View File

@@ -24,6 +24,8 @@
*/ */
package org.alfresco.repo.security.permissions; package org.alfresco.repo.security.permissions;
import java.util.Set;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
/** /**
@@ -40,7 +42,7 @@ public interface DynamicAuthority
* *
* @param nodeRef * @param nodeRef
* @param userName * @param userName
* @return * @return true if the current user has the authority
*/ */
public boolean hasAuthority(NodeRef nodeRef, String userName); public boolean hasAuthority(NodeRef nodeRef, String userName);
@@ -48,7 +50,15 @@ public interface DynamicAuthority
* If this authority is granted this method provides the string * If this authority is granted this method provides the string
* representation of the granted authority. * representation of the granted authority.
* *
* @return * @return the authority taht may be assigned
*/ */
public String getAuthority(); public String getAuthority();
/**
* For what permission checks is this dynamic authority required?
* If null, it is required for all checks.
*
* @return the set of permissions for which this dynamic authority should be evaluated
*/
public Set<PermissionReference> requiredFor();
} }

View File

@@ -41,14 +41,16 @@ public interface PermissionReference extends Serializable
* Get the QName of the type or aspect against which the permission is * Get the QName of the type or aspect against which the permission is
* defined. * defined.
* *
* @return * @return the qname
*/ */
public QName getQName(); public QName getQName();
/** /**
* Get the name of the permission * Get the name of the permission
* *
* @return * @return the name
*/ */
public String getName(); public String getName();
} }

View File

@@ -27,6 +27,7 @@ package org.alfresco.repo.security.permissions;
import java.util.Set; import java.util.Set;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
@@ -50,8 +51,8 @@ public interface PermissionServiceSPI extends PermissionService
/** /**
* Get the permissions that can be set for a given type * Get the permissions that can be set for a given type
* *
* @param nodeRef * @param type
* @return * @return the set of permissions
*/ */
public Set<PermissionReference> getSettablePermissionReferences(QName type); public Set<PermissionReference> getSettablePermissionReferences(QName type);
@@ -59,7 +60,7 @@ public interface PermissionServiceSPI extends PermissionService
* Get the permissions that can be set for a given type * Get the permissions that can be set for a given type
* *
* @param nodeRef * @param nodeRef
* @return * @return the set of permissions
*/ */
public Set<PermissionReference> getSettablePermissionReferences(NodeRef nodeRef); public Set<PermissionReference> getSettablePermissionReferences(NodeRef nodeRef);
@@ -68,7 +69,7 @@ public interface PermissionServiceSPI extends PermissionService
* nothing of the parent permissions) * nothing of the parent permissions)
* *
* @param nodeRef * @param nodeRef
* @return * @return the node permission entry
*/ */
public NodePermissionEntry getSetPermissions(NodeRef nodeRef); public NodePermissionEntry getSetPermissions(NodeRef nodeRef);
@@ -78,7 +79,7 @@ public interface PermissionServiceSPI extends PermissionService
* *
* @param nodeRef * @param nodeRef
* @param perm * @param perm
* @return * @return the access status
*/ */
public AccessStatus hasPermission(NodeRef nodeRef, PermissionReference perm); public AccessStatus hasPermission(NodeRef nodeRef, PermissionReference perm);
@@ -87,9 +88,8 @@ public interface PermissionServiceSPI extends PermissionService
* permission for the given authentication to access the specified name. * permission for the given authentication to access the specified name.
* *
* @param nodeRef * @param nodeRef
* @param auth
* @param perm * @param perm
* @return * @return the node permission entry
*/ */
public NodePermissionEntry explainPermission(NodeRef nodeRef, PermissionReference perm); public NodePermissionEntry explainPermission(NodeRef nodeRef, PermissionReference perm);
@@ -124,7 +124,7 @@ public interface PermissionServiceSPI extends PermissionService
* *
* @param qname - may be null if the permission name is unique * @param qname - may be null if the permission name is unique
* @param permissionName * @param permissionName
* @return * @return the permission reference
*/ */
public PermissionReference getPermissionReference(QName qname, String permissionName); public PermissionReference getPermissionReference(QName qname, String permissionName);
@@ -132,7 +132,7 @@ public interface PermissionServiceSPI extends PermissionService
* Get the permission reference by permission name. * Get the permission reference by permission name.
* *
* @param permissionName * @param permissionName
* @return * @return the permission reference
*/ */
public PermissionReference getPermissionReference(String permissionName); public PermissionReference getPermissionReference(String permissionName);
@@ -141,9 +141,20 @@ public interface PermissionServiceSPI extends PermissionService
* Get the string that can be used to identify the given permission reference. * Get the string that can be used to identify the given permission reference.
* *
* @param permissionReference * @param permissionReference
* @return * @return the permission short name
*/ */
public String getPermission(PermissionReference permissionReference); public String getPermission(PermissionReference permissionReference);
/**
* Delete permissions for the given recipient.
* @param recipient
*/
public void deletePermissions(String recipient); public void deletePermissions(String recipient);
/**
* Get the permissions set for the store
* @param storeRef
* @return - the node permission entry
*/
public NodePermissionEntry getSetPermissions(StoreRef storeRef);
} }

View File

@@ -27,6 +27,12 @@ package org.alfresco.repo.security.permissions;
import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.AuthorityType;
/**
* A basic access control entry
*
* @author andyh
*
*/
public class SimpleAccessControlEntry implements AccessControlEntry public class SimpleAccessControlEntry implements AccessControlEntry
{ {
/** /**
@@ -76,31 +82,56 @@ public class SimpleAccessControlEntry implements AccessControlEntry
return position; return position;
} }
/**
* Set the status
* @param accessStatus
*/
public void setAccessStatus(AccessStatus accessStatus) public void setAccessStatus(AccessStatus accessStatus)
{ {
this.accessStatus = accessStatus; this.accessStatus = accessStatus;
} }
/**
* Set the type
* @param aceType
*/
public void setAceType(ACEType aceType) public void setAceType(ACEType aceType)
{ {
this.aceType = aceType; this.aceType = aceType;
} }
/**
* Set the authority
* @param authority
*/
public void setAuthority(String authority) public void setAuthority(String authority)
{ {
this.authority = authority; this.authority = authority;
} }
/**
* Set the context
* @param context
*/
public void setContext(AccessControlEntryContext context) public void setContext(AccessControlEntryContext context)
{ {
this.context = context; this.context = context;
} }
/**
* Set the permission
* @param permission
*/
public void setPermission(PermissionReference permission) public void setPermission(PermissionReference permission)
{ {
this.permission = permission; this.permission = permission;
} }
/**
* Set the position
* @param position
*/
public void setPosition(Integer position) public void setPosition(Integer position)
{ {
this.position = position; this.position = position;
@@ -127,5 +158,20 @@ public class SimpleAccessControlEntry implements AccessControlEntry
} }
} }
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("[");
builder.append(getPermission()).append(", ");
builder.append(getAuthority()).append(", ");
builder.append(getAccessStatus()).append(", ");
builder.append(getAceType()).append(", ");
builder.append(getPosition()).append(", ");
builder.append(getContext());
builder.append("]");
return builder.toString();
}
} }

View File

@@ -24,6 +24,12 @@
*/ */
package org.alfresco.repo.security.permissions; package org.alfresco.repo.security.permissions;
/**
* Basic implementation of access control list properties
*
* @author andyh
*
*/
public class SimpleAccessControlListProperties implements AccessControlListProperties public class SimpleAccessControlListProperties implements AccessControlListProperties
{ {
/** /**
@@ -43,6 +49,8 @@ public class SimpleAccessControlListProperties implements AccessControlListPrope
private Boolean versioned; private Boolean versioned;
private Long id;
public String getAclId() public String getAclId()
{ {
return aclId; return aclId;
@@ -73,35 +81,73 @@ public class SimpleAccessControlListProperties implements AccessControlListPrope
return versioned; return versioned;
} }
/**
* Set the acl id
* @param aclId
*/
public void setAclId(String aclId) public void setAclId(String aclId)
{ {
this.aclId = aclId; this.aclId = aclId;
} }
/**
* Set the acl type
* @param aclType
*/
public void setAclType(ACLType aclType) public void setAclType(ACLType aclType)
{ {
this.aclType = aclType; this.aclType = aclType;
} }
/**
* Set the acl version
* @param aclVersion
*/
public void setAclVersion(Long aclVersion) public void setAclVersion(Long aclVersion)
{ {
this.aclVersion = aclVersion; this.aclVersion = aclVersion;
} }
/**
* Set inheritance
* @param inherits
*/
public void setInherits(boolean inherits) public void setInherits(boolean inherits)
{ {
this.inherits = inherits; this.inherits = inherits;
} }
/**
* Set latest
* @param latest
*/
public void setLatest(boolean latest) public void setLatest(boolean latest)
{ {
this.latest = latest; this.latest = latest;
} }
/**
* Set versioned
* @param versioned
*/
public void setVersioned(boolean versioned) public void setVersioned(boolean versioned)
{ {
this.versioned = versioned; this.versioned = versioned;
} }
public Long getId()
{
return id;
}
/**
* Set the id
* @param id
*/
public void setId(Long id)
{
this.id = id;
}

View File

@@ -25,18 +25,22 @@
package org.alfresco.repo.security.permissions.dynamic; package org.alfresco.repo.security.permissions.dynamic;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.DynamicAuthority; import org.alfresco.repo.security.permissions.DynamicAuthority;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.repo.security.permissions.impl.ModelDAO;
import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockStatus; import org.alfresco.service.cmr.lock.LockStatus;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.util.EqualsHelper;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
/** /**
@@ -48,6 +52,11 @@ public class LockOwnerDynamicAuthority implements DynamicAuthority, Initializing
private NodeService nodeService; private NodeService nodeService;
private ModelDAO modelDAO;
private List<String> requiredFor;
private Set<PermissionReference> whenRequired;
public boolean hasAuthority(final NodeRef nodeRef, final String userName) public boolean hasAuthority(final NodeRef nodeRef, final String userName)
{ {
@@ -101,16 +110,64 @@ public class LockOwnerDynamicAuthority implements DynamicAuthority, Initializing
{ {
throw new IllegalStateException("The NodeService service must be set"); throw new IllegalStateException("The NodeService service must be set");
} }
if(modelDAO == null)
{
throw new IllegalStateException("The ModelDAO service must be set");
}
// buld the permission set
if(requiredFor != null)
{
whenRequired = new HashSet<PermissionReference>();
for(String permission : requiredFor)
{
PermissionReference permissionReference = modelDAO.getPermissionReference(null, permission);
whenRequired.addAll(modelDAO.getGranteePermissions(permissionReference));
whenRequired.addAll(modelDAO.getGrantingPermissions(permissionReference));
}
}
} }
/**
* Set the lock service
* @param lockService
*/
public void setLockService(LockService lockService) public void setLockService(LockService lockService)
{ {
this.lockService = lockService; this.lockService = lockService;
} }
/**
* Set the node service
* @param nodeService
*/
public void setNodeService(NodeService nodeService) public void setNodeService(NodeService nodeService)
{ {
this.nodeService = nodeService; this.nodeService = nodeService;
} }
/**
* Set the permissions model dao
* @param modelDAO
*/
public void setModelDAO(ModelDAO modelDAO)
{
this.modelDAO = modelDAO;
}
/**
* Set the permissions for which this dynamic authority is required
* @param requiredFor
*/
public void setRequiredFor(List<String> requiredFor)
{
this.requiredFor = requiredFor;
}
public Set<PermissionReference> requiredFor()
{
return whenRequired;
}
} }

View File

@@ -24,6 +24,9 @@
*/ */
package org.alfresco.repo.security.permissions.dynamic; package org.alfresco.repo.security.permissions.dynamic;
import java.io.Serializable;
import java.util.Map;
import javax.transaction.UserTransaction; import javax.transaction.UserTransaction;
import junit.framework.TestCase; import junit.framework.TestCase;
@@ -43,10 +46,17 @@ import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.ApplicationContextHelper;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
/**
* Test the lock owner dynaic authority
*
* @author andyh
*
*/
public class LockOwnerDynamicAuthorityTest extends TestCase public class LockOwnerDynamicAuthorityTest extends TestCase
{ {
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(); private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
@@ -73,11 +83,17 @@ public class LockOwnerDynamicAuthorityTest extends TestCase
private OwnableService ownableService; private OwnableService ownableService;
/**
*
*/
public LockOwnerDynamicAuthorityTest() public LockOwnerDynamicAuthorityTest()
{ {
super(); super();
} }
/**
* @param arg0
*/
public LockOwnerDynamicAuthorityTest(String arg0) public LockOwnerDynamicAuthorityTest(String arg0)
{ {
super(arg0); super(arg0);
@@ -137,6 +153,9 @@ public class LockOwnerDynamicAuthorityTest extends TestCase
super.tearDown(); super.tearDown();
} }
/**
*
*/
public void testSetup() public void testSetup()
{ {
assertNotNull(nodeService); assertNotNull(nodeService);
@@ -144,6 +163,9 @@ public class LockOwnerDynamicAuthorityTest extends TestCase
assertNotNull(lockService); assertNotNull(lockService);
} }
/**
*
*/
public void testUnSet() public void testUnSet()
{ {
permissionService.setPermission(rootNodeRef, "andy", PermissionService.ALL_PERMISSIONS, true); permissionService.setPermission(rootNodeRef, "andy", PermissionService.ALL_PERMISSIONS, true);
@@ -152,6 +174,9 @@ public class LockOwnerDynamicAuthorityTest extends TestCase
authenticationService.clearCurrentSecurityContext(); authenticationService.clearCurrentSecurityContext();
} }
/**
*
*/
public void testPermissionWithNoLockAspect() public void testPermissionWithNoLockAspect()
{ {
authenticationService.authenticate("andy", "andy".toCharArray()); authenticationService.authenticate("andy", "andy".toCharArray());
@@ -169,6 +194,9 @@ public class LockOwnerDynamicAuthorityTest extends TestCase
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rootNodeRef, PermissionService.CANCEL_CHECK_OUT)); assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rootNodeRef, PermissionService.CANCEL_CHECK_OUT));
} }
/**
*
*/
public void testPermissionWithLockAspect() public void testPermissionWithLockAspect()
{ {
permissionService.setPermission(rootNodeRef, "andy", PermissionService.ALL_PERMISSIONS, true); permissionService.setPermission(rootNodeRef, "andy", PermissionService.ALL_PERMISSIONS, true);
@@ -228,6 +256,9 @@ public class LockOwnerDynamicAuthorityTest extends TestCase
} }
/**
*
*/
public void testCheckOutCheckInAuthorities() public void testCheckOutCheckInAuthorities()
{ {
permissionService.setPermission(rootNodeRef, "andy", PermissionService.ALL_PERMISSIONS, true); permissionService.setPermission(rootNodeRef, "andy", PermissionService.ALL_PERMISSIONS, true);
@@ -356,11 +387,13 @@ public class LockOwnerDynamicAuthorityTest extends TestCase
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode,
PermissionService.LOCK)); PermissionService.LOCK));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, @SuppressWarnings("unused")
Map<QName, Serializable> properties = nodeService.getProperties(testNode);
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode,
PermissionService.UNLOCK)); PermissionService.UNLOCK));
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT)); assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_OUT));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN)); assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CHECK_IN));
assertEquals(AccessStatus.DENIED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT)); assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.CANCEL_CHECK_OUT));
authenticationService.authenticate("lemur", "lemur".toCharArray()); authenticationService.authenticate("lemur", "lemur".toCharArray());
@@ -390,6 +423,9 @@ public class LockOwnerDynamicAuthorityTest extends TestCase
} }
/**
*
*/
public void testCeckInCheckOut() public void testCeckInCheckOut()
{ {

View File

@@ -24,24 +24,39 @@
*/ */
package org.alfresco.repo.security.permissions.dynamic; package org.alfresco.repo.security.permissions.dynamic;
import java.util.Set;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.DynamicAuthority; import org.alfresco.repo.security.permissions.DynamicAuthority;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.util.EqualsHelper; import org.alfresco.util.EqualsHelper;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
/**
* The owner dynamic authority
* @author andyh
*
*/
public class OwnerDynamicAuthority implements DynamicAuthority, InitializingBean public class OwnerDynamicAuthority implements DynamicAuthority, InitializingBean
{ {
private OwnableService ownableService; private OwnableService ownableService;
/**
* Standard construction
*/
public OwnerDynamicAuthority() public OwnerDynamicAuthority()
{ {
super(); super();
} }
/**
* Set the ownable service
* @param ownableService
*/
public void setOwnableService(OwnableService ownableService) public void setOwnableService(OwnableService ownableService)
{ {
this.ownableService = ownableService; this.ownableService = ownableService;
@@ -72,4 +87,9 @@ public class OwnerDynamicAuthority implements DynamicAuthority, InitializingBean
return PermissionService.OWNER_AUTHORITY; return PermissionService.OWNER_AUTHORITY;
} }
public Set<PermissionReference> requiredFor()
{
return null;
}
} }

View File

@@ -37,7 +37,7 @@ public abstract class AbstractPermissionReference implements PermissionReference
private int hashcode = 0; private int hashcode = 0;
private String str = null; private String str = null;
public AbstractPermissionReference() protected AbstractPermissionReference()
{ {
super(); super();
} }
@@ -54,6 +54,10 @@ public abstract class AbstractPermissionReference implements PermissionReference
return false; return false;
} }
AbstractPermissionReference other = (AbstractPermissionReference)o; AbstractPermissionReference other = (AbstractPermissionReference)o;
if(other.hashCode() != this.hashCode())
{
return false;
}
return this.getName().equals(other.getName()) && this.getQName().equals(other.getQName()); return this.getName().equals(other.getName()) && this.getQName().equals(other.getQName());
} }

View File

@@ -29,6 +29,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.node.db.NodeDaoService;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao; import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.repo.security.permissions.PermissionReference; import org.alfresco.repo.security.permissions.PermissionReference;
@@ -80,6 +81,10 @@ public class AbstractPermissionTest extends BaseSpringTest
protected AuthorityService authorityService; protected AuthorityService authorityService;
protected NodeDaoService nodeDaoService;
protected AclDaoComponent aclDaoComponent;
public AbstractPermissionTest() public AbstractPermissionTest()
{ {
super(); super();
@@ -103,6 +108,8 @@ public class AbstractPermissionTest extends BaseSpringTest
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName()); authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao"); authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
nodeDaoService = (NodeDaoService) applicationContext.getBean("nodeDaoService");
aclDaoComponent = (AclDaoComponent) applicationContext.getBean("aclDaoComponent");
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.nanoTime()); StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.nanoTime());

View File

@@ -24,27 +24,83 @@
*/ */
package org.alfresco.repo.security.permissions.impl; package org.alfresco.repo.security.permissions.impl;
import java.util.HashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
/** /**
* A simple permission reference (not persisted). * A simple permission reference (not persisted). A permission is identified by name for a given type, which is
* * identified by its qualified name.
* A permission is identified by name for a given type, which is identified by its qualified name.
* *
* @author andyh * @author andyh
*/ */
public class PermissionReferenceImpl extends AbstractPermissionReference public class PermissionReferenceImpl extends AbstractPermissionReference
{ {
private static ReadWriteLock lock = new ReentrantReadWriteLock();
private static HashMap<QName, HashMap<String, PermissionReferenceImpl>> instances = new HashMap<QName, HashMap<String, PermissionReferenceImpl>>();
/** /**
* *
*/ */
private static final long serialVersionUID = -8639601925783501443L; private static final long serialVersionUID = -8639601925783501443L;
private QName qName; private QName qName;
private String name; private String name;
public PermissionReferenceImpl(QName qName, String name) /**
* Factory method to create permission references
* @param qName
* @param name
* @return the permissions reference
*/
public static PermissionReferenceImpl getPermissionReference(QName qName, String name)
{
lock.readLock().lock();
try
{
HashMap<String, PermissionReferenceImpl> typed = instances.get(qName);
if(typed != null)
{
PermissionReferenceImpl instance = typed.get(name);
if(instance != null)
{
return instance;
}
}
}
finally
{
lock.readLock().unlock();
}
lock.writeLock().lock();
try
{
HashMap<String, PermissionReferenceImpl> typed = instances.get(qName);
if(typed == null)
{
typed = new HashMap<String, PermissionReferenceImpl>();
instances.put(qName, typed);
}
PermissionReferenceImpl instance = typed.get(name);
if(instance == null)
{
instance = new PermissionReferenceImpl(qName, name);
typed.put(name, instance);
}
return instance;
}
finally
{
lock.writeLock().unlock();
}
}
protected PermissionReferenceImpl(QName qName, String name)
{ {
this.qName = qName; this.qName = qName;
this.name = name; this.name = name;

View File

@@ -44,8 +44,10 @@ import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.security.permissions.AccessControlEntry; import org.alfresco.repo.security.permissions.AccessControlEntry;
import org.alfresco.repo.security.permissions.AccessControlList; import org.alfresco.repo.security.permissions.AccessControlList;
import org.alfresco.repo.security.permissions.AccessControlListProperties;
import org.alfresco.repo.security.permissions.DynamicAuthority; import org.alfresco.repo.security.permissions.DynamicAuthority;
import org.alfresco.repo.security.permissions.NodePermissionEntry; import org.alfresco.repo.security.permissions.NodePermissionEntry;
import org.alfresco.repo.security.permissions.PermissionEntry; import org.alfresco.repo.security.permissions.PermissionEntry;
@@ -129,8 +131,10 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
private PolicyComponent policyComponent; private PolicyComponent policyComponent;
private AclDaoComponent aclDaoComponent; private AclDaoComponent aclDaoComponent;
private PermissionReference allPermissionReference;
/* /**
* Standard spring construction. * Standard spring construction.
*/ */
public PermissionServiceImpl() public PermissionServiceImpl()
@@ -142,46 +146,89 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
// Inversion of control // Inversion of control
// //
/**
* Set the dictionary service
* @param dictionaryService
*/
public void setDictionaryService(DictionaryService dictionaryService) public void setDictionaryService(DictionaryService dictionaryService)
{ {
this.dictionaryService = dictionaryService; this.dictionaryService = dictionaryService;
} }
/**
* Set the permissions model dao
*
* @param modelDAO
*/
public void setModelDAO(ModelDAO modelDAO) public void setModelDAO(ModelDAO modelDAO)
{ {
this.modelDAO = modelDAO; this.modelDAO = modelDAO;
} }
/**
* Set the node service.
*
* @param nodeService
*/
public void setNodeService(NodeService nodeService) public void setNodeService(NodeService nodeService)
{ {
this.nodeService = nodeService; this.nodeService = nodeService;
} }
/**
* Set the tenant service.
* @param tenantService
*/
public void setTenantService(TenantService tenantService) public void setTenantService(TenantService tenantService)
{ {
this.tenantService = tenantService; this.tenantService = tenantService;
} }
/**
* Set the permissions dao component
*
* @param permissionsDaoComponent
*/
public void setPermissionsDaoComponent(PermissionsDaoComponent permissionsDaoComponent) public void setPermissionsDaoComponent(PermissionsDaoComponent permissionsDaoComponent)
{ {
this.permissionsDaoComponent = permissionsDaoComponent; this.permissionsDaoComponent = permissionsDaoComponent;
} }
/**
* Set the authentication component.
*
* @param authenticationComponent
*/
public void setAuthenticationComponent(AuthenticationComponent authenticationComponent) public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
{ {
this.authenticationComponent = authenticationComponent; this.authenticationComponent = authenticationComponent;
} }
/**
* Set the authority service.
*
* @param authorityService
*/
public void setAuthorityService(AuthorityService authorityService) public void setAuthorityService(AuthorityService authorityService)
{ {
this.authorityService = authorityService; this.authorityService = authorityService;
} }
/**
* Set the dynamic authorities
*
* @param dynamicAuthorities
*/
public void setDynamicAuthorities(List<DynamicAuthority> dynamicAuthorities) public void setDynamicAuthorities(List<DynamicAuthority> dynamicAuthorities)
{ {
this.dynamicAuthorities = dynamicAuthorities; this.dynamicAuthorities = dynamicAuthorities;
} }
/**
* Set the ACL DAO component.
*
* @param aclDaoComponent
*/
public void setAclDaoComponent(AclDaoComponent aclDaoComponent) public void setAclDaoComponent(AclDaoComponent aclDaoComponent)
{ {
this.aclDaoComponent = aclDaoComponent; this.aclDaoComponent = aclDaoComponent;
@@ -198,11 +245,22 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
this.accessCache = accessCache; this.accessCache = accessCache;
} }
/**
* Set the policy component
*
* @param policyComponent
*/
public void setPolicyComponent(PolicyComponent policyComponent) public void setPolicyComponent(PolicyComponent policyComponent)
{ {
this.policyComponent = policyComponent; this.policyComponent = policyComponent;
} }
/**
* Cache clear on move node
*
* @param oldChildAssocRef
* @param newChildAssocRef
*/
public void onMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef) public void onMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef)
{ {
accessCache.clear(); accessCache.clear();
@@ -249,6 +307,8 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"), ContentModel.TYPE_BASE, new JavaBehaviour(this, "onMoveNode")); policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"), ContentModel.TYPE_BASE, new JavaBehaviour(this, "onMoveNode"));
allPermissionReference = getPermissionReference(ALL_PERMISSIONS);
} }
// //
@@ -374,14 +434,6 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return doAvmCan(nodeRef, permIn); return doAvmCan(nodeRef, permIn);
} }
// Allow permissions for nodes that do not exist
if (!nodeService.exists(nodeRef))
{
return AccessStatus.ALLOWED;
}
final PermissionReference perm; final PermissionReference perm;
if (permIn.equals(OLD_ALL_PERMISSIONS_REFERENCE)) if (permIn.equals(OLD_ALL_PERMISSIONS_REFERENCE))
{ {
@@ -392,20 +444,45 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
perm = permIn; perm = permIn;
} }
if(AuthenticationUtil.getCurrentEffectiveUserName() == null)
{
return AccessStatus.DENIED;
}
if(AuthenticationUtil.getCurrentEffectiveUserName().equals(AuthenticationUtil.getSystemUserName())) // Allow permissions for nodes that do not exist
if (!nodeService.exists(nodeRef))
{ {
return AccessStatus.ALLOWED; return AccessStatus.ALLOWED;
} }
// New ACLs
AccessControlListProperties properties = permissionsDaoComponent.getAccessControlListProperties(nodeRef);
if ((properties != null) && (properties.getAclType() != null) && (properties.getAclType() != ACLType.OLD))
{
QName typeQname = nodeService.getType(nodeRef);
Set<QName> aspectQNames = nodeService.getAspects(nodeRef);
PermissionContext context = new PermissionContext(typeQname);
context.getAspects().addAll(aspectQNames);
Authentication auth = AuthenticationUtil.getCurrentEffectiveAuthentication();
String user = AuthenticationUtil.getCurrentEffectiveUserName();
for (String dynamicAuthority : getDynamicAuthorities(auth, nodeRef, perm))
{
context.addDynamicAuthorityAssignment(user, dynamicAuthority);
}
return hasPermission(properties.getId(), context, perm);
}
if (AuthenticationUtil.getCurrentEffectiveUserName() == null)
{
return AccessStatus.DENIED;
}
if (AuthenticationUtil.getCurrentEffectiveUserName().equals(AuthenticationUtil.getSystemUserName()))
{
return AccessStatus.ALLOWED;
}
// Get the current authentications // Get the current authentications
// Use the smart authentication cache to improve permissions performance // Use the smart authentication cache to improve permissions performance
Authentication auth = AuthenticationUtil.getCurrentEffectiveAuthentication(); Authentication auth = AuthenticationUtil.getCurrentEffectiveAuthentication();
final Set<String> authorisations = getAuthorisations(auth, nodeRef); final Set<String> authorisations = getAuthorisations(auth, nodeRef, perm);
// If the node does not support the given permission there is no point // If the node does not support the given permission there is no point
// doing the test // doing the test
@@ -494,7 +571,8 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return hasPermission(aclID, context, getPermissionReference(permission)); return hasPermission(aclID, context, getPermissionReference(permission));
} }
public AccessStatus hasPermission(Long aclId, PermissionContext context, PermissionReference permission)
private AccessStatus hasPermission(Long aclId, PermissionContext context, PermissionReference permission)
{ {
if (aclId == null) if (aclId == null)
{ {
@@ -506,16 +584,16 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return AccessStatus.DENIED; return AccessStatus.DENIED;
} }
if(AuthenticationUtil.getCurrentEffectiveUserName() == null) if (AuthenticationUtil.getCurrentEffectiveUserName() == null)
{ {
return AccessStatus.DENIED; return AccessStatus.DENIED;
} }
if(AuthenticationUtil.getCurrentEffectiveUserName().equals(AuthenticationUtil.getSystemUserName())) if (AuthenticationUtil.getCurrentEffectiveUserName().equals(AuthenticationUtil.getSystemUserName()))
{ {
return AccessStatus.ALLOWED; return AccessStatus.ALLOWED;
} }
// Get the current authentications // Get the current authentications
// Use the smart authentication cache to improve permissions performance // Use the smart authentication cache to improve permissions performance
Authentication auth = AuthenticationUtil.getCurrentEffectiveAuthentication(); Authentication auth = AuthenticationUtil.getCurrentEffectiveAuthentication();
@@ -529,10 +607,17 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
// If the node does not support the given permission there is no point // If the node does not support the given permission there is no point
// doing the test // doing the test
QName typeQname = context.getType(); final QName typeQname = context.getType();
Set<QName> aspectQNames = context.getAspects(); final Set<QName> aspectQNames = context.getAspects();
Set<PermissionReference> available = modelDAO.getAllPermissions(typeQname, aspectQNames); Set<PermissionReference> available = AuthenticationUtil.runAs(new RunAsWork<Set<PermissionReference>>()
{
public Set<PermissionReference> doWork() throws Exception
{
return modelDAO.getAllPermissions(typeQname, aspectQNames);
}
}, AuthenticationUtil.getSystemUserName());
available.add(getAllPermissionReference()); available.add(getAllPermissionReference());
available.add(OLD_ALL_PERMISSIONS_REFERENCE); available.add(OLD_ALL_PERMISSIONS_REFERENCE);
@@ -555,22 +640,40 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
if (context.getStoreAcl() == null) if (context.getStoreAcl() == null)
{ {
AclTest aclTest = new AclTest(permission, typeQname, aspectQNames); AclTest aclTest = new AclTest(permission, typeQname, aspectQNames);
result = aclTest.evaluate(authorisations, aclId); result = aclTest.evaluate(authorisations, aclId, context);
} }
else else
{ {
Set<String> storeAuthorisations = getAuthorisations(auth, (PermissionContext)null); Set<String> storeAuthorisations = getAuthorisations(auth, (PermissionContext) null);
AclTest aclTest = new AclTest(permission, typeQname, aspectQNames); AclTest aclTest = new AclTest(permission, typeQname, aspectQNames);
result = aclTest.evaluate(authorisations, aclId) && aclTest.evaluate(storeAuthorisations, context.getStoreAcl()); result = aclTest.evaluate(authorisations, aclId, context) && aclTest.evaluate(storeAuthorisations, context.getStoreAcl(), context);
} }
AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED;
return status; return status;
} }
/**
* Control permissions cache - only used when we do old style permission evaluations
* - which should only be in DM stores where no permissions have been set
*
* @author andyh
*
*/
enum CacheType enum CacheType
{ {
HAS_PERMISSION, SINGLE_PERMISSION, SINGLE_PERMISSION_GLOBAL; /**
* cache full check
*/
HAS_PERMISSION,
/**
* Cache single permission check
*/
SINGLE_PERMISSION,
/**
* Cache single permission check for global permission checks
*/
SINGLE_PERMISSION_GLOBAL;
} }
/** /**
@@ -591,11 +694,10 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* Get the authorisations for the currently authenticated user * Get the authorisations for the currently authenticated user
* *
* @param auth * @param auth
* @return * @return the set of authorisations
*/ */
private Set<String> getAuthorisations(Authentication auth, NodeRef nodeRef) private Set<String> getAuthorisations(Authentication auth, NodeRef nodeRef, PermissionReference required)
{ {
nodeRef = tenantService.getName(nodeRef);
HashSet<String> auths = new HashSet<String>(); HashSet<String> auths = new HashSet<String>();
// No authenticated user then no permissions // No authenticated user then no permissions
@@ -605,33 +707,53 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
} }
// TODO: Refactor and use the authentication service for this. // TODO: Refactor and use the authentication service for this.
User user = (User) auth.getPrincipal(); User user = (User) auth.getPrincipal();
String username = user.getUsername(); String username = user.getUsername();
auths.add(username); auths.add(username);
if (tenantService.getBaseNameUser(username).equalsIgnoreCase(PermissionService.GUEST_AUTHORITY)) if (tenantService.getBaseNameUser(username).equalsIgnoreCase(PermissionService.GUEST_AUTHORITY))
{ {
auths.add(PermissionService.GUEST_AUTHORITY); auths.add(PermissionService.GUEST_AUTHORITY);
} }
for (GrantedAuthority authority : auth.getAuthorities()) for (GrantedAuthority authority : auth.getAuthorities())
{ {
auths.add(authority.getAuthority()); auths.add(authority.getAuthority());
} }
auths.addAll(getDynamicAuthorities(auth, nodeRef, required));
auths.addAll(authorityService.getAuthorities());
return auths;
}
private Set<String> getDynamicAuthorities(Authentication auth, NodeRef nodeRef, PermissionReference required)
{
HashSet<String> auths = new HashSet<String>();
if (auth == null)
{
return auths;
}
User user = (User) auth.getPrincipal();
String username = user.getUsername();
nodeRef = tenantService.getName(nodeRef);
if (nodeRef != null) if (nodeRef != null)
{ {
if (dynamicAuthorities != null) if (dynamicAuthorities != null)
{ {
for (DynamicAuthority da : dynamicAuthorities) for (DynamicAuthority da : dynamicAuthorities)
{ {
if (da.hasAuthority(nodeRef, username)) Set<PermissionReference> requiredFor = da.requiredFor();
if ((requiredFor == null) || (requiredFor.contains(required)))
{ {
auths.add(da.getAuthority()); if (da.hasAuthority(nodeRef, username))
{
auths.add(da.getAuthority());
}
} }
} }
} }
} }
auths.addAll(authorityService.getAuthorities());
return auths; return auths;
} }
@@ -688,7 +810,8 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
deletePermission(storeRef, authority, getPermissionReference(perm)); deletePermission(storeRef, authority, getPermissionReference(perm));
} }
public void deletePermission(StoreRef storeRef, String authority, PermissionReference perm)
private void deletePermission(StoreRef storeRef, String authority, PermissionReference perm)
{ {
permissionsDaoComponent.deletePermission(storeRef, authority, perm); permissionsDaoComponent.deletePermission(storeRef, authority, perm);
accessCache.clear(); accessCache.clear();
@@ -706,7 +829,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
setPermission(storeRef, authority, getPermissionReference(perm), allow); setPermission(storeRef, authority, getPermissionReference(perm), allow);
} }
public void setPermission(StoreRef storeRef, String authority, PermissionReference permission, boolean allow) private void setPermission(StoreRef storeRef, String authority, PermissionReference permission, boolean allow)
{ {
permissionsDaoComponent.setPermission(storeRef, authority, permission, allow); permissionsDaoComponent.setPermission(storeRef, authority, permission, allow);
accessCache.clear(); accessCache.clear();
@@ -736,7 +859,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
deletePermission(nodeRef, authority, permission); deletePermission(nodeRef, authority, permission);
} }
public void deletePermission(NodeRef nodeRef, String authority, PermissionReference perm) private void deletePermission(NodeRef nodeRef, String authority, PermissionReference perm)
{ {
permissionsDaoComponent.deletePermission(tenantService.getName(nodeRef), authority, perm); permissionsDaoComponent.deletePermission(tenantService.getName(nodeRef), authority, perm);
accessCache.clear(); accessCache.clear();
@@ -748,7 +871,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
accessCache.clear(); accessCache.clear();
} }
public void setPermission(NodeRef nodeRef, String authority, PermissionReference perm, boolean allow) private void setPermission(NodeRef nodeRef, String authority, PermissionReference perm, boolean allow)
{ {
permissionsDaoComponent.setPermission(tenantService.getName(nodeRef), authority, perm, allow); permissionsDaoComponent.setPermission(tenantService.getName(nodeRef), authority, perm, allow);
accessCache.clear(); accessCache.clear();
@@ -756,14 +879,14 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
public void setPermission(PermissionEntry permissionEntry) public void setPermission(PermissionEntry permissionEntry)
{ {
// TODO - not MT-enabled nodeRef - currently only used by tests // TODO - not MT-enabled nodeRef - currently only used by tests
permissionsDaoComponent.setPermission(permissionEntry); permissionsDaoComponent.setPermission(permissionEntry);
accessCache.clear(); accessCache.clear();
} }
public void setPermission(NodePermissionEntry nodePermissionEntry) public void setPermission(NodePermissionEntry nodePermissionEntry)
{ {
// TODO - not MT-enabled nodeRef- currently only used by tests // TODO - not MT-enabled nodeRef- currently only used by tests
permissionsDaoComponent.setPermission(nodePermissionEntry); permissionsDaoComponent.setPermission(nodePermissionEntry);
accessCache.clear(); accessCache.clear();
} }
@@ -789,7 +912,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
public PermissionReference getAllPermissionReference() public PermissionReference getAllPermissionReference()
{ {
return getPermissionReference(ALL_PERMISSIONS); return allPermissionReference;
} }
public String getPermission(PermissionReference permissionReference) public String getPermission(PermissionReference permissionReference)
@@ -922,7 +1045,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* *
* @param authorisations * @param authorisations
* @param nodeRef * @param nodeRef
* @return * @return true if allowed
*/ */
boolean evaluate(Set<String> authorisations, NodeRef nodeRef) boolean evaluate(Set<String> authorisations, NodeRef nodeRef)
{ {
@@ -937,7 +1060,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* @param nodeRef * @param nodeRef
* @param denied * @param denied
* @param recursiveIn * @param recursiveIn
* @return * @return true if allowed
*/ */
boolean evaluate(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied, MutableBoolean recursiveIn) boolean evaluate(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied, MutableBoolean recursiveIn)
{ {
@@ -1063,10 +1186,10 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return success; return success;
} }
public boolean hasSinglePermission(Set<String> authorisations, NodeRef nodeRef) boolean hasSinglePermission(Set<String> authorisations, NodeRef nodeRef)
{ {
nodeRef = tenantService.getName(nodeRef); nodeRef = tenantService.getName(nodeRef);
Serializable key = generateKey(authorisations, nodeRef, this.required, CacheType.SINGLE_PERMISSION_GLOBAL); Serializable key = generateKey(authorisations, nodeRef, this.required, CacheType.SINGLE_PERMISSION_GLOBAL);
AccessStatus status = accessCache.get(key); AccessStatus status = accessCache.get(key);
@@ -1089,10 +1212,10 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
} }
public boolean hasSinglePermission(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied) boolean hasSinglePermission(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied)
{ {
nodeRef = tenantService.getName(nodeRef); nodeRef = tenantService.getName(nodeRef);
// Add any denied permission to the denied list - these can not // Add any denied permission to the denied list - these can not
// then // then
// be used to given authentication. // be used to given authentication.
@@ -1179,7 +1302,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* Check if we have a global permission * Check if we have a global permission
* *
* @param authorisations * @param authorisations
* @return * @return true if allowed
*/ */
private boolean checkGlobalPermissions(Set<String> authorisations) private boolean checkGlobalPermissions(Set<String> authorisations)
{ {
@@ -1197,7 +1320,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* Get the list of permissions denied for this node. * Get the list of permissions denied for this node.
* *
* @param nodeRef * @param nodeRef
* @return * @return the list of denied permissions
*/ */
Set<Pair<String, PermissionReference>> getDenied(NodeRef nodeRef) Set<Pair<String, PermissionReference>> getDenied(NodeRef nodeRef)
{ {
@@ -1249,7 +1372,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* @param authorisations * @param authorisations
* @param nodeRef * @param nodeRef
* @param denied * @param denied
* @return * @return true if the check is required
*/ */
boolean checkRequired(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied) boolean checkRequired(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied)
{ {
@@ -1284,7 +1407,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* the set of authorities * the set of authorities
* @param denied - * @param denied -
* the set of denied permissions/authority pais * the set of denied permissions/authority pais
* @return * @return true if granted
*/ */
private boolean isGranted(PermissionEntry pe, Set<String> authorisations, Set<Pair<String, PermissionReference>> denied) private boolean isGranted(PermissionEntry pe, Set<String> authorisations, Set<Pair<String, PermissionReference>> denied)
{ {
@@ -1426,13 +1549,10 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* @param nodeRef * @param nodeRef
* @param denied * @param denied
* @param recursiveIn * @param recursiveIn
* @return * @return true if granted
*/ */
boolean evaluate(Set<String> authorisations, Long aclId) boolean evaluate(Set<String> authorisations, Long aclId, PermissionContext context)
{ {
// Do we defer our required test to a parent (yes if not null)
MutableBoolean recursiveOut = null;
// Start out true and "and" all other results // Start out true and "and" all other results
boolean success = true; boolean success = true;
@@ -1442,7 +1562,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
{ {
// We have to do the test as no parent will help us out // We have to do the test as no parent will help us out
success &= hasSinglePermission(authorisations, aclId); success &= hasSinglePermission(authorisations, aclId, context);
if (!success) if (!success)
{ {
@@ -1455,7 +1575,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
{ {
// Build a new test // Build a new test
AclTest nt = new AclTest(pr, typeQName, aspectQNames); AclTest nt = new AclTest(pr, typeQName, aspectQNames);
success &= nt.evaluate(authorisations, aclId); success &= nt.evaluate(authorisations, aclId, context);
if (!success) if (!success)
{ {
return false; return false;
@@ -1465,7 +1585,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return success; return success;
} }
public boolean hasSinglePermission(Set<String> authorisations, Long aclId) boolean hasSinglePermission(Set<String> authorisations, Long aclId, PermissionContext context)
{ {
// Check global permission // Check global permission
@@ -1474,7 +1594,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return true; return true;
} }
return checkRequired(authorisations, aclId); return checkRequired(authorisations, aclId, context);
} }
@@ -1482,7 +1602,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* Check if we have a global permission * Check if we have a global permission
* *
* @param authorisations * @param authorisations
* @return * @return true if granted
*/ */
private boolean checkGlobalPermissions(Set<String> authorisations) private boolean checkGlobalPermissions(Set<String> authorisations)
{ {
@@ -1502,9 +1622,9 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* @param authorisations * @param authorisations
* @param nodeRef * @param nodeRef
* @param denied * @param denied
* @return * @return true if a check is required
*/ */
boolean checkRequired(Set<String> authorisations, Long aclId) boolean checkRequired(Set<String> authorisations, Long aclId, PermissionContext context)
{ {
AccessControlList acl = aclDaoComponent.getAccessControlList(aclId); AccessControlList acl = aclDaoComponent.getAccessControlList(aclId);
@@ -1519,7 +1639,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
// We could have other voting style mechanisms here // We could have other voting style mechanisms here
for (AccessControlEntry ace : acl.getEntries()) for (AccessControlEntry ace : acl.getEntries())
{ {
if (isGranted(ace, authorisations, denied)) if (isGranted(ace, authorisations, denied, context))
{ {
return true; return true;
} }
@@ -1538,14 +1658,39 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
* the set of authorities * the set of authorities
* @param denied - * @param denied -
* the set of denied permissions/authority pais * the set of denied permissions/authority pais
* @return * @return true if granted
*/ */
private boolean isGranted(AccessControlEntry ace, Set<String> authorisations, Set<Pair<String, PermissionReference>> denied) private boolean isGranted(AccessControlEntry ace, Set<String> authorisations, Set<Pair<String, PermissionReference>> denied, PermissionContext context)
{ {
// If the permission entry denies then we just deny // If the permission entry denies then we just deny
if (ace.getAccessStatus() == AccessStatus.DENIED) if (ace.getAccessStatus() == AccessStatus.DENIED)
{ {
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), ace.getPermission())); denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), ace.getPermission()));
Set<PermissionReference> granters = modelDAO.getGrantingPermissions(ace.getPermission());
for (PermissionReference granter : granters)
{
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), granter));
}
// All the things granted by this permission must be
// denied
Set<PermissionReference> grantees = modelDAO.getGranteePermissions(ace.getPermission());
for (PermissionReference grantee : grantees)
{
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), grantee));
}
// All permission excludes all permissions available for
// the node.
if (ace.getPermission().equals(getAllPermissionReference()) || ace.getPermission().equals(OLD_ALL_PERMISSIONS_REFERENCE))
{
for (PermissionReference deny : modelDAO.getAllPermissions(context.getType(), context.getAspects()))
{
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), deny));
}
}
return false; return false;
} }
@@ -1611,7 +1756,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
// If the permission has a match in both the authorities and // If the permission has a match in both the authorities and
// granters list it is allowed // granters list it is allowed
// It applies to the current user and it is granted // It applies to the current user and it is granted
if (authorisations.contains(pe.getAuthority()) && granters.contains(pe.getPermissionReference())) if (granters.contains(pe.getPermissionReference()) && authorisations.contains(pe.getAuthority()))
{ {
{ {
return true; return true;

View File

@@ -35,8 +35,10 @@ import net.sf.acegisecurity.GrantedAuthority;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.model.filefolder.FileFolderServiceImpl; import org.alfresco.repo.model.filefolder.FileFolderServiceImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessControlEntry;
import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.security.permissions.PermissionEntry; import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AccessStatus;
@@ -135,6 +137,9 @@ public class PermissionServiceTest extends AbstractPermissionTest
public Object doWork() throws Exception public Object doWork() throws Exception
{ {
assertEquals("andy", AuthenticationUtil.getCurrentRealUserName());
assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName());
assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.ALLOWED); assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.ALLOWED);
assertEquals("andy", AuthenticationUtil.getCurrentRealUserName()); assertEquals("andy", AuthenticationUtil.getCurrentRealUserName());
@@ -318,6 +323,24 @@ public class PermissionServiceTest extends AbstractPermissionTest
// testUnset(); // testUnset();
} }
private void printPermissions(NodeRef nodeRef, String path)
{
Long id = nodeDaoService.getNode(nodeRef).getAccessControlList().getId();
System.out.println(path + " has "+id);
for(AccessControlEntry entry : aclDaoComponent.getAccessControlList(id).getEntries())
{
System.out.println("\t\t "+id+" "+entry);
}
List<ChildAssociationRef> children = nodeService.getChildAssocs(nodeRef);
for(ChildAssociationRef child: children)
{
String newPath = path+"/"+child.getQName();
printPermissions(child.getChildRef(), newPath);
}
}
public void testSetNodePermissionEntry() public void testSetNodePermissionEntry()
{ {
runAs("andy"); runAs("andy");
@@ -1740,10 +1763,14 @@ public class PermissionServiceTest extends AbstractPermissionTest
assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ_CHILDREN)) == AccessStatus.ALLOWED); assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ_CHILDREN)) == AccessStatus.ALLOWED);
assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ_CONTENT)) == AccessStatus.ALLOWED); assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ_CONTENT)) == AccessStatus.ALLOWED);
//printPermissions(rootNodeRef, "/");
permissionService.deletePermission(new SimplePermissionEntry(n2, getPermission(PermissionService.READ_CHILDREN), "andy", AccessStatus.ALLOWED)); permissionService.deletePermission(new SimplePermissionEntry(n2, getPermission(PermissionService.READ_CHILDREN), "andy", AccessStatus.ALLOWED));
permissionService.deletePermission(new SimplePermissionEntry(n2, getPermission(PermissionService.READ_PROPERTIES), "andy", AccessStatus.ALLOWED)); permissionService.deletePermission(new SimplePermissionEntry(n2, getPermission(PermissionService.READ_PROPERTIES), "andy", AccessStatus.ALLOWED));
permissionService.deletePermission(new SimplePermissionEntry(n2, getPermission(PermissionService.READ_CONTENT), "andy", AccessStatus.ALLOWED)); permissionService.deletePermission(new SimplePermissionEntry(n2, getPermission(PermissionService.READ_CONTENT), "andy", AccessStatus.ALLOWED));
printPermissions(rootNodeRef, "/");
runAs("andy"); runAs("andy");
assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ)) == AccessStatus.ALLOWED); assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ)) == AccessStatus.ALLOWED);
assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ_PROPERTIES)) == AccessStatus.ALLOWED); assertFalse(permissionService.hasPermission(n2, getPermission(PermissionService.READ_PROPERTIES)) == AccessStatus.ALLOWED);

View File

@@ -27,6 +27,7 @@ package org.alfresco.repo.security.permissions.impl;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.repo.security.permissions.AccessControlListProperties;
import org.alfresco.repo.security.permissions.NodePermissionEntry; import org.alfresco.repo.security.permissions.NodePermissionEntry;
import org.alfresco.repo.security.permissions.PermissionEntry; import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference; import org.alfresco.repo.security.permissions.PermissionReference;
@@ -39,25 +40,27 @@ import org.alfresco.service.cmr.security.AccessPermission;
* *
* @author andyh * @author andyh
*/ */
public interface PermissionsDaoComponent public interface PermissionsDaoComponent
{ {
/** /**
* Get the permissions that have been set on a given node. * Get the permissions that have been set on a given node.
* *
* @param nodeRef * @param nodeRef
* @return * @return the node permission entry
*/ */
public NodePermissionEntry getPermissions(NodeRef nodeRef); public NodePermissionEntry getPermissions(NodeRef nodeRef);
/** /**
* Delete the access control list and all access control entries for the node. * Delete the access control list and all access control entries for the node.
* *
* @param nodeRef the node for which to delete permission * @param nodeRef
* the node for which to delete permission
*/ */
public void deletePermissions(NodeRef nodeRef); public void deletePermissions(NodeRef nodeRef);
/** /**
* Remove all permissions for the specified authority * Remove all permissions for the specified authority
*
* @param authority * @param authority
*/ */
public void deletePermissions(String authority); public void deletePermissions(String authority);
@@ -65,25 +68,29 @@ public interface PermissionsDaoComponent
/** /**
* Delete permission entries for the given node and authority * Delete permission entries for the given node and authority
* *
* @param nodeRef the node to query against * @param nodeRef
* @param authority the specific authority to query against * the node to query against
* @param authority
* the specific authority to query against
*/ */
public void deletePermissions(NodeRef nodeRef, String authority); public void deletePermissions(NodeRef nodeRef, String authority);
/** /**
* Delete as single permission entry, if a match is found. * Delete as single permission entry, if a match is found. This deleted one permission on the node. It does not
* This deleted one permission on the node. It does not affect the persistence of any other permissions. * affect the persistence of any other permissions.
* *
* @param nodeRef the node with the access control list * @param nodeRef
* @param authority the specific authority to look for * the node with the access control list
* @param permission the permission to look for * @param authority
* the specific authority to look for
* @param permission
* the permission to look for
*/ */
public void deletePermission(NodeRef nodeRef, String authority, PermissionReference permission); public void deletePermission(NodeRef nodeRef, String authority, PermissionReference permission);
/** /**
* Set a permission on a node. * Set a permission on a node. If the node has no permissions set then a default node permission (allowing
* If the node has no permissions set then a default node permission (allowing inheritance) will be created to * inheritance) will be created to contain the permission entry.
* contain the permission entry.
* *
* @param nodeRef * @param nodeRef
* @param authority * @param authority
@@ -122,7 +129,7 @@ public interface PermissionsDaoComponent
*/ */
public boolean getInheritParentPermissions(NodeRef nodeRef); public boolean getInheritParentPermissions(NodeRef nodeRef);
/** /**
* Get all the permissions set for the given authority * Get all the permissions set for the given authority
* *
* @param authority * @param authority
@@ -132,9 +139,13 @@ public interface PermissionsDaoComponent
/** /**
* Find nodes which have the given permisson for the given authority * Find nodes which have the given permisson for the given authority
* @param authority - the authority to match *
* @param permission - the permission to match * @param authority -
* @param allow - true to match allow, false to match deny * the authority to match
* @param permission -
* the permission to match
* @param allow -
* true to match allow, false to match deny
* @return - the set of matching nodes * @return - the set of matching nodes
*/ */
public Set<NodeRef> findNodeByPermission(String authority, PermissionReference permission, boolean allow); public Set<NodeRef> findNodeByPermission(String authority, PermissionReference permission, boolean allow);
@@ -175,8 +186,18 @@ public interface PermissionsDaoComponent
/** /**
* Get permission masks set on a store * Get permission masks set on a store
*
* @param storeRef * @param storeRef
* @return * @return the node permission entry
*/ */
public NodePermissionEntry getPermissions(StoreRef storeRef); public NodePermissionEntry getPermissions(StoreRef storeRef);
/**
* Get the properties for the access control list
*
* @param nodeRef
* @return the properties for the access control list
*/
public AccessControlListProperties getAccessControlListProperties(NodeRef nodeRef);
} }

View File

@@ -46,6 +46,13 @@ public final class SimplePermissionReference extends AbstractPermissionReference
private static HashMap<QName, HashMap<String, SimplePermissionReference>> instances = new HashMap<QName, HashMap<String, SimplePermissionReference>>(); private static HashMap<QName, HashMap<String, SimplePermissionReference>> instances = new HashMap<QName, HashMap<String, SimplePermissionReference>>();
/**
* Factory method to create simple permission refrences
*
* @param qName
* @param name
* @return a simple permission reference
*/
public static SimplePermissionReference getPermissionReference(QName qName, String name) public static SimplePermissionReference getPermissionReference(QName qName, String name)
{ {
lock.readLock().lock(); lock.readLock().lock();
@@ -101,8 +108,7 @@ public final class SimplePermissionReference extends AbstractPermissionReference
private String name; private String name;
// TODO: make protected protected SimplePermissionReference(QName qName, String name)
public SimplePermissionReference(QName qName, String name)
{ {
super(); super();
this.qName = qName; this.qName = qName;

View File

@@ -59,6 +59,12 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
/**
* Enforce permission after the method calll
*
* @author andyh
*
*/
public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider, InitializingBean public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider, InitializingBean
{ {
private static Log log = LogFactory.getLog(ACLEntryAfterInvocationProvider.class); private static Log log = LogFactory.getLog(ACLEntryAfterInvocationProvider.class);
@@ -74,6 +80,9 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
private int maxPermissionChecks; private int maxPermissionChecks;
private long maxPermissionCheckTimeMillis; private long maxPermissionCheckTimeMillis;
/**
* Default constructor
*/
public ACLEntryAfterInvocationProvider() public ACLEntryAfterInvocationProvider()
{ {
super(); super();
@@ -81,51 +90,92 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
maxPermissionCheckTimeMillis = Long.MAX_VALUE; maxPermissionCheckTimeMillis = Long.MAX_VALUE;
} }
/**
* Set the permission service.
*
* @param permissionService
*/
public void setPermissionService(PermissionService permissionService) public void setPermissionService(PermissionService permissionService)
{ {
this.permissionService = permissionService; this.permissionService = permissionService;
} }
/**
* Get the permission service.
* @return - the permission service
*/
public PermissionService getPermissionService() public PermissionService getPermissionService()
{ {
return permissionService; return permissionService;
} }
/**
* Get the namespace prefix resolver
* @return the namespace prefix resolver
*/
public NamespacePrefixResolver getNamespacePrefixResolver() public NamespacePrefixResolver getNamespacePrefixResolver()
{ {
return nspr; return nspr;
} }
/**
* Set the namespace prefix resolver
* @param nspr
*/
public void setNamespacePrefixResolver(NamespacePrefixResolver nspr) public void setNamespacePrefixResolver(NamespacePrefixResolver nspr)
{ {
this.nspr = nspr; this.nspr = nspr;
} }
/**
* Get the node service
* @return the node service
*/
public NodeService getNodeService() public NodeService getNodeService()
{ {
return nodeService; return nodeService;
} }
/**
* Set the node service
* @param nodeService
*/
public void setNodeService(NodeService nodeService) public void setNodeService(NodeService nodeService)
{ {
this.nodeService = nodeService; this.nodeService = nodeService;
} }
/**
* Get the authentication service
* @return the authentication service
*/
public AuthenticationService getAuthenticationService() public AuthenticationService getAuthenticationService()
{ {
return authenticationService; return authenticationService;
} }
/**
* Set the authentication service
* @param authenticationService
*/
public void setAuthenticationService(AuthenticationService authenticationService) public void setAuthenticationService(AuthenticationService authenticationService)
{ {
this.authenticationService = authenticationService; this.authenticationService = authenticationService;
} }
/**
* Set the max number of permission checks
* @param maxPermissionChecks
*/
public void setMaxPermissionChecks(int maxPermissionChecks) public void setMaxPermissionChecks(int maxPermissionChecks)
{ {
this.maxPermissionChecks = maxPermissionChecks; this.maxPermissionChecks = maxPermissionChecks;
} }
/**
* Set the max time for permission checks
* @param maxPermissionCheckTimeMillis
*/
public void setMaxPermissionCheckTimeMillis(long maxPermissionCheckTimeMillis) public void setMaxPermissionCheckTimeMillis(long maxPermissionCheckTimeMillis)
{ {
this.maxPermissionCheckTimeMillis = maxPermissionCheckTimeMillis; this.maxPermissionCheckTimeMillis = maxPermissionCheckTimeMillis;
@@ -261,7 +311,8 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
} }
public NodeRef decide(
private NodeRef decide(
Authentication authentication, Authentication authentication,
Object object, Object object,
ConfigAttributeDefinition config, ConfigAttributeDefinition config,
@@ -304,7 +355,7 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
return returnedObject; return returnedObject;
} }
public FileInfo decide( private FileInfo decide(
Authentication authentication, Authentication authentication,
Object object, Object object,
ConfigAttributeDefinition config, ConfigAttributeDefinition config,
@@ -336,7 +387,7 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
return definitions; return definitions;
} }
public ChildAssociationRef decide(Authentication authentication, Object object, ConfigAttributeDefinition config, private ChildAssociationRef decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
ChildAssociationRef returnedObject) throws AccessDeniedException ChildAssociationRef returnedObject) throws AccessDeniedException
{ {
@@ -376,7 +427,7 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
return returnedObject; return returnedObject;
} }
public ResultSet decide(Authentication authentication, Object object, ConfigAttributeDefinition config, private ResultSet decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
ResultSet returnedObject) throws AccessDeniedException ResultSet returnedObject) throws AccessDeniedException
{ {
@@ -473,7 +524,7 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
return filteringResultSet; return filteringResultSet;
} }
public Collection decide(Authentication authentication, Object object, ConfigAttributeDefinition config, private Collection decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
Collection returnedObject) throws AccessDeniedException Collection returnedObject) throws AccessDeniedException
{ {
@@ -594,7 +645,7 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
return returnedObject; return returnedObject;
} }
public Object[] decide(Authentication authentication, Object object, ConfigAttributeDefinition config, private Object[] decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
Object[] returnedObject) throws AccessDeniedException Object[] returnedObject) throws AccessDeniedException
{ {
@@ -742,7 +793,7 @@ public class ACLEntryAfterInvocationProvider implements AfterInvocationProvider,
QName qName = QName.createQName(qNameString, nspr); QName qName = QName.createQName(qNameString, nspr);
required = new SimplePermissionReference(qName, permissionString); required = SimplePermissionReference.getPermissionReference(qName, permissionString);
} }
} }
} }

View File

@@ -77,6 +77,10 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
private AuthorityService authorityService; private AuthorityService authorityService;
/**
* Default constructor
*
*/
public ACLEntryVoter() public ACLEntryVoter()
{ {
super(); super();
@@ -85,46 +89,82 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
// ~ Methods // ~ Methods
// ================================================================ // ================================================================
/**
* Set the permission service
* @param permissionService
*/
public void setPermissionService(PermissionService permissionService) public void setPermissionService(PermissionService permissionService)
{ {
this.permissionService = permissionService; this.permissionService = permissionService;
} }
/**
* Get the permission service
* @return the permission service
*/
public PermissionService getPermissionService() public PermissionService getPermissionService()
{ {
return permissionService; return permissionService;
} }
/**
* Get the name space prefix resolver
* @return the name space prefix resolver
*/
public NamespacePrefixResolver getNamespacePrefixResolver() public NamespacePrefixResolver getNamespacePrefixResolver()
{ {
return nspr; return nspr;
} }
/**
* Set the name space prefix resolver
* @param nspr
*/
public void setNamespacePrefixResolver(NamespacePrefixResolver nspr) public void setNamespacePrefixResolver(NamespacePrefixResolver nspr)
{ {
this.nspr = nspr; this.nspr = nspr;
} }
/**
* Get the node service
* @return the node service
*/
public NodeService getNodeService() public NodeService getNodeService()
{ {
return nodeService; return nodeService;
} }
/**
* Set the node service
* @param nodeService
*/
public void setNodeService(NodeService nodeService) public void setNodeService(NodeService nodeService)
{ {
this.nodeService = nodeService; this.nodeService = nodeService;
} }
/**
* Get the authentication service
* @return the authentication service
*/
public AuthenticationService getAuthenticationService() public AuthenticationService getAuthenticationService()
{ {
return authenticationService; return authenticationService;
} }
/**
* Set the authentication service
* @param authenticationService
*/
public void setAuthenticationService(AuthenticationService authenticationService) public void setAuthenticationService(AuthenticationService authenticationService)
{ {
this.authenticationService = authenticationService; this.authenticationService = authenticationService;
} }
/**
* Set the authority service
* @param authorityService
*/
public void setAuthorityService(AuthorityService authorityService) public void setAuthorityService(AuthorityService authorityService)
{ {
this.authorityService = authorityService; this.authorityService = authorityService;
@@ -434,7 +474,7 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
QName qName = QName.createQName(qNameString, nspr); QName qName = QName.createQName(qNameString, nspr);
required = new SimplePermissionReference(qName, permissionString); required = SimplePermissionReference.getPermissionReference(qName, permissionString);
} }
else if (typeString.equals(ACL_METHOD)) else if (typeString.equals(ACL_METHOD))
{ {

View File

@@ -71,7 +71,7 @@ public abstract class AbstractPermission extends AbstractPermissionReference imp
private Set<RequiredPermission> requiredPermissions = new HashSet<RequiredPermission>(); private Set<RequiredPermission> requiredPermissions = new HashSet<RequiredPermission>();
public AbstractPermission(QName typeQName) protected AbstractPermission(QName typeQName)
{ {
super(); super();
this.typeQName = typeQName; this.typeQName = typeQName;
@@ -134,11 +134,19 @@ public abstract class AbstractPermission extends AbstractPermissionReference imp
return name; return name;
} }
/**
* Get the required permissions
* @return the required permissions
*/
public final Set<RequiredPermission> getRequiredPermissions() public final Set<RequiredPermission> getRequiredPermissions()
{ {
return Collections.unmodifiableSet(requiredPermissions); return Collections.unmodifiableSet(requiredPermissions);
} }
/**
* Get the type for this permission
* @return the type
*/
public final QName getTypeQName() public final QName getTypeQName()
{ {
return typeQName; return typeQName;

View File

@@ -67,6 +67,10 @@ public class ModelPermissionEntry implements PermissionEntry, XMLModelInitialisa
private NodeRef nodeRef; private NodeRef nodeRef;
/**
* Create a permission model entry with the given node context
* @param nodeRef (may be null)
*/
public ModelPermissionEntry(NodeRef nodeRef) public ModelPermissionEntry(NodeRef nodeRef)
{ {
super(); super();
@@ -83,6 +87,10 @@ public class ModelPermissionEntry implements PermissionEntry, XMLModelInitialisa
return getRecipient(); return getRecipient();
} }
/**
* Synonym for authority
* @return recipient/authority
*/
public String getRecipient() public String getRecipient()
{ {
return recipient; return recipient;
@@ -145,6 +153,6 @@ public class ModelPermissionEntry implements PermissionEntry, XMLModelInitialisa
Element permissionReferenceElement = element.element(PERMISSION_REFERENCE); Element permissionReferenceElement = element.element(PERMISSION_REFERENCE);
QName typeQName = QName.createQName(permissionReferenceElement.attributeValue(TYPE), nspr); QName typeQName = QName.createQName(permissionReferenceElement.attributeValue(TYPE), nspr);
String name = permissionReferenceElement.attributeValue(NAME); String name = permissionReferenceElement.attributeValue(NAME);
permissionReference = new PermissionReferenceImpl(typeQName, name); permissionReference = PermissionReferenceImpl.getPermissionReference(typeQName, name);
} }
} }

View File

@@ -75,6 +75,11 @@ public class Permission extends AbstractPermission implements XMLModelInitialisa
private boolean requiresType; private boolean requiresType;
/**
* A permission for the given type
*
* @param typeQName
*/
public Permission(QName typeQName) public Permission(QName typeQName)
{ {
super(typeQName); super(typeQName);
@@ -141,25 +146,41 @@ public class Permission extends AbstractPermission implements XMLModelInitialisa
String grantedName = grantedToGroupsElement.attributeValue(GTG_NAME); String grantedName = grantedToGroupsElement.attributeValue(GTG_NAME);
grantedToGroups.add(new PermissionReferenceImpl(qName, grantedName)); grantedToGroups.add(PermissionReferenceImpl.getPermissionReference(qName, grantedName));
} }
} }
/**
* Default deny/allow for this permission
* @return the access status
*/
public AccessStatus getDefaultPermission() public AccessStatus getDefaultPermission()
{ {
return defaultPermission; return defaultPermission;
} }
/**
* Get the groups for which this permission is granted (by definition - filled in by the model API)
* @return the specifed groups
*/
public Set<PermissionReference> getGrantedToGroups() public Set<PermissionReference> getGrantedToGroups()
{ {
return Collections.unmodifiableSet(grantedToGroups); return Collections.unmodifiableSet(grantedToGroups);
} }
/**
* Should this permission be shown to the UI?
* @return return true if the permission be shown in the UI.
*/
public boolean isExposed() public boolean isExposed()
{ {
return isExposed; return isExposed;
} }
/**
* Does a node have to have the type/aspect for the permission to apply?
* @return true if a node must have the type/aspect for the permission to apply.
*/
public boolean isTypeRequired() public boolean isTypeRequired()
{ {
return requiresType; return requiresType;

View File

@@ -83,6 +83,10 @@ public final class PermissionGroup extends AbstractPermissionReference implement
private boolean requiresType; private boolean requiresType;
/**
* Permission group for the given type or aspect.
* @param container
*/
public PermissionGroup(QName container) public PermissionGroup(QName container)
{ {
super(); super();
@@ -160,11 +164,15 @@ public final class PermissionGroup extends AbstractPermissionReference implement
qName = container; qName = container;
} }
String refName = includePermissionGroupElement.attributeValue(PERMISSION_GROUP); String refName = includePermissionGroupElement.attributeValue(PERMISSION_GROUP);
PermissionReference permissionReference = new PermissionReferenceImpl(qName, refName); PermissionReference permissionReference = PermissionReferenceImpl.getPermissionReference(qName, refName);
includedPermissionGroups.add(permissionReference); includedPermissionGroups.add(permissionReference);
} }
} }
/**
* What permission groups are included in this one (for ease of definition)
* @return - the set of included permission from teh definitio
*/
public Set<PermissionReference> getIncludedPermissionGroups() public Set<PermissionReference> getIncludedPermissionGroups()
{ {
return Collections.unmodifiableSet(includedPermissionGroups); return Collections.unmodifiableSet(includedPermissionGroups);
@@ -175,6 +183,10 @@ public final class PermissionGroup extends AbstractPermissionReference implement
return name; return name;
} }
/**
* Does this permission group allow full control?
* @return true if this definition allows full control
*/
public boolean isAllowFullControl() public boolean isAllowFullControl()
{ {
return allowFullControl; return allowFullControl;
@@ -185,22 +197,37 @@ public final class PermissionGroup extends AbstractPermissionReference implement
return container; return container;
} }
/**
* Does this definition extend another (from a base type as defined in the DD)
* @return true if the permission is extended from another type
*/
public boolean isExtends() public boolean isExtends()
{ {
return extendz; return extendz;
} }
/**
* Get the class
* @return - the class
*/
public QName getTypeQName() public QName getTypeQName()
{ {
return type; return type;
} }
/**
* Expose in the UI?
* @return exposed -> true
*/
public boolean isExposed() public boolean isExposed()
{ {
return isExposed; return isExposed;
} }
/**
* Does a node have to have a the type for the permission to apply?
* @return true if a node has to have the type for the permission to apply.
*/
public boolean isTypeRequired() public boolean isTypeRequired()
{ {
return requiresType; return requiresType;

View File

@@ -26,15 +26,17 @@ package org.alfresco.repo.security.permissions.impl.model;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.Serializable;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.alfresco.repo.security.permissions.PermissionEntry; import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.repo.security.permissions.PermissionReference; import org.alfresco.repo.security.permissions.PermissionReference;
@@ -128,6 +130,10 @@ public class PermissionModel implements ModelDAO, InitializingBean
private Collection<QName> allAspects; private Collection<QName> allAspects;
/**
* Default constructor
*
*/
public PermissionModel() public PermissionModel()
{ {
super(); super();
@@ -135,16 +141,28 @@ public class PermissionModel implements ModelDAO, InitializingBean
// IOC // IOC
/**
* Set the model
* @param model
*/
public void setModel(String model) public void setModel(String model)
{ {
this.model = model; this.model = model;
} }
/**
* Set the dictionary service
* @param dictionaryService
*/
public void setDictionaryService(DictionaryService dictionaryService) public void setDictionaryService(DictionaryService dictionaryService)
{ {
this.dictionaryService = dictionaryService; this.dictionaryService = dictionaryService;
} }
/**
* Set the node service
* @param nodeService
*/
public void setNodeService(NodeService nodeService) public void setNodeService(NodeService nodeService)
{ {
this.nodeService = nodeService; this.nodeService = nodeService;
@@ -160,11 +178,12 @@ public class PermissionModel implements ModelDAO, InitializingBean
{ {
addPermissionModel(this.model); addPermissionModel(this.model);
} }
/** /**
* Adds a permission model * Adds a permission model
* *
* @param model path to the permission model to add * @param model
* path to the permission model to add
*/ */
public void addPermissionModel(String model) public void addPermissionModel(String model)
{ {
@@ -229,10 +248,10 @@ public class PermissionModel implements ModelDAO, InitializingBean
globalPermissions.add(globalPermission); globalPermissions.add(globalPermission);
} }
// Cache all aspect list // Cache all aspect list
allAspects = dictionaryService.getAllAspects(); allAspects = dictionaryService.getAllAspects();
} }
/* /*
@@ -263,11 +282,20 @@ public class PermissionModel implements ModelDAO, InitializingBean
} }
/**
* Set the default access status
* @return the default access status
*/
public AccessStatus getDefaultPermission() public AccessStatus getDefaultPermission()
{ {
return defaultPermission; return defaultPermission;
} }
/**
* Get the default acces status for the givne permission
* @param pr
* @return the access status
*/
public AccessStatus getDefaultPermission(PermissionReference pr) public AccessStatus getDefaultPermission(PermissionReference pr)
{ {
Permission p = permissionMap.get(pr); Permission p = permissionMap.get(pr);
@@ -286,6 +314,10 @@ public class PermissionModel implements ModelDAO, InitializingBean
return Collections.unmodifiableSet(globalPermissions); return Collections.unmodifiableSet(globalPermissions);
} }
/**
* Get the permission sets by type
* @return the permission sets by type
*/
public Map<QName, PermissionSet> getPermissionSets() public Map<QName, PermissionSet> getPermissionSets()
{ {
return Collections.unmodifiableMap(permissionSets); return Collections.unmodifiableMap(permissionSets);
@@ -408,14 +440,15 @@ public class PermissionModel implements ModelDAO, InitializingBean
{ {
if (pg.isTypeRequired() == typeRequired) if (pg.isTypeRequired() == typeRequired)
{ {
target.add(pg); target.add(SimplePermissionReference.getPermissionReference(pg.getQName(), pg.getName()));
} }
} }
else if (exposedOnly) else if (exposedOnly)
{ {
if (pg.isTypeRequired() == typeRequired) if (pg.isTypeRequired() == typeRequired)
{ {
target.add(getBasePermissionGroup(pg)); PermissionReference base = getBasePermissionGroup(pg);
target.add(SimplePermissionReference.getPermissionReference(base.getQName(), base.getName()));
} }
} }
} }
@@ -426,7 +459,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
{ {
if (p.isTypeRequired() == typeRequired) if (p.isTypeRequired() == typeRequired)
{ {
target.add(p); target.add(SimplePermissionReference.getPermissionReference(p.getQName(), p.getName()));
} }
} }
} }
@@ -440,7 +473,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
mergePermissions(target, aspect, exposedOnly, false); mergePermissions(target, aspect, exposedOnly, false);
} }
} }
public Set<PermissionReference> getAllPermissions(NodeRef nodeRef) public Set<PermissionReference> getAllPermissions(NodeRef nodeRef)
{ {
return getAllPermissionsImpl(nodeService.getType(nodeRef), nodeService.getAspects(nodeRef), false); return getAllPermissionsImpl(nodeService.getType(nodeRef), nodeService.getAspects(nodeRef), false);
@@ -459,11 +492,10 @@ public class PermissionModel implements ModelDAO, InitializingBean
private Set<PermissionReference> getAllPermissionsImpl(QName typeName, Set<QName> aspects, boolean exposedOnly) private Set<PermissionReference> getAllPermissionsImpl(QName typeName, Set<QName> aspects, boolean exposedOnly)
{ {
Set<PermissionReference> permissions = new LinkedHashSet<PermissionReference>(256, 1.0f); Set<PermissionReference> permissions = new LinkedHashSet<PermissionReference>(256, 1.0f);
ClassDefinition cd = dictionaryService.getClass(typeName); ClassDefinition cd = dictionaryService.getClass(typeName);
permissions.addAll(getAllPermissionsImpl(typeName, exposedOnly)); permissions.addAll(getAllPermissionsImpl(typeName, exposedOnly));
if (cd != null) if (cd != null)
{ {
Set<QName> defaultAspects = new HashSet<QName>(); Set<QName> defaultAspects = new HashSet<QName>();
@@ -491,7 +523,12 @@ public class PermissionModel implements ModelDAO, InitializingBean
Set<PermissionReference> granters = grantingPermissions.get(permissionReference); Set<PermissionReference> granters = grantingPermissions.get(permissionReference);
if (granters == null) if (granters == null)
{ {
granters = getGrantingPermissionsImpl(permissionReference); Set<PermissionReference> internal = getGrantingPermissionsImpl(permissionReference);
granters = new HashSet<PermissionReference>();
for (PermissionReference grantee : internal)
{
granters.add(SimplePermissionReference.getPermissionReference(grantee.getQName(), grantee.getName()));
}
granters = Collections.unmodifiableSet(granters); granters = Collections.unmodifiableSet(granters);
grantingPermissions.put(permissionReference, granters); grantingPermissions.put(permissionReference, granters);
} }
@@ -564,7 +601,12 @@ public class PermissionModel implements ModelDAO, InitializingBean
Set<PermissionReference> grantees = granteePermissions.get(permissionReference); Set<PermissionReference> grantees = granteePermissions.get(permissionReference);
if (grantees == null) if (grantees == null)
{ {
grantees = getGranteePermissionsImpl(permissionReference); Set<PermissionReference> internal = getGranteePermissionsImpl(permissionReference);
grantees = new HashSet<PermissionReference>();
for (PermissionReference grantee : internal)
{
grantees.add(SimplePermissionReference.getPermissionReference(grantee.getQName(), grantee.getName()));
}
grantees = Collections.unmodifiableSet(grantees); grantees = Collections.unmodifiableSet(grantees);
granteePermissions.put(permissionReference, grantees); granteePermissions.put(permissionReference, grantees);
} }
@@ -591,7 +633,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
{ {
if (pg.getTypeQName() != null) if (pg.getTypeQName() != null)
{ {
permissions.addAll(getGranteePermissions(new SimplePermissionReference(pg.getTypeQName(), pg.getName()))); permissions.addAll(getGranteePermissions(SimplePermissionReference.getPermissionReference(pg.getTypeQName(), pg.getName())));
} }
else else
{ {
@@ -600,7 +642,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
if (parent != null) if (parent != null)
{ {
classDefinition = dictionaryService.getClass(parent); classDefinition = dictionaryService.getClass(parent);
PermissionGroup attempt = getPermissionGroupOrNull(new SimplePermissionReference(parent, pg.getName())); PermissionGroup attempt = getPermissionGroupOrNull(SimplePermissionReference.getPermissionReference(parent, pg.getName()));
if (attempt != null) if (attempt != null)
{ {
permissions.addAll(getGranteePermissions(attempt)); permissions.addAll(getGranteePermissions(attempt));
@@ -642,11 +684,11 @@ public class PermissionModel implements ModelDAO, InitializingBean
{ {
for (PermissionGroup pg : ps.getPermissionGroups()) for (PermissionGroup pg : ps.getPermissionGroups())
{ {
permissions.add(pg); permissions.add(SimplePermissionReference.getPermissionReference(pg.getQName(), pg.getName()));
} }
for (Permission p : ps.getPermissions()) for (Permission p : ps.getPermissions())
{ {
permissions.add(p); permissions.add(SimplePermissionReference.getPermissionReference(p.getQName(), p.getName()));
} }
} }
return permissions; return permissions;
@@ -656,7 +698,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
* Support to find permission groups * Support to find permission groups
* *
* @param target * @param target
* @return * @return the permission group
*/ */
private PermissionGroup getPermissionGroupOrNull(PermissionReference target) private PermissionGroup getPermissionGroupOrNull(PermissionReference target)
{ {
@@ -668,7 +710,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
* Support to get a permission group * Support to get a permission group
* *
* @param target * @param target
* @return * @return the permission group
*/ */
private PermissionGroup getPermissionGroup(PermissionReference target) private PermissionGroup getPermissionGroup(PermissionReference target)
{ {
@@ -684,7 +726,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
* Get the base permission group for a given permission group. * Get the base permission group for a given permission group.
* *
* @param pg * @param pg
* @return * @return the permission group
*/ */
private synchronized PermissionGroup getBasePermissionGroupOrNull(PermissionGroup pg) private synchronized PermissionGroup getBasePermissionGroupOrNull(PermissionGroup pg)
{ {
@@ -701,7 +743,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
* Query the model for a base permission group Uses the Data Dictionary to reolve inheritance * Query the model for a base permission group Uses the Data Dictionary to reolve inheritance
* *
* @param pg * @param pg
* @return * @return the permission group
*/ */
private PermissionGroup getBasePermissionGroupOrNullImpl(PermissionGroup pg) private PermissionGroup getBasePermissionGroupOrNullImpl(PermissionGroup pg)
{ {
@@ -713,7 +755,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
{ {
if (pg.getTypeQName() != null) if (pg.getTypeQName() != null)
{ {
return getPermissionGroup(new SimplePermissionReference(pg.getTypeQName(), pg.getName())); return getPermissionGroup(SimplePermissionReference.getPermissionReference(pg.getTypeQName(), pg.getName()));
} }
else else
{ {
@@ -722,7 +764,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
while ((parent = classDefinition.getParentName()) != null) while ((parent = classDefinition.getParentName()) != null)
{ {
classDefinition = dictionaryService.getClass(parent); classDefinition = dictionaryService.getClass(parent);
PermissionGroup attempt = getPermissionGroupOrNull(new SimplePermissionReference(parent, pg.getName())); PermissionGroup attempt = getPermissionGroupOrNull(SimplePermissionReference.getPermissionReference(parent, pg.getName()));
if ((attempt != null) && (!attempt.isExtends())) if ((attempt != null) && (!attempt.isExtends()))
{ {
return attempt; return attempt;
@@ -747,23 +789,184 @@ public class PermissionModel implements ModelDAO, InitializingBean
return pg; return pg;
} }
static Serializable generateKey(PermissionReference required, QName qName, Set<QName> aspectQNames, RequiredPermission.On on) static RequiredKey generateKey(PermissionReference required, QName qName, Set<QName> aspectQNames, RequiredPermission.On on)
{ {
LinkedHashSet<Serializable> key = new LinkedHashSet<Serializable>(); return RequiredKey.getRequiredKey(required, qName, aspectQNames, on);
key.add(required.toString());
key.add(qName);
key.addAll(aspectQNames);
key.add(on.toString());
return key;
} }
private HashMap<Serializable, Set<PermissionReference>> requiredPermissionsCache = new HashMap<Serializable, Set<PermissionReference>>(1024); /**
* Cache key
* @author andyh
*
*/
public static class RequiredKey
{
PermissionReference required;
QName qName;
Set<QName> aspectQNames;
RequiredPermission.On on;
int hashCode = 0;
private static ReadWriteLock lock = new ReentrantReadWriteLock();
private static HashMap<PermissionReference, HashMap<QName, HashMap<Set<QName>, EnumMap<RequiredPermission.On, RequiredKey>>>> instances = new HashMap<PermissionReference, HashMap<QName, HashMap<Set<QName>, EnumMap<RequiredPermission.On, RequiredKey>>>>();
/**
* factory for the key
*
* @param required
* @param qName
* @param aspectQNames
* @param on
* @return the key
*/
public static RequiredKey getRequiredKey(PermissionReference required, QName qName, Set<QName> aspectQNames, RequiredPermission.On on)
{
lock.readLock().lock();
try
{
HashMap<QName, HashMap<Set<QName>, EnumMap<RequiredPermission.On, RequiredKey>>> byPermRef = instances.get(required);
if (byPermRef != null)
{
HashMap<Set<QName>, EnumMap<RequiredPermission.On, RequiredKey>> byType = byPermRef.get(qName);
if(byType != null)
{
EnumMap<RequiredPermission.On, RequiredKey> byAspects = byType.get(aspectQNames);
if(byAspects != null)
{
RequiredKey instance = byAspects.get(on);
if(instance != null)
{
return instance;
}
}
}
}
}
finally
{
lock.readLock().unlock();
}
lock.writeLock().lock();
try
{
HashMap<QName, HashMap<Set<QName>, EnumMap<RequiredPermission.On, RequiredKey>>> byPermRef = instances.get(required);
if (byPermRef == null)
{
byPermRef = new HashMap<QName, HashMap<Set<QName>, EnumMap<RequiredPermission.On, RequiredKey>>>();
instances.put(required, byPermRef);
}
HashMap<Set<QName>, EnumMap<RequiredPermission.On, RequiredKey>> byType = byPermRef.get(qName);
if(byType == null)
{
byType = new HashMap<Set<QName>, EnumMap<RequiredPermission.On, RequiredKey>>();
byPermRef.put(qName, byType);
}
EnumMap<RequiredPermission.On, RequiredKey> byAspects = byType.get(aspectQNames);
if(byAspects == null)
{
byAspects = new EnumMap<RequiredPermission.On, RequiredKey>(RequiredPermission.On.class);
byType.put(aspectQNames, byAspects);
}
RequiredKey instance = byAspects.get(on);
if(instance == null)
{
instance = new RequiredKey(required, qName, aspectQNames, on);
byAspects.put(on, instance);
}
return instance;
}
finally
{
lock.writeLock().unlock();
}
}
RequiredKey(PermissionReference required, QName qName, Set<QName> aspectQNames, RequiredPermission.On on)
{
this.required = required;
this.qName = qName;
this.aspectQNames = aspectQNames;
this.on = on;
}
@Override
public int hashCode()
{
if (hashCode == 0)
{
final int PRIME = 1000003;
int result = 1;
result = PRIME * result + ((aspectQNames == null) ? 0 : aspectQNames.hashCode());
result = PRIME * result + ((on == null) ? 0 : on.ordinal());
result = PRIME * result + ((qName == null) ? 0 : qName.hashCode());
result = PRIME * result + ((required == null) ? 0 : required.hashCode());
hashCode = result;
}
return hashCode;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final RequiredKey other = (RequiredKey) obj;
if (required == null)
{
if (other.required != null)
return false;
}
else if (!required.equals(other.required))
return false;
if (qName == null)
{
if (other.qName != null)
return false;
}
else if (!qName.equals(other.qName))
return false;
if (on == null)
{
if (other.on != null)
return false;
}
else if (!on.equals(other.on))
return false;
if (aspectQNames == null)
{
if (other.aspectQNames != null)
return false;
}
else if (!aspectQNames.equals(other.aspectQNames))
return false;
return true;
}
}
private HashMap<RequiredKey, Set<PermissionReference>> requiredPermissionsCache = new HashMap<RequiredKey, Set<PermissionReference>>(1024);
public Set<PermissionReference> getRequiredPermissions(PermissionReference required, QName qName, Set<QName> aspectQNames, RequiredPermission.On on) public Set<PermissionReference> getRequiredPermissions(PermissionReference required, QName qName, Set<QName> aspectQNames, RequiredPermission.On on)
{ {
// Cache lookup as this is static // Cache lookup as this is static
Serializable key = generateKey(required, qName, aspectQNames, on); RequiredKey key = generateKey(required, qName, aspectQNames, on);
Set<PermissionReference> answer = requiredPermissionsCache.get(key); Set<PermissionReference> answer = requiredPermissionsCache.get(key);
if (answer == null) if (answer == null)
@@ -788,7 +991,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
* *
* @param required * @param required
* @param on * @param on
* @return * @return the set of permission references
*/ */
private Set<PermissionReference> getRequirementsForPermission(PermissionReference required, RequiredPermission.On on) private Set<PermissionReference> getRequirementsForPermission(PermissionReference required, RequiredPermission.On on)
{ {
@@ -814,7 +1017,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
* @param on * @param on
* @param qName * @param qName
* @param aspectQNames * @param aspectQNames
* @return * @return the set of permission references
*/ */
private Set<PermissionReference> getRequirementsForPermissionGroup(PermissionGroup target, RequiredPermission.On on, QName qName, Set<QName> aspectQNames) private Set<PermissionReference> getRequirementsForPermissionGroup(PermissionGroup target, RequiredPermission.On on, QName qName, Set<QName> aspectQNames)
{ {
@@ -861,7 +1064,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
* @param pr * @param pr
* @param typeQname * @param typeQname
* @param aspects * @param aspects
* @return * @return true if dynamic
*/ */
private boolean isPartOfDynamicPermissionGroup(PermissionReference pr, QName typeQname, Set<QName> aspects) private boolean isPartOfDynamicPermissionGroup(PermissionReference pr, QName typeQname, Set<QName> aspects)
{ {
@@ -883,7 +1086,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
* Utility method to find a permission * Utility method to find a permission
* *
* @param perm * @param perm
* @return * @return the permission
*/ */
private Permission getPermissionOrNull(PermissionReference perm) private Permission getPermissionOrNull(PermissionReference perm)
{ {
@@ -905,7 +1108,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
{ {
if (pg.getTypeQName() != null) if (pg.getTypeQName() != null)
{ {
return checkPermission(new SimplePermissionReference(pg.getTypeQName(), pg.getName())); return checkPermission(SimplePermissionReference.getPermissionReference(pg.getTypeQName(), pg.getName()));
} }
else else
{ {
@@ -914,7 +1117,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
while ((parent = classDefinition.getParentName()) != null) while ((parent = classDefinition.getParentName()) != null)
{ {
classDefinition = dictionaryService.getClass(parent); classDefinition = dictionaryService.getClass(parent);
PermissionGroup attempt = getPermissionGroupOrNull(new SimplePermissionReference(parent, pg.getName())); PermissionGroup attempt = getPermissionGroupOrNull(SimplePermissionReference.getPermissionReference(parent, pg.getName()));
if ((attempt != null) && attempt.isAllowFullControl()) if ((attempt != null) && attempt.isAllowFullControl())
{ {
return true; return true;
@@ -970,13 +1173,13 @@ public class PermissionModel implements ModelDAO, InitializingBean
{ {
for (PermissionGroup pg : ps.getPermissionGroups()) for (PermissionGroup pg : ps.getPermissionGroups())
{ {
permissionGroupMap.put(pg, pg); permissionGroupMap.put(SimplePermissionReference.getPermissionReference(pg.getQName(), pg.getName()), pg);
permissionReferenceMap.put(pg.toString(), pg); permissionReferenceMap.put(pg.toString(), SimplePermissionReference.getPermissionReference(pg.getQName(), pg.getName()));
} }
for (Permission p : ps.getPermissions()) for (Permission p : ps.getPermissions())
{ {
permissionReferenceMap.put(p.toString(), p); permissionReferenceMap.put(p.toString(), SimplePermissionReference.getPermissionReference(p.getQName(), p.getName()));
permissionMap.put(p, p); permissionMap.put(SimplePermissionReference.getPermissionReference(p.getQName(), p.getName()), p);
} }
} }
@@ -995,7 +1198,8 @@ public class PermissionModel implements ModelDAO, InitializingBean
} }
else else
{ {
uniqueMap.put(pg.getName(), getBasePermissionGroup(pg)); PermissionReference base = getBasePermissionGroup(pg);
uniqueMap.put(pg.getName(), SimplePermissionReference.getPermissionReference(base.getQName(), base.getName()));
} }
} }
for (Permission p : ps.getPermissions()) for (Permission p : ps.getPermissions())
@@ -1011,7 +1215,7 @@ public class PermissionModel implements ModelDAO, InitializingBean
} }
else else
{ {
uniqueMap.put(p.getName(), p); uniqueMap.put(p.getName(), SimplePermissionReference.getPermissionReference(p.getQName(), p.getName()));
} }
} }
} }
@@ -1020,8 +1224,8 @@ public class PermissionModel implements ModelDAO, InitializingBean
{ {
throw new IllegalStateException("There must not be a permission with the same name as the ALL_PERMISSION constant: " + PermissionService.ALL_PERMISSIONS); throw new IllegalStateException("There must not be a permission with the same name as the ALL_PERMISSION constant: " + PermissionService.ALL_PERMISSIONS);
} }
uniqueMap.put(PermissionService.ALL_PERMISSIONS, new SimplePermissionReference(QName uniqueMap.put(PermissionService.ALL_PERMISSIONS, SimplePermissionReference.getPermissionReference(QName.createQName(NamespaceService.SECURITY_MODEL_1_0_URI,
.createQName(NamespaceService.SECURITY_MODEL_1_0_URI, PermissionService.ALL_PERMISSIONS), PermissionService.ALL_PERMISSIONS)); PermissionService.ALL_PERMISSIONS), PermissionService.ALL_PERMISSIONS));
} }

View File

@@ -193,12 +193,12 @@ public class PermissionServiceNOOPImpl
public PermissionReference getPermissionReference(QName qname, String permissionName) public PermissionReference getPermissionReference(QName qname, String permissionName)
{ {
return new PermissionReferenceImpl(qname, permissionName); return PermissionReferenceImpl.getPermissionReference(qname, permissionName);
} }
public PermissionReference getPermissionReference(String permissionName) public PermissionReference getPermissionReference(String permissionName)
{ {
return new PermissionReferenceImpl(QName.createQName("uri", "local"), permissionName); return PermissionReferenceImpl.getPermissionReference(QName.createQName("uri", "local"), permissionName);
} }
public NodePermissionEntry getSetPermissions(NodeRef nodeRef) public NodePermissionEntry getSetPermissions(NodeRef nodeRef)
@@ -284,6 +284,11 @@ public class PermissionServiceNOOPImpl
{ {
return Collections.<AccessPermission>emptySet(); return Collections.<AccessPermission>emptySet();
} }
public NodePermissionEntry getSetPermissions(StoreRef storeRef)
{
return new SimpleNodePermissionEntry(null, true, Collections.<PermissionEntry>emptySet());
}
} }

View File

@@ -27,6 +27,7 @@ package org.alfresco.service.cmr.security;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.repo.security.permissions.PermissionReference;
import org.alfresco.service.Auditable; import org.alfresco.service.Auditable;
import org.alfresco.service.PublicService; import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
@@ -230,9 +231,9 @@ public interface PermissionService
/** /**
* Check if a permission is allowed on an acl. * Check if a permission is allowed on an acl.
* @param aclID * @param aclID
* @param owner * @param context
* @param permission * @param permission
* @return * @return the access status
*/ */
@Auditable(parameters = { "aclID", "context", "permission" }) @Auditable(parameters = { "aclID", "context", "permission" })
public AccessStatus hasPermission(Long aclID, PermissionContext context, String permission); public AccessStatus hasPermission(Long aclID, PermissionContext context, String permission);
@@ -377,7 +378,7 @@ public interface PermissionService
* @param authority * @param authority
* @param permission * @param permission
*/ */
@Auditable(key = Auditable.Key.ARG_0, parameters = { "StoreRef", "authority", "permission" }) @Auditable(key = Auditable.Key.ARG_0, parameters = { "storeRef", "authority", "permission" })
public void deletePermission(StoreRef storeRef, String authority, String permission); public void deletePermission(StoreRef storeRef, String authority, String permission);
/** /**
@@ -386,7 +387,7 @@ public interface PermissionService
* @param storeRef * @param storeRef
* @param authority * @param authority
*/ */
@Auditable(key = Auditable.Key.ARG_0, parameters = { "StoreRef", "authority" }) @Auditable(key = Auditable.Key.ARG_0, parameters = { "storeRef", "authority" })
public void clearPermission(StoreRef storeRef, String authority); public void clearPermission(StoreRef storeRef, String authority);
/** /**
@@ -394,16 +395,17 @@ public interface PermissionService
* *
* @param storeRef * @param storeRef
*/ */
@Auditable(key = Auditable.Key.ARG_0, parameters = { "StoreRef" }) @Auditable(key = Auditable.Key.ARG_0, parameters = { "storeRef" })
public void deletePermissions(StoreRef storeRef); public void deletePermissions(StoreRef storeRef);
/** /**
* Get all the AccessPermissions that are set for anyone for the given node * Get all the AccessPermissions that are set for anyone for the given node
* *
* @param nodeRef - * @param storeRef -
* the reference to the node * the reference to the store
* @return the set of allowed permissions * @return the set of allowed permissions
*/ */
@Auditable(key = Auditable.Key.ARG_0, parameters = { "StoreRef" }) @Auditable(key = Auditable.Key.ARG_0, parameters = { "storeRef" })
public Set<AccessPermission> getAllSetPermissions(StoreRef storeRef); public Set<AccessPermission> getAllSetPermissions(StoreRef storeRef);
} }