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