ExpectAces implements ProgressCheckFactory { @NotNull public static JsonKeys keys() { return KEYS; }  @NotNull static JsonKeys keys(); @Override ProgressCheck newInstance(final JsonObject config); @Deprecated
    static final String CONFIG_PRINCIPAL; @Deprecated
    static final String CONFIG_PRINCIPALS; @Deprecated
    static final String CONFIG_EXPECTED_ACES; @Deprecated
    static final String CONFIG_NOT_EXPECTED_ACES; @Deprecated
    static final String CONFIG_AFTER_PACKAGE_ID_RULES; @Deprecated
    static final String ACE_PARAM_TYPE; @Deprecated
    static final String ACE_PARAM_PRIVILEGES; @Deprecated
    static final String ACE_PARAM_PATH; static final String DELIM_PARAM; static final String DELIM_VALUE; static final String DELIM_LIST; }
@Test public void testNewInstance_expectedAces() throws Exception { final String principal = "nouser"; final String spec = "type=allow;path=/foo1;privileges=jcr:read"; final List<ExpectAces.AceCriteria> expectCriterias = Collections.singletonList( ExpectAces.AceCriteria.parse(principal, spec).getOrDefault(null) ); ExpectAces.Check check1 = checkFor(key("principal", principal) .key(ExpectAces.keys().expectedAces(), arr(spec)).get()); Assert.assertEquals("expect expectedAces", expectCriterias, check1.expectedAces); }
@Test public void testNewInstance_notExpectedAces() throws Exception { final String principal = "nouser"; final String spec = "type=allow;path=/foo1;privileges=jcr:read"; final List<ExpectAces.AceCriteria> expectCriterias = Collections.singletonList( ExpectAces.AceCriteria.parse(principal, spec).getOrDefault(null) ); ExpectAces.Check check1 = checkFor(key("principal", principal) .key(ExpectAces.keys().notExpectedAces(), arr(spec)).get()); Assert.assertEquals("expect notExpectedAces", expectCriterias, check1.notExpectedAces); }
@Test public void testCheck_startedScan() throws Exception { ExpectAces.Check check = checkFor(obj() .key(ExpectAces.keys().principal(), "nouser") .key(ExpectAces.keys().expectedAces(), arr() .val("type=allow;path=/foo1;privileges=jcr:read") .val("type=allow;path=/foo1;privileges=rep:write") ) .key(ExpectAces.keys().notExpectedAces(), arr() .val("type=allow;path=/foo2;privileges=jcr:read") .val("type=allow;path=/foo2;privileges=rep:write") .val("type=allow;path=/foo3;privileges=rep:write") ) .get()); final Principal principal = new PrincipalImpl("nouser"); new OakMachine.Builder().build().adminInitAndInspect(session -> { final JackrabbitAccessControlManager accessControlManager = (JackrabbitAccessControlManager) session.getAccessControlManager(); final PrivilegeManager privilegeManager = ((JackrabbitWorkspace) session.getWorkspace()).getPrivilegeManager(); final Privilege jcrRead = privilegeManager.getPrivilege("jcr:read"); final Node foo1 = session.getRootNode().addNode("foo1", resolver.getJCRName(NameConstants.NT_FOLDER)); foo1.addMixin("rep:AccessControllable"); final Node foo2 = session.getRootNode().addNode("foo2", resolver.getJCRName(NameConstants.NT_FOLDER)); foo2.addMixin("rep:AccessControllable"); session.save(); for (String path : new String[]{"/foo1", "/foo2"}) { for (AccessControlPolicyIterator policyIt = accessControlManager.getApplicablePolicies(path); policyIt.hasNext(); ) { AccessControlPolicy policy = policyIt.nextAccessControlPolicy(); if (policy instanceof JackrabbitAccessControlList) { JackrabbitAccessControlList acl = (JackrabbitAccessControlList) policy; acl.addEntry(principal, new Privilege[]{jcrRead}, true); accessControlManager.setPolicy(path, acl); } } } check.afterExtract(PackageId.fromString("foo"), session); check.startedScan(); check.afterExtract(PackageId.fromString("foo"), session); check.afterExtract(PackageId.fromString("foo"), session); check.finishedScan(); }); Assert.assertEquals("expected violation count", 1, check.getReportedViolations().stream().filter(viol -> viol.getDescription().startsWith("expected: ")).count()); Assert.assertEquals("expected violated spec ends with rep:write", 1, check.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("expected: ") && viol.getDescription().endsWith("rep:write")).count()); Assert.assertEquals("unexpected violation count", 1, check.getReportedViolations().stream().filter(viol -> viol.getDescription().startsWith("unexpected: ")).count()); Assert.assertEquals("unexpected violated spec ends with jcr:read", 1, check.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("unexpected: ") && viol.getDescription().endsWith("jcr:read")).count()); }
@Test public void testShouldExpectAfterExtract() throws Exception { ExpectAces.Check check1 = checkFor(key("principal", "nouser").get()); assertTrue("expect true for empty", check1.shouldExpectAfterExtract(PackageId.fromString("foo"))); ExpectAces.Check check2 = checkFor(key("principal", "nouser") .key(ExpectAces.keys().afterPackageIdRules(), arr().val(key("type", "include").key("pattern", "^my_packages:.*"))).get()); assertFalse("expect false", check2.shouldExpectAfterExtract(PackageId.fromString("adamcin:test:1.0"))); assertTrue("expect true", check2.shouldExpectAfterExtract(PackageId.fromString("my_packages:test:1.0"))); }
@Test public void testSuppressAfterExtractViolationIfExpectationSatisfiedAfterScanPackage() throws Exception { final PackageId fooId = PackageId.fromString("some"); final PackageId barEmbedId = PackageId.fromString("other"); final EmbeddedPackageInstallable installable = new EmbeddedPackageInstallable(fooId, "", barEmbedId); ExpectAces.Check check = checkFor(obj() .key(ExpectAces.keys().principal(), "nouser") .key("ignoreNestedPackages", true) .key(ExpectAces.keys().expectedAces(), arr() .val("type=allow;path=/foo1;privileges=jcr:read") .val("type=allow;path=/foo1;privileges=rep:write") ) .key(ExpectAces.keys().notExpectedAces(), arr() .val("type=allow;path=/foo2;privileges=jcr:read") .val("type=allow;path=/foo2;privileges=rep:write") .val("type=allow;path=/foo3;privileges=rep:write") ) .get()); final Principal principal = new PrincipalImpl("nouser"); new OakMachine.Builder().build().adminInitAndInspect(session -> { final JackrabbitAccessControlManager accessControlManager = (JackrabbitAccessControlManager) session.getAccessControlManager(); final PrivilegeManager privilegeManager = ((JackrabbitWorkspace) session.getWorkspace()).getPrivilegeManager(); final Privilege jcrRead = privilegeManager.getPrivilege("jcr:read"); final Node foo1 = session.getRootNode().addNode("foo1", resolver.getJCRName(NameConstants.NT_FOLDER)); foo1.addMixin("rep:AccessControllable"); final Node foo2 = session.getRootNode().addNode("foo2", resolver.getJCRName(NameConstants.NT_FOLDER)); foo2.addMixin("rep:AccessControllable"); session.save(); for (String path : new String[]{"/foo1", "/foo2"}) { for (AccessControlPolicyIterator policyIt = accessControlManager.getApplicablePolicies(path); policyIt.hasNext(); ) { AccessControlPolicy policy = policyIt.nextAccessControlPolicy(); if (policy instanceof JackrabbitAccessControlList) { JackrabbitAccessControlList acl = (JackrabbitAccessControlList) policy; acl.addEntry(principal, new Privilege[]{jcrRead}, true); accessControlManager.setPolicy(path, acl); } } } check.startedScan(); check.identifyPackage(fooId, null); check.afterExtract(fooId, session); check.beforeSlingInstall(fooId, installable, session); check.identifyEmbeddedPackage(barEmbedId, fooId, installable); check.afterExtract(barEmbedId, session); check.afterScanPackage(fooId, session); check.finishedScan(); }); Assert.assertEquals("expected violation count", 1, check.getReportedViolations().stream().filter(viol -> viol.getDescription().startsWith("expected: ")).count()); Assert.assertEquals("expected violated spec ends with rep:write", 1, check.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("expected: ") && viol.getDescription().endsWith("rep:write")).count()); Assert.assertEquals("unexpected violation count", 1, check.getReportedViolations().stream().filter(viol -> viol.getDescription().startsWith("unexpected: ")).count()); Assert.assertEquals("unexpected violated spec ends with jcr:read", 1, check.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("unexpected: ") && viol.getDescription().endsWith("jcr:read")).count()); new OakMachine.Builder().build().adminInitAndInspect(session -> { final JackrabbitAccessControlManager accessControlManager = (JackrabbitAccessControlManager) session.getAccessControlManager(); final PrivilegeManager privilegeManager = ((JackrabbitWorkspace) session.getWorkspace()).getPrivilegeManager(); final Privilege jcrRead = privilegeManager.getPrivilege("jcr:read"); final Node foo1 = session.getRootNode().addNode("foo1", resolver.getJCRName(NameConstants.NT_FOLDER)); foo1.addMixin("rep:AccessControllable"); final Node foo2 = session.getRootNode().addNode("foo2", resolver.getJCRName(NameConstants.NT_FOLDER)); foo2.addMixin("rep:AccessControllable"); session.save(); for (String path : new String[]{"/foo1", "/foo2"}) { for (AccessControlPolicyIterator policyIt = accessControlManager.getApplicablePolicies(path); policyIt.hasNext(); ) { AccessControlPolicy policy = policyIt.nextAccessControlPolicy(); if (policy instanceof JackrabbitAccessControlList) { JackrabbitAccessControlList acl = (JackrabbitAccessControlList) policy; acl.addEntry(principal, new Privilege[]{jcrRead}, true); accessControlManager.setPolicy(path, acl); } } } check.startedScan(); check.identifyPackage(fooId, null); check.afterExtract(fooId, session); check.beforeSlingInstall(fooId, installable, session); check.identifyEmbeddedPackage(barEmbedId, fooId, installable); foo2.remove(); check.afterExtract(barEmbedId, session); check.afterScanPackage(fooId, session); check.finishedScan(); }); Assert.assertEquals("expected violation count", 1, check.getReportedViolations().stream().filter(viol -> viol.getDescription().startsWith("expected: ")).count()); Assert.assertEquals("expected violated spec ends with rep:write", 1, check.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("expected: ") && viol.getDescription().endsWith("rep:write")).count()); Assert.assertEquals("no unexpected violations", 0, check.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("unexpected: ")).count()); }
@Test public void testSuppressAfterExtractViolationIfExpectationSatisfiedAfterScanPackage_multipleViolators() throws Exception { final String foo1 = "/foo1"; final String foo2 = "/foo2"; final PackageId container = PackageId.fromString("container"); final PackageId embed1 = PackageId.fromString("embed1"); SlingInstallable installable1 = mock(SlingInstallable.class); when(installable1.getParentId()).thenReturn(embed1); EmbeddedPackageInstallable epInstallable1 = new EmbeddedPackageInstallable(container, "", embed1); final PackageId embed2 = PackageId.fromString("embed2"); SlingInstallable installable2 = mock(SlingInstallable.class); when(installable2.getParentId()).thenReturn(embed2); EmbeddedPackageInstallable epInstallable2 = new EmbeddedPackageInstallable(container, "", embed2); final PackageId embed3 = PackageId.fromString("embed3"); SlingInstallable installable3 = mock(SlingInstallable.class); when(installable3.getParentId()).thenReturn(embed3); EmbeddedPackageInstallable epInstallable3 = new EmbeddedPackageInstallable(container, "", embed3); final Principal principal = new PrincipalImpl("nouser"); final List<String> repoInits = Arrays.asList( "create service user nouser", "create path (nt:folder) /foo1", "set ACL on /foo1", " allow jcr:read for nouser", "end", "create path (nt:folder) /foo2", "set ACL on /foo2", " allow jcr:read for nouser", "end" ); final ExpectAces.Check check1 = checkFor(obj() .key(ExpectAces.keys().principal(), "nouser") .key(ExpectAces.keys().expectedAces(), arr() .val("type=allow;path=/foo1;privileges=jcr:read") .val("type=allow;path=/foo1;privileges=rep:write") ) .get()); new OakpalPlan.Builder(null, null) .withRepoInits(repoInits) .build().toOakMachineBuilder(null, getClass().getClassLoader()).build() .adminInitAndInspect(session -> { check1.startedScan(); check1.identifyPackage(container, null); check1.afterExtract(container, session); check1.beforeSlingInstall(container, epInstallable1, session); check1.identifyEmbeddedPackage(embed1, container, epInstallable1); check1.afterExtract(embed1, session); check1.beforeSlingInstall(container, epInstallable2, session); check1.identifyEmbeddedPackage(embed2, container, epInstallable2); check1.afterExtract(embed2, session); check1.beforeSlingInstall(container, epInstallable3, session); check1.identifyEmbeddedPackage(embed3, container, epInstallable3); check1.afterExtract(embed3, session); check1.beforeSlingInstall(container, installable1, session); check1.beforeSlingInstall(container, installable2, session); check1.beforeSlingInstall(container, installable3, session); check1.afterScanPackage(container, session); check1.finishedScan(); }); Assert.assertEquals("expected violation count", 1, check1.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("expected: ")).count()); Assert.assertEquals("expected violated spec ends with rep:write", 1, check1.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("expected: ") && viol.getDescription().contains("/foo1") && viol.getDescription().endsWith("rep:write")).count()); Assert.assertEquals("no unexpected violations", 0, check1.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("unexpected: ")).count()); final Violation exViolation1 = check1.getReportedViolations().stream().findFirst().get(); assertEquals("expected violators", Stream.of(container).collect(Collectors.toSet()), new HashSet<>(exViolation1.getPackages())); new OakpalPlan.Builder(null, null) .withRepoInits(repoInits) .build().toOakMachineBuilder(null, getClass().getClassLoader()).build() .adminInitAndInspect(session -> { check1.startedScan(); check1.identifyPackage(container, null); check1.afterExtract(container, session); check1.beforeSlingInstall(container, epInstallable1, session); check1.identifyEmbeddedPackage(embed1, container, epInstallable1); resetAcl(session.getNode(foo1), (acl, privMan) -> { Stream.of(acl.getAccessControlEntries()) .filter(composeTest1(AccessControlEntry::getPrincipal, principal::equals)) .forEachOrdered(uncheckVoid1(acl::removeAccessControlEntry)); acl.addEntry(principal, new Privilege[]{privMan.getPrivilege("rep:write")}, true); }); check1.afterExtract(embed1, session); check1.beforeSlingInstall(container, epInstallable2, session); check1.identifyEmbeddedPackage(embed2, container, epInstallable2); check1.afterExtract(embed2, session); check1.beforeSlingInstall(container, epInstallable3, session); check1.identifyEmbeddedPackage(embed3, container, epInstallable3); check1.afterExtract(embed3, session); check1.beforeSlingInstall(container, installable1, session); check1.beforeSlingInstall(container, installable2, session); check1.beforeSlingInstall(container, installable3, session); check1.afterScanPackage(container, session); check1.finishedScan(); }); Assert.assertEquals("expected violation count", 1, check1.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("expected: ")).count()); Assert.assertEquals("expected violated spec ends with jcr:read", 1, check1.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("expected: ") && viol.getDescription().contains("/foo1") && viol.getDescription().endsWith("jcr:read")).count()); Assert.assertEquals("no unexpected violations", 0, check1.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("unexpected: ")).count()); final Violation exViolation2 = check1.getReportedViolations().stream().findFirst().get(); assertEquals("expected violators", Stream.of(embed1, container).collect(Collectors.toSet()), new HashSet<>(exViolation2.getPackages())); final ExpectAces.Check check2 = checkFor(obj() .key(ExpectAces.keys().principal(), "nouser") .key(ExpectAces.keys().notExpectedAces(), arr() .val("type=allow;path=/foo2;privileges=jcr:read") .val("type=allow;path=/foo2;privileges=rep:write") .val("type=allow;path=/foo3;privileges=rep:write") ) .get()); new OakpalPlan.Builder(null, null) .withRepoInits(repoInits) .build().toOakMachineBuilder(null, getClass().getClassLoader()).build() .adminInitAndInspect(session -> { check2.startedScan(); check2.identifyPackage(container, null); check2.afterExtract(container, session); check2.beforeSlingInstall(embed1, epInstallable1, session); check2.identifyEmbeddedPackage(embed1, container, epInstallable1); check2.afterExtract(embed1, session); check2.beforeSlingInstall(embed2, epInstallable2, session); check2.identifyEmbeddedPackage(embed2, container, epInstallable2); check2.afterExtract(embed2, session); check2.beforeSlingInstall(embed3, epInstallable3, session); check2.identifyEmbeddedPackage(embed3, container, epInstallable3); check2.afterExtract(embed3, session); check2.beforeSlingInstall(container, installable1, session); check2.beforeSlingInstall(container, installable2, session); check2.beforeSlingInstall(container, installable3, session); check2.afterScanPackage(container, session); check2.finishedScan(); }); Assert.assertEquals("unexpected violation count", 1, check2.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("unexpected: ")).count()); Assert.assertEquals("unexpected violated spec ends with jcr:read", 1, check2.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("unexpected: ") && viol.getDescription().contains("/foo2") && viol.getDescription().endsWith("jcr:read")).count()); Assert.assertEquals("no expected violations", 0, check2.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("expected: ")).count()); final Violation unViolation1 = check2.getReportedViolations().stream().findFirst().get(); assertEquals("expected violators", Stream.of(container).collect(Collectors.toSet()), new HashSet<>(unViolation1.getPackages())); new OakpalPlan.Builder(null, null) .withRepoInits(repoInits) .build().toOakMachineBuilder(null, getClass().getClassLoader()).build() .adminInitAndInspect(session -> { check2.startedScan(); check2.identifyPackage(container, null); resetAcl(session.getNode(foo2), (acl, priv) -> { Stream.of(acl.getAccessControlEntries()) .forEachOrdered(uncheckVoid1(acl::removeAccessControlEntry)); }); check2.afterExtract(container, session); check2.beforeSlingInstall(embed1, epInstallable1, session); check2.identifyEmbeddedPackage(embed1, container, epInstallable1); resetAcl(session.getNode(foo2), (acl, priv) -> { acl.addEntry(principal, Stream.of("rep:write") .map(uncheck1(priv::getPrivilege)).toArray(Privilege[]::new), true); }); check2.afterExtract(embed1, session); check2.beforeSlingInstall(embed2, epInstallable2, session); check2.identifyEmbeddedPackage(embed2, container, epInstallable2); check2.afterExtract(embed2, session); check2.beforeSlingInstall(embed3, epInstallable3, session); check2.identifyEmbeddedPackage(embed3, container, epInstallable3); session.getNode(foo2).remove(); check2.afterExtract(embed3, session); check2.beforeSlingInstall(container, installable1, session); check2.beforeSlingInstall(container, installable2, session); Node node3 = JcrUtils.getOrCreateByPath("/foo3", "nt:folder", session); resetAcl(node3, (acl, priv) -> { acl.addEntry(principal, new Privilege[]{priv.getPrivilege("rep:write")}, true); }); check2.appliedRepoInitScripts(container, Collections.emptyList(), installable2, session); check2.beforeSlingInstall(container, installable3, session); check2.afterScanPackage(container, session); check2.finishedScan(); }); assertEquals("expect 2 unexpected violations", 2, check2.getReportedViolations().size()); final Collection<Violation> unViolations = check2.getReportedViolations(); assertTrue("all start with unexpected " + unViolations, unViolations.stream() .allMatch(vio -> vio.getDescription().startsWith("unexpected: "))); assertEquals("one contains /foo2: " + unViolations, 1, unViolations.stream() .filter(vio -> vio.getDescription().contains("/foo2")).count()); assertEquals("one contains /foo3: " + unViolations, 1, unViolations.stream() .filter(vio -> vio.getDescription().contains("/foo3")).count()); assertEquals("expected violators of /foo2", Stream.of(embed1).collect(Collectors.toSet()), unViolations.stream() .filter(vio -> vio.getDescription().contains("/foo2")) .flatMap(Fun.compose1(Violation::getPackages, Collection::stream)) .collect(Collectors.toSet())); assertEquals("expected violators of /foo3", Stream.of(embed2, container).collect(Collectors.toSet()), unViolations.stream() .filter(vio -> vio.getDescription().contains("/foo3")) .flatMap(Fun.compose1(Violation::getPackages, Collection::stream)) .collect(Collectors.toSet())); }
@Test public void testBeforeSlingInstallAndAfterScanPackage() throws Exception { ExpectAces.Check check = checkFor(obj() .key(ExpectAces.keys().principal(), "nouser") .key(ExpectAces.keys().expectedAces(), arr() .val("type=allow;path=/foo1;privileges=jcr:read") .val("type=allow;path=/foo1;privileges=rep:write") ) .key(ExpectAces.keys().notExpectedAces(), arr() .val("type=allow;path=/foo2;privileges=jcr:read") .val("type=allow;path=/foo2;privileges=rep:write") .val("type=allow;path=/foo3;privileges=rep:write") ) .get()); final Principal principal = new PrincipalImpl("nouser"); new OakMachine.Builder().build().adminInitAndInspect(session -> { final JackrabbitAccessControlManager accessControlManager = (JackrabbitAccessControlManager) session.getAccessControlManager(); final PrivilegeManager privilegeManager = ((JackrabbitWorkspace) session.getWorkspace()).getPrivilegeManager(); final Privilege jcrRead = privilegeManager.getPrivilege("jcr:read"); final Node foo1 = session.getRootNode().addNode("foo1", resolver.getJCRName(NameConstants.NT_FOLDER)); foo1.addMixin("rep:AccessControllable"); final Node foo2 = session.getRootNode().addNode("foo2", resolver.getJCRName(NameConstants.NT_FOLDER)); foo2.addMixin("rep:AccessControllable"); session.save(); for (String path : new String[]{"/foo1", "/foo2"}) { for (AccessControlPolicyIterator policyIt = accessControlManager.getApplicablePolicies(path); policyIt.hasNext(); ) { AccessControlPolicy policy = policyIt.nextAccessControlPolicy(); if (policy instanceof JackrabbitAccessControlList) { JackrabbitAccessControlList acl = (JackrabbitAccessControlList) policy; acl.addEntry(principal, new Privilege[]{jcrRead}, true); accessControlManager.setPolicy(path, acl); } } } check.afterExtract(PackageId.fromString("foo"), session); check.startedScan(); check.afterExtract(PackageId.fromString("foo"), session); check.afterExtract(PackageId.fromString("foo"), session); check.finishedScan(); }); Assert.assertEquals("expected violation count", 1, check.getReportedViolations().stream().filter(viol -> viol.getDescription().startsWith("expected: ")).count()); Assert.assertEquals("expected violated spec ends with rep:write", 1, check.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("expected: ") && viol.getDescription().endsWith("rep:write")).count()); Assert.assertEquals("unexpected violation count", 1, check.getReportedViolations().stream().filter(viol -> viol.getDescription().startsWith("unexpected: ")).count()); Assert.assertEquals("unexpected violated spec ends with jcr:read", 1, check.getReportedViolations().stream() .filter(viol -> viol.getDescription().startsWith("unexpected: ") && viol.getDescription().endsWith("jcr:read")).count()); }