Giter VIP home page Giter VIP logo

spring-security-acl-mongodb's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

spring-security-acl-mongodb's Issues

readAclsById is not working correctly!

Unit Test:

    @Test
    @WithMockUser
    public void testReadAclsById() throws Exception {
        // Arrange
        TestDomainObject domainObject = new TestDomainObject();
        TestDomainObject firstObject = new TestDomainObject();
        TestDomainObject secondObject = new TestDomainObject();
        TestDomainObject thirdObject = new TestDomainObject();
        TestDomainObject unrelatedObject = new TestDomainObject();

        ObjectIdentity objectIdentity = new ObjectIdentityImpl(Class.forName(domainObject.getClass().getName()), domainObject.getId());

        MongoAcl parent = new MongoAcl(domainObject.getId(), domainObject.getClass().getName(), UUID.randomUUID().toString(),"owner", null, true);
        MongoAcl child1 = new MongoAcl(firstObject.getId(), firstObject.getClass().getName(), UUID.randomUUID().toString(), "Tim Test", parent.getId(), true);
        MongoAcl child2 = new MongoAcl(secondObject.getId(), secondObject.getClass().getName(), UUID.randomUUID().toString(), "Petty Pattern", parent.getId(), true);
        MongoAcl child3 = new MongoAcl(thirdObject.getId(), thirdObject.getClass().getName(), UUID.randomUUID().toString(), "Sam Sample", parent.getId(), true);
        MongoAcl nonChild = new MongoAcl(unrelatedObject.getId(), unrelatedObject.getClass().getName(), UUID.randomUUID().toString());

        DomainObjectPermission permission = new DomainObjectPermission(UUID.randomUUID().toString(),
            SecurityContextHolder.getContext().getAuthentication().getName(),
            BasePermission.READ.getMask() | BasePermission.WRITE.getMask(),
            true, true, true);

        parent.getPermissions().add(permission);
        child1.getPermissions().add(permission);
        child2.getPermissions().add(permission);

        // MongoAcl must has owner

        aclRepository.save(parent);
        aclRepository.save(child1);
        aclRepository.save(child2);
        aclRepository.save(child3);
        aclRepository.save(nonChild);

        // Act
        List<Sid> sids = new LinkedList<>();
        sids.add(new PrincipalSid(SecurityContextHolder.getContext().getAuthentication().getName()));

        //List<ObjectIdentity> childObjects = aclService.findChildren(objectIdentity);
        List<ObjectIdentity> childObjects = aclService.findChildren(objectIdentity);
        Map<ObjectIdentity, Acl> resultUser = aclService.readAclsById(childObjects, sids);

        // Assert
        assertThat(childObjects.size(), is(equalTo(3)));
        assertThat(resultUser.keySet().size(), is(equalTo(3)));
        resultUser.values().removeIf(Objects::isNull);
        resultUser.keySet().forEach(objectIdentity1 -> {
            Acl acl = resultUser.get(objectIdentity1);
            System.out.println("ACE Size found: " + acl.getEntries().size());
        });
        assertThat(resultUser.keySet().size(), is(equalTo(3)));
    }

the result is:

ACE Size found: 0
ACE Size found: 1
ACE Size found: 1

but it should be 1,1,1, because parent,child1,child2 should have permission!

Post filter and paging

Hi, this project looks really interesting. I'm always on the lookout of a Spring ACL implementation that provides row level security. The downfall I see in many of them is that the data that comes back from the database is post filtered with only the rows the authenticated principal has access to. The issue I have had in the past with this is that it ruins database paging.

Does this library augment mongo queries with the desired permission checks when querying collections before the call is made to retrieve a collection, or is this done as a post filter mechanism?

Thanks

MongoAcl must has owner for aclService.findChildren function

unit test:

    @Test
    @WithMockUser
    public void testReadAclsById() throws Exception {
        // Arrange
        TestDomainObject domainObject = new TestDomainObject();
        TestDomainObject firstObject = new TestDomainObject();
        TestDomainObject secondObject = new TestDomainObject();
        TestDomainObject thirdObject = new TestDomainObject();
        TestDomainObject unrelatedObject = new TestDomainObject();

        ObjectIdentity objectIdentity = new ObjectIdentityImpl(Class.forName(domainObject.getClass().getName()), domainObject.getId());

        MongoAcl parent = new MongoAcl(domainObject.getId(), domainObject.getClass().getName(), UUID.randomUUID().toString());
        MongoAcl child1 = new MongoAcl(firstObject.getId(), firstObject.getClass().getName(), UUID.randomUUID().toString(), "Tim Test", parent.getId(), true);
        MongoAcl child2 = new MongoAcl(secondObject.getId(), secondObject.getClass().getName(), UUID.randomUUID().toString(), "Petty Pattern", parent.getId(), true);
        MongoAcl child3 = new MongoAcl(thirdObject.getId(), thirdObject.getClass().getName(), UUID.randomUUID().toString(), "Sam Sample", parent.getId(), true);
        MongoAcl nonChild = new MongoAcl(unrelatedObject.getId(), unrelatedObject.getClass().getName(), UUID.randomUUID().toString());

        DomainObjectPermission permission = new DomainObjectPermission(UUID.randomUUID().toString(),
            SecurityContextHolder.getContext().getAuthentication().getName(),
            BasePermission.READ.getMask() | BasePermission.WRITE.getMask(),
            true, true, true);

        parent.getPermissions().add(permission);
        child1.getPermissions().add(permission);
        child2.getPermissions().add(permission);

        // MongoAcl must has owner

        aclRepository.save(parent);
        aclRepository.save(child1);
        aclRepository.save(child2);
        aclRepository.save(child3);
        aclRepository.save(nonChild);

        // Act
        List<Sid> sids = new LinkedList<>();
        sids.add(new PrincipalSid(SecurityContextHolder.getContext().getAuthentication().getName()));

        List<ObjectIdentity> childObjects = aclService.findChildren(objectIdentity);
        //List<ObjectIdentity> childObjects = aclService.findChildren(new ObjectIdentityImpl(Class.forName(firstObject.getClass().getName()), firstObject.getId()));
        Map<ObjectIdentity, Acl> resultUser = aclService.readAclsById(childObjects, sids);

        // Assert
        assertThat(resultUser.keySet().size(), is(equalTo(1)));
    }

and aclService.findChildren has such exception:

java.lang.IllegalArgumentException: Principal required

	at org.springframework.util.Assert.hasText(Assert.java:181)
	at org.springframework.security.acls.domain.PrincipalSid.<init>(PrincipalSid.java:44)
	at org.springframework.security.acls.mongodb.BasicLookupStrategy.convertToAcl(BasicLookupStrategy.java:213)

exception of ReadAclsById twice.

unit test is a little modification from another test, I just want to compare result of two readAclsById, but get the exception.

    @Test
    @WithMockUser
    public void testReadAclsByIdTwice() throws Exception {
        // Arrange
        TestDomainObject domainObject = new TestDomainObject();
        TestDomainObject firstObject = new TestDomainObject();
        TestDomainObject secondObject = new TestDomainObject();
        TestDomainObject thirdObject = new TestDomainObject();
        TestDomainObject unrelatedObject = new TestDomainObject();

        ObjectIdentity objectIdentity = new ObjectIdentityImpl(Class.forName(domainObject.getClass().getName()), domainObject.getId());

        MongoAcl parent = new MongoAcl(domainObject.getId(), domainObject.getClass().getName(), UUID.randomUUID().toString(),"owner", null, true);
        MongoAcl child1 = new MongoAcl(firstObject.getId(), firstObject.getClass().getName(), UUID.randomUUID().toString(), "Tim Test", parent.getId(), true);
        MongoAcl child2 = new MongoAcl(secondObject.getId(), secondObject.getClass().getName(), UUID.randomUUID().toString(), "Petty Pattern", parent.getId(), true);
        MongoAcl child3 = new MongoAcl(thirdObject.getId(), thirdObject.getClass().getName(), UUID.randomUUID().toString(), "Sam Sample", parent.getId(), true);
        MongoAcl nonChild = new MongoAcl(unrelatedObject.getId(), unrelatedObject.getClass().getName(), UUID.randomUUID().toString());

        DomainObjectPermission permission = new DomainObjectPermission(UUID.randomUUID().toString(),
            "user-0",
            BasePermission.READ.getMask() | BasePermission.WRITE.getMask(),
            true, true, true);

        parent.getPermissions().add(permission);
        child1.getPermissions().add(permission);
        child2.getPermissions().add(permission);

        // MongoAcl must has owner

        aclRepository.save(parent);
        aclRepository.save(child1);
        aclRepository.save(child2);
        aclRepository.save(child3);
        aclRepository.save(nonChild);

        // Act
        List<Sid> sids = new LinkedList<>();
        sids.add(new PrincipalSid("user-0"));

        List<Sid> sids1 = new LinkedList<>();
        sids.add(new PrincipalSid("owner"));

        //List<ObjectIdentity> childObjects = aclService.findChildren(objectIdentity);
        List<ObjectIdentity> childObjects = aclService.findChildren(objectIdentity);

        //Map<ObjectIdentity, Acl> resultOwner = aclService.readAclsById(childObjects, sids1);
        Map<ObjectIdentity, Acl> resultUser = aclService.readAclsById(childObjects, sids);

        // Assert
        assertThat(childObjects.size(), is(equalTo(3)));
        assertThat(resultUser.keySet().size(), is(equalTo(3)));
        resultUser.values().removeIf(Objects::isNull);
        resultUser.keySet().forEach(objectIdentity1 -> {
            Acl acl = resultUser.get(objectIdentity1);
            System.out.println("ACE Size found: " + acl.getEntries().size());
        });
        assertThat(resultUser.keySet().size(), is(equalTo(3)));
    }

The Exception is:

java.lang.IllegalStateException: Error: SID-filtered element detected when implementation does not perform SID filtering - have you added something to the cache manually?

	at org.springframework.security.acls.mongodb.BasicLookupStrategy.readAclsById(BasicLookupStrategy.java:122)
	at org.springframework.security.acls.mongodb.MongoDBAclService.readAclsById(MongoDBAclService.java:96)
	at io.pinzi.security.AclUnitTest.testReadAclsByIdTwice(AclUnitTest.java:458)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

The strange thing is , if I comment anyone of next two lines, the code works ok:

        //Map<ObjectIdentity, Acl> resultOwner = aclService.readAclsById(childObjects, sids1);
        Map<ObjectIdentity, Acl> resultUser = aclService.readAclsById(childObjects, sids);

Release, release, release

How come this is not yet part of the official Spring Security release? Have you contacted anybody in the Spring community about it?
In case they are not willing to embrace this for whatever reason, can I suggest you release this independently, so that we can pull a dependency rather than building it locally?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.