diff --git a/gradle.properties b/gradle.properties index 2c33e03..bd5bb21 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -projectVersion=4.0.0.BUILD-SNAPSHOT +projectVersion=4.0.0.BSA grailsVersion=4.0.0.RC1 gormVersion=7.0.0.RC2 gradleWrapperVersion=4.9 @@ -7,4 +7,4 @@ springSecurityVersion=5.1.2.RELEASE springSecurityCoreVersion=4.0.0.M2 javaServletApiVersion=3.1.0 micronautVersion=1.0.5 -hibernateCoreVersion=5.3.7.Final \ No newline at end of file +hibernateCoreVersion=5.3.7.Final diff --git a/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/AclUtilServiceSpec.groovy b/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/AclUtilServiceSpec.groovy index 5d0a55c..a7657e0 100644 --- a/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/AclUtilServiceSpec.groovy +++ b/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/acl/AclUtilServiceSpec.groovy @@ -175,4 +175,36 @@ class AclUtilServiceSpec extends AbstractAclSpec { ProxyUtils.isProxy report.getClass() aclUtilService.hasPermission(authenticateAsUser(false), report, WRITE) } + + void 'change owner'() { + given: + buildReports() + AclSid sid = new AclSid(sid: 'ben', principal: true).save(failOnError: true) + def report = Report.get(report1Id) + AclClass aclClass = new AclClass(className: Report.name).save(failOnError: true) + AclObjectIdentity aclObjectIdentity = new AclObjectIdentity( + aclClass: aclClass, + objectId: report1Id, + owner: sid, + entriesInheriting: true).save(failOnError: true) + + new AclEntry( + aclObjectIdentity: aclObjectIdentity, + sid: sid, + mask: 1, + granting: true).save(failOnError: true) + flushAndClear() + + expect: 'persistent data to be same as Acl' + aclUtilService.readAcl(report).owner.principal == AclObjectIdentity.findByObjectId(report1Id).owner.sid + + when: + authenticateAsAdmin() + aclUtilService.changeOwner(report, 'admin') + flushAndClear() + + then: "compare Acl with persistent data" + def aoi1 = AclObjectIdentity.findByObjectId(report1Id) + aclUtilService.readAcl(report).owner.principal == aoi1.owner.sid + } } diff --git a/plugin/grails-app/services/grails/plugin/springsecurity/acl/AclUtilService.groovy b/plugin/grails-app/services/grails/plugin/springsecurity/acl/AclUtilService.groovy index 59c987f..f6ac8c6 100644 --- a/plugin/grails-app/services/grails/plugin/springsecurity/acl/AclUtilService.groovy +++ b/plugin/grails-app/services/grails/plugin/springsecurity/acl/AclUtilService.groovy @@ -102,11 +102,12 @@ class AclUtilService { * Update the owner of the domain class instance. * * @param domainObject the domain class instance - * @param newOwnerUsername the new username + * @param newRecipient can be a username, role name, Sid, or Authentication */ - void changeOwner(domainObject, String newUsername) { + void changeOwner(domainObject, recipient) { MutableAcl acl = readAcl(domainObject) - acl.owner = new PrincipalSid(newUsername) + Sid newSid = createSid(recipient) + acl.owner = newSid aclService.updateAcl acl } diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/acl/AbstractAclObjectIdentity.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/acl/AbstractAclObjectIdentity.groovy index fe9edb6..c8d0cad 100644 --- a/plugin/src/main/groovy/grails/plugin/springsecurity/acl/AbstractAclObjectIdentity.groovy +++ b/plugin/src/main/groovy/grails/plugin/springsecurity/acl/AbstractAclObjectIdentity.groovy @@ -14,6 +14,8 @@ */ package grails.plugin.springsecurity.acl +import grails.gorm.dirty.checking.DirtyCheck + import groovy.transform.EqualsAndHashCode import groovy.transform.ToString @@ -25,6 +27,7 @@ import groovy.transform.ToString */ @EqualsAndHashCode(includes=['aclClass', 'parent', 'owner', 'entriesInheriting']) @ToString(includeNames=true) +@DirtyCheck abstract class AbstractAclObjectIdentity implements Serializable { AclClass aclClass