UserQueryManager { @NotNull public Iterator<Authorizable> findAuthorizables(@NotNull Query query) throws RepositoryException { XPathQueryBuilder builder = new XPathQueryBuilder(); query.build(builder); if (builder.getMaxCount() == 0) { return Collections.emptyIterator(); } String statement = buildXPathStatement(builder); final String groupId = builder.getGroupID(); if (groupId == null || isEveryone(groupId)) { long offset = builder.getOffset(); Iterator<Authorizable> result = findAuthorizables(statement, builder.getMaxCount(), offset, null); if (groupId == null) { return result; } else { return Iterators.filter(result, authorizable -> !groupId.equals(getID(authorizable))); } } else { Iterator<Authorizable> result = findAuthorizables(statement, Long.MAX_VALUE, 0, null); Predicate<Authorizable> filter; if (builder.isDeclaredMembersOnly()) { filter = new DeclaredMembershipPredicate(userManager, groupId); } else { filter = new GroupPredicate(userManager, groupId, false); } return ResultIterator.create(builder.getOffset(), builder.getMaxCount(), Iterators.filter(result, filter)); } } UserQueryManager(@NotNull UserManagerImpl userManager,
                            @NotNull NamePathMapper namePathMapper,
                            @NotNull ConfigurationParameters config,
                            @NotNull Root root); @NotNull Iterator<Authorizable> findAuthorizables(@NotNull Query query); @NotNull Iterator<Authorizable> findAuthorizables(@NotNull String relPath,
                                                    @Nullable String value,
                                                    @NotNull AuthorizableType authorizableType); @NotNull Iterator<Authorizable> findAuthorizables(@NotNull String relPath,
                                                    @Nullable String value,
                                                    @NotNull AuthorizableType authorizableType,
                                                    boolean exact);  }
@Test public void testFindNodesExact() throws Exception { Value vs = valueFactory.createValue("value \\, containing backslash"); user.setProperty(propertyName, vs); root.commit(); Iterator<Authorizable> result = queryMgr.findAuthorizables(propertyName, "value \\, containing backslash", AuthorizableType.USER, true); assertResultContainsAuthorizables(result, user); }
@Test public void testFindNodesNonExact() throws Exception { Value vs = valueFactory.createValue("value \\, containing backslash"); user.setProperty(propertyName, vs); root.commit(); Iterator<Authorizable> result = queryMgr.findAuthorizables(propertyName, "value \\, containing backslash", AuthorizableType.USER, false); assertResultContainsAuthorizables(result, user); }
@Test public void testFindNodesNonExactWithApostrophe() throws Exception { Value vs = valueFactory.createValue("value ' with apostrophe"); user.setProperty(propertyName, vs); root.commit(); Iterator<Authorizable> result = queryMgr.findAuthorizables(propertyName, "value ' with apostrophe", AuthorizableType.USER, false); assertResultContainsAuthorizables(result, user); }
@Test public void testFindNodesExactWithApostrophe() throws Exception { Value vs = valueFactory.createValue("value ' with apostrophe"); user.setProperty(propertyName, vs); root.commit(); Iterator<Authorizable> result = queryMgr.findAuthorizables(propertyName, "value ' with apostrophe", AuthorizableType.USER, true); assertResultContainsAuthorizables(result, user); }
@Test public void testFindWithCurrentRelPathTypeMismatch() throws Exception { user.setProperty(propertyName, v); root.commit(); Iterator<Authorizable> result = queryMgr.findAuthorizables("./" + propertyName, v.getString(), AuthorizableType.GROUP, false); assertResultContainsAuthorizables(result); }
@Test public void testFindWithCurrentRelPath() throws Exception { user.setProperty(propertyName, v); root.commit(); Iterator<Authorizable> result = queryMgr.findAuthorizables("./" + propertyName, v.getString(), AuthorizableType.USER, false); assertResultContainsAuthorizables(result, user); }
@Test public void testFindWithRelPath() throws Exception { user.setProperty(propertyName, v); root.commit(); Iterator<Authorizable> result = queryMgr.findAuthorizables("rel/path/to/" + propertyName, v.getString(), AuthorizableType.USER, false); assertResultContainsAuthorizables(result); }
@Test public void testFindWithRelPathMultipleSelectorNames() throws Exception { user.setProperty(propertyName, v); Group g = createGroup("g", null); g.setProperty("rel/path/to/" + propertyName, v); root.commit(); for (AuthorizableType type : new AuthorizableType[] {AuthorizableType.AUTHORIZABLE, AuthorizableType.GROUP}) { Iterator<Authorizable> result = queryMgr.findAuthorizables("rel/path/to/" + propertyName, v.getString(), type, false); assertResultContainsAuthorizables(result, g); } }
@Test public void testFindWithRelPathTypeMismatch() throws Exception { user.setProperty(propertyName, v); Group g = createGroup("g", null); g.setProperty("rel/path/to/" + propertyName, v); root.commit(); Iterator<Authorizable> result = queryMgr.findAuthorizables("rel/path/to/" + propertyName, v.getString(), AuthorizableType.USER, false); assertResultContainsAuthorizables(result); }
@Test public void testFilterDuplicateResults() throws Exception { user.setProperty(propertyName, v); user.setProperty("rel/path/to/" + propertyName, v); root.commit(); Iterator<Authorizable> result = queryMgr.findAuthorizables(propertyName, v.getString(), AuthorizableType.AUTHORIZABLE, false); assertResultContainsAuthorizables(result, user); }
@Test public void testQueryMaxCountZero() throws Exception { Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> queryBuilder) { queryBuilder.setLimit(0, 0); } }; assertSame(Collections.emptyIterator(), queryMgr.findAuthorizables(q)); }
@Test public void testQueryScopeEveryoneNonExisting() throws Exception { String userId = user.getID(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.nameMatches(userId)); builder.setScope(EveryonePrincipal.NAME, false); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result, user); }
@Test public void testQueryScopeEveryoneFiltersEveryone() throws Exception { Group g = createGroup(null, EveryonePrincipal.getInstance()); g.setProperty(propertyName, v); user.setProperty(propertyName, v); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.eq(propertyName, v)); builder.setScope(EveryonePrincipal.NAME, false); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result, user); }
@Test public void testQueryScopeEveryoneWithIdDiffersPrincipalName() throws Exception { Group g = createGroup("eGroup", EveryonePrincipal.getInstance()); g.setProperty(propertyName, v); user.setProperty(propertyName, v); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.eq(propertyName, v)); builder.setScope("eGroup", false); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result, user); }
@Test public void testQueryNoScope() throws Exception { Group g = createGroup(null, EveryonePrincipal.getInstance()); g.setProperty(propertyName, v); user.setProperty(propertyName, v); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.eq(propertyName, v)); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result, user, g); }
@Test public void testQueryScopeNotMember() throws Exception { createGroup("g1", null); user.setProperty(propertyName, v); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.eq(propertyName, v)); builder.setScope("g1", false); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result); }
@Test public void testQueryScopeDeclaredMember() throws Exception { Group g = createGroup("g1", null); g.addMember(user); user.setProperty(propertyName, v); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.eq(propertyName, v)); builder.setScope("g1", false); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result, user); }
@Test public void testQueryScopeDeclaredMembership() throws Exception { Group g = createGroup("g1", null); Group g2 = createGroup("g2", null); g.addMember(g2); g2.addMember(user); user.setProperty(propertyName, v); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.eq(propertyName, v)); builder.setScope("g1", true); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result); }
@Test public void testQueryScopeInheritedMembership() throws Exception { Group g = createGroup("g1", null); Group g2 = createGroup("g2", null); g.addMember(g2); g2.addMember(user); user.setProperty(propertyName, v); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.eq(propertyName, v)); builder.setScope("g1", false); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result, user); }
@Test public void testQueryBoundWithoutSortOrder() throws Exception { Group g = createGroup("g1", null); g.setProperty(propertyName, valueFactory.createValue(50)); Group g2 = createGroup("g2", null); g2.setProperty(propertyName, valueFactory.createValue(60)); user.setProperty(propertyName, valueFactory.createValue(101)); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setLimit(valueFactory.createValue(100), Long.MAX_VALUE); builder.setCondition(builder.gt(propertyName, valueFactory.createValue(20))); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result, user, g, g2); }
@Test public void testQueryBoundWithSortOrder() throws Exception { Group g = createGroup("g1", null); g.setProperty(propertyName, valueFactory.createValue(50)); Group g2 = createGroup("g2", null); g2.setProperty(propertyName, valueFactory.createValue(60)); user.setProperty(propertyName, valueFactory.createValue(101)); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setLimit(valueFactory.createValue(100), Long.MAX_VALUE); builder.setSortOrder(propertyName, QueryBuilder.Direction.ASCENDING); builder.setCondition(builder.gt(propertyName, valueFactory.createValue(20))); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result, user); }
@Test public void testQueryBoundWithSortOrderMissingCondition() throws Exception { Group g = createGroup("g1", null); g.setProperty(propertyName, valueFactory.createValue(50)); Group g2 = createGroup("g2", null); g2.setProperty(propertyName, valueFactory.createValue(60)); user.setProperty(propertyName, valueFactory.createValue(101)); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setLimit(valueFactory.createValue(100), Long.MAX_VALUE); builder.setSortOrder(propertyName, QueryBuilder.Direction.ASCENDING); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result, user); }
@Test public void testQuerySortIgnoreCase() throws Exception { Group g = createGroup("g1", null); g.setProperty(propertyName, valueFactory.createValue("aaa")); Group g2 = createGroup("g2", null); g2.setProperty(propertyName, valueFactory.createValue("BBB")); user.setProperty(propertyName, valueFactory.createValue("c")); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.exists(propertyName)); builder.setSortOrder(propertyName, QueryBuilder.Direction.DESCENDING, true); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertEquals(ImmutableList.of(user, g2, g), ImmutableList.copyOf(result)); }
@Test public void testQuerySortRespectCase() throws Exception { Group g = createGroup("g1", null); g.setProperty(propertyName, valueFactory.createValue("aaa")); Group g2 = createGroup("g2", null); g2.setProperty(propertyName, valueFactory.createValue("BBB")); user.setProperty(propertyName, valueFactory.createValue("c")); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.exists(propertyName)); builder.setSortOrder(propertyName, QueryBuilder.Direction.DESCENDING, false); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertEquals(ImmutableList.of(user, g, g2), ImmutableList.copyOf(result)); }
@Test public void testQueryNameMatchesWithUnderscoreId() throws Exception { Group g = createGroup("group_with_underscore", null); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.nameMatches("group_with_underscore")); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result, g); }
@Test public void testQueryNameMatchesWithUnderscorePrincipalName() throws Exception { Group g = createGroup("g", new PrincipalImpl("group_with_underscore")); root.commit(); Query q = new Query() { @Override public <T> void build(@NotNull QueryBuilder<T> builder) { builder.setCondition(builder.nameMatches("group_with_underscore")); } }; Iterator<Authorizable> result = queryMgr.findAuthorizables(q); assertResultContainsAuthorizables(result, g); }
@Test public void testFindWhenRootTreeIsSearchRoot() throws Exception { ConfigurationParameters config = ConfigurationParameters.of(PARAM_GROUP_PATH, PathUtils.ROOT_PATH); SecurityProvider sp = SecurityProviderBuilder.newBuilder().with(ConfigurationParameters.of(UserConfiguration.NAME, config)).withRootProvider(getRootProvider()).withTreeProvider(getTreeProvider()).build(); UserManagerImpl umgr = new UserManagerImpl(root, getPartialValueFactory(), sp); UserQueryManager uqm = new UserQueryManager(umgr, getNamePathMapper(), config, root); Iterator<Authorizable> result = uqm.findAuthorizables(REP_AUTHORIZABLE_ID, DEFAULT_ADMIN_ID, AuthorizableType.AUTHORIZABLE); assertTrue(result.hasNext()); }
@Test public void testFindReservedProperty() throws Exception { user.setProperty("subtree/"+REP_DISABLED, valueFactory.createValue("disabled")); Iterator<Authorizable> result = queryMgr.findAuthorizables(REP_DISABLED, "disabled", AuthorizableType.USER); assertFalse(result.hasNext()); user.removeProperty("subtree/"+REP_DISABLED); user.disable("disabled"); result = queryMgr.findAuthorizables(REP_DISABLED, "disabled", AuthorizableType.USER); assertTrue(result.hasNext()); }
@Test public void testFindResultNotAccessible() throws Exception { user.setProperty("profile/name", valueFactory.createValue("userName")); AccessControlManager acMgr = getAccessControlManager(root); JackrabbitAccessControlList acl = AccessControlUtils.getAccessControlList(acMgr, PathUtils.concat(user.getPath(), "profile")); if (acl != null && acl.addAccessControlEntry(user.getPrincipal(), privilegesFromNames(JCR_READ))) { acMgr.setPolicy(acl.getPath(), acl); } root.commit(); try (ContentSession cs = login(new SimpleCredentials(user.getID(), user.getID().toCharArray()))) { Root r = cs.getLatestRoot(); UserManagerImpl uMgr = new UserManagerImpl(r, getPartialValueFactory(), getSecurityProvider()); UserQueryManager uqm = new UserQueryManager(uMgr, getNamePathMapper(), ConfigurationParameters.EMPTY, r); Iterator<Authorizable> result = uqm.findAuthorizables("name", "userName", AuthorizableType.USER); assertFalse(result.hasNext()); } }