Fixed permissions data access

Some tweaks to select and joins


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2816 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-05-10 17:03:29 +00:00
parent 14b4890e6c
commit f559ae62ce
20 changed files with 518 additions and 370 deletions

View File

@@ -151,14 +151,14 @@
<!-- Permission related caches --> <!-- Permission related caches -->
<!-- approx 40MB memory required --> <!-- approx 40MB memory required -->
<cache <cache
name="org.alfresco.repo.domain.hibernate.DbAuthorityImpl" name="org.alfresco.repo.domain.hibernate.DbAccessControlListImpl"
maxElementsInMemory="10000" maxElementsInMemory="10000"
eternal="true" eternal="true"
overflowToDisk="false"/> overflowToDisk="false"/>
<!-- approx 2MB memory required --> <!-- approx ??MB memory required -->
<cache <cache
name="org.alfresco.repo.domain.hibernate.DbPermissionImpl" name="org.alfresco.repo.domain.hibernate.DbAccessControlListImpl.entries"
maxElementsInMemory="500" maxElementsInMemory="10000"
eternal="true" eternal="true"
overflowToDisk="false"/> overflowToDisk="false"/>
<!-- approx 35MB memory required --> <!-- approx 35MB memory required -->
@@ -167,9 +167,15 @@
maxElementsInMemory="25000" maxElementsInMemory="25000"
eternal="true" eternal="true"
overflowToDisk="false"/> overflowToDisk="false"/>
<!-- approx 2MB memory required -->
<cache
name="org.alfresco.repo.domain.hibernate.DbPermissionImpl"
maxElementsInMemory="500"
eternal="true"
overflowToDisk="false"/>
<!-- approx 40MB memory required --> <!-- approx 40MB memory required -->
<cache <cache
name="org.alfresco.repo.domain.hibernate.DbAccessControlListImpl" name="org.alfresco.repo.domain.hibernate.DbAuthorityImpl"
maxElementsInMemory="10000" maxElementsInMemory="10000"
eternal="true" eternal="true"
overflowToDisk="false"/> overflowToDisk="false"/>

View File

@@ -72,4 +72,10 @@ public interface DbAccessControlEntry
* @param allowed * @param allowed
*/ */
public void setAllowed(boolean allowed); public void setAllowed(boolean allowed);
/**
* Helper method to delete the instance and make sure that all
* inverse associations are properly maintained.
*/
public void delete();
} }

View File

@@ -16,6 +16,10 @@
*/ */
package org.alfresco.repo.domain; package org.alfresco.repo.domain;
import java.util.Set;
import org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl;
/** /**
* The interface to support persistence of node access control entries in hibernate * The interface to support persistence of node access control entries in hibernate
@@ -30,22 +34,48 @@ public interface DbAccessControlList
public void setNode(Node node); public void setNode(Node node);
/**
*
* @return Returns the access control entries for this access control list
*/
public Set<DbAccessControlEntry> getEntries();
/** /**
* Get inheritance behaviour * Get inheritance behaviour
* @return * @return Returns the inheritance status of this list
*/ */
public boolean getInherits(); public boolean getInherits();
/** /**
* Set inheritance behaviour * Set inheritance behaviour
* @param inherits * @param inherits true to set the permissions to inherit
*/ */
public void setInherits(boolean inherits); public void setInherits(boolean inherits);
public int deleteEntriesForAuthority(String authorityKey);
public int deleteEntriesForPermission(DbPermissionKey permissionKey);
public int deleteEntry(String authorityKey, DbPermissionKey permissionKey);
/** /**
* Delete the entries related to this access control list * Delete the entries related to this access control list
* *
* @return Returns the number of entries deleted * @return Returns the number of entries deleted
*/ */
public int deleteEntries(); public int deleteEntries();
public DbAccessControlEntry getEntry(String authorityKey, DbPermissionKey permissionKey);
/**
* Factory method to create an entry and wire it up.
* Note that the returned value may still be transient. Saving it should be fine, but
* is not required.
*
* @param permission the mandatory permission association with this entry
* @param authority the mandatory authority. Must not be transient.
* @param allowed allowed or disallowed. Must not be transient.
* @return Returns the new entry
*/
public DbAccessControlEntryImpl newEntry(DbPermission permission, DbAuthority authority, boolean allowed);
} }

View File

@@ -51,4 +51,10 @@ public interface DbPermission extends Serializable
* @param name the name of the permission * @param name the name of the permission
*/ */
public void setName(String name); public void setName(String name);
/**
* @return Returns a key combining the {@link #getTypeQname() type}
* and {@link #getName() name}
*/
public DbPermissionKey getKey();
} }

View File

@@ -0,0 +1,102 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.domain;
import java.io.Serializable;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
/**
* Compound key for persistence of {@link org.alfresco.repo.domain.DbPermission}.
*
* @author Derek Hulley
*/
public class DbPermissionKey implements Serializable
{
private static final long serialVersionUID = -1667797216480779296L;
private QName typeQname;
private String name;
public DbPermissionKey()
{
}
public DbPermissionKey(QName typeQname, String name)
{
this.typeQname = typeQname;
this.name = name;
}
public String toString()
{
return ("DbPermissionKey" +
"[ type=" + typeQname +
", name=" + name +
"]");
}
public int hashCode()
{
return this.name.hashCode();
}
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
else if (!(obj instanceof DbPermissionKey))
{
return false;
}
DbPermissionKey that = (DbPermissionKey) obj;
return (EqualsHelper.nullSafeEquals(this.typeQname, that.typeQname)
&& EqualsHelper.nullSafeEquals(this.name, that.name)
);
}
public QName getTypeQname()
{
return typeQname;
}
/**
* Tamper-proof method only to be used by introspectors
*/
@SuppressWarnings("unused")
private void setTypeQname(QName typeQname)
{
this.typeQname = typeQname;
}
public String getName()
{
return name;
}
/**
* Tamper-proof method only to be used by introspectors
*/
@SuppressWarnings("unused")
private void setName(String name)
{
this.name = name;
}
}

View File

@@ -80,5 +80,5 @@ public interface Node
public DbAccessControlList getAccessControlList(); public DbAccessControlList getAccessControlList();
// public void setAccessControlList(DbAccessControlList accessControlList); public void setAccessControlList(DbAccessControlList accessControlList);
} }

View File

@@ -27,7 +27,7 @@ import org.alfresco.util.EqualsHelper;
* *
* @author andyh * @author andyh
*/ */
public class DbAccessControlEntryImpl implements DbAccessControlEntry public class DbAccessControlEntryImpl extends LifecycleAdapter implements DbAccessControlEntry
{ {
/** The object id */ /** The object id */
private long id; private long id;
@@ -56,7 +56,7 @@ public class DbAccessControlEntryImpl implements DbAccessControlEntry
sb.append("DbAccessControlEntryImpl") sb.append("DbAccessControlEntryImpl")
.append("[ id=").append(id) .append("[ id=").append(id)
.append(", acl=").append(accessControlList.getId()) .append(", acl=").append(accessControlList.getId())
.append(", permission=").append(permission.getId()) .append(", permission=").append(permission.getKey())
.append(", authority=").append(authority.getRecipient()) .append(", authority=").append(authority.getRecipient())
.append("]"); .append("]");
return sb.toString(); return sb.toString();
@@ -74,16 +74,14 @@ public class DbAccessControlEntryImpl implements DbAccessControlEntry
return false; return false;
} }
DbAccessControlEntry other = (DbAccessControlEntry) o; DbAccessControlEntry other = (DbAccessControlEntry) o;
return (this.allowed == other.isAllowed()) return (EqualsHelper.nullSafeEquals(this.permission, other.getPermission())
&& EqualsHelper.nullSafeEquals(this.accessControlList, other.getAccessControlList()) && EqualsHelper.nullSafeEquals(this.authority, other.getAuthority()));
&& EqualsHelper.nullSafeEquals(this.permission, other.getPermission())
&& EqualsHelper.nullSafeEquals(this.authority, other.getAuthority());
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
int hashCode = accessControlList.hashCode(); int hashCode = 0;
if (permission != null) if (permission != null)
{ {
hashCode = hashCode * 37 + permission.hashCode(); hashCode = hashCode * 37 + permission.hashCode();
@@ -92,33 +90,9 @@ public class DbAccessControlEntryImpl implements DbAccessControlEntry
{ {
hashCode = hashCode * 37 + authority.hashCode(); hashCode = hashCode * 37 + authority.hashCode();
} }
hashCode = hashCode * 37 + (allowed ? 1 : 0);
return hashCode; return hashCode;
} }
/**
* Factory method to create an entry and wire it in to the contained nodePermissionEntry
*
* @param accessControlList the list of entries that this one belongs to
* @param permission the mandatory permission association with this entry
* @param authority the mandatory authority
* @param allowed allowed or disallowed
* @return Returns an unpersisted entity
*/
public static DbAccessControlEntryImpl create(
DbAccessControlList accessControlList,
DbPermission permission,
DbAuthority authority,
boolean allowed)
{
DbAccessControlEntryImpl accessControlEntry = new DbAccessControlEntryImpl();
accessControlEntry.setAccessControlList(accessControlList);
accessControlEntry.setPermission(permission);
accessControlEntry.setAuthority(authority);
accessControlEntry.setAllowed(allowed);
return accessControlEntry;
}
public long getId() public long getId()
{ {
return id; return id;
@@ -171,4 +145,13 @@ public class DbAccessControlEntryImpl implements DbAccessControlEntry
{ {
this.allowed = allowed; this.allowed = allowed;
} }
public void delete()
{
// remove the instance from the access control list
@SuppressWarnings("unused")
boolean removed = getAccessControlList().getEntries().remove(this);
// delete the instance
getSession().delete(this);
}
} }

View File

@@ -16,13 +16,20 @@
*/ */
package org.alfresco.repo.domain.hibernate; package org.alfresco.repo.domain.hibernate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.domain.DbAccessControlEntry;
import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.DbAuthority;
import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.DbPermissionKey;
import org.alfresco.repo.domain.Node; import org.alfresco.repo.domain.Node;
import org.alfresco.util.EqualsHelper; import org.alfresco.util.EqualsHelper;
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.CallbackException;
import org.hibernate.Query;
import org.hibernate.Session; import org.hibernate.Session;
/** /**
@@ -36,8 +43,14 @@ public class DbAccessControlListImpl extends LifecycleAdapter implements DbAcces
private long id; private long id;
private Node node; private Node node;
private Set<DbAccessControlEntry> entries;
private boolean inherits; private boolean inherits;
public DbAccessControlListImpl()
{
entries = new HashSet<DbAccessControlEntry>(5);
}
@Override @Override
public String toString() public String toString()
{ {
@@ -45,6 +58,7 @@ public class DbAccessControlListImpl extends LifecycleAdapter implements DbAcces
sb.append("DbAccessControlListImpl") sb.append("DbAccessControlListImpl")
.append("[ id=").append(id) .append("[ id=").append(id)
.append(", node=").append(node) .append(", node=").append(node)
.append(", entries=").append(entries.size())
.append(", inherits=").append(inherits) .append(", inherits=").append(inherits)
.append("]"); .append("]");
return sb.toString(); return sb.toString();
@@ -73,35 +87,6 @@ public class DbAccessControlListImpl extends LifecycleAdapter implements DbAcces
return (node == null ? 0 : node.hashCode()); return (node == null ? 0 : node.hashCode());
} }
public int deleteEntries()
{
/*
* This can use a delete direct to the database as well, but then care must be taken
* to evict the instances from the session.
*/
// bypass L2 cache and get all entries for this list
Query query = getSession()
.getNamedQuery(PermissionsDaoComponentImpl.QUERY_GET_AC_ENTRIES_FOR_AC_LIST)
.setLong("accessControlListId", this.id);
int count = HibernateHelper.deleteQueryResults(getSession(), query);
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + count + " access entries for access control list " + this.id);
}
return count;
}
/**
* Ensures that all this access control list's entries have been deleted.
*/
public boolean onDelete(Session session) throws CallbackException
{
deleteEntries();
return super.onDelete(session);
}
public long getId() public long getId()
{ {
return id; return id;
@@ -126,9 +111,18 @@ public class DbAccessControlListImpl extends LifecycleAdapter implements DbAcces
this.node = node; this.node = node;
} }
public DbAccessControlListImpl() public Set<DbAccessControlEntry> getEntries()
{ {
super(); return entries;
}
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setEntries(Set<DbAccessControlEntry> entries)
{
this.entries = entries;
} }
public boolean getInherits() public boolean getInherits()
@@ -140,4 +134,112 @@ public class DbAccessControlListImpl extends LifecycleAdapter implements DbAcces
{ {
this.inherits = inherits; this.inherits = inherits;
} }
/**
* @see #deleteEntry(String, DbPermissionKey)
*/
public int deleteEntriesForAuthority(String authority)
{
return deleteEntry(authority, null);
}
/**
* @see #deleteEntry(String, DbPermissionKey)
*/
public int deleteEntriesForPermission(DbPermissionKey permissionKey)
{
return deleteEntry(null, permissionKey);
}
public int deleteEntry(String authority, DbPermissionKey permissionKey)
{
List<DbAccessControlEntry> toDelete = new ArrayList<DbAccessControlEntry>(2);
for (DbAccessControlEntry entry : entries)
{
if (authority != null && !authority.equals(entry.getAuthority().getRecipient()))
{
// authority is not a match
continue;
}
else if (permissionKey != null && !permissionKey.equals(entry.getPermission().getKey()))
{
// permission is not a match
continue;
}
toDelete.add(entry);
}
// delete them
for (DbAccessControlEntry entry : toDelete)
{
// remove from the entry list
entry.delete();
}
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + toDelete.size() + " access entries: \n" +
" access control list: " + id + "\n" +
" authority: " + authority + "\n" +
" permission: " + permissionKey);
}
return toDelete.size();
}
public int deleteEntries()
{
/*
* We don't do the full delete-remove-from-set thing here. Just delete each child entity
* and then clear the entry set.
*/
Session session = getSession();
List<DbAccessControlEntry> toDelete = new ArrayList<DbAccessControlEntry>(entries);
// delete each entry
for (DbAccessControlEntry entry : toDelete)
{
session.delete(entry);
}
// clear the list
int count = entries.size();
entries.clear();
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + count + " access entries for access control list " + this.id);
}
return count;
}
public DbAccessControlEntry getEntry(String authority, DbPermissionKey permissionKey)
{
for (DbAccessControlEntry entry : entries)
{
DbAuthority authorityEntity = entry.getAuthority();
DbPermission permissionEntity = entry.getPermission();
// check for a match
if (authorityEntity.getRecipient().equals(authority)
&& permissionEntity.getKey().equals(permissionKey))
{
// found it
return entry;
}
}
return null;
}
public DbAccessControlEntryImpl newEntry(DbPermission permission, DbAuthority authority, boolean allowed)
{
DbAccessControlEntryImpl accessControlEntry = new DbAccessControlEntryImpl();
// fill
accessControlEntry.setAccessControlList(this);
accessControlEntry.setPermission(permission);
accessControlEntry.setAuthority(authority);
accessControlEntry.setAllowed(allowed);
// save it
getSession().save(accessControlEntry);
// maintain inverse set on the acl
getEntries().add(accessControlEntry);
// done
return accessControlEntry;
}
} }

View File

@@ -38,11 +38,11 @@ public class DbAuthorityImpl extends LifecycleAdapter implements DbAuthority
private static Log logger = LogFactory.getLog(DbAuthorityImpl.class); private static Log logger = LogFactory.getLog(DbAuthorityImpl.class);
private String recipient; private String recipient;
private Set<String> externalKeys = new HashSet<String>(); private Set<String> externalKeys;
public DbAuthorityImpl() public DbAuthorityImpl()
{ {
super(); externalKeys = new HashSet<String>();
} }
@Override @Override
@@ -76,8 +76,8 @@ public class DbAuthorityImpl extends LifecycleAdapter implements DbAuthority
// bypass L2 cache and get all entries for this list // bypass L2 cache and get all entries for this list
Query query = getSession() Query query = getSession()
.getNamedQuery(PermissionsDaoComponentImpl.QUERY_GET_AC_ENTRIES_FOR_AUTHORITY) .getNamedQuery(PermissionsDaoComponentImpl.QUERY_GET_AC_ENTRIES_FOR_AUTHORITY)
.setString("recipient", this.recipient); .setString("authorityRecipient", this.recipient);
int count = HibernateHelper.deleteQueryResults(getSession(), query); int count = HibernateHelper.deleteDbAccessControlEntries(getSession(), query);
// done // done
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
@@ -115,4 +115,16 @@ public class DbAuthorityImpl extends LifecycleAdapter implements DbAuthority
{ {
this.externalKeys = externalKeys; this.externalKeys = externalKeys;
} }
/**
* Helper method to find an authority based on its natural key
*
* @param session the Hibernate session to use
* @param authority the authority name
* @return Returns an existing instance or null if not found
*/
public static DbAuthority find(Session session, String authority)
{
return (DbAuthority) session.get(DbAuthorityImpl.class, authority);
}
} }

View File

@@ -17,6 +17,7 @@
package org.alfresco.repo.domain.hibernate; package org.alfresco.repo.domain.hibernate;
import org.alfresco.repo.domain.DbPermission; import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.DbPermissionKey;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper; import org.alfresco.util.EqualsHelper;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@@ -90,7 +91,7 @@ public class DbPermissionImpl extends LifecycleAdapter implements DbPermission
Query query = getSession() Query query = getSession()
.getNamedQuery(PermissionsDaoComponentImpl.QUERY_GET_AC_ENTRIES_FOR_PERMISSION) .getNamedQuery(PermissionsDaoComponentImpl.QUERY_GET_AC_ENTRIES_FOR_PERMISSION)
.setSerializable("permissionId", this.id); .setSerializable("permissionId", this.id);
int count = HibernateHelper.deleteQueryResults(getSession(), query); int count = HibernateHelper.deleteDbAccessControlEntries(getSession(), query);
// done // done
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
@@ -142,6 +143,11 @@ public class DbPermissionImpl extends LifecycleAdapter implements DbPermission
this.name = name; this.name = name;
} }
public DbPermissionKey getKey()
{
return new DbPermissionKey(typeQname, name);
}
/** /**
* Helper method to find a permission based on its natural key * Helper method to find a permission based on its natural key
* *

View File

@@ -16,8 +16,7 @@
*/ */
package org.alfresco.repo.domain.hibernate; package org.alfresco.repo.domain.hibernate;
import org.hibernate.CacheMode; import org.alfresco.repo.domain.DbAccessControlEntry;
import org.hibernate.ObjectDeletedException;
import org.hibernate.Query; import org.hibernate.Query;
import org.hibernate.ScrollMode; import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults; import org.hibernate.ScrollableResults;
@@ -32,38 +31,27 @@ public class HibernateHelper
{ {
/** /**
* Helper method to scroll through the results of a query and delete all the * Helper method to scroll through the results of a query and delete all the
* results, performing batch flushes. This will handle large resultsets by * resulting access control entries, performing batch flushes.
* pulling the results directly in from the query. For certain circumstances, it
* may be better to perform a bulk delete directly instead.
* *
* @param session the session to use for the deletions * @param session the session to use for the deletions
* @param query the query with all parameters set * @param query the query with all parameters set and that will return
* @return Returns the number of entities deleted, regardless of type * {@link org.alfresco.repo.domain.DbAccessControlEntry access control entry} instances
* @return Returns the number of entries deleted
*/ */
public static int deleteQueryResults(Session session, Query query) public static int deleteDbAccessControlEntries(Session session, Query query)
{ {
ScrollableResults entities = query.setCacheMode(CacheMode.IGNORE).scroll(ScrollMode.FORWARD_ONLY); ScrollableResults entities = query.scroll(ScrollMode.FORWARD_ONLY);
int count = 0; int count = 0;
while (entities.next()) while (entities.next())
{ {
Object[] entityResults = entities.get(); DbAccessControlEntry entry = (DbAccessControlEntry) entities.get(0);
for (Object object : entityResults) entry.delete();
{
try
{
session.delete(object);
}
catch (ObjectDeletedException e)
{
// ignore - it's what we wanted
}
if (++count % 50 == 0) if (++count % 50 == 0)
{ {
session.flush(); session.flush();
session.clear(); session.clear();
} }
} }
}
return count; return count;
} }
} }

View File

@@ -18,6 +18,7 @@ package org.alfresco.repo.domain.hibernate;
import java.io.Serializable; import java.io.Serializable;
import org.alfresco.error.AlfrescoRuntimeException;
import org.hibernate.CallbackException; import org.hibernate.CallbackException;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.classic.Lifecycle; import org.hibernate.classic.Lifecycle;
@@ -37,6 +38,10 @@ public abstract class LifecycleAdapter implements Lifecycle
*/ */
protected Session getSession() protected Session getSession()
{ {
if (session == null)
{
throw new AlfrescoRuntimeException("Hibernate entity is not part of a session: " + this);
}
return session; return session;
} }

View File

@@ -28,9 +28,9 @@
name="store" name="store"
class="org.alfresco.repo.domain.hibernate.StoreImpl" class="org.alfresco.repo.domain.hibernate.StoreImpl"
not-null="true" not-null="true"
lazy="no-proxy" lazy="proxy"
optimistic-lock="true" optimistic-lock="true"
fetch="select"> fetch="join">
<column name="protocol" not-null="true" /> <column name="protocol" not-null="true" />
<column name="identifier" not-null="true" /> <column name="identifier" not-null="true" />
</many-to-one> </many-to-one>
@@ -43,8 +43,8 @@
name="accessControlList" name="accessControlList"
class="org.alfresco.repo.domain.hibernate.DbAccessControlListImpl" class="org.alfresco.repo.domain.hibernate.DbAccessControlListImpl"
property-ref="node" property-ref="node"
lazy="no-proxy" lazy="false"
fetch="select" fetch="join"
cascade="delete" /> cascade="delete" />
<!-- forward assoc to properties --> <!-- forward assoc to properties -->
<map <map
@@ -74,10 +74,10 @@
<set <set
name="aspects" name="aspects"
table="node_aspects" table="node_aspects"
lazy="true" lazy="false"
sort="unsorted"
inverse="false" inverse="false"
fetch="select" sort="unsorted"
fetch="join"
optimistic-lock="true" optimistic-lock="true"
cascade="delete" > cascade="delete" >
<key column="node_id" not-null="true" /> <key column="node_id" not-null="true" />

View File

@@ -34,6 +34,7 @@ import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.domain.Store; import org.alfresco.repo.domain.Store;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
/** /**
* Bean containing all the persistence data representing a <b>node</b>. * Bean containing all the persistence data representing a <b>node</b>.
@@ -134,12 +135,13 @@ public class NodeImpl extends LifecycleAdapter implements Node
return false; return false;
} }
Node that = (Node) obj; Node that = (Node) obj;
return (this.getNodeRef().equals(that.getNodeRef())); return (EqualsHelper.nullSafeEquals(getStore(), that.getStore())
&& EqualsHelper.nullSafeEquals(getUuid(), that.getUuid()));
} }
public int hashCode() public int hashCode()
{ {
return getNodeRef().hashCode(); return getUuid().hashCode();
} }
// @Override // @Override
@@ -316,11 +318,7 @@ public class NodeImpl extends LifecycleAdapter implements Node
return accessControlList; return accessControlList;
} }
/** public void setAccessControlList(DbAccessControlList accessControlList)
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setAccessControlList(DbAccessControlList accessControlList)
{ {
this.accessControlList = accessControlList; this.accessControlList = accessControlList;
} }

View File

@@ -27,6 +27,16 @@
<column name="node_id" /> <column name="node_id" />
</many-to-one> </many-to-one>
<set name="entries"
inverse="true"
lazy="false"
cascade="delete"
optimistic-lock="true"
fetch="join" >
<key column="acl_id" />
<one-to-many class="org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl" />
</set>
<property name="inherits" column="inherits" type="boolean" not-null="true" /> <property name="inherits" column="inherits" type="boolean" not-null="true" />
</class> </class>
@@ -83,7 +93,7 @@
dynamic-insert="false" dynamic-insert="false"
dynamic-update="false" dynamic-update="false"
select-before-update="false" select-before-update="false"
lazy="true" lazy="false"
optimistic-lock="version" > optimistic-lock="version" >
<id name="id" column="id" type="long" > <id name="id" column="id" type="long" >
@@ -104,7 +114,7 @@
dynamic-insert="false" dynamic-insert="false"
dynamic-update="false" dynamic-update="false"
select-before-update="false" select-before-update="false"
lazy="true" lazy="false"
optimistic-lock="version" > optimistic-lock="version" >
<id name="recipient" column="recipient" type="string" length="100" /> <id name="recipient" column="recipient" type="string" length="100" />
@@ -133,24 +143,6 @@
permission.name = :permissionName permission.name = :permissionName
</query> </query>
<query name="permission.GetAccessControlEntriesForAccessControlList" cacheable="true" >
select
ace
from
org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl as ace
where
ace.accessControlList.id = :accessControlListId
</query>
<query name="permission.GetAccessControlEntriesForPermission">
select
ace
from
org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl as ace
where
ace.permission.id = :permissionId
</query>
<query name="permission.GetAccessControlEntriesForAuthority"> <query name="permission.GetAccessControlEntriesForAuthority">
select select
ace ace
@@ -160,41 +152,4 @@
ace.authority.recipient = :authorityRecipient ace.authority.recipient = :authorityRecipient
</query> </query>
<query name="permission.GetAccessControlEntriesForAuthorityAndNode">
select
ace
from
org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl as ace
where
ace.authority.recipient = :authorityRecipient and
ace.accessControlList.node.store.key.protocol = :storeProtocol and
ace.accessControlList.node.store.key.identifier = :storeIdentifier and
ace.accessControlList.node.uuid = :nodeUuid
</query>
<query name="permission.GetAccessControlEntryForAll">
select
ace
from
org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl as ace
where
ace.permission.typeQname = :permissionTypeQName and
ace.permission.name = :permissionName and
ace.authority.recipient = :authorityRecipient and
ace.accessControlList.node.store.key.protocol = :storeProtocol and
ace.accessControlList.node.store.key.identifier = :storeIdentifier and
ace.accessControlList.node.uuid = :nodeUuid
</query>
<query name="permission.GetAccessControlListForNode" cacheable="true" >
select
acl
from
org.alfresco.repo.domain.hibernate.DbAccessControlListImpl as acl
where
acl.node.store.key.protocol = :storeProtocol and
acl.node.store.key.identifier = :storeIdentifier and
acl.node.uuid = :nodeUuid
</query>
</hibernate-mapping> </hibernate-mapping>

View File

@@ -16,9 +16,9 @@
*/ */
package org.alfresco.repo.domain.hibernate; package org.alfresco.repo.domain.hibernate;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.cache.SimpleCache;
@@ -26,6 +26,7 @@ import org.alfresco.repo.domain.DbAccessControlEntry;
import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.DbAccessControlList;
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.DbPermissionKey;
import org.alfresco.repo.domain.Node; import org.alfresco.repo.domain.Node;
import org.alfresco.repo.node.db.NodeDaoService; import org.alfresco.repo.node.db.NodeDaoService;
import org.alfresco.repo.security.permissions.NodePermissionEntry; import org.alfresco.repo.security.permissions.NodePermissionEntry;
@@ -56,12 +57,8 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements PermissionsDaoComponent public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements PermissionsDaoComponent
{ {
public static final String QUERY_GET_PERMISSION = "permission.GetPermission"; public static final String QUERY_GET_PERMISSION = "permission.GetPermission";
public static final String QUERY_GET_AC_LIST_FOR_NODE = "permission.GetAccessControlListForNode";
public static final String QUERY_GET_AC_ENTRIES_FOR_AC_LIST = "permission.GetAccessControlEntriesForAccessControlList";
public static final String QUERY_GET_AC_ENTRIES_FOR_AUTHORITY = "permission.GetAccessControlEntriesForAuthority"; public static final String QUERY_GET_AC_ENTRIES_FOR_AUTHORITY = "permission.GetAccessControlEntriesForAuthority";
public static final String QUERY_GET_AC_ENTRIES_FOR_PERMISSION = "permission.GetAccessControlEntriesForPermission"; public static final String QUERY_GET_AC_ENTRIES_FOR_PERMISSION = "permission.GetAccessControlEntriesForPermission";
public static final String QUERY_GET_AC_ENTRIES_FOR_AUTHORITY_AND_NODE = "permission.GetAccessControlEntriesForAuthorityAndNode";
public static final String QUERY_GET_AC_ENTRY_FOR_ALL = "permission.GetAccessControlEntryForAll";
private NodeDaoService nodeDaoService; private NodeDaoService nodeDaoService;
private SimpleCache<NodeRef, SimpleNodePermissionEntry> nullPermissionCache; private SimpleCache<NodeRef, SimpleNodePermissionEntry> nullPermissionCache;
@@ -93,13 +90,16 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
{ {
return npe; return npe;
} }
Node node = getNode(nodeRef);
// get the persisted version // get the persisted version
DbAccessControlList acl = getAccessControlList(nodeRef, false); DbAccessControlList acl = getAccessControlList(node, false);
if (acl == null) if (acl == null)
{ {
// there isn't an access control list for the node - spoof a null one // there isn't an access control list for the node - spoof a null one
SimpleNodePermissionEntry snpe = new SimpleNodePermissionEntry( SimpleNodePermissionEntry snpe = new SimpleNodePermissionEntry(
nodeRef, true, Collections.<SimplePermissionEntry> emptySet()); nodeRef,
true,
Collections.<SimplePermissionEntry> emptySet());
npe = snpe; npe = snpe;
nullPermissionCache.put(nodeRef, snpe); nullPermissionCache.put(nodeRef, snpe);
} }
@@ -122,46 +122,18 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
* @param create - create the object if it is missing * @param create - create the object if it is missing
* @return Returns the current access control list or null if not found * @return Returns the current access control list or null if not found
*/ */
private DbAccessControlList getAccessControlList(final NodeRef nodeRef, boolean create) private DbAccessControlList getAccessControlList(Node node, boolean create)
{ {
// get the access control list for the node DbAccessControlList acl = node.getAccessControlList();
HibernateCallback callback = new HibernateCallback() if (acl == null && create)
{ {
public Object doInHibernate(Session session) acl = createAccessControlList(node);
{
Query query = session.getNamedQuery(PermissionsDaoComponentImpl.QUERY_GET_AC_LIST_FOR_NODE);
query.setString("storeProtocol", nodeRef.getStoreRef().getProtocol())
.setString("storeIdentifier", nodeRef.getStoreRef().getIdentifier())
.setString("nodeUuid", nodeRef.getId());
return query.list();
}
};
@SuppressWarnings("unchecked")
List<DbAccessControlList> results = (List<DbAccessControlList>) getHibernateTemplate().execute(callback);
DbAccessControlList acl = null;
if (results.size() == 0)
{
// create it
if (create)
{
acl = createAccessControlList(nodeRef);
}
// else null will be returned
}
else if (results.size() > 0)
{
acl = (DbAccessControlList) results.get(0);
}
else if (results.size() > 1)
{
logger.warn("Duplicate access control lists for node: " + nodeRef);
acl = (DbAccessControlList) results.get(0);
} }
// done // done
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug("Retrieved access control list: \n" + logger.debug("Retrieved access control list: \n" +
" node: " + nodeRef + "\n" + " node: " + node.getNodeRef() + "\n" +
" list: " + acl); " list: " + acl);
} }
return acl; return acl;
@@ -171,16 +143,17 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
* Creates an access control list for the node and removes the entry from * Creates an access control list for the node and removes the entry from
* the nullPermsionCache. * the nullPermsionCache.
*/ */
private DbAccessControlList createAccessControlList(final NodeRef nodeRef) private DbAccessControlList createAccessControlList(Node node)
{ {
// get the node referenced
Node node = getNode(nodeRef);
DbAccessControlList acl = new DbAccessControlListImpl(); DbAccessControlList acl = new DbAccessControlListImpl();
acl.setNode(node); acl.setNode(node);
acl.setInherits(true); acl.setInherits(true);
getHibernateTemplate().save(acl); getHibernateTemplate().save(acl);
// maintain inverse
node.setAccessControlList(acl);
NodeRef nodeRef = node.getNodeRef();
nullPermissionCache.remove(nodeRef); nullPermissionCache.remove(nodeRef);
// done // done
@@ -209,17 +182,21 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
public void deletePermissions(NodeRef nodeRef) public void deletePermissions(NodeRef nodeRef)
{ {
DbAccessControlList acl = getAccessControlList(nodeRef, false); Node node = getNode(nodeRef);
DbAccessControlList acl = getAccessControlList(node, false);
if (acl != null) if (acl != null)
{ {
// delete the access control list - it will cascade to the entries // delete the access control list - it will cascade to the entries
getHibernateTemplate().delete(acl); getHibernateTemplate().delete(acl);
// maintain inverse
node.setAccessControlList(null);
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void deletePermissions(final String authority) public void deletePermissions(final String authority)
{ {
// get the authority
HibernateCallback callback = new HibernateCallback() HibernateCallback callback = new HibernateCallback()
{ {
public Object doInHibernate(Session session) public Object doInHibernate(Session session)
@@ -227,7 +204,7 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
Query query = session Query query = session
.getNamedQuery(QUERY_GET_AC_ENTRIES_FOR_AUTHORITY) .getNamedQuery(QUERY_GET_AC_ENTRIES_FOR_AUTHORITY)
.setString("authorityRecipient", authority); .setString("authorityRecipient", authority);
return (Integer) HibernateHelper.deleteQueryResults(session, query); return (Integer) HibernateHelper.deleteDbAccessControlEntries(session, query);
} }
}; };
Integer deletedCount = (Integer) getHibernateTemplate().execute(callback); Integer deletedCount = (Integer) getHibernateTemplate().execute(callback);
@@ -240,20 +217,13 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
public void deletePermissions(final NodeRef nodeRef, final String authority) public void deletePermissions(final NodeRef nodeRef, final String authority)
{ {
HibernateCallback callback = new HibernateCallback() Node node = getNode(nodeRef);
DbAccessControlList acl = node.getAccessControlList();
int deletedCount = 0;
if (acl != null)
{ {
public Object doInHibernate(Session session) deletedCount = acl.deleteEntriesForAuthority(authority);
{
Query query = session
.getNamedQuery(QUERY_GET_AC_ENTRIES_FOR_AUTHORITY_AND_NODE)
.setString("authorityRecipient", authority)
.setString("storeProtocol", nodeRef.getStoreRef().getProtocol())
.setString("storeIdentifier", nodeRef.getStoreRef().getIdentifier())
.setString("nodeUuid", nodeRef.getId());
return HibernateHelper.deleteQueryResults(session, query);
} }
};
Integer deletedCount = (Integer) getHibernateTemplate().execute(callback);
// done // done
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
@@ -268,38 +238,39 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
* the given criteria. Note that the access control list for the node is * the given criteria. Note that the access control list for the node is
* not deleted. * not deleted.
*/ */
public void deletePermission(final NodeRef nodeRef, final String authority, final PermissionReference permission) public void deletePermission(NodeRef nodeRef, String authority, PermissionReference permission)
{ {
// get the entry Node node = getNode(nodeRef);
DbAccessControlEntry entry = getAccessControlEntry(nodeRef, authority, permission); DbAccessControlList acl = node.getAccessControlList();
if (entry != null) int deletedCount = 0;
if (acl != null)
{ {
getHibernateTemplate().delete(entry); DbPermissionKey permissionKey = new DbPermissionKey(permission.getQName(), permission.getName());
deletedCount = acl.deleteEntry(authority, permissionKey);
}
// done // done
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug("Deleted entry for criteria: \n" + logger.debug("Deleted " + deletedCount + "entries for criteria: \n" +
" node: " + nodeRef + "\n" + " node: " + nodeRef + "\n" +
" authority: " + authority + "\n" + " permission: " + permission + "\n" +
" permission: " + permission); " authority: " + authority);
}
} }
} }
public void setPermission(NodeRef nodeRef, String authority, PermissionReference permission, boolean allow) public void setPermission(NodeRef nodeRef, String authority, PermissionReference permission, boolean allow)
{ {
Node node = getNode(nodeRef);
// get the entry // get the entry
DbAccessControlEntry entry = getAccessControlEntry(nodeRef, authority, permission); DbAccessControlEntry entry = getAccessControlEntry(node, authority, permission);
if (entry == null) if (entry == null)
{ {
// need to create it // need to create it
DbAccessControlList dbAccessControlList = getAccessControlList(nodeRef, true); DbAccessControlList dbAccessControlList = getAccessControlList(node, true);
DbPermission dbPermission = getPermission(permission, true); DbPermission dbPermission = getPermission(permission, true);
DbAuthority dbAuthority = getAuthority(authority, true); DbAuthority dbAuthority = getAuthority(authority, true);
// set persistent objects // set persistent objects
entry = DbAccessControlEntryImpl.create(dbAccessControlList, dbPermission, dbAuthority, allow); entry = dbAccessControlList.newEntry(dbPermission, dbAuthority, allow);
// save it
getHibernateTemplate().save(entry);
// drop the entry from the null cache // drop the entry from the null cache
nullPermissionCache.remove(nodeRef); nullPermissionCache.remove(nodeRef);
// done // done
@@ -326,31 +297,22 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
* @return Returns all access control entries that match the criteria * @return Returns all access control entries that match the criteria
*/ */
private DbAccessControlEntry getAccessControlEntry( private DbAccessControlEntry getAccessControlEntry(
final NodeRef nodeRef, Node node,
final String authority, String authority,
final PermissionReference permission) PermissionReference permission)
{ {
HibernateCallback callback = new HibernateCallback() DbAccessControlList acl = getAccessControlList(node, false);
DbAccessControlEntry entry = null;
if (acl != null)
{ {
public Object doInHibernate(Session session) DbPermissionKey permissionKey = new DbPermissionKey(permission.getQName(), permission.getName());
{ entry = acl.getEntry(authority, permissionKey);
Query query = session
.getNamedQuery(QUERY_GET_AC_ENTRY_FOR_ALL)
.setString("permissionTypeQName", permission.getQName().toString())
.setString("permissionName", permission.getName())
.setString("authorityRecipient", authority)
.setString("storeProtocol", nodeRef.getStoreRef().getProtocol())
.setString("storeIdentifier", nodeRef.getStoreRef().getIdentifier())
.setString("nodeUuid", nodeRef.getId());
return (DbAccessControlEntry) query.uniqueResult();
} }
};
DbAccessControlEntry entry = (DbAccessControlEntry) getHibernateTemplate().execute(callback);
// done // done
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug("" + (entry == null ? "Did not find" : "Found") + "entry for criteria: \n" + logger.debug("" + (entry == null ? "Did not find" : "Found") + "entry for criteria: \n" +
" node: " + nodeRef + "\n" + " node: " + node.getId() + "\n" +
" authority: " + authority + "\n" + " authority: " + authority + "\n" +
" permission: " + permission); " permission: " + permission);
} }
@@ -383,15 +345,9 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
{ {
final QName qname = permissionRef.getQName(); final QName qname = permissionRef.getQName();
final String name = permissionRef.getName(); final String name = permissionRef.getName();
Session session = getSession();
HibernateCallback callback = new HibernateCallback() DbPermission dbPermission = DbPermissionImpl.find(session, qname, name);
{
public Object doInHibernate(Session session)
{
return DbPermissionImpl.find(session, qname, name);
}
};
DbPermission dbPermission = (DbPermission) getHibernateTemplate().execute(callback);
// create if necessary // create if necessary
if ((dbPermission == null) && create) if ((dbPermission == null) && create)
@@ -416,24 +372,21 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
public void setPermission(NodePermissionEntry nodePermissionEntry) public void setPermission(NodePermissionEntry nodePermissionEntry)
{ {
NodeRef nodeRef = nodePermissionEntry.getNodeRef(); NodeRef nodeRef = nodePermissionEntry.getNodeRef();
// get the access control list Node node = getNode(nodeRef);
DbAccessControlList acl = getAccessControlList(nodeRef, false);
if (acl == null) // Get the access control list
// Note the logic here requires to know whether it was created or not
DbAccessControlList acl = getAccessControlList(node, false);
if (acl != null)
{ {
// drop the list
getHibernateTemplate().delete(acl);
// update node
node.setAccessControlList(null);
}
// create the access control list // create the access control list
acl = createAccessControlList(nodeRef); acl = createAccessControlList(node);
}
else
{
// remove entries associated with the list
int deleted = acl.deleteEntries();
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + deleted + " entries for access control list: \n" +
" acl: " + acl);
}
getSession().flush();
}
// set attributes // set attributes
acl.setInherits(nodePermissionEntry.inheritPermissions()); acl.setInherits(nodePermissionEntry.inheritPermissions());
@@ -447,24 +400,37 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
DbPermission permissionEntity = getPermission(permission, true); DbPermission permissionEntity = getPermission(permission, true);
DbAuthority authorityEntity = getAuthority(authority, true); DbAuthority authorityEntity = getAuthority(authority, true);
DbAccessControlEntryImpl entry = DbAccessControlEntryImpl.create( @SuppressWarnings("unused")
acl, DbAccessControlEntryImpl entry = acl.newEntry(permissionEntity, authorityEntity, isAllowed);
permissionEntity,
authorityEntity,
isAllowed);
getHibernateTemplate().save(entry);
} }
} }
public void setInheritParentPermissions(NodeRef nodeRef, boolean inheritParentPermissions) public void setInheritParentPermissions(NodeRef nodeRef, boolean inheritParentPermissions)
{ {
DbAccessControlList acl = getAccessControlList(nodeRef, true); Node node = getNode(nodeRef);
acl.setInherits(inheritParentPermissions);
DbAccessControlList acl = null;
if (!inheritParentPermissions)
{
// Inheritance == true is the default, so only force a create of the ACL if the value false
acl = getAccessControlList(node, true);
acl.setInherits(false);
}
else
{
acl = getAccessControlList(node, false);
if (acl != null)
{
acl.setInherits(true);
}
}
} }
public boolean getInheritParentPermissions(NodeRef nodeRef) public boolean getInheritParentPermissions(NodeRef nodeRef)
{ {
DbAccessControlList acl = getAccessControlList(nodeRef, false); Node node = getNode(nodeRef);
DbAccessControlList acl = getAccessControlList(node, false);
if (acl == null) if (acl == null)
{ {
return true; return true;
@@ -484,7 +450,7 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
{ {
ParameterCheck.mandatory("acl", acl); ParameterCheck.mandatory("acl", acl);
} }
List<DbAccessControlEntry> entries = getEntriesForList(acl); Set<DbAccessControlEntry> entries = acl.getEntries();
SimpleNodePermissionEntry snpe = new SimpleNodePermissionEntry( SimpleNodePermissionEntry snpe = new SimpleNodePermissionEntry(
acl.getNode().getNodeRef(), acl.getNode().getNodeRef(),
acl.getInherits(), acl.getInherits(),
@@ -492,38 +458,11 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
return snpe; return snpe;
} }
/**
* Executes a query to retrieve the access control list's entries
*
* @param acl the access control list
* @return Returns a list of the entries
*/
@SuppressWarnings("unchecked")
private List<DbAccessControlEntry> getEntriesForList(final DbAccessControlList acl)
{
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery(QUERY_GET_AC_ENTRIES_FOR_AC_LIST);
query.setLong("accessControlListId", acl.getId());
return query.list();
}
};
List<DbAccessControlEntry> entries = (List<DbAccessControlEntry>) getHibernateTemplate().execute(callback);
// done
if (logger.isDebugEnabled())
{
logger.debug("Found " + entries.size() + " entries for access control list " + acl.getId());
}
return entries;
}
/** /**
* @param entries access control entries * @param entries access control entries
* @return Returns a unique set of entries that can be given back to the outside world * @return Returns a unique set of entries that can be given back to the outside world
*/ */
private Set<SimplePermissionEntry> createSimplePermissionEntries(List<DbAccessControlEntry> entries) private Set<SimplePermissionEntry> createSimplePermissionEntries(Collection<DbAccessControlEntry> entries)
{ {
if (entries == null) if (entries == null)
{ {

View File

@@ -23,9 +23,9 @@
<many-to-one <many-to-one
name="rootNode" name="rootNode"
not-null="true" not-null="true"
lazy="false" lazy="proxy"
class="org.alfresco.repo.domain.hibernate.NodeImpl" class="org.alfresco.repo.domain.hibernate.NodeImpl"
fetch="join" > fetch="select" >
<column name="root_node_id" /> <column name="root_node_id" />
</many-to-one> </many-to-one>
</class> </class>

View File

@@ -123,7 +123,7 @@ public class StoreImpl implements Store
return key; return key;
} }
public synchronized void setKey(StoreKey key) public void setKey(StoreKey key)
{ {
refWriteLock.lock(); refWriteLock.lock();
try try

View File

@@ -182,6 +182,23 @@ public class PermissionServiceTest extends AbstractPermissionTest
testSetNodePermissionEntry2(); testSetNodePermissionEntry2();
} }
public void testDoubleSetAllowDeny()
{
Set<? extends PermissionEntry> permissionEntries = null;
// add-remove andy-all
permissionService.setPermission(rootNodeRef, "andy", permissionService.getAllPermission(), true);
permissionService.setPermission(rootNodeRef, "andy", permissionService.getAllPermission(), false);
permissionService.deletePermission(rootNodeRef, "andy", permissionService.getAllPermission());
permissionEntries = permissionService.getSetPermissions(rootNodeRef).getPermissionEntries();
assertEquals(0, permissionEntries.size());
// add-remove andy-read
permissionService.setPermission(rootNodeRef, "andy", PermissionService.READ, true);
permissionService.setPermission(rootNodeRef, "andy", PermissionService.READ, false);
permissionService.deletePermission(rootNodeRef, "andy", PermissionService.READ);
permissionEntries = permissionService.getSetPermissions(rootNodeRef).getPermissionEntries();
assertEquals(0, permissionEntries.size());
}
public void testSetPermissionEntryElements() public void testSetPermissionEntryElements()
{ {
// add andy-all (allow) // add andy-all (allow)

View File

@@ -119,13 +119,6 @@ public class HibernatePermissionTest extends BaseSpringTest
// throw the reference away and get the a new one for the id // throw the reference away and get the a new one for the id
permission = (DbPermission) getSession().load(DbPermissionImpl.class, id); permission = (DbPermission) getSession().load(DbPermissionImpl.class, id);
assertNotNull("Permission not found", permission); assertNotNull("Permission not found", permission);
assertEquals("Test", permission.getName());
assertEquals(qname, permission.getTypeQname());
// Test key
permission = (DbPermission) getSession().load(DbPermissionImpl.class, id);
assertNotNull("Permission not found", permission);
assertEquals("Test", permission.getName());
assertEquals(qname, permission.getTypeQname()); assertEquals(qname, permission.getTypeQname());
} }
@@ -175,21 +168,21 @@ public class HibernatePermissionTest extends BaseSpringTest
DbAccessControlList accessControlList = new DbAccessControlListImpl(); DbAccessControlList accessControlList = new DbAccessControlListImpl();
accessControlList.setNode(node); accessControlList.setNode(node);
accessControlList.setInherits(true); accessControlList.setInherits(true);
Serializable nodeAclId = getSession().save(accessControlList);
DbAuthority recipient = new DbAuthorityImpl(); DbAuthority recipient = new DbAuthorityImpl();
recipient.setRecipient("Test"); recipient.setRecipient("Test");
recipient.getExternalKeys().add("One"); recipient.getExternalKeys().add("One");
getSession().save(recipient);
DbPermission permission = new DbPermissionImpl(); DbPermission permission = new DbPermissionImpl();
permission.setTypeQname(qname); permission.setTypeQname(qname);
permission.setName("Test"); permission.setName("Test");
DbAccessControlEntry accessControlEntry = DbAccessControlEntryImpl.create(accessControlList, permission, recipient, true);
Serializable nodeAclId = getSession().save(accessControlList);
getSession().save(recipient);
getSession().save(permission); getSession().save(permission);
Serializable aceEntryId = getSession().save(accessControlEntry);
DbAccessControlEntry accessControlEntry = accessControlList.newEntry(permission, recipient, true);
Long aceEntryId = accessControlEntry.getId();
assertNotNull("Entry is still transient", aceEntryId);
accessControlEntry = (DbAccessControlEntry) getSession().load(DbAccessControlEntryImpl.class, aceEntryId); accessControlEntry = (DbAccessControlEntry) getSession().load(DbAccessControlEntryImpl.class, aceEntryId);
assertNotNull("Permission entry not found", accessControlEntry); assertNotNull("Permission entry not found", accessControlEntry);
@@ -197,7 +190,7 @@ public class HibernatePermissionTest extends BaseSpringTest
assertNotNull(accessControlEntry.getAccessControlList()); assertNotNull(accessControlEntry.getAccessControlList());
assertTrue(accessControlEntry.getAccessControlList().getInherits()); assertTrue(accessControlEntry.getAccessControlList().getInherits());
assertNotNull(accessControlEntry.getPermission()); assertNotNull(accessControlEntry.getPermission());
assertEquals("Test", accessControlEntry.getPermission().getName()); assertEquals("Test", accessControlEntry.getPermission().getKey().getName());
assertNotNull(accessControlEntry.getAuthority()); assertNotNull(accessControlEntry.getAuthority());
assertEquals("Test", accessControlEntry.getAuthority().getRecipient()); assertEquals("Test", accessControlEntry.getAuthority().getRecipient());
assertEquals(1, accessControlEntry.getAuthority().getExternalKeys().size()); assertEquals(1, accessControlEntry.getAuthority().getExternalKeys().size());