Skip to content

SOLR-15738: Convert v2 security APIs to annotations#897

Merged
gerlowskija merged 17 commits intoapache:mainfrom
gerlowskija:SOLR-15738-v2-security-annotation-conversion
Jun 21, 2022
Merged

SOLR-15738: Convert v2 security APIs to annotations#897
gerlowskija merged 17 commits intoapache:mainfrom
gerlowskija:SOLR-15738-v2-security-annotation-conversion

Conversation

@gerlowskija
Copy link
Contributor

@gerlowskija gerlowskija commented Jun 7, 2022

Description

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. Many security APIs
remain on the "old" framework.

Solution

This commit converts the APIs from the following apispec files to the
"new" framework:

  • cluster.security.authentication
  • cluster.security.authorization
  • cluster.security.BasicAuth.Commands
  • cluster.security.JwtAuth.Commands
  • cluster.security.MultiPluginAuth.Commands
  • cluster.security.RuleBasedAuthorization
  • cluster.security.authentication.Commands
  • cluster.security.authorization.Commands

Tests

None yet, but I intend to add some prior to merging.

Checklist

Please review the following and check all that apply:

  • I have reviewed the guidelines for How to Contribute and my code conforms to the standards described there to the best of my ability.
  • I have created a Jira issue and added the issue ID to my pull request title.
  • I have given Solr maintainers access to contribute to my PR branch. (optional but recommended)
  • I have developed this patch against the main branch.
  • I have run ./gradlew check.
  • I have added tests for my changes.

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.

Several other security apispec files still remain, including:
  - cluster.security.BasicAuth.Commands
  - cluster.security.JwtAuth.Commands
  - cluster.security.MultiPluginAuth.Commands
  - cluster.security.RuleBasedAuthorization
  - cluster.security.authentication.Commands
  - cluster.security.authorization.Commands

The first four entries in the list above are plugin-specific commands
for the `POST /cluster/security/[authentication|authorization]`
endpoints.  The last two entries (c.s.authentication.Commands and
c.s.authorization.Commands) are fallbacks for the POST endpoints, to
cover the case where no authc/authz plugins are defined.  It's unclear
whether or not these are needed going forward.
@gerlowskija gerlowskija marked this pull request as draft June 7, 2022 16:12
/**
* 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's stick to the /api/* prefix instead of /v2/* prefix ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting point, I think we have the /v2/ in the other modifications? I checked https://github.com/apache/solr/blob/main/solr/core/src/java/org/apache/solr/handler/admin/api/SchemaBulkModifyAPI.java#L31 for example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've always had the slightest preference for /v2, because while v1 and v2 both exist, it's easy to imagine a user getting confused and looking for a v1 endpoint under the /api path, because hey, it is an api after all. But that's very hypothetical and not something I care much about. But if you guys do, I'm happy to change all of these instances to one or the other.

Just lmk which one wins out and I'll do a separate PR to find-replace it everywhere (it's going to be in a ton of places).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense!

@noblepaul
Copy link
Contributor

noblepaul commented Jun 8, 2022

Do we really need separate classes for specifying the EndPoint ? can we just make them internal to SeciurityConfHandler ?

We should have concrete POJOs that describe the payloads ?

@gerlowskija
Copy link
Contributor Author

Do we really need separate classes for specifying the EndPoint ? can we just make them internal to SeciurityConfHandler ?

The API classes can be internal if there's consensus for that, but my personal vote would be that they stay separate.

  1. The current mapping of APIs -> RequestHandlers is based entirely on the v1 API without any consideration of v2. There's no reason in a v2 world for the GET /cluster/aliases API to live in CollectionsHandler.java.
  2. Many of our RequestHandler's are absolute monsters. The more code we can keep out of those files, the better IMO. Particularly since one of my ultimate goals is to see the "meat" of our APIs move from SomeRequestHandler.handleRequestBody to these individual API classes.

We should have concrete POJOs that describe the payloads ?

We do, yep. You didn't see any at the time of your previous comment because I had only pushed up 2 of the GET APIs at that point (which of course don't have payloads). I've updated the PR to cover all of the security APIs, so you should see payload POJOs now if you take another look (e.g. JWTConfigurationPayload, UpdateRuleBasedAuthPermissionPayload, etc.)

}
}

public int hashCode() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't you think we should cash and reuse the hash ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several of the instance variables we use to compute the hashCode here are non-final. I'd bet those vars are unlikely to change in practice, but I wasn't confident enough in that to put in caching here, just in case.

path = {"/cluster/security/authentication"},
method = POST,
permission = SECURITY_EDIT_PERM)
public void updateAuthenticationConfig(SolrQueryRequest req, SolrQueryResponse rsp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't we have concrete classes as params ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should, but I'm not sure what they would be. This file is the annotation conversion for cluster.security.authentication.Commands.json, which is the POST api loaded when no authentication plugin is in use.

The old apispec file didn't define any commands, and there are no examples in the ref-guide (afaict) that show what commands are supported in the no-authc-plugin case.

So in short, I only did things this way because (1) I don't know what the concrete classes should be, and (2) this had parity with the apispec, so it seemed at least pass-able.

(This is also the situation on DefaultUpdateAuthorizationConfigAPI below)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing a little more digging here, it looks like SecurityConfHandler actually has other logic that will short circuit this case (i.e. a POST to /authentication or /authorization when no plugin is configured) with a 400 (see here).

Afaict, the only purpose these classes (and the apispecs they came from) serve is to make sure users get a helpful error message about "No plugin being configured", rather than the less-helpful 404 users would get if no API was registered at all until a plugin was registered.

This also explains why the original apispecs didn't list any commands: because the API was only a placeholder to produce a comprehensible error message, it never offered actual functionality. I'm going to rename these classes and add Javadocs so this is all clearer. But I don't think I'll be able to change the concrete-payload-class thing, unless there's something I'm still missing?

path = {"/cluster/security/authorization"},
method = POST,
permission = SECURITY_EDIT_PERM)
public void updateAuthorizationConfig(SolrQueryRequest req, SolrQueryResponse rsp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

concrete classes here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(See my reply on DefaultUpdateAuthenticationConfigAPI above)

@gerlowskija gerlowskija marked this pull request as ready for review June 10, 2022 14:35
Copy link
Contributor

@epugh epugh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. How the auth stuff works is a bit opaque to me, but the conversion aspect makes sense.

@gerlowskija
Copy link
Contributor Author

Alright, thanks for the reviews guys. Gonna merge this and close out the ticket. Only a few more conversions to do!

@gerlowskija gerlowskija merged commit bf0b2b0 into apache:main Jun 21, 2022
@gerlowskija gerlowskija deleted the SOLR-15738-v2-security-annotation-conversion branch June 21, 2022 15:42
gerlowskija added a commit that referenced this pull request Jun 21, 2022
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants