Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User Profile: Activate user profile API #82400

Merged
merged 12 commits into from
Jan 17, 2022

Conversation

ywangd
Copy link
Member

@ywangd ywangd commented Jan 11, 2022

This PR adds a REST endpoint to activate user profile.

Notes:

  • As discussed, the activate request currently has an empty request body. This means all information is extracted from the Authentication object. In future, we will support request body so that extra information, e.g. displayName, can be specified by the calling application.
  • Since authentication object has not been updated for domain, for now, the profile creation and update do not record domain related information either.

@ywangd ywangd added >enhancement WIP :Security/Security Security issues without another label v8.1.0 labels Jan 11, 2022
Copy link

@Lee2885 Lee2885 left a comment

Choose a reason for hiding this comment

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

@ywangd ywangd marked this pull request as ready for review January 14, 2022 00:46
@elasticmachine elasticmachine added the Team:Security Meta label for security team label Jan 14, 2022
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-security (Team:Security)


@Override
protected void doExecute(Task task, ActivateProfileRequest request, ActionListener<ActivateProfileResponse> listener) {
try (ThreadContext.StoredContext ignore = threadContext.stashContext()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I realise this is taken from TransportGrantApiKeyAction, but I think you could make use of SecurityContext#executeWithAuthentication to simplify it all.

Copy link
Member Author

Choose a reason for hiding this comment

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

I am not entirely sure about using SecurityContext#executeWithAuthentication. It is currently only used for secondary authentication where I think it is a better fit because the it means to pretend the secondary authentication is the only authentication object and forget about the initial authentication entirely.

Grant is very similar. Indeed, it currently has the same practical behaviour once the authentication from the request body is resolved. But I think the semantics is slight different. There were discussions about how the grant type requests could work in the background and one proposal is to serialised both authentication objects. This may not end up to be the solution. But I think it does highlight the difference between grant and secondary authentication in that Grant needs 2 authentiation objects to fully work. So I'd refrain from using SecurityContext#executeWithAuthentication right now.

Also, in the latest commit I extracted a superclass for grant type action to have common executeWithGrantAuthentication method. So hopefully this refactoring can still achieve better simplicity without resorting to SecurityContext#executeWithAuthentication.

request.getGrant(),
request,
ActionListener.wrap(
authentication -> profileService.activateProfile(authentication, listener.map(ActivateProfileResponse::new)),
Copy link
Contributor

Choose a reason for hiding this comment

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

I would avoid passing in the authentication as a parameter, instead you could make the service only activate the profile of the currently authenticated user. Otherwise there is the potential for ambiguity, when the two authentications diverge.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is only possible if we replace authentication with SecurityContext#executeWithAuthentication. As commented above, I am not entirely convinced about this approach. Replacing authentication object also incur additional serialisation cost which I am not fond of either. We have many methods that accept Authentication as a parameter, e.g. methods of TokenService, ApiKeyService, CompositeRolesStore etc. Given callers of these methods are well controlled, I am not too worried about the confusion. I can also add some comment to help clarify the usage.

TransportRequest transportRequest,
ActionListener<Authentication> listener
) {
switch (grant.getType()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The switch basically chooses between new UsernamePasswordToken(grant.getUsername(), grant.getPassword()) and new BearerToken(grant.getAccessToken()), plus it validates the grant.Type() request parameter. I think this method can be improved for readability.

Copy link
Member Author

Choose a reason for hiding this comment

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

This method is also copied from TransportGrantApiKeyAction. I had a TODO in the beginning of this method and was meant to refactor it in a separate PR. But we may as well handle it now. I extracted Grant into a separate class and extract base classes for both GrantApiKey and ActivateProfile related classes. Hopefully the new change makes it read better.

Copy link
Contributor

@albertzaharovits albertzaharovits left a comment

Choose a reason for hiding this comment

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

LGTM Yang!
I only had a couple of small comments, but I admit I wasn't very diligent on this one. This being a new API (rather than changing an existing one), I'll go over it again when all the pieces are in place, notably the core change #82639 .

@ywangd ywangd removed the WIP label Jan 17, 2022
@ywangd ywangd merged commit 3c131e6 into elastic:master Jan 17, 2022
@ywangd ywangd mentioned this pull request Feb 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>enhancement :Security/Security Security issues without another label Team:Security Meta label for security team v8.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants