From fb88b0268aa0c7f14d77ae425b4851a8bedd2327 Mon Sep 17 00:00:00 2001 From: Christine Poerschke Date: Fri, 22 Jan 2021 12:10:10 +0000 Subject: [PATCH] SOLR-15073: Fix ClassCastException in SystemInfoHandler.getSecurityInfo (#2210) --- solr/CHANGES.txt | 2 + .../solr/handler/admin/SystemInfoHandler.java | 10 ++- .../handler/admin/SystemInfoHandlerTest.java | 83 +++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 7a17a75f75f..c07d2513ae9 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -364,6 +364,8 @@ Bug Fixes * SOLR-15070: Suggester requests made with SolrJ can now use XMLResponseParser (Jason Gerlowski) +* SOLR-15073: Fix ClassCastException in SystemInfoHandler.getSecurityInfo. (Nikolay Ivanov, Christine Poerschke) + Other Changes --------------------- diff --git a/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java index eb11b66ffd9..3cf8469d64d 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java @@ -323,6 +323,14 @@ public class SystemInfoHandler extends RequestHandlerBase * Get Security Info */ public SimpleOrderedMap getSecurityInfo(SolrQueryRequest req) + { + return getSecurityInfo(cc, req); + } + + /** + * Get Security Info + */ + public static SimpleOrderedMap getSecurityInfo(CoreContainer cc, SolrQueryRequest req) { SimpleOrderedMap info = new SimpleOrderedMap<>(); @@ -344,7 +352,7 @@ public class SystemInfoHandler extends RequestHandlerBase // Mapped roles for this principal @SuppressWarnings("resource") AuthorizationPlugin auth = cc==null? null: cc.getAuthorizationPlugin(); - if (auth != null) { + if (auth instanceof RuleBasedAuthorizationPluginBase) { RuleBasedAuthorizationPluginBase rbap = (RuleBasedAuthorizationPluginBase) auth; Set roles = rbap.getUserRoles(req.getUserPrincipal()); info.add("roles", roles); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/SystemInfoHandlerTest.java b/solr/core/src/test/org/apache/solr/handler/admin/SystemInfoHandlerTest.java index f0126990757..035e1c23b09 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/SystemInfoHandlerTest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/SystemInfoHandlerTest.java @@ -18,12 +18,27 @@ package org.apache.solr.handler.admin; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; +import java.security.Principal; import java.util.Arrays; +import java.util.Collections; import com.codahale.metrics.Gauge; import org.apache.solr.SolrTestCase; +import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.util.SimpleOrderedMap; +import org.apache.solr.core.CoreContainer; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.request.SolrQueryRequestBase; +import org.apache.solr.security.AuthenticationPlugin; +import org.apache.solr.security.AuthorizationPlugin; +import org.apache.solr.security.JWTPrincipal; +import org.apache.solr.security.MockAuthenticationPlugin; +import org.apache.solr.security.MockAuthorizationPlugin; +import org.apache.solr.security.RuleBasedAuthorizationPlugin; +import org.apache.solr.security.RuleBasedAuthorizationPluginBase; import org.apache.solr.util.stats.MetricUtils; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; public class SystemInfoHandlerTest extends SolrTestCase { @@ -50,4 +65,72 @@ public class SystemInfoHandlerTest extends SolrTestCase { } } + private static final String userName = "foobar"; + + public void testGetSecurityInfoAuthorizationPlugin() throws Exception { + final AuthorizationPlugin authorizationPlugin = new MockAuthorizationPlugin(); + doTestGetSecurityInfo(authorizationPlugin); + } + + public void testGetSecurityInfoRuleBasedAuthorizationPlugin() throws Exception { + SolrTestCaseJ4.assumeWorkingMockito(); + final RuleBasedAuthorizationPluginBase ruleBasedAuthorizationPlugin = Mockito.mock(RuleBasedAuthorizationPlugin.class); + Mockito.doReturn(Collections.EMPTY_SET).when(ruleBasedAuthorizationPlugin).getUserRoles(ArgumentMatchers.any(Principal.class)); + doTestGetSecurityInfo(ruleBasedAuthorizationPlugin); + } + + private static void doTestGetSecurityInfo(AuthorizationPlugin authorizationPlugin) throws Exception { + final AuthenticationPlugin authenticationPlugin = new MockAuthenticationPlugin() { + @Override + public String getName() { + return "mock authentication plugin name"; + } + }; + doTestGetSecurityInfo(null, null); + doTestGetSecurityInfo(authenticationPlugin, null); + doTestGetSecurityInfo(null, authorizationPlugin); + doTestGetSecurityInfo(authenticationPlugin, authorizationPlugin); + } + + private static void doTestGetSecurityInfo(AuthenticationPlugin authenticationPlugin, AuthorizationPlugin authorizationPlugin) throws Exception { + + SolrTestCaseJ4.assumeWorkingMockito(); + + final CoreContainer cc = Mockito.mock(CoreContainer.class); + { + Mockito.doReturn(authenticationPlugin).when(cc).getAuthenticationPlugin(); + Mockito.doReturn(authorizationPlugin).when(cc).getAuthorizationPlugin(); + } + + final SolrQueryRequest req = Mockito.mock(SolrQueryRequestBase.class); + { + final Principal principal = Mockito.mock(JWTPrincipal.class); + Mockito.doReturn(userName).when(principal).getName(); + Mockito.doReturn(principal).when(req).getUserPrincipal(); + } + + final SimpleOrderedMap si = SystemInfoHandler.getSecurityInfo(cc, req); + + if (authenticationPlugin != null) { + assertEquals(authenticationPlugin.getName(), si.remove("authenticationPlugin")); + } else { + assertNull(si.remove("authenticationPlugin")); + } + + if (authorizationPlugin != null) { + assertEquals(authorizationPlugin.getClass().getName(), si.remove("authorizationPlugin")); + if (authorizationPlugin instanceof RuleBasedAuthorizationPluginBase) { + assertNotNull(si.remove("roles")); + } else { + assertNull(si.remove("roles")); + } + } else { + assertNull(si.remove("authorizationPlugin")); + } + + assertEquals(userName, si.remove("username")); + + assertEquals("Unexpected additional info: " + si, 0, si.size()); + } + }