You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2018/08/09 02:24:42 UTC
[sling-org-apache-sling-app-cms] 06/07: Adding the ability to
perform search as an elevated permissions user
This is an automated email from the ASF dual-hosted git repository.
dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git
commit 8820eb13c534fbe7df1b85e9c0935a9c394d6093
Author: Dan Klco <dk...@apache.org>
AuthorDate: Wed Aug 8 22:24:12 2018 -0400
Adding the ability to perform search as an elevated permissions user
---
.../apache/sling/cms/reference/SearchService.java | 43 ++++++++++
.../cms/reference/impl/SearchServiceImpl.java | 94 ++++++++++++++++++++++
.../apache/sling/cms/reference/models/Search.java | 28 ++++++-
.../main/resources/OSGI-INF/l10n/bundle.properties | 32 ++++++++
.../reference/components/general/search/search.jsp | 2 +-
5 files changed, 196 insertions(+), 3 deletions(-)
diff --git a/reference/src/main/java/org/apache/sling/cms/reference/SearchService.java b/reference/src/main/java/org/apache/sling/cms/reference/SearchService.java
new file mode 100644
index 0000000..1261e4a
--- /dev/null
+++ b/reference/src/main/java/org/apache/sling/cms/reference/SearchService.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.cms.reference;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.ResourceResolver;
+
+/**
+ * Service for managing the search user.
+ */
+public interface SearchService {
+
+ /**
+ * Closes the resource resolver if appropriate
+ *
+ * @param resolver the resource resolver used in search
+ */
+ void finalize(ResourceResolver resolver);
+
+ /**
+ * Gets either the service user resource resolver of the request resource
+ * resolver depending if the service user is configured.
+ *
+ * @param request the request from which to retrieve the request resource
+ * resolver (if service user not configured)
+ * @return the appropriate resource resolvers
+ */
+ public ResourceResolver getResourceResolver(SlingHttpServletRequest request);
+}
diff --git a/reference/src/main/java/org/apache/sling/cms/reference/impl/SearchServiceImpl.java b/reference/src/main/java/org/apache/sling/cms/reference/impl/SearchServiceImpl.java
new file mode 100644
index 0000000..690d58a
--- /dev/null
+++ b/reference/src/main/java/org/apache/sling/cms/reference/impl/SearchServiceImpl.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.cms.reference.impl;
+
+import java.util.HashMap;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.cms.reference.SearchService;
+import org.apache.sling.cms.reference.impl.SearchServiceImpl.Config;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of the SearchService
+ */
+@Component(service = { SearchService.class })
+@Designate(ocd = Config.class)
+public class SearchServiceImpl implements SearchService {
+
+ private static final Logger log = LoggerFactory.getLogger(SearchServiceImpl.class);
+
+ @Reference
+ private ResourceResolverFactory factory;
+
+ private Config config;
+
+ @ObjectClassDefinition(name = "%cms.reference.search.name", description = "%cms.reference.search.description", localization = "OSGI-INF/l10n/bundle")
+ public @interface Config {
+
+ @AttributeDefinition(name = "%searchServiceUsername.name", description = "%searchServiceUsername.description")
+ String searchServiceUsername();
+ }
+
+ @Activate
+ public void init(Config config) {
+ this.config = config;
+ }
+
+ @Override
+ public ResourceResolver getResourceResolver(SlingHttpServletRequest request) {
+ if (config != null && StringUtils.isNotBlank(config.searchServiceUsername())) {
+ try {
+ log.debug("Retrieving Service User {}", config.searchServiceUsername());
+ return factory.getServiceResourceResolver(new HashMap<String, Object>() {
+ private static final long serialVersionUID = 1L;
+
+ {
+ put(ResourceResolverFactory.SUBSERVICE, config.searchServiceUsername());
+ }
+ });
+ } catch (LoginException e) {
+ log.warn("Failed to retrieve Service User {}, falling back to request user",
+ config.searchServiceUsername());
+ return request.getResourceResolver();
+ }
+ } else {
+ log.debug("Using request user");
+ return request.getResourceResolver();
+ }
+ }
+
+ @Override
+ public void finalize(ResourceResolver resolver) {
+ if (resolver != null && resolver.isLive() && StringUtils.isNotBlank(config.searchServiceUsername())
+ && config.searchServiceUsername().equals(resolver.getUserID())) {
+ resolver.close();
+ }
+ }
+
+}
diff --git a/reference/src/main/java/org/apache/sling/cms/reference/models/Search.java b/reference/src/main/java/org/apache/sling/cms/reference/models/Search.java
index 9b596af..cc6fdd9 100644
--- a/reference/src/main/java/org/apache/sling/cms/reference/models/Search.java
+++ b/reference/src/main/java/org/apache/sling/cms/reference/models/Search.java
@@ -17,8 +17,11 @@
package org.apache.sling.cms.reference.models;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.Iterator;
-import java.util.*;
+import java.util.List;
+import java.util.Set;
import javax.annotation.PostConstruct;
import javax.jcr.query.Query;
@@ -27,7 +30,10 @@ import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.util.Text;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.cms.reference.SearchService;
import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.annotations.injectorspecific.OSGiService;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -61,8 +67,13 @@ public class Search {
private List<Resource> results = new ArrayList<Resource>();
+ @OSGiService
+ private SearchService searchService;
+
private int start;
+ private ResourceResolver resolver;
+
public Search(SlingHttpServletRequest request) {
this.request = request;
}
@@ -102,10 +113,12 @@ public class Search {
String term = Text.escapeIllegalXpathSearchChars(request.getParameter(TERM_PARAMETER)).replaceAll("'", "''");
+ resolver = searchService.getResourceResolver(request);
+
String query = "SELECT * FROM [sling:Page] AS p WHERE [jcr:content/published]=true AND (p.[jcr:content/hideInSitemap] IS NULL OR p.[jcr:content/hideInSitemap] <> true) AND ISDESCENDANTNODE(p, '"
+ basePath + "') AND CONTAINS(p.*, '" + term + "') ORDER BY [jcr:score]";
log.debug("Searching for pages with {} under {} with query: {}", term, basePath, query);
- Iterator<Resource> res = request.getResourceResolver().findResources(query, Query.JCR_SQL2);
+ Iterator<Resource> res = resolver.findResources(query, Query.JCR_SQL2);
while (res.hasNext()) {
Resource result = res.next();
if (!distinct.contains(result.getPath())) {
@@ -148,6 +161,17 @@ public class Search {
log.debug("Loaded pages {}", Arrays.toString(pages));
}
+ /**
+ * This is a horrible hack to close the resource resolver used for retrieving
+ * the search results
+ *
+ * @return true, always
+ */
+ public String getFinalize() {
+ searchService.finalize(resolver);
+ return "";
+ }
+
public boolean isFirst() {
return page == 0;
}
diff --git a/reference/src/main/resources/OSGI-INF/l10n/bundle.properties b/reference/src/main/resources/OSGI-INF/l10n/bundle.properties
new file mode 100644
index 0000000..6141e55
--- /dev/null
+++ b/reference/src/main/resources/OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,32 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+#
+# This file contains localization strings for configuration labels and
+# descriptions as used in the metatype.xml descriptor generated by the
+# the Sling SCR plugin
+
+## Search Service Entries
+cms.reference.search.name=Apache Sling Reference Search Configuration
+cms.reference.search.description=Configuration for the Reference \
+Search component
+
+searchServiceUsername.name=Search Service User Name
+searchServiceUsername.description=The name of a service user to use \
+to use for searching, if not specified, the current user will be used
\ No newline at end of file
diff --git a/reference/src/main/resources/jcr_root/apps/reference/components/general/search/search.jsp b/reference/src/main/resources/jcr_root/apps/reference/components/general/search/search.jsp
index 4e08f17..0e5e080 100644
--- a/reference/src/main/resources/jcr_root/apps/reference/components/general/search/search.jsp
+++ b/reference/src/main/resources/jcr_root/apps/reference/components/general/search/search.jsp
@@ -38,4 +38,4 @@
</div>
<sling:call script="pagination.jsp" />
</div>
-</c:if>
\ No newline at end of file
+</c:if>${search.finalize}
\ No newline at end of file