Skip to content

Conversation

@albertzaharovits
Copy link
Contributor

This adds the security authenticate API.
This API is exceptional because it does not have a request body 🦄
I have added EmptyBodyRequest up from the security package.

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-security

* under the License.
*/

package org.elasticsearch.client;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

not in the .security package.

return request;
}

}
Copy link
Contributor Author

@albertzaharovits albertzaharovits Sep 9, 2018

Choose a reason for hiding this comment

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

The request is a singleton, so there is no need for a "request converter function". The converted is a member of the singleton.

static {
PARSER.declareString(constructorArg(), USERNAME);
PARSER.declareStringArray(optionalConstructorArg(), ROLES);
PARSER.declareStringOrNull(optionalConstructorArg(), FULL_NAME);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

declareStringOrNull together with optionalConstructorArg is extra cautious.
I am comfortable with it, although I guess optional is unnecessary.

(Map<String, Object>) a[4], (Boolean) a[5]));
static {
PARSER.declareString(constructorArg(), USERNAME);
PARSER.declareStringArray(optionalConstructorArg(), ROLES);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If there would have been a null version for this I would have picked it.
I see the XContentBuilder adds null for every object type it serializes but the parser is not expecting null for each of these, maybe it should?
In addition to the empty collection vs null, in JSON we could also have the field missing 🎃 Do we have a rule for these?

Copy link
Contributor Author

@albertzaharovits albertzaharovits Sep 14, 2018

Choose a reason for hiding this comment

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

XContentBuilder serializes null arrays with a null JSON value

but ObjectParser will fail to parse it
public void declareStringArray(BiConsumer<Value, List<String>> consumer, ParseField field) {
.

In practice this should not happen because on the server side we don't serialize null arrays in this case, but there is no guarantee for this, as there are no assertions.

Copy link
Member

Choose a reason for hiding this comment

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

I think the parser should handle nulls; how about adding support to object parser to have a string array or null?


The returned `AuthenticateResponse` contains a single field, `user`. This field
, accessed with `getUser`, contains all the information about this
authenticated user.
Copy link
Contributor Author

@albertzaharovits albertzaharovits Sep 9, 2018

Choose a reason for hiding this comment

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

I wonder if could link to javadocs here ? I would like to link to the User javadoc class.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure about that, maybe @nik9000 knows? I am pretty sure he was working on some improvements around the docs for the HLRC

Copy link
Contributor Author

Choose a reason for hiding this comment

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

there is a way to point to the root Javadoc, see /docs/java-rest/high-level/getting-started.asciidoc but I wanted a link to a specific class's javadoc. There does not seem to be any practical way for this (other than crafting rickety links).

Copy link
Contributor

@debadair debadair Oct 26, 2018

Choose a reason for hiding this comment

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

@albertzaharovits We can make the links slightly-less rickety by adding shared attributes for the javadoc package URLs. For example, if we define:

:javadoc-client: {rest-high-level-client-javadoc}/org/elasticsearch/client

Then you can link to specific classes in the client package by specifying {javadoc-client}/ClassName.html.

If that seems workable, I can add the attributes to the Versions.asciidoc file: #34934

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@debadair
I will be trying it, thank you for the air support!

Copy link
Contributor

@hub-cap hub-cap left a comment

Choose a reason for hiding this comment

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

I dont see any tests other than the documentation ones. I also noticed there is no SecurityIT, like the other tests have in HLRC's test module. Maybe this PR can add it :)

}

/**
* Authenticate the current user (pertaining to request headers)
Copy link
Member

Choose a reason for hiding this comment

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

I'd remove pertaining to request headers since there is PKI which doesn't use headers

import org.elasticsearch.client.EmptyBodyRequest;
import org.elasticsearch.client.Request;

public class AuthenticateRequest extends EmptyBodyRequest {
Copy link
Member

Choose a reason for hiding this comment

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

add javadocs and make the class final

import java.io.IOException;
import java.util.Objects;

public class AuthenticateResponse {
Copy link
Member

Choose a reason for hiding this comment

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

make the class final and add javadocs

(Map<String, Object>) a[4], (Boolean) a[5]));
static {
PARSER.declareString(constructorArg(), USERNAME);
PARSER.declareStringArray(optionalConstructorArg(), ROLES);
Copy link
Member

Choose a reason for hiding this comment

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

I think the parser should handle nulls; how about adding support to object parser to have a string array or null?

@Nullable private final String email;

private User(String username, @Nullable String[] roles, @Nullable String fullName, @Nullable String email,
@Nullable Map<String, Object> metadata, Boolean enabled) {
Copy link
Member

Choose a reason for hiding this comment

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

how about we just accept the boolean primitive here?

/**
* An authenticated user
*/
public class User {
Copy link
Member

Choose a reason for hiding this comment

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

make the class final


The returned `AuthenticateResponse` contains a single field, `user`. This field
, accessed with `getUser`, contains all the information about this
authenticated user.
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure about that, maybe @nik9000 knows? I am pretty sure he was working on some improvements around the docs for the HLRC

@albertzaharovits
Copy link
Contributor Author

run gradle build tests SUCCESS

@albertzaharovits
Copy link
Contributor Author

run sample packaging tests

@colings86 colings86 added v6.6.0 and removed v6.5.0 labels Oct 25, 2018
Copy link
Contributor

@hub-cap hub-cap left a comment

Choose a reason for hiding this comment

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

super minor stuff. <3 and it looks like its very close to being done!

Copy link
Member

@jaymode jaymode left a comment

Choose a reason for hiding this comment

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

This is looking good, just a few comments

public final class User {

private final String username;
private final Collection<String> roles;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is a Collection now instead of List.

--------------------------------------------------
<1> `getUser` retrieves the `User` instance containing the information,
see {javadoc-client}/security/user/User.html.
<2> `enabled` tells if this user is usable or is deactivated.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

well... this is always true in the current implementation. If the user would have been disabled the _authenticate call would be failing.

@albertzaharovits
Copy link
Contributor Author

@jaymode @hub-cap thank for your input on this.
May you please have another pass over it?

@albertzaharovits
Copy link
Contributor Author

test this please

Copy link
Member

@jaymode jaymode left a comment

Choose a reason for hiding this comment

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

I left one comment, otherwise LGTM

}

public Request getRequest() {
return request;
Copy link
Member

Choose a reason for hiding this comment

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

I think we should return a new request with this method; the request member is not immutable so we should not allow it to be returned via a public API

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a very good point!

@albertzaharovits
Copy link
Contributor Author

@albertzaharovits albertzaharovits merged commit bdd8460 into elastic:master Oct 31, 2018
@albertzaharovits albertzaharovits deleted the hlrc_authenticate branch October 31, 2018 12:49
albertzaharovits added a commit that referenced this pull request Oct 31, 2018
This adds the security `_authenticate` API to the HLREST client.
It is unlike some of the other APIs because the request does not
have a body.
The commit also creates the `User` entity. It is important
to note that the `User` entity does not have the `enabled`
flag. The `enabled` flag is part of the response, alongside
the `User` entity.
Moreover this adds the `SecurityIT` test class
(extending `ESRestHighLevelClientTestCase`).

Relates #29827
albertzaharovits added a commit that referenced this pull request Nov 8, 2018
This follows #33552 , when the `_authenticate` API added a new
`User` object for the API's response. This changes the `put_user`
API to also employ a `User` object in the request.
The User object changed slightly.
A bug with put_user only putting/updating enabled (but not disabled)
users has been fixed.
albertzaharovits added a commit that referenced this pull request Nov 8, 2018
This follows #33552 , when the `_authenticate` API added a new
`User` object for the API's response. This changes the `put_user`
API to also employ a `User` object in the request.
The User object changed slightly.
A bug with put_user only putting/updating enabled (but not disabled)
users has been fixed.
@jpountz jpountz removed the :Security/Authentication Logging in, Usernames/passwords, Realms (Native/LDAP/AD/SAML/PKI/etc) label Jan 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants