-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Move XContent generation to HasPrivilegesResponse #35616
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,11 +9,14 @@ | |
| import org.elasticsearch.action.ActionResponse; | ||
| import org.elasticsearch.common.io.stream.StreamInput; | ||
| import org.elasticsearch.common.io.stream.StreamOutput; | ||
| import org.elasticsearch.common.xcontent.ToXContentObject; | ||
| import org.elasticsearch.common.xcontent.XContentBuilder; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.ArrayList; | ||
| import java.util.Collection; | ||
| import java.util.Collections; | ||
| import java.util.Comparator; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
@@ -22,24 +25,35 @@ | |
| /** | ||
| * Response for a {@link HasPrivilegesRequest} | ||
| */ | ||
| public class HasPrivilegesResponse extends ActionResponse { | ||
| public class HasPrivilegesResponse extends ActionResponse implements ToXContentObject { | ||
| private String username; | ||
| private boolean completeMatch; | ||
| private Map<String, Boolean> cluster; | ||
| private List<ResourcePrivileges> index; | ||
| private Map<String, List<ResourcePrivileges>> application; | ||
|
|
||
| public HasPrivilegesResponse() { | ||
| this(true, Collections.emptyMap(), Collections.emptyList(), Collections.emptyMap()); | ||
| this("", true, Collections.emptyMap(), Collections.emptyList(), Collections.emptyMap()); | ||
| } | ||
|
|
||
| public HasPrivilegesResponse(boolean completeMatch, Map<String, Boolean> cluster, Collection<ResourcePrivileges> index, | ||
| public HasPrivilegesResponse(String username, boolean completeMatch, Map<String, Boolean> cluster, Collection<ResourcePrivileges> index, | ||
| Map<String, Collection<ResourcePrivileges>> application) { | ||
| super(); | ||
| this.username = username; | ||
| this.completeMatch = completeMatch; | ||
| this.cluster = new HashMap<>(cluster); | ||
| this.index = new ArrayList<>(index); | ||
| this.index = sorted(new ArrayList<>(index)); | ||
| this.application = new HashMap<>(); | ||
| application.forEach((key, val) -> this.application.put(key, Collections.unmodifiableList(new ArrayList<>(val)))); | ||
| application.forEach((key, val) -> this.application.put(key, Collections.unmodifiableList(sorted(new ArrayList<>(val))))); | ||
| } | ||
|
|
||
| private static List<ResourcePrivileges> sorted(List<ResourcePrivileges> resources) { | ||
| Collections.sort(resources, Comparator.comparing(o -> o.resource)); | ||
| return resources; | ||
| } | ||
|
|
||
| public String getUsername() { | ||
| return username; | ||
| } | ||
|
|
||
| public boolean isCompleteMatch() { | ||
|
|
@@ -62,13 +76,40 @@ public Map<String, List<ResourcePrivileges>> getApplicationPrivileges() { | |
| return Collections.unmodifiableMap(application); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object o) { | ||
| if (this == o) { | ||
| return true; | ||
| } | ||
| if (o == null || getClass() != o.getClass()) { | ||
| return false; | ||
| } | ||
| final HasPrivilegesResponse response = (HasPrivilegesResponse) o; | ||
| return completeMatch == response.completeMatch | ||
| && Objects.equals(username, response.username) | ||
| && Objects.equals(cluster, response.cluster) | ||
| && Objects.equals(index, response.index) | ||
| && Objects.equals(application, response.application); | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hash(username, completeMatch, cluster, index, application); | ||
| } | ||
|
|
||
| public void readFrom(StreamInput in) throws IOException { | ||
| super.readFrom(in); | ||
| completeMatch = in.readBoolean(); | ||
| if (in.getVersion().onOrAfter(Version.V_7_0_0)) { | ||
| cluster = in.readMap(StreamInput::readString, StreamInput::readBoolean); | ||
| } | ||
| index = readResourcePrivileges(in); | ||
| if (in.getVersion().onOrAfter(Version.V_6_4_0)) { | ||
| application = in.readMap(StreamInput::readString, HasPrivilegesResponse::readResourcePrivileges); | ||
| } | ||
| if (in.getVersion().onOrAfter(Version.V_7_0_0)) { | ||
| username = in.readString(); | ||
| } | ||
| } | ||
|
|
||
| private static List<ResourcePrivileges> readResourcePrivileges(StreamInput in) throws IOException { | ||
|
|
@@ -86,10 +127,16 @@ private static List<ResourcePrivileges> readResourcePrivileges(StreamInput in) t | |
| public void writeTo(StreamOutput out) throws IOException { | ||
| super.writeTo(out); | ||
| out.writeBoolean(completeMatch); | ||
| if (out.getVersion().onOrAfter(Version.V_7_0_0)) { | ||
| out.writeMap(cluster, StreamOutput::writeString, StreamOutput::writeBoolean); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand this is the oversight you've mentioned
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes - I actually noticed it while working on application privileges, but forgot to come back and fix it. |
||
| writeResourcePrivileges(out, index); | ||
| if (out.getVersion().onOrAfter(Version.V_6_4_0)) { | ||
| out.writeMap(application, StreamOutput::writeString, HasPrivilegesResponse::writeResourcePrivileges); | ||
| } | ||
| if (out.getVersion().onOrAfter(Version.V_7_0_0)) { | ||
| out.writeString(username); | ||
| } | ||
| } | ||
|
|
||
| private static void writeResourcePrivileges(StreamOutput out, List<ResourcePrivileges> privileges) throws IOException { | ||
|
|
@@ -100,6 +147,49 @@ private static void writeResourcePrivileges(StreamOutput out, List<ResourcePrivi | |
| } | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return getClass().getSimpleName() + "{" | ||
| + "username=" + username + "," | ||
| + "completeMatch=" + completeMatch + "," | ||
| + "cluster=" + cluster + "," | ||
| + "index=" + index + "," | ||
| + "application=" + application | ||
| + "}"; | ||
| } | ||
|
|
||
| @Override | ||
| public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
| builder.startObject() | ||
| .field("username", username) | ||
| .field("has_all_requested", completeMatch); | ||
|
|
||
| builder.field("cluster"); | ||
| builder.map(cluster); | ||
|
|
||
| appendResources(builder, "index", index); | ||
|
|
||
| builder.startObject("application"); | ||
| for (String app : application.keySet()) { | ||
| appendResources(builder, app, application.get(app)); | ||
| } | ||
| builder.endObject(); | ||
|
|
||
| builder.endObject(); | ||
| return builder; | ||
| } | ||
|
|
||
| private void appendResources(XContentBuilder builder, String field, List<HasPrivilegesResponse.ResourcePrivileges> privileges) | ||
| throws IOException { | ||
| builder.startObject(field); | ||
| for (HasPrivilegesResponse.ResourcePrivileges privilege : privileges) { | ||
| builder.field(privilege.getResource()); | ||
| builder.map(privilege.getPrivileges()); | ||
| } | ||
| builder.endObject(); | ||
| } | ||
|
|
||
|
|
||
| public static class ResourcePrivileges { | ||
| private final String resource; | ||
| private final Map<String, Boolean> privileges; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be using a
Setin this circumstances.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I was starting from scratch, then so would I, but that would require changing the return types on
getIndexPrivilegesandgetApplicationPrivilegeswhich seemed more invasive than was justified by this PR.I'm happy to revist that choice if you want - I went back-and-forth many times while making the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's good like it is , it's more civilized, otherwise it would indeed indeed violate the scope of this PR. I think I see the privilege code as new code where creative destruction is more loosely permitted.
But I still think it would be nice to do this change in a follow-up. I am happy to pick it up if you wish.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's all yours :)