This is an automated email from the ASF dual-hosted git repository.
gerlowskija pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_9x by this push:
new 20671df3ac7 SOLR-15738: Convert v2 security APIs to annotations (#897)
20671df3ac7 is described below
commit 20671df3ac7328c65ffd965bbe595c120a57145d
Author: Jason Gerlowski <[email protected]>
AuthorDate: Tue Jun 21 11:42:51 2022 -0400
SOLR-15738: Convert v2 security APIs to annotations (#897)
Solr's been in the slow process of moving its v2 APIs away from the
existing apispec/mapping framework towards one that relies on more
explicit annotations to specify API properties.
This commit converts the APIs from the cluster.security.authentication
and cluster.security.authorization apispec files to the "new" framework.
---
.../src/java/org/apache/solr/api/AnnotatedApi.java | 29 ++++
solr/core/src/java/org/apache/solr/api/ApiBag.java | 19 ++-
.../solr/handler/admin/SecurityConfHandler.java | 28 ++--
.../admin/api/GetAuthenticationConfigAPI.java | 50 +++++++
.../admin/api/GetAuthorizationConfigAPI.java | 49 +++++++
.../admin/api/ModifyBasicAuthConfigAPI.java | 47 +++++++
.../admin/api/ModifyMultiPluginAuthConfigAPI.java | 57 ++++++++
.../api/ModifyNoAuthPluginSecurityConfigAPI.java | 50 +++++++
.../api/ModifyNoAuthzPluginSecurityConfigAPI.java | 50 +++++++
.../admin/api/ModifyRuleBasedAuthConfigAPI.java | 64 +++++++++
.../org/apache/solr/security/MultiAuthPlugin.java | 7 +-
.../security/RuleBasedAuthorizationPluginBase.java | 7 +-
.../security/Sha256AuthenticationProvider.java | 7 +-
.../org/apache/solr/cloud/TestConfigSetsAPI.java | 4 +-
.../handler/admin/V2SecurityAPIMappingTest.java | 154 +++++++++++++++++++++
.../admin/api/ModifyJWTAuthPluginConfigAPI.java | 39 ++++++
.../solr/handler/admin/api/package-info.java | 18 +++
.../apache/solr/security/jwt/JWTAuthPlugin.java | 6 +-
.../admin/api/V2JWTSecurityApiMappingTest.java | 65 +++++++++
.../solr/handler/admin/api/package-info.java | 19 +++
.../request/beans/DeleteBasicAuthUserPayload.java | 22 +++
.../beans/SetRuleBasedAuthPermissionPayload.java | 43 ++++++
.../UpdateRuleBasedAuthPermissionPayload.java | 44 ++++++
.../handler/admin/api/JWTConfigurationPayload.java | 87 ++++++++++++
.../solr/handler/admin/api/package-info.java | 19 +++
.../cluster.security.BasicAuth.Commands.json | 23 ---
.../apispec/cluster.security.JwtAuth.Commands.json | 18 ---
.../cluster.security.MultiPluginAuth.Commands.json | 27 ----
.../cluster.security.RuleBasedAuthorization.json | 129 -----------------
.../cluster.security.authentication.Commands.json | 12 --
.../apispec/cluster.security.authentication.json | 12 --
.../cluster.security.authorization.Commands.json | 13 --
.../apispec/cluster.security.authorization.json | 13 --
.../apache/solr/common/util/JsonValidatorTest.java | 21 ---
34 files changed, 965 insertions(+), 287 deletions(-)
diff --git a/solr/core/src/java/org/apache/solr/api/AnnotatedApi.java
b/solr/core/src/java/org/apache/solr/api/AnnotatedApi.java
index 905157cf71a..468e5cbec95 100644
--- a/solr/core/src/java/org/apache/solr/api/AnnotatedApi.java
+++ b/solr/core/src/java/org/apache/solr/api/AnnotatedApi.java
@@ -34,6 +34,8 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SpecProvider;
@@ -335,6 +337,33 @@ public class AnnotatedApi extends Api implements
PermissionNameProvider, Closeab
}
}
+ public int hashCode() {
+ return new HashCodeBuilder()
+ .append(command)
+ .append(method)
+ .append(obj)
+ .append(paramsCount)
+ .append(parameterClass)
+ .append(isWrappedInPayloadObj)
+ .toHashCode();
+ }
+
+ public boolean equals(Object rhs) {
+ if (null == rhs) return false;
+ if (this == rhs) return true;
+ if (getClass() != rhs.getClass()) return false;
+
+ final Cmd rhsCast = (Cmd) rhs;
+ return new EqualsBuilder()
+ .append(command, rhsCast.command)
+ .append(method, rhsCast.method)
+ .append(obj, rhsCast.obj)
+ .append(paramsCount, rhsCast.paramsCount)
+ .append(parameterClass, rhsCast.parameterClass)
+ .append(isWrappedInPayloadObj, rhsCast.isWrappedInPayloadObj)
+ .isEquals();
+ }
+
private void checkForErrorInPayload(CommandOperation cmd) {
if (cmd.hasError()) {
throw new ApiBag.ExceptionWithErrObject(
diff --git a/solr/core/src/java/org/apache/solr/api/ApiBag.java
b/solr/core/src/java/org/apache/solr/api/ApiBag.java
index 5a790e91895..53927c68be5 100644
--- a/solr/core/src/java/org/apache/solr/api/ApiBag.java
+++ b/solr/core/src/java/org/apache/solr/api/ApiBag.java
@@ -26,6 +26,7 @@ import static
org.apache.solr.common.util.ValidatingJsonMap.NOT_NULL;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
@@ -149,16 +150,28 @@ public class ApiBag {
private Collection<AnnotatedApi> combinedApis;
protected CommandAggregatingAnnotatedApi(AnnotatedApi api) {
- super(api.spec, api.getEndPoint(), api.getCommands(), null);
+ super(api.spec, api.getEndPoint(), Maps.newHashMap(api.getCommands()),
null);
combinedApis = Lists.newArrayList();
}
public void combineWith(AnnotatedApi api) {
// Merge in new 'command' entries
- getCommands().putAll(api.getCommands());
+ boolean newCommandsAdded = false;
+ for (Map.Entry<String, AnnotatedApi.Cmd> entry :
api.getCommands().entrySet()) {
+ // Skip registering command if it's identical to an already registered
command.
+ if (getCommands().containsKey(entry.getKey())
+ && getCommands().get(entry.getKey()).equals(entry.getValue())) {
+ continue;
+ }
+
+ newCommandsAdded = true;
+ getCommands().put(entry.getKey(), entry.getValue());
+ }
// Reference to Api must be saved to to merge uncached values (i.e.
'spec') lazily
- combinedApis.add(api);
+ if (newCommandsAdded) {
+ combinedApis.add(api);
+ }
}
@Override
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/SecurityConfHandler.java
b/solr/core/src/java/org/apache/solr/handler/admin/SecurityConfHandler.java
index 3108a2132ef..eda280a98c8 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/SecurityConfHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/SecurityConfHandler.java
@@ -29,6 +29,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import org.apache.solr.api.AnnotatedApi;
import org.apache.solr.api.Api;
import org.apache.solr.api.ApiBag;
import org.apache.solr.api.ApiBag.ReqHandlerToApi;
@@ -41,6 +42,10 @@ import org.apache.solr.common.util.Utils;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.handler.RequestHandlerUtils;
+import org.apache.solr.handler.admin.api.GetAuthenticationConfigAPI;
+import org.apache.solr.handler.admin.api.GetAuthorizationConfigAPI;
+import org.apache.solr.handler.admin.api.ModifyNoAuthPluginSecurityConfigAPI;
+import org.apache.solr.handler.admin.api.ModifyNoAuthzPluginSecurityConfigAPI;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.security.AuthenticationPlugin;
@@ -277,20 +282,27 @@ public abstract class SecurityConfHandler extends
RequestHandlerBase
synchronized (this) {
if (apis == null) {
Collection<Api> apis = new ArrayList<>();
- final SpecProvider authcCommands =
- Utils.getSpec("cluster.security.authentication.Commands");
- final SpecProvider authzCommands =
- Utils.getSpec("cluster.security.authorization.Commands");
- apis.add(new ReqHandlerToApi(this,
Utils.getSpec("cluster.security.authentication")));
- apis.add(new ReqHandlerToApi(this,
Utils.getSpec("cluster.security.authorization")));
+ // GET Apis are the same regardless of which plugins are registered
+ apis.addAll(AnnotatedApi.getApis(new
GetAuthenticationConfigAPI(this)));
+ apis.addAll(AnnotatedApi.getApis(new
GetAuthorizationConfigAPI(this)));
+
+ // POST Apis come from the specific authc/z plugin registered (with
a fallback used if
+ // the plugin isn't a SpecProvider).
+ final Api defaultAuthcApi =
+ AnnotatedApi.getApis(new
ModifyNoAuthPluginSecurityConfigAPI(this)).get(0);
+ final Api defaultAuthzApi =
+ AnnotatedApi.getApis(new
ModifyNoAuthzPluginSecurityConfigAPI(this)).get(0);
+
SpecProvider authcSpecProvider =
() -> {
AuthenticationPlugin authcPlugin =
cores.getAuthenticationPlugin();
return authcPlugin != null && authcPlugin instanceof
SpecProvider
? ((SpecProvider) authcPlugin).getSpec()
- : authcCommands.getSpec();
+ : defaultAuthcApi.getSpec();
};
+ // TODO Can we remove this extra ReqHandlerToApi wrapping - nothing
but the schema from
+ // the POST authc/authz is getting used.
apis.add(
new ReqHandlerToApi(this, authcSpecProvider) {
@Override
@@ -309,7 +321,7 @@ public abstract class SecurityConfHandler extends
RequestHandlerBase
AuthorizationPlugin authzPlugin =
cores.getAuthorizationPlugin();
return authzPlugin != null && authzPlugin instanceof
SpecProvider
? ((SpecProvider) authzPlugin).getSpec()
- : authzCommands.getSpec();
+ : defaultAuthzApi.getSpec();
};
apis.add(
new ApiBag.ReqHandlerToApi(this, authzSpecProvider) {
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/api/GetAuthenticationConfigAPI.java
b/solr/core/src/java/org/apache/solr/handler/admin/api/GetAuthenticationConfigAPI.java
new file mode 100644
index 00000000000..9a7b7947689
--- /dev/null
+++
b/solr/core/src/java/org/apache/solr/handler/admin/api/GetAuthenticationConfigAPI.java
@@ -0,0 +1,50 @@
+/*
+ * 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.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.GET;
+import static
org.apache.solr.security.PermissionNameProvider.Name.SECURITY_READ_PERM;
+
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.handler.admin.SecurityConfHandler;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/**
+ * V2 API for fetching the authentication section from Solr's security.json
configuration.
+ *
+ * <p>This API (GET /v2/cluster/security/authentication) is analogous to the
v1 `GET
+ * /solr/admin/authentication` API.
+ */
+public class GetAuthenticationConfigAPI {
+
+ private final SecurityConfHandler securityConfHandler;
+
+ public GetAuthenticationConfigAPI(SecurityConfHandler securityConfHandler) {
+ this.securityConfHandler = securityConfHandler;
+ }
+
+ @EndPoint(
+ path = {"/cluster/security/authentication"},
+ method = GET,
+ permission = SECURITY_READ_PERM)
+ public void fetchAuthenticationConfig(SolrQueryRequest req,
SolrQueryResponse rsp)
+ throws Exception {
+ securityConfHandler.handleRequestBody(req, rsp);
+ }
+}
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/api/GetAuthorizationConfigAPI.java
b/solr/core/src/java/org/apache/solr/handler/admin/api/GetAuthorizationConfigAPI.java
new file mode 100644
index 00000000000..aa4edbdf1e2
--- /dev/null
+++
b/solr/core/src/java/org/apache/solr/handler/admin/api/GetAuthorizationConfigAPI.java
@@ -0,0 +1,49 @@
+/*
+ * 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.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.GET;
+import static
org.apache.solr.security.PermissionNameProvider.Name.SECURITY_READ_PERM;
+
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.handler.admin.SecurityConfHandler;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/**
+ * V2 API for fetching the authorization section of Solr's security.json
configuration.
+ *
+ * <p>This API (GET /v2/cluster/security/authorization) is analogous to the v1
`GET
+ * /solr/admin/authorization` API.
+ */
+public class GetAuthorizationConfigAPI {
+ private final SecurityConfHandler securityConfHandler;
+
+ public GetAuthorizationConfigAPI(SecurityConfHandler securityConfHandler) {
+ this.securityConfHandler = securityConfHandler;
+ }
+
+ @EndPoint(
+ path = {"/cluster/security/authorization"},
+ method = GET,
+ permission = SECURITY_READ_PERM)
+ public void fetchAuthorizationConfig(SolrQueryRequest req, SolrQueryResponse
rsp)
+ throws Exception {
+ securityConfHandler.handleRequestBody(req, rsp);
+ }
+}
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyBasicAuthConfigAPI.java
b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyBasicAuthConfigAPI.java
new file mode 100644
index 00000000000..dd7e488b43d
--- /dev/null
+++
b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyBasicAuthConfigAPI.java
@@ -0,0 +1,47 @@
+/*
+ * 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.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static
org.apache.solr.security.PermissionNameProvider.Name.SECURITY_EDIT_PERM;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.solr.api.Command;
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.api.PayloadObj;
+
+/** V2 API to modify configuration for Solr's {@link
org.apache.solr.security.BasicAuthPlugin} */
+@EndPoint(
+ path = {"/cluster/security/authentication"},
+ method = POST,
+ permission = SECURITY_EDIT_PERM)
+public class ModifyBasicAuthConfigAPI {
+
+ @Command(name = "set-user")
+ public void createUsers(PayloadObj<Map<String, String>>
usersToCreatePayload) {
+ // Method stub used only to produce v2 API spec; implementation/body empty.
+ throw new IllegalStateException();
+ }
+
+ @Command(name = "delete-user")
+ public void deleteUsers(PayloadObj<List<String>> usersToDeletePayload) {
+ // Method stub used only to produce v2 API spec; implementation/body empty.
+ throw new IllegalStateException();
+ }
+}
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyMultiPluginAuthConfigAPI.java
b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyMultiPluginAuthConfigAPI.java
new file mode 100644
index 00000000000..b9a19eb1ce1
--- /dev/null
+++
b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyMultiPluginAuthConfigAPI.java
@@ -0,0 +1,57 @@
+/*
+ * 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.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static
org.apache.solr.security.PermissionNameProvider.Name.SECURITY_EDIT_PERM;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.solr.api.Command;
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.api.PayloadObj;
+import org.apache.solr.security.MultiAuthPlugin;
+
+/** V2 API to modify configuration options for the {@link MultiAuthPlugin}. */
+@EndPoint(
+ path = {"/cluster/security/authentication"},
+ method = POST,
+ permission = SECURITY_EDIT_PERM)
+public class ModifyMultiPluginAuthConfigAPI {
+
+ @Command(name = "set-user")
+ public void createUsers(PayloadObj<Map<String, String>>
usersToCreatePayload) {
+ // Method stub used only to produce v2 API spec; implementation/body empty.
+ throw new IllegalStateException();
+ }
+
+ @Command(name = "delete-user")
+ public void deleteUsers(PayloadObj<List<String>> usersToDeletePayload) {
+ // Method stub used only to produce v2 API spec; implementation/body empty.
+ throw new IllegalStateException();
+ }
+
+ // TODO This is a good candidate to create an actual Payload class instead
of relying on the
+ // generic Map, if someone understands what syntax this API actually takes.
The apispec
+ // this code was mirrored from is vague, and the ref-guide has no examples
afaict.
+ @Command(name = "set-property")
+ public void setProperties(PayloadObj<Map<String, Object>> propertyPayload) {
+ // Method stub used only to produce v2 API spec; implementation/body empty.
+ throw new IllegalStateException();
+ }
+}
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyNoAuthPluginSecurityConfigAPI.java
b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyNoAuthPluginSecurityConfigAPI.java
new file mode 100644
index 00000000000..031410e2a46
--- /dev/null
+++
b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyNoAuthPluginSecurityConfigAPI.java
@@ -0,0 +1,50 @@
+/*
+ * 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.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static
org.apache.solr.security.PermissionNameProvider.Name.SECURITY_EDIT_PERM;
+
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.handler.admin.SecurityConfHandler;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/**
+ * V2 API for POST requests received when no authentication plugin is active.
+ *
+ * <p>Solr's security APIs only supports authc config modifications once an
Authentication plugin is
+ * in place. So this API serves solely as a placeholder that allows {@link
SecurityConfHandler} to
+ * return a helpful error message (instead of the opaque 404 that users would
get without this API).
+ */
+public class ModifyNoAuthPluginSecurityConfigAPI {
+ private final SecurityConfHandler securityConfHandler;
+
+ public ModifyNoAuthPluginSecurityConfigAPI(SecurityConfHandler
securityConfHandler) {
+ this.securityConfHandler = securityConfHandler;
+ }
+
+ @EndPoint(
+ path = {"/cluster/security/authentication"},
+ method = POST,
+ permission = SECURITY_EDIT_PERM)
+ public void updateAuthenticationConfig(SolrQueryRequest req,
SolrQueryResponse rsp)
+ throws Exception {
+ securityConfHandler.handleRequestBody(req, rsp);
+ }
+}
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyNoAuthzPluginSecurityConfigAPI.java
b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyNoAuthzPluginSecurityConfigAPI.java
new file mode 100644
index 00000000000..c90c5fd2b02
--- /dev/null
+++
b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyNoAuthzPluginSecurityConfigAPI.java
@@ -0,0 +1,50 @@
+/*
+ * 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.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static
org.apache.solr.security.PermissionNameProvider.Name.SECURITY_EDIT_PERM;
+
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.handler.admin.SecurityConfHandler;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+
+/**
+ * V2 API for POST requests received when no authorization plugin is active.
+ *
+ * <p>Solr's security APIs only supports authz config modifications once an
Authorization plugin is
+ * in place. So this API serves solely as a placeholder that allows {@link
SecurityConfHandler} to
+ * return a helpful error message (instead of the opaque 404 that users would
get without this API).
+ */
+public class ModifyNoAuthzPluginSecurityConfigAPI {
+ private final SecurityConfHandler securityConfHandler;
+
+ public ModifyNoAuthzPluginSecurityConfigAPI(SecurityConfHandler
securityConfHandler) {
+ this.securityConfHandler = securityConfHandler;
+ }
+
+ @EndPoint(
+ path = {"/cluster/security/authorization"},
+ method = POST,
+ permission = SECURITY_EDIT_PERM)
+ public void updateAuthorizationConfig(SolrQueryRequest req,
SolrQueryResponse rsp)
+ throws Exception {
+ securityConfHandler.handleRequestBody(req, rsp);
+ }
+}
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyRuleBasedAuthConfigAPI.java
b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyRuleBasedAuthConfigAPI.java
new file mode 100644
index 00000000000..03ba29bae73
--- /dev/null
+++
b/solr/core/src/java/org/apache/solr/handler/admin/api/ModifyRuleBasedAuthConfigAPI.java
@@ -0,0 +1,64 @@
+/*
+ * 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.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static
org.apache.solr.security.PermissionNameProvider.Name.SECURITY_EDIT_PERM;
+
+import java.util.Map;
+import org.apache.solr.api.Command;
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.api.PayloadObj;
+import
org.apache.solr.client.solrj.request.beans.SetRuleBasedAuthPermissionPayload;
+import
org.apache.solr.client.solrj.request.beans.UpdateRuleBasedAuthPermissionPayload;
+
+/**
+ * V2 API to modify configuration options for the {@link
+ * org.apache.solr.security.RuleBasedAuthorizationPlugin}.
+ */
+@EndPoint(
+ path = {"/cluster/security/authorization"},
+ method = POST,
+ permission = SECURITY_EDIT_PERM)
+public class ModifyRuleBasedAuthConfigAPI {
+
+ @Command(name = "set-permission")
+ public void setPermission(PayloadObj<SetRuleBasedAuthPermissionPayload>
permissionPayloadObj) {
+ // Method stub used only to produce v2 API spec; implementation/body empty.
+ throw new IllegalStateException();
+ }
+
+ @Command(name = "update-permission")
+ public void updatePermission(
+ PayloadObj<UpdateRuleBasedAuthPermissionPayload> permissionPayloadObj) {
+ // Method stub used only to produce v2 API spec; implementation/body empty.
+ throw new IllegalStateException();
+ }
+
+ @Command(name = "delete-permission")
+ public void deletePermission(PayloadObj<Integer> indexToDeletePayloadObj) {
+ // Method stub used only to produce v2 API spec; implementation/body empty.
+ throw new IllegalStateException();
+ }
+
+ @Command(name = "set-user-role")
+ public void setUserRole(PayloadObj<Map<String, Object>>
userRoleMapPayloadObj) {
+ // Method stub used only to produce v2 API spec; implementation/body empty.
+ throw new IllegalStateException();
+ }
+}
diff --git a/solr/core/src/java/org/apache/solr/security/MultiAuthPlugin.java
b/solr/core/src/java/org/apache/solr/security/MultiAuthPlugin.java
index e82f8b9c549..9281f88023c 100644
--- a/solr/core/src/java/org/apache/solr/security/MultiAuthPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/MultiAuthPlugin.java
@@ -29,14 +29,16 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.http.HttpRequest;
import org.apache.http.protocol.HttpContext;
import org.apache.lucene.util.ResourceLoader;
+import org.apache.solr.api.AnnotatedApi;
+import org.apache.solr.api.Api;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.SpecProvider;
import org.apache.solr.common.StringUtils;
import org.apache.solr.common.util.CommandOperation;
-import org.apache.solr.common.util.Utils;
import org.apache.solr.common.util.ValidatingJsonMap;
import org.apache.solr.core.CoreContainer;
+import org.apache.solr.handler.admin.api.ModifyMultiPluginAuthConfigAPI;
import org.apache.solr.metrics.SolrMetricsContext;
import org.eclipse.jetty.client.api.Request;
@@ -266,7 +268,8 @@ public class MultiAuthPlugin extends AuthenticationPlugin
@Override
public ValidatingJsonMap getSpec() {
- return
Utils.getSpec("cluster.security.MultiPluginAuth.Commands").getSpec();
+ final List<Api> apis = AnnotatedApi.getApis(new
ModifyMultiPluginAuthConfigAPI());
+ return apis.get(0).getSpec();
}
@Override
diff --git
a/solr/core/src/java/org/apache/solr/security/RuleBasedAuthorizationPluginBase.java
b/solr/core/src/java/org/apache/solr/security/RuleBasedAuthorizationPluginBase.java
index 73ad414f2e8..fc917cad38a 100644
---
a/solr/core/src/java/org/apache/solr/security/RuleBasedAuthorizationPluginBase.java
+++
b/solr/core/src/java/org/apache/solr/security/RuleBasedAuthorizationPluginBase.java
@@ -32,10 +32,12 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
+import org.apache.solr.api.AnnotatedApi;
+import org.apache.solr.api.Api;
import org.apache.solr.common.SpecProvider;
import org.apache.solr.common.util.CommandOperation;
-import org.apache.solr.common.util.Utils;
import org.apache.solr.common.util.ValidatingJsonMap;
+import org.apache.solr.handler.admin.api.ModifyRuleBasedAuthConfigAPI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -397,6 +399,7 @@ public abstract class RuleBasedAuthorizationPluginBase
@Override
public ValidatingJsonMap getSpec() {
- return Utils.getSpec("cluster.security.RuleBasedAuthorization").getSpec();
+ final List<Api> apis = AnnotatedApi.getApis(new
ModifyRuleBasedAuthConfigAPI());
+ return apis.get(0).getSpec();
}
}
diff --git
a/solr/core/src/java/org/apache/solr/security/Sha256AuthenticationProvider.java
b/solr/core/src/java/org/apache/solr/security/Sha256AuthenticationProvider.java
index 9a2fba3101b..d7c20b4c5b9 100644
---
a/solr/core/src/java/org/apache/solr/security/Sha256AuthenticationProvider.java
+++
b/solr/core/src/java/org/apache/solr/security/Sha256AuthenticationProvider.java
@@ -31,9 +31,11 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
+import org.apache.solr.api.AnnotatedApi;
+import org.apache.solr.api.Api;
import org.apache.solr.common.util.CommandOperation;
-import org.apache.solr.common.util.Utils;
import org.apache.solr.common.util.ValidatingJsonMap;
+import org.apache.solr.handler.admin.api.ModifyBasicAuthConfigAPI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -173,7 +175,8 @@ public class Sha256AuthenticationProvider
@Override
public ValidatingJsonMap getSpec() {
- return Utils.getSpec("cluster.security.BasicAuth.Commands").getSpec();
+ final List<Api> apis = AnnotatedApi.getApis(new
ModifyBasicAuthConfigAPI());
+ return apis.get(0).getSpec();
}
static final Set<String> supported_ops = ImmutableSet.of("set-user",
"delete-user");
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestConfigSetsAPI.java
b/solr/core/src/test/org/apache/solr/cloud/TestConfigSetsAPI.java
index 740f234e88b..ac6a04e8a28 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestConfigSetsAPI.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestConfigSetsAPI.java
@@ -67,6 +67,7 @@ import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.api.AnnotatedApi;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.BaseHttpSolrClient;
@@ -95,6 +96,7 @@ import org.apache.solr.common.util.ValidatingJsonMap;
import org.apache.solr.core.ConfigSetProperties;
import org.apache.solr.core.ConfigSetService;
import org.apache.solr.core.TestSolrConfigHandler;
+import org.apache.solr.handler.admin.api.ModifyBasicAuthConfigAPI;
import org.apache.solr.security.AuthorizationContext;
import org.apache.solr.security.AuthorizationPlugin;
import org.apache.solr.security.AuthorizationResponse;
@@ -1881,7 +1883,7 @@ public class TestConfigSetsAPI extends SolrCloudTestCase {
@Override
public ValidatingJsonMap getSpec() {
- return
Utils.getSpec("cluster.security.BasicAuth.Commands").getSpec();
+ return AnnotatedApi.getApis(new
ModifyBasicAuthConfigAPI()).get(0).getSpec();
}
@Override
diff --git
a/solr/core/src/test/org/apache/solr/handler/admin/V2SecurityAPIMappingTest.java
b/solr/core/src/test/org/apache/solr/handler/admin/V2SecurityAPIMappingTest.java
new file mode 100644
index 00000000000..1cc621a74f4
--- /dev/null
+++
b/solr/core/src/test/org/apache/solr/handler/admin/V2SecurityAPIMappingTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.solr.handler.admin;
+
+import java.util.HashMap;
+import java.util.Set;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.api.AnnotatedApi;
+import org.apache.solr.api.Api;
+import org.apache.solr.api.ApiBag;
+import org.apache.solr.handler.admin.api.GetAuthenticationConfigAPI;
+import org.apache.solr.handler.admin.api.GetAuthorizationConfigAPI;
+import org.apache.solr.handler.admin.api.ModifyBasicAuthConfigAPI;
+import org.apache.solr.handler.admin.api.ModifyMultiPluginAuthConfigAPI;
+import org.apache.solr.handler.admin.api.ModifyNoAuthPluginSecurityConfigAPI;
+import org.apache.solr.handler.admin.api.ModifyNoAuthzPluginSecurityConfigAPI;
+import org.apache.solr.handler.admin.api.ModifyRuleBasedAuthConfigAPI;
+import org.junit.Before;
+import org.junit.Test;
+
+public class V2SecurityAPIMappingTest extends SolrTestCaseJ4 {
+
+ private ApiBag apiBag;
+ private SecurityConfHandler mockHandler;
+
+ @Before
+ public void setupApiBag() {
+ apiBag = new ApiBag(false);
+ mockHandler = null;
+ }
+
+ // Test the GET /cluster/security/[authentication|authorization] APIs
registered regardless of
+ // security plugin
+ @Test
+ public void testMappingForUniversalGetApis() {
+ apiBag.registerObject(new GetAuthenticationConfigAPI(mockHandler));
+ apiBag.registerObject(new GetAuthorizationConfigAPI(mockHandler));
+
+ assertAnnotatedApiExistsFor("GET", "/cluster/security/authentication");
+ assertAnnotatedApiExistsFor("GET", "/cluster/security/authorization");
+ }
+
+ // Test the POST /cluster/security/[authentication|authorization] APIs
registered when no plugins
+ // are configured.
+ @Test
+ public void testDefaultPostAPIs() {
+ apiBag.registerObject(new
ModifyNoAuthPluginSecurityConfigAPI(mockHandler));
+ apiBag.registerObject(new
ModifyNoAuthzPluginSecurityConfigAPI(mockHandler));
+
+ // Authc API
+ final AnnotatedApi updateAuthcConfig =
+ assertAnnotatedApiExistsFor("POST",
"/cluster/security/authentication");
+ assertEquals(1, updateAuthcConfig.getCommands().size());
+ // empty-string is the placeholder for POST APIs without an explicit
command.
+ assertEquals("",
updateAuthcConfig.getCommands().keySet().iterator().next());
+
+ // Authz API
+ final AnnotatedApi updateAuthzConfig =
+ assertAnnotatedApiExistsFor("POST", "/cluster/security/authorization");
+ assertEquals(1, updateAuthzConfig.getCommands().size());
+ // empty-string is the placeholder for POST APIs without an explicit
command.
+ assertEquals("",
updateAuthzConfig.getCommands().keySet().iterator().next());
+ }
+
+ @Test
+ public void testBasicAuthApiMapping() {
+ apiBag.registerObject(new ModifyBasicAuthConfigAPI());
+
+ final AnnotatedApi updateAuthcConfig =
+ assertAnnotatedApiExistsFor("POST",
"/cluster/security/authentication");
+ assertEquals(2, updateAuthcConfig.getCommands().size());
+ final Set<String> commandNames = updateAuthcConfig.getCommands().keySet();
+ assertTrue(
+ "Expected 'set-user' to be in the command list: " + commandNames,
+ commandNames.contains("set-user"));
+ assertTrue(
+ "Expected 'delete-user' to be in the command list: " + commandNames,
+ commandNames.contains("delete-user"));
+ }
+
+ @Test
+ public void testMultiAuthApiMapping() {
+ apiBag.registerObject(new ModifyMultiPluginAuthConfigAPI());
+
+ final AnnotatedApi updateAuthcConfig =
+ assertAnnotatedApiExistsFor("POST",
"/cluster/security/authentication");
+ assertEquals(3, updateAuthcConfig.getCommands().size());
+ final Set<String> commandNames = updateAuthcConfig.getCommands().keySet();
+ assertTrue(
+ "Expected 'set-user' to be in the command list: " + commandNames,
+ commandNames.contains("set-user"));
+ assertTrue(
+ "Expected 'delete-user' to be in the command list: " + commandNames,
+ commandNames.contains("delete-user"));
+ assertTrue(
+ "Expected 'set-property' to be in the command list: " + commandNames,
+ commandNames.contains("set-property"));
+ }
+
+ @Test
+ public void testRuleBasedAuthzApiMapping() {
+ apiBag.registerObject(new ModifyRuleBasedAuthConfigAPI());
+
+ final AnnotatedApi updateAuthzConfig =
+ assertAnnotatedApiExistsFor("POST", "/cluster/security/authorization");
+ assertEquals(4, updateAuthzConfig.getCommands().size());
+ final Set<String> commandNames = updateAuthzConfig.getCommands().keySet();
+ assertTrue(
+ "Expected 'set-permission' to be in the command list: " + commandNames,
+ commandNames.contains("set-permission"));
+ assertTrue(
+ "Expected 'update-permission' to be in the command list: " +
commandNames,
+ commandNames.contains("update-permission"));
+ assertTrue(
+ "Expected 'delete-permission' to be in the command list: " +
commandNames,
+ commandNames.contains("delete-permission"));
+ assertTrue(
+ "Expected 'set-user-role' to be in the command list: " + commandNames,
+ commandNames.contains("set-user-role"));
+ }
+
+ private AnnotatedApi assertAnnotatedApiExistsFor(String method, String path)
{
+ final HashMap<String, String> parts = new HashMap<>();
+ final Api api = apiBag.lookup(path, method, parts);
+ if (api == null) {
+ fail("Expected to find API for path [" + path + "], but no API mapping
found.");
+ }
+ if (!(api instanceof AnnotatedApi)) {
+ fail(
+ "Expected AnnotatedApi for path ["
+ + path
+ + "], but found non-annotated API ["
+ + api
+ + "]");
+ }
+
+ return (AnnotatedApi) api;
+ }
+}
diff --git
a/solr/modules/jwt-auth/src/java/org/apache/solr/handler/admin/api/ModifyJWTAuthPluginConfigAPI.java
b/solr/modules/jwt-auth/src/java/org/apache/solr/handler/admin/api/ModifyJWTAuthPluginConfigAPI.java
new file mode 100644
index 00000000000..ea24208c66e
--- /dev/null
+++
b/solr/modules/jwt-auth/src/java/org/apache/solr/handler/admin/api/ModifyJWTAuthPluginConfigAPI.java
@@ -0,0 +1,39 @@
+/*
+ * 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.solr.handler.admin.api;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static
org.apache.solr.security.PermissionNameProvider.Name.SECURITY_EDIT_PERM;
+
+import org.apache.solr.api.Command;
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.api.PayloadObj;
+
+/** V2 API for modifying configuration for Solr's JWTAuthPlugin. */
+@EndPoint(
+ path = {"/cluster/security/authentication"},
+ method = POST,
+ permission = SECURITY_EDIT_PERM)
+public class ModifyJWTAuthPluginConfigAPI {
+
+ @Command(name = "set-property")
+ public void setProperties(PayloadObj<JWTConfigurationPayload>
propertyPayload) {
+ // Method stub used only to produce v2 API spec; implementation/body empty.
+ throw new IllegalStateException();
+ }
+}
diff --git
a/solr/modules/jwt-auth/src/java/org/apache/solr/handler/admin/api/package-info.java
b/solr/modules/jwt-auth/src/java/org/apache/solr/handler/admin/api/package-info.java
new file mode 100644
index 00000000000..f16f5f29a4e
--- /dev/null
+++
b/solr/modules/jwt-auth/src/java/org/apache/solr/handler/admin/api/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+/** API endpoint and associated files for the JWT Authentication Plugin */
+package org.apache.solr.handler.admin.api;
diff --git
a/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java
b/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java
index 0b468063d77..e5d42ca8f81 100644
---
a/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java
+++
b/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java
@@ -49,6 +49,8 @@ import org.apache.http.HttpHeaders;
import org.apache.http.HttpRequest;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.protocol.HttpContext;
+import org.apache.solr.api.AnnotatedApi;
+import org.apache.solr.api.Api;
import org.apache.solr.client.solrj.impl.Http2SolrClient;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SpecProvider;
@@ -57,6 +59,7 @@ import org.apache.solr.common.util.CommandOperation;
import org.apache.solr.common.util.Utils;
import org.apache.solr.common.util.ValidatingJsonMap;
import org.apache.solr.core.CoreContainer;
+import org.apache.solr.handler.admin.api.ModifyJWTAuthPluginConfigAPI;
import org.apache.solr.security.AuthenticationPlugin;
import org.apache.solr.security.ConfigEditablePlugin;
import
org.apache.solr.security.jwt.JWTAuthPlugin.JWTAuthenticationResponse.AuthCode;
@@ -705,7 +708,8 @@ public class JWTAuthPlugin extends AuthenticationPlugin
@Override
public ValidatingJsonMap getSpec() {
- return Utils.getSpec("cluster.security.JwtAuth.Commands").getSpec();
+ final List<Api> apis = AnnotatedApi.getApis(new
ModifyJWTAuthPluginConfigAPI());
+ return apis.get(0).getSpec();
}
/**
diff --git
a/solr/modules/jwt-auth/src/test/org/apache/solr/handler/admin/api/V2JWTSecurityApiMappingTest.java
b/solr/modules/jwt-auth/src/test/org/apache/solr/handler/admin/api/V2JWTSecurityApiMappingTest.java
new file mode 100644
index 00000000000..252f8b9f953
--- /dev/null
+++
b/solr/modules/jwt-auth/src/test/org/apache/solr/handler/admin/api/V2JWTSecurityApiMappingTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.solr.handler.admin.api;
+
+import java.util.HashMap;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.api.AnnotatedApi;
+import org.apache.solr.api.Api;
+import org.apache.solr.api.ApiBag;
+import org.junit.Before;
+import org.junit.Test;
+
+public class V2JWTSecurityApiMappingTest extends SolrTestCaseJ4 {
+
+ private ApiBag apiBag;
+
+ @Before
+ public void setupApiBag() {
+ apiBag = new ApiBag(false);
+ }
+
+ @Test
+ public void testJwtConfigApiMapping() {
+ apiBag.registerObject(new ModifyJWTAuthPluginConfigAPI());
+
+ // Authc API
+ final AnnotatedApi updateAuthcConfig =
+ assertAnnotatedApiExistsFor("POST",
"/cluster/security/authentication");
+ assertEquals(1, updateAuthcConfig.getCommands().size());
+ assertEquals("set-property",
updateAuthcConfig.getCommands().keySet().iterator().next());
+ }
+
+ private AnnotatedApi assertAnnotatedApiExistsFor(String method, String path)
{
+ final HashMap<String, String> parts = new HashMap<>();
+ final Api api = apiBag.lookup(path, method, parts);
+ if (api == null) {
+ fail("Expected to find API for path [" + path + "], but no API mapping
found.");
+ }
+ if (!(api instanceof AnnotatedApi)) {
+ fail(
+ "Expected AnnotatedApi for path ["
+ + path
+ + "], but found non-annotated API ["
+ + api
+ + "]");
+ }
+
+ return (AnnotatedApi) api;
+ }
+}
diff --git
a/solr/modules/jwt-auth/src/test/org/apache/solr/handler/admin/api/package-info.java
b/solr/modules/jwt-auth/src/test/org/apache/solr/handler/admin/api/package-info.java
new file mode 100644
index 00000000000..563aabcd128
--- /dev/null
+++
b/solr/modules/jwt-auth/src/test/org/apache/solr/handler/admin/api/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+/** Tests for the API(s) bundled with the jwt-auth module. */
+package org.apache.solr.handler.admin.api;
diff --git
a/solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/DeleteBasicAuthUserPayload.java
b/solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/DeleteBasicAuthUserPayload.java
new file mode 100644
index 00000000000..72ca11d69d2
--- /dev/null
+++
b/solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/DeleteBasicAuthUserPayload.java
@@ -0,0 +1,22 @@
+/*
+ * 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.solr.client.solrj.request.beans;
+
+import org.apache.solr.common.util.ReflectMapWriter;
+
+public class DeleteBasicAuthUserPayload implements ReflectMapWriter {}
diff --git
a/solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/SetRuleBasedAuthPermissionPayload.java
b/solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/SetRuleBasedAuthPermissionPayload.java
new file mode 100644
index 00000000000..7ada44aee09
--- /dev/null
+++
b/solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/SetRuleBasedAuthPermissionPayload.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.solr.client.solrj.request.beans;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.solr.common.annotation.JsonProperty;
+import org.apache.solr.common.util.ReflectMapWriter;
+
+public class SetRuleBasedAuthPermissionPayload implements ReflectMapWriter {
+ @JsonProperty public String name;
+
+ // TODO Do we support enum's: only acceptable values here are GET, POST,
DELETE, and PUT
+ @JsonProperty public String method;
+
+ @JsonProperty public List<String> collection;
+
+ @JsonProperty public List<String> path;
+
+ @JsonProperty public Integer index;
+
+ @JsonProperty public Integer before;
+
+ @JsonProperty public Map<String, Object> params;
+
+ @JsonProperty(required = true)
+ public List<String> role;
+}
diff --git
a/solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/UpdateRuleBasedAuthPermissionPayload.java
b/solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/UpdateRuleBasedAuthPermissionPayload.java
new file mode 100644
index 00000000000..f002a08250f
--- /dev/null
+++
b/solr/solrj/src/java/org/apache/solr/client/solrj/request/beans/UpdateRuleBasedAuthPermissionPayload.java
@@ -0,0 +1,44 @@
+/*
+ * 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.solr.client.solrj.request.beans;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.solr.common.annotation.JsonProperty;
+import org.apache.solr.common.util.ReflectMapWriter;
+
+public class UpdateRuleBasedAuthPermissionPayload implements ReflectMapWriter {
+ @JsonProperty public String name;
+
+ // TODO Do we support enum's: only acceptable values here are GET, POST,
DELETE, and PUT
+ @JsonProperty public String method;
+
+ @JsonProperty public List<String> collection;
+
+ @JsonProperty public List<String> path;
+
+ @JsonProperty(required = true)
+ public Integer index;
+
+ @JsonProperty public Integer before;
+
+ @JsonProperty public Map<String, Object> params;
+
+ @JsonProperty(required = true)
+ public List<String> role;
+}
diff --git
a/solr/solrj/src/java/org/apache/solr/handler/admin/api/JWTConfigurationPayload.java
b/solr/solrj/src/java/org/apache/solr/handler/admin/api/JWTConfigurationPayload.java
new file mode 100644
index 00000000000..07f1c63bd80
--- /dev/null
+++
b/solr/solrj/src/java/org/apache/solr/handler/admin/api/JWTConfigurationPayload.java
@@ -0,0 +1,87 @@
+/*
+ * 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.solr.handler.admin.api;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.solr.common.annotation.JsonProperty;
+import org.apache.solr.common.util.ReflectMapWriter;
+
+public class JWTConfigurationPayload implements ReflectMapWriter {
+
+ @JsonProperty public Boolean blockUnknown;
+
+ @JsonProperty public String principalClaim;
+
+ @JsonProperty public Boolean requireExp;
+
+ @JsonProperty public List<String> algAllowlist;
+
+ @JsonProperty public Long jwkCacheDur;
+
+ @JsonProperty public Map<String, Object> claimsMatch;
+
+ // TODO Should this be a List<String> instead of a whitespace delimited
string?
+ @JsonProperty public String scope;
+
+ @JsonProperty public String realm;
+
+ // TODO Should this be a List<String> instead of a whitespace delimited
string?
+ @JsonProperty public String rolesClaim;
+
+ @JsonProperty public String adminUiScope;
+
+ @JsonProperty public List<String> redirectUris;
+
+ @JsonProperty public Boolean requireIss;
+
+ @JsonProperty public List<Issuer> issuers;
+
+ @JsonProperty public String trustedCertsFile;
+
+ @JsonProperty public List<String> trustedCerts;
+
+ // Prior to supporting an array of issuers, legacy syntax supported
properties for a single issuer
+ // at the top-level.
+ @JsonProperty public String name;
+ @JsonProperty public List<String> jwksUrl;
+ @JsonProperty public Map<String, Object> jwk;
+ @JsonProperty public String iss;
+ @JsonProperty public String aud;
+ @JsonProperty public String wellKnownUrl;
+ @JsonProperty public String authorizationEndpoint;
+ @JsonProperty public String clientId;
+
+ public static class Issuer implements ReflectMapWriter {
+ @JsonProperty public String name;
+
+ @JsonProperty public String wellKnownUrl;
+
+ @JsonProperty public String clientId;
+
+ @JsonProperty public List<String> jwksUrl;
+
+ @JsonProperty public Map<String, Object> jwk;
+
+ @JsonProperty public String iss;
+
+ @JsonProperty public String aud;
+
+ @JsonProperty public String authorizationEndpoint;
+ }
+}
diff --git
a/solr/solrj/src/java/org/apache/solr/handler/admin/api/package-info.java
b/solr/solrj/src/java/org/apache/solr/handler/admin/api/package-info.java
new file mode 100644
index 00000000000..993c5b4c4ed
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/handler/admin/api/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+/** Payload implementations for APIs associated with the jwt-auth optional
module */
+package org.apache.solr.handler.admin.api;
diff --git
a/solr/solrj/src/resources/apispec/cluster.security.BasicAuth.Commands.json
b/solr/solrj/src/resources/apispec/cluster.security.BasicAuth.Commands.json
deleted file mode 100644
index ba03e03324b..00000000000
--- a/solr/solrj/src/resources/apispec/cluster.security.BasicAuth.Commands.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "documentation":
"https://solr.apache.org/guide/basic-authentication-plugin.html",
- "description": "Modifies the configuration of Basic authentication, allowing
you to add or remove users and their passwords.",
- "methods": [
- "POST"
- ],
- "url": {
- "paths": [
- "/cluster/security/authentication"
- ]
- },
- "commands": {
- "set-user": {
- "type":"object",
- "description": "The set-user command allows you to add users and change
their passwords. Usernames and passwords are expressed as key-value pairs in a
JSON object.",
- "additionalProperties": true
- },
- "delete-user": {
- "description": "Delete a user or a list of users. Passwords do not need
to be provided, simply list the users in a JSON array, separated by colons.",
- "type":"string"
- }
- }
-}
diff --git
a/solr/solrj/src/resources/apispec/cluster.security.JwtAuth.Commands.json
b/solr/solrj/src/resources/apispec/cluster.security.JwtAuth.Commands.json
deleted file mode 100644
index d4f43dfd11f..00000000000
--- a/solr/solrj/src/resources/apispec/cluster.security.JwtAuth.Commands.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "documentation":
"https://solr.apache.org/guide/jwt-authentication-plugin.html",
- "description": "Modifies the configuration of JWT token authentication.",
- "methods": [
- "POST"
- ],
- "url": {
- "paths": [
- "/cluster/security/authentication"
- ]
- },
- "commands": {
- "set-property": {
- "type":"object",
- "description": "The set-property command lets you set any of the
configuration parameters supported by this plugin"
- }
- }
-}
diff --git
a/solr/solrj/src/resources/apispec/cluster.security.MultiPluginAuth.Commands.json
b/solr/solrj/src/resources/apispec/cluster.security.MultiPluginAuth.Commands.json
deleted file mode 100644
index e77f693c8a8..00000000000
---
a/solr/solrj/src/resources/apispec/cluster.security.MultiPluginAuth.Commands.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "documentation":
"https://solr.apache.org/guide/basic-authentication-plugin.html",
- "description": "Modifies the configuration of the multi-auth plugin. Each
command should be wrapped in a single key object that identifies the scheme.
The embedded command is then passed to the scheme specific plugin.",
- "methods": [
- "POST"
- ],
- "url": {
- "paths": [
- "/cluster/security/authentication"
- ]
- },
- "commands": {
- "set-user": {
- "type":"object",
- "description": "The set-user command allows you to add users and change
their passwords. Usernames and passwords are expressed as key-value pairs in a
JSON object.",
- "additionalProperties": true
- },
- "delete-user": {
- "description": "Delete a user or a list of users. Passwords do not need
to be provided, simply list the users in a JSON array, separated by colons.",
- "type":"object"
- },
- "set-property": {
- "type":"object",
- "description": "The set-property command lets you set any of the
configuration parameters supported by this plugin"
- }
- }
-}
diff --git
a/solr/solrj/src/resources/apispec/cluster.security.RuleBasedAuthorization.json
b/solr/solrj/src/resources/apispec/cluster.security.RuleBasedAuthorization.json
deleted file mode 100644
index ad4aac1d9e3..00000000000
---
a/solr/solrj/src/resources/apispec/cluster.security.RuleBasedAuthorization.json
+++ /dev/null
@@ -1,129 +0,0 @@
-{
- "documentation":
"https://solr.apache.org/guide/rule-based-authorization-plugin.html",
- "description": "Defines roles for accessing Solr, and assigns users to those
roles. Use this API to change user authorizations to each of Solr's
components.",
- "methods": [
- "POST"
- ],
- "url": {
- "paths": [
- "/cluster/security/authorization"
- ]
- },
- "commands": {
- "set-permission": {
- "type":"object",
- "description": "Create a new permission, overwrite an existing
permission definition, or assign a pre-defined permission to a role.",
- "properties": {
- "name":{
- "type":"string",
- "description": "The name of the permission. The name will be used to
update or delete the permission later."
- },
- "method":{
- "type":"string",
- "enum":["GET", "POST", "DELETE","PUT"],
- "description": "HTTP methods that are allowed for this permission.
You could allow only GET requests, or have a role that allows PUT and POST
requests. The method values that are allowed for this property are GET, POST,
PUT, DELETE and HEAD."
- },
-
- "collection":{
- "type":"array",
- "items": {
- "type": "string"
- },
- "description":"The collection or collections the permission will
apply to. When the path that will be allowed is collection-specific, such as
when setting permissions to allow use of the Schema API, omitting the
collection property will allow the defined path and/or method for all
collections. However, when the path is one that is non-collection-specific,
such as the Collections API, the collection value must be null. In this case,
two permissions may need to be created; one fo [...]
- },
-
- "path":{
- "type":"array",
- "items": {
- "type": "string"
- },
- "description":"A request handler name, such as /update or /select. A
wild card is supported, to allow for all paths as appropriate (such as,
/update/*)."
- },
- "index": {
- "type": "integer",
- "description": "The index of the permission you wish to overwrite.
Skip this if it is a new permission that should be created."
- },
- "before":{
- "type": "integer",
- "description":"This property allows ordering of permissions. The
value for this property is the name of the permission that this new permission
should be placed before in security.json."
- },
- "params":{
- "type":"object",
- "additionalProperties":true,
- "description": "The names and values of request parameters. This
property can be omitted if all request parameters are allowed, but will
restrict access only to the values provided if defined."
- },
- "role": {
- "type": "array",
- "items": {
- "type": "string",
- "description": "The name of the role(s) to give this permission.
This name will be used to map user IDs to the role to grant these permissions.
The value can be wildcard such as (*), which means that any user is OK, but no
user is NOT OK."
- }
- }
- },
- "required": [
- "role"
- ]
- },
- "update-permission": {
- "type":"object",
- "properties": {
- "name": {
- "type": "string",
- "description": "The name of the permission. The name will be used to
update or delete the permission later."
- },
- "method": {
- "type": "string",
- "description": "HTTP methods that are allowed for this permission.
You could allow only GET requests, or have a role that allows PUT and POST
requests. The method values that are allowed for this property are GET, POST,
PUT, DELETE and HEAD."
- },
- "collection": {
- "type":"array",
- "items": {
- "type": "string"
- },
- "description": "The collection or collections the permission will
apply to. When the path that will be allowed is collection-specific, such as
when setting permissions to allow use of the Schema API, omitting the
collection property will allow the defined path and/or method for all
collections. However, when the path is one that is non-collection-specific,
such as the Collections API, the collection value must be null. In this case,
two permissions may need to be created; one f [...]
- },
- "path": {
- "type":"array",
- "items": {
- "type": "string"
- },
- "description": "A request handler name, such as /update or /select.
A wild card is supported, to allow for all paths as appropriate (such as,
/update/*)."
- },
- "index": {
- "type": "integer",
- "description": "The index of the permission you wish to overwrite."
- },
- "before": {
- "type": "integer",
- "description": "This property allows ordering of permissions. The
value for this property is the index of the permission that this new permission
should be placed before in security.json."
- },
- "role": {
- "type": "array",
- "items": {
- "type": "string",
- "description": "The name of the role(s) to give this permission.
This name will be used to map user IDs to the role to grant these permissions.
The value can be wildcard such as (*), which means that any user is OK, but no
user is NOT OK."
- }
- },
- "params": {
- "type": "object",
- "additionalProperties": true,
- "description": "The names and values of request parameters. This
property can be omitted if all request parameters are allowed, but will
restrict access only to the values provided if defined."
- }
- },
- "required": [
- "role",
- "index"
- ]
- },
- "delete-permission":{
- "description":"delete a permission by its index",
- "type":"integer"
- },
- "set-user-role": {
- "type":"object",
- "description": "A single command allows roles to be mapped to users. To
remove a user's permission, you should set the role to null. The key is always
a user id and the value is one or more role names.",
- "additionalProperties":true
-
- }
- }
-}
diff --git
a/solr/solrj/src/resources/apispec/cluster.security.authentication.Commands.json
b/solr/solrj/src/resources/apispec/cluster.security.authentication.Commands.json
deleted file mode 100644
index b71911cf9e4..00000000000
---
a/solr/solrj/src/resources/apispec/cluster.security.authentication.Commands.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "documentation": "https://solr.apache.org/guide/securing-solr.html",
- "description":"This is a placeholder output when no authentication is
configured",
- "methods": [
- "POST"
- ],
- "url": {
- "paths": [
- "/cluster/security/authentication"
- ]
- }
-}
diff --git
a/solr/solrj/src/resources/apispec/cluster.security.authentication.json
b/solr/solrj/src/resources/apispec/cluster.security.authentication.json
deleted file mode 100644
index d912f147961..00000000000
--- a/solr/solrj/src/resources/apispec/cluster.security.authentication.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "documentation":
"https://solr.apache.org/guide/authentication-and-authorization-plugins.html",
- "description": "Shows the configuration for authentication, including users,
classes (type of authentication) and other parameters.",
- "methods": [
- "GET"
- ],
- "url": {
- "paths": [
- "/cluster/security/authentication"
- ]
- }
-}
diff --git
a/solr/solrj/src/resources/apispec/cluster.security.authorization.Commands.json
b/solr/solrj/src/resources/apispec/cluster.security.authorization.Commands.json
deleted file mode 100644
index dfa47b552a0..00000000000
---
a/solr/solrj/src/resources/apispec/cluster.security.authorization.Commands.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "documentation": "https://solr.apache.org/guide/securing-solr.html",
- "description":"This is a placeholder output when no authorization is
configured",
- "methods": [
- "POST"
- ],
- "url": {
- "paths": [
- "/cluster/security/authorization"
- ]
- }
-
-}
diff --git
a/solr/solrj/src/resources/apispec/cluster.security.authorization.json
b/solr/solrj/src/resources/apispec/cluster.security.authorization.json
deleted file mode 100644
index 798f80453ad..00000000000
--- a/solr/solrj/src/resources/apispec/cluster.security.authorization.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "documentation":
"https://solr.apache.org/guide/authentication-and-authorization-plugins.html",
- "description":"Shows the configuration for authorization, including the
classes (type of authorization), permissions, user-roles, and other
parameters.",
- "methods": [
- "GET"
- ],
- "url": {
- "paths": [
- "/cluster/security/authorization"
- ]
- }
-
-}
diff --git
a/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java
b/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java
index d6e6361f3e9..225474a68e0 100644
--- a/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java
@@ -17,16 +17,10 @@
package org.apache.solr.common.util;
import java.util.List;
-import java.util.Map;
import org.apache.solr.SolrTestCaseJ4;
public class JsonValidatorTest extends SolrTestCaseJ4 {
- public void testSchema() {
- checkSchema("cluster.security.BasicAuth.Commands");
- checkSchema("cluster.security.RuleBasedAuthorization");
- }
-
public void testSchemaValidation() {
final JsonSchemaValidator personSchemaValidator =
new JsonSchemaValidator(
@@ -187,19 +181,4 @@ public class JsonValidatorTest extends SolrTestCaseJ4 {
mutuallyExclusivePropertiesValidator.validateJson(Utils.fromJSONString("" +
"{'a':'val'}"));
assertNull(errs);
}
-
- private void checkSchema(String name) {
- ValidatingJsonMap spec = Utils.getSpec(name).getSpec();
- @SuppressWarnings({"rawtypes"})
- Map commands = (Map) spec.get("commands");
- for (Object o : commands.entrySet()) {
- @SuppressWarnings({"rawtypes"})
- Map.Entry cmd = (Map.Entry) o;
- try {
- JsonSchemaValidator validator = new JsonSchemaValidator((Map)
cmd.getValue());
- } catch (Exception e) {
- throw new RuntimeException("Error in command " + cmd.getKey() + " in
schema " + name, e);
- }
- }
- }
}