1+ /*
2+ * Licensed to Elasticsearch under one or more contributor
3+ * license agreements. See the NOTICE file distributed with
4+ * this work for additional information regarding copyright
5+ * ownership. Elasticsearch licenses this file to you under
6+ * the Apache License, Version 2.0 (the "License"); you may
7+ * not use this file except in compliance with the License.
8+ * You may obtain a copy of the License at
9+ *
10+ * http://www.apache.org/licenses/LICENSE-2.0
11+ *
12+ * Unless required by applicable law or agreed to in writing,
13+ * software distributed under the License is distributed on an
14+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+ * KIND, either express or implied. See the License for the
16+ * specific language governing permissions and limitations
17+ * under the License.
18+ */
19+
20+ package org .elasticsearch .client .security .user .privileges ;
21+
22+ import org .elasticsearch .common .ParseField ;
23+ import org .elasticsearch .common .Strings ;
24+ import org .elasticsearch .common .xcontent .ConstructingObjectParser ;
25+ import org .elasticsearch .common .xcontent .ToXContentObject ;
26+ import org .elasticsearch .common .xcontent .XContentBuilder ;
27+ import org .elasticsearch .common .xcontent .XContentHelper ;
28+ import org .elasticsearch .common .xcontent .XContentParser ;
29+ import org .elasticsearch .common .xcontent .XContentType ;
30+
31+ import java .io .IOException ;
32+ import java .util .Collection ;
33+ import java .util .Collections ;
34+ import java .util .HashSet ;
35+ import java .util .Objects ;
36+ import java .util .Set ;
37+
38+ import static org .elasticsearch .common .xcontent .ConstructingObjectParser .constructorArg ;
39+
40+ /**
41+ * Represents privileges over resources that are scoped under an application.
42+ * The application, resources and privileges are completely managed by the
43+ * client and can be arbitrary string identifiers. Elasticsearch is not
44+ * concerned by any resources under an application scope.
45+ */
46+ public final class ApplicationResourcePrivileges implements ToXContentObject {
47+
48+ private static final ParseField APPLICATION = new ParseField ("application" );
49+ private static final ParseField PRIVILEGES = new ParseField ("privileges" );
50+ private static final ParseField RESOURCES = new ParseField ("resources" );
51+
52+ @ SuppressWarnings ("unchecked" )
53+ static final ConstructingObjectParser <ApplicationResourcePrivileges , Void > PARSER = new ConstructingObjectParser <>(
54+ "application_privileges" , false , constructorObjects -> {
55+ // Don't ignore unknown fields. It is dangerous if the object we parse is also
56+ // part of a request that we build later on, and the fields that we now ignore will
57+ // end up being implicitly set to null in that request.
58+ int i = 0 ;
59+ final String application = (String ) constructorObjects [i ++];
60+ final Collection <String > privileges = (Collection <String >) constructorObjects [i ++];
61+ final Collection <String > resources = (Collection <String >) constructorObjects [i ];
62+ return new ApplicationResourcePrivileges (application , privileges , resources );
63+ });
64+
65+ static {
66+ PARSER .declareString (constructorArg (), APPLICATION );
67+ PARSER .declareStringArray (constructorArg (), PRIVILEGES );
68+ PARSER .declareStringArray (constructorArg (), RESOURCES );
69+ }
70+
71+ private final String application ;
72+ private final Set <String > privileges ;
73+ private final Set <String > resources ;
74+
75+ /**
76+ * Constructs privileges for resources under an application scope.
77+ *
78+ * @param application
79+ * The application name. This identifier is completely under the
80+ * clients control.
81+ * @param privileges
82+ * The privileges names. Cannot be null or empty. Privilege
83+ * identifiers are completely under the clients control.
84+ * @param resources
85+ * The resources names. Cannot be null or empty. Resource identifiers
86+ * are completely under the clients control.
87+ */
88+ public ApplicationResourcePrivileges (String application , Collection <String > privileges , Collection <String > resources ) {
89+ if (Strings .isNullOrEmpty (application )) {
90+ throw new IllegalArgumentException ("application privileges must have an application name" );
91+ }
92+ if (null == privileges || privileges .isEmpty ()) {
93+ throw new IllegalArgumentException ("application privileges must define at least one privilege" );
94+ }
95+ if (null == resources || resources .isEmpty ()) {
96+ throw new IllegalArgumentException ("application privileges must refer to at least one resource" );
97+ }
98+ this .application = application ;
99+ this .privileges = Collections .unmodifiableSet (new HashSet <>(privileges ));
100+ this .resources = Collections .unmodifiableSet (new HashSet <>(resources ));
101+ }
102+
103+ public String getApplication () {
104+ return application ;
105+ }
106+
107+ public Set <String > getResources () {
108+ return this .resources ;
109+ }
110+
111+ public Set <String > getPrivileges () {
112+ return this .privileges ;
113+ }
114+
115+ @ Override
116+ public boolean equals (Object o ) {
117+ if (this == o ) {
118+ return true ;
119+ }
120+ if (o == null || this .getClass () != o .getClass ()) {
121+ return false ;
122+ }
123+ ApplicationResourcePrivileges that = (ApplicationResourcePrivileges ) o ;
124+ return application .equals (that .application )
125+ && privileges .equals (that .privileges )
126+ && resources .equals (that .resources );
127+ }
128+
129+ @ Override
130+ public int hashCode () {
131+ return Objects .hash (application , privileges , resources );
132+ }
133+
134+ @ Override
135+ public String toString () {
136+ try {
137+ return XContentHelper .toXContent (this , XContentType .JSON , true ).utf8ToString ();
138+ } catch (IOException e ) {
139+ throw new RuntimeException ("Unexpected" , e );
140+ }
141+ }
142+
143+ @ Override
144+ public XContentBuilder toXContent (XContentBuilder builder , Params params ) throws IOException {
145+ builder .startObject ();
146+ builder .field (APPLICATION .getPreferredName (), application );
147+ builder .field (PRIVILEGES .getPreferredName (), privileges );
148+ builder .field (RESOURCES .getPreferredName (), resources );
149+ return builder .endObject ();
150+ }
151+
152+ public static ApplicationResourcePrivileges fromXContent (XContentParser parser ) {
153+ return PARSER .apply (parser , null );
154+ }
155+
156+ }
0 commit comments