diff --git a/Rhino.Security.Tests/DeleteEntityEventListenerFixture.cs b/Rhino.Security.Tests/DeleteEntityEventListenerFixture.cs new file mode 100644 index 0000000..a3c3697 --- /dev/null +++ b/Rhino.Security.Tests/DeleteEntityEventListenerFixture.cs @@ -0,0 +1,59 @@ +namespace Rhino.Security.Tests +{ + using System; + using NHibernate.Criterion; + using Rhino.Security.Model; + using Xunit; + + public class DeleteEntityEventListenerFixture : DatabaseFixture + { + [Fact] + public void DoesDeletingEntityRemoveEntityReferences() { + var account = new Account() { Name = "Bob" }; + session.Save(account); + authorizationRepository.AssociateEntityWith(account, "Important Accounts"); + session.Flush(); + + Guid securityKey = Security.ExtractKey(account); + + // Confirm EntityReference for the new account exists. + EntityReference reference = session.CreateCriteria() + .Add(Restrictions.Eq("EntitySecurityKey", securityKey)) + .SetCacheable(true) + .UniqueResult(); + + Assert.NotNull(reference); + + // Create a permission for the entity + this.permissionsBuilderService.Allow("/Account/Edit").For(this.user).On(account).DefaultLevel().Save(); + + // Confirm the permissison for the entity exists + Permission permission = session.CreateCriteria() + .Add(Restrictions.Eq("EntitySecurityKey", securityKey)) + .SetCacheable(true) + .UniqueResult(); + + Assert.NotNull(permission); + + // Delete account + session.Delete(account); + session.Flush(); + + // Confirm EntityReference was removed + reference = session.CreateCriteria() + .Add(Restrictions.Eq("EntitySecurityKey", securityKey)) + .SetCacheable(true) + .UniqueResult(); + + Assert.Null(reference); + + // Confirm the permissison for the entity was removed + permission = session.CreateCriteria() + .Add(Restrictions.Eq("EntitySecurityKey", securityKey)) + .SetCacheable(true) + .UniqueResult(); + + Assert.Null(permission); + } + } +} diff --git a/Rhino.Security.Tests/Rhino.Security.Tests-vs2008.csproj b/Rhino.Security.Tests/Rhino.Security.Tests-vs2008.csproj index 6b276e4..0ca58de 100644 --- a/Rhino.Security.Tests/Rhino.Security.Tests-vs2008.csproj +++ b/Rhino.Security.Tests/Rhino.Security.Tests-vs2008.csproj @@ -91,6 +91,7 @@ + diff --git a/Rhino.Security/DeleteEntityEventListener.cs b/Rhino.Security/DeleteEntityEventListener.cs new file mode 100644 index 0000000..9f3306c --- /dev/null +++ b/Rhino.Security/DeleteEntityEventListener.cs @@ -0,0 +1,69 @@ +namespace Rhino.Security +{ + using System; + using System.Collections.Generic; + using NHibernate.Criterion; + using NHibernate.Event; + using Rhino.Security.Model; + + /// + /// Litenens for when a secured entity is deleted from the system and deletes + /// associated security data. + /// + [Serializable] + public class DeleteEntityEventListener : IPreDeleteEventListener + { + #region IPreDeleteEventListener Members + + /// + /// Handles PreDelete event to delete an entity's associated security data. + /// + /// Event object containing the delete operation information. + /// False, indicating the delete operation should not be vetoed. + public bool OnPreDelete(PreDeleteEvent deleteEvent) { + var securityKey = Security.ExtractKey(deleteEvent.Entity); + + if (!Guid.Empty.Equals(securityKey)) { + EntityReference entityReference = deleteEvent.Session.CreateCriteria() + .Add(Restrictions.Eq("EntitySecurityKey", securityKey)) + .SetCacheable(true) + .UniqueResult(); + + if (entityReference != null) { + var childSession = deleteEvent.Session.GetSession(NHibernate.EntityMode.Poco); + + childSession.Delete(entityReference); + + //Also remove EntityReferencesToEntitiesGroups and Permissions that reference this entity + + //Get list of EntitiesGroups that have the entity as a member + IEnumerable entitiesGroups = childSession.CreateCriteria() + .CreateCriteria("Entities") + .Add(Restrictions.Eq("EntitySecurityKey", securityKey)) + .SetCacheable(true) + .List(); + + foreach (EntitiesGroup group in entitiesGroups) { + group.Entities.Remove(entityReference); + } + + ////Get list of Permissions that references the entity + IEnumerable permissions = childSession.CreateCriteria() + .Add(Restrictions.Eq("EntitySecurityKey", securityKey)) + .SetCacheable(true) + .List(); + + foreach (Permission permission in permissions) { + childSession.Delete(permission); + } + + childSession.Flush(); + } + } + + return false; + } + + #endregion + } +} diff --git a/Rhino.Security/Rhino.Security-vs2008.csproj b/Rhino.Security/Rhino.Security-vs2008.csproj index 153bffc..8f1a76e 100644 --- a/Rhino.Security/Rhino.Security-vs2008.csproj +++ b/Rhino.Security/Rhino.Security-vs2008.csproj @@ -161,6 +161,7 @@ +