This is an automated email from the ASF dual-hosted git repository.
dineshkumar-yadav pushed a commit to branch ranger-2.9
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/ranger-2.9 by this push:
new 51f9ef3e4 RANGER-5648: Solr authorization fails with NPE (#1046)
51f9ef3e4 is described below
commit 51f9ef3e4dc05aefe5810208548e1612621d279a
Author: Sanket-Shelar <[email protected]>
AuthorDate: Tue Jul 7 11:46:31 2026 +0530
RANGER-5648: Solr authorization fails with NPE (#1046)
---
plugin-solr/pom.xml | 12 +++
.../solr/authorizer/RangerSolrAuthorizer.java | 103 ++++++++++++---------
.../solr/authorizer/TestRangerSolrAuthorizer.java | 90 ++++++++++++++++++
3 files changed, 163 insertions(+), 42 deletions(-)
diff --git a/plugin-solr/pom.xml b/plugin-solr/pom.xml
index 7b957e4c7..7d7f2ff4a 100644
--- a/plugin-solr/pom.xml
+++ b/plugin-solr/pom.xml
@@ -119,5 +119,17 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <version>${junit.jupiter.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-junit-jupiter</artifactId>
+ <version>${mockito.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git
a/plugin-solr/src/main/java/org/apache/ranger/authorization/solr/authorizer/RangerSolrAuthorizer.java
b/plugin-solr/src/main/java/org/apache/ranger/authorization/solr/authorizer/RangerSolrAuthorizer.java
index 6ac7cbc2b..690984470 100644
---
a/plugin-solr/src/main/java/org/apache/ranger/authorization/solr/authorizer/RangerSolrAuthorizer.java
+++
b/plugin-solr/src/main/java/org/apache/ranger/authorization/solr/authorizer/RangerSolrAuthorizer.java
@@ -70,6 +70,7 @@
public class RangerSolrAuthorizer extends SearchComponent implements
AuthorizationPlugin {
private static final Logger logger = LoggerFactory
.getLogger(RangerSolrAuthorizer.class);
+ private static final String PLUGIN_NOT_INITIALIZED_MSG = "Access denied:
authorizer is not initialized.";
private List<FieldToAttributeMapping> fieldAttributeMappings = new
LinkedList<>();
@@ -150,43 +151,7 @@ public void init(NamedList args) {
@Override
public void init(Map<String, Object> initInfo) {
logger.info("init()");
-
- try {
- RangerBasePlugin me = solrPlugin;
- if (me == null) {
- synchronized(RangerSolrAuthorizer.class) {
- me = solrPlugin;
- logger.info("RangerSolrAuthorizer():
init called");
- if (me == null) {
- authToJAASFile();
- logger.info("Creating
RangerSolrPlugin");
- me = solrPlugin = new
RangerBasePlugin("solr", "solr");
- }
- logger.info("Calling
solrPlugin.init()");
- solrPlugin.init();
- solrPlugin.setResultProcessor(new
RangerSolrAuditHandler(solrPlugin.getConfig()));
- }
- }
-
- useProxyIP = solrPlugin.getConfig().getBoolean(
- RangerSolrConstants.PROP_USE_PROXY_IP,
useProxyIP);
- proxyIPHeader = solrPlugin.getConfig().get(
-
RangerSolrConstants.PROP_PROXY_IP_HEADER, proxyIPHeader);
- // First get from the -D property
- solrAppName =
System.getProperty("solr.kerberos.jaas.appname",
- solrAppName);
- // Override if required from Ranger properties
- solrAppName = solrPlugin.getConfig().get(
- RangerSolrConstants.PROP_SOLR_APP_NAME,
solrAppName);
-
- logger.info("init(): useProxyIP=" + useProxyIP);
- logger.info("init(): proxyIPHeader=" + proxyIPHeader);
- logger.info("init(): solrAppName=" + solrAppName);
- logger.info("init(): KerberosName.rules="
- + MiscUtil.getKerberosNamesRules());
- } catch (Throwable t) {
- logger.error("Error creating and initializing
RangerBasePlugin()", t);
- }
+ getPlugin();
}
/*
@@ -197,18 +162,26 @@ public void init(Map<String, Object> initInfo) {
@Override
public void close() throws IOException {
logger.info("close() called");
+
+ RangerBasePlugin plugin = solrPlugin;
+
+ if (plugin == null) {
+ return;
+ }
try {
- solrPlugin.cleanup();
+ plugin.cleanup();
/* Solr shutdown is not graceful so that JVM shutdown
hooks
* are not always invoked and the audit store are not
flushed. So
* we are forcing a cleanup here.
*/
- if (solrPlugin.getAuditProviderFactory() != null) {
- solrPlugin.getAuditProviderFactory().shutdown();
+ if (plugin.getAuditProviderFactory() != null) {
+ plugin.getAuditProviderFactory().shutdown();
}
} catch (Throwable t) {
logger.error("Error cleaning up Ranger plugin. Ignoring
error", t);
- }
+ } finally {
+ solrPlugin = null;
+ }
}
/*
@@ -220,7 +193,16 @@ public void close() throws IOException {
*/
@Override
public AuthorizationResponse authorize(AuthorizationContext context) {
- boolean isDenied = false;
+ RangerBasePlugin solrPlugin = getPlugin();
+
+ if (solrPlugin == null) {
+ MiscUtil.logErrorMessageByInterval(logger,
PLUGIN_NOT_INITIALIZED_MSG);
+ AuthorizationResponse resp = new AuthorizationResponse(503);
+ resp.setMessage(PLUGIN_NOT_INITIALIZED_MSG);
+ return resp;
+ }
+
+ boolean isDenied = false;
try {
if (logger.isDebugEnabled()) {
@@ -530,6 +512,43 @@ public String getDescription() {
return "Handle Query Document Authorization";
}
+ private RangerBasePlugin getPlugin() {
+ RangerBasePlugin ret = solrPlugin;
+
+ if (ret == null) {
+ synchronized (RangerSolrAuthorizer.class) {
+ ret = solrPlugin;
+
+ if (ret == null) {
+ try {
+ initializeSolrPlugin();
+
+ ret = solrPlugin;
+ } catch (Throwable t) {
+ logger.error("Error creating and initializing
RangerBasePlugin()", t);
+ }
+ }
+ }
+ }
+
+ return ret;
+ }
+
+ private void initializeSolrPlugin() {
+ authToJAASFile();
+
+ RangerBasePlugin plugin = new RangerBasePlugin("solr", "solr");
+
+ plugin.init();
+ plugin.setResultProcessor(new
RangerSolrAuditHandler(plugin.getConfig()));
+
+ useProxyIP =
plugin.getConfig().getBoolean(RangerSolrConstants.PROP_USE_PROXY_IP,
useProxyIP);
+ proxyIPHeader =
plugin.getConfig().get(RangerSolrConstants.PROP_PROXY_IP_HEADER, proxyIPHeader);
+ solrAppName =
plugin.getConfig().get(RangerSolrConstants.PROP_SOLR_APP_NAME,
System.getProperty("solr.kerberos.jaas.appname", solrAppName));
+
+ solrPlugin = plugin;
+ }
+
private void authToJAASFile() {
try {
MiscUtil.setUGIFromJAASConfig(solrAppName);
diff --git
a/plugin-solr/src/test/java/org/apache/ranger/authorization/solr/authorizer/TestRangerSolrAuthorizer.java
b/plugin-solr/src/test/java/org/apache/ranger/authorization/solr/authorizer/TestRangerSolrAuthorizer.java
new file mode 100644
index 000000000..67e1a856a
--- /dev/null
+++
b/plugin-solr/src/test/java/org/apache/ranger/authorization/solr/authorizer/TestRangerSolrAuthorizer.java
@@ -0,0 +1,90 @@
+/*
+ * 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.ranger.authorization.solr.authorizer;
+
+import org.apache.solr.security.AuthorizationContext;
+import org.apache.solr.security.AuthorizationResponse;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+
+/**
+ * @generated by Cursor
+ * @description : Unit Test cases for RangerSqoopAuthorizer
+ */
+
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerSolrAuthorizer {
+ @Test
+ public void
test01_authorize_whenPluginNotInitialized_returns503WithoutNpe() throws
Exception {
+ resetPluginState();
+
+ RangerSolrAuthorizer authorizer = new RangerSolrAuthorizer();
+ AuthorizationContext context = mock(AuthorizationContext.class);
+
+ AuthorizationResponse response = assertDoesNotThrow(() ->
authorizer.authorize(context));
+
+ assertEquals(503, response.statusCode);
+ }
+
+ @Test
+ public void test02_close_whenPluginNull_doesNotThrow() throws Exception {
+ resetPluginState();
+
+ RangerSolrAuthorizer authorizer = new RangerSolrAuthorizer();
+
+ assertDoesNotThrow(authorizer::close);
+ }
+
+ @Test
+ public void test03_init_whenPluginCreationFails_leavesPluginNull() throws
Exception {
+ resetPluginState();
+
+ RangerSolrAuthorizer authorizer = new RangerSolrAuthorizer();
+
+ authorizer.init(Collections.emptyMap());
+
+ assertEquals(null, getStaticField("solrPlugin"));
+ }
+
+ private static void resetPluginState() throws Exception {
+ setStaticField("solrPlugin", null);
+ }
+
+ private static void setStaticField(String fieldName, Object value) throws
Exception {
+ Field field = RangerSolrAuthorizer.class.getDeclaredField(fieldName);
+ field.setAccessible(true);
+ field.set(null, value);
+ }
+
+ private static Object getStaticField(String fieldName) throws Exception {
+ Field field = RangerSolrAuthorizer.class.getDeclaredField(fieldName);
+ field.setAccessible(true);
+ return field.get(null);
+ }
+}