001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.bean.openapi3;
018
019import static org.apache.juneau.commons.utils.AssertionUtils.*;
020import static org.apache.juneau.commons.utils.CollectionUtils.*;
021import static org.apache.juneau.commons.utils.Utils.*;
022import static org.apache.juneau.internal.ConverterUtils.*;
023
024import java.util.*;
025
026import org.apache.juneau.commons.collections.*;
027
028/**
029 * Allows configuration of the supported OAuth Flows.
030 *
031 * <p>
032 * The OAuthFlows Object allows configuration of the supported OAuth Flows. This object contains the configuration
033 * for different OAuth 2.0 flows that can be used to secure the API. Each flow type has its own specific configuration
034 * requirements and use cases.
035 *
036 * <h5 class='section'>OpenAPI Specification:</h5>
037 * <p>
038 * The OAuthFlows Object is composed of the following fields:
039 * <ul class='spaced-list'>
040 *    <li><c>implicit</c> ({@link OAuthFlow}) - Configuration for the OAuth Implicit flow
041 *    <li><c>password</c> ({@link OAuthFlow}) - Configuration for the OAuth Resource Owner Password flow
042 *    <li><c>clientCredentials</c> ({@link OAuthFlow}) - Configuration for the OAuth Client Credentials flow
043 *    <li><c>authorizationCode</c> ({@link OAuthFlow}) - Configuration for the OAuth Authorization Code flow
044 * </ul>
045 *
046 * <h5 class='section'>Example:</h5>
047 * <p class='bcode'>
048 *    <jc>// Construct using SwaggerBuilder.</jc>
049 *    OAuthFlows <jv>x</jv> = <jsm>oauthFlows</jsm>()
050 *       .setAuthorizationCode(<jsm>oauthFlow</jsm>()
051 *          .setAuthorizationUrl(<js>"https://example.com/oauth/authorize"</js>)
052 *          .setTokenUrl(<js>"https://example.com/oauth/token"</js>));
053 *
054 *    <jc>// Serialize using JsonSerializer.</jc>
055 *    String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>x</jv>);
056 *
057 *    <jc>// Or just use toString() which does the same as above.</jc>
058 *    <jv>json</jv> = <jv>x</jv>.toString();
059 * </p>
060 * <p class='bcode'>
061 *    <jc>// Output</jc>
062 *    {
063 *       <js>"authorizationCode"</js>: {
064 *          <js>"authorizationUrl"</js>: <js>"https://example.com/oauth/authorize"</js>,
065 *          <js>"tokenUrl"</js>: <js>"https://example.com/oauth/token"</js>
066 *       }
067 *    }
068 * </p>
069 *
070 * <h5 class='section'>See Also:</h5><ul>
071 *    <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#oauth-flows-object">OpenAPI Specification &gt; OAuth Flows Object</a>
072 *    <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/authentication/oauth2/">OpenAPI OAuth2 Authentication</a>
073 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
074 * </ul>
075 */
076public class OAuthFlows extends OpenApiElement {
077
078   private OAuthFlow implicit, password, clientCredentials, authorizationCode;
079
080   /**
081    * Default constructor.
082    */
083   public OAuthFlows() {}
084
085   /**
086    * Copy constructor.
087    *
088    * @param copyFrom The object to copy.
089    */
090   public OAuthFlows(OAuthFlows copyFrom) {
091      super(copyFrom);
092
093      this.implicit = copyFrom.implicit;
094      this.password = copyFrom.password;
095      this.clientCredentials = copyFrom.clientCredentials;
096      this.authorizationCode = copyFrom.authorizationCode;
097   }
098
099   /**
100    * Make a deep copy of this object.
101    *
102    * @return A deep copy of this object.
103    */
104   public OAuthFlows copy() {
105      return new OAuthFlows(this);
106   }
107
108   @Override /* Overridden from SwaggerElement */
109   public <T> T get(String property, Class<T> type) {
110      assertArgNotNull("property", property);
111      return switch (property) {
112         case "implicit" -> toType(getImplicit(), type);
113         case "password" -> toType(getPassword(), type);
114         case "clientCredentials" -> toType(getClientCredentials(), type);
115         case "authorizationCode" -> toType(getAuthorizationCode(), type);
116         default -> super.get(property, type);
117      };
118   }
119
120   /**
121    * Bean property getter:  <property>authorizationCode</property>.
122    *
123    * <p>
124    * Describes the type of items in the array.
125    *
126    * @return The property value, or <jk>null</jk> if it is not set.
127    */
128   public OAuthFlow getAuthorizationCode() { return authorizationCode; }
129
130   /**
131    * Bean property getter:  <property>clientCredentials</property>.
132    *
133    * <p>
134    * Describes the type of items in the array.
135    *
136    * @return The property value, or <jk>null</jk> if it is not set.
137    */
138   public OAuthFlow getClientCredentials() { return clientCredentials; }
139
140   /**
141    * Bean property getter:  <property>implicit</property>.
142    *
143    * <p>
144    * Describes the type of items in the array.
145    *
146    * @return The property value, or <jk>null</jk> if it is not set.
147    */
148   public OAuthFlow getImplicit() { return implicit; }
149
150   /**
151    * Bean property getter:  <property>password</property>.
152    *
153    * <p>
154    * Describes the type of items in the array.
155    *
156    * @return The property value, or <jk>null</jk> if it is not set.
157    */
158   public OAuthFlow getPassword() { return password; }
159
160   @Override /* Overridden from SwaggerElement */
161   public Set<String> keySet() {
162      // @formatter:off
163      var s = setb(String.class)
164         .addIf(nn(authorizationCode), "authorizationCode")
165         .addIf(nn(clientCredentials), "clientCredentials")
166         .addIf(nn(implicit), "implicit")
167         .addIf(nn(password), "password")
168         .build();
169      // @formatter:on
170      return new MultiSet<>(s, super.keySet());
171   }
172
173   @Override /* Overridden from SwaggerElement */
174   public OAuthFlows set(String property, Object value) {
175      assertArgNotNull("property", property);
176      return switch (property) {
177         case "authorizationCode" -> setAuthorizationCode(toType(value, OAuthFlow.class));
178         case "clientCredentials" -> setClientCredentials(toType(value, OAuthFlow.class));
179         case "implicit" -> setImplicit(toType(value, OAuthFlow.class));
180         case "password" -> setPassword(toType(value, OAuthFlow.class));
181         default -> {
182            super.set(property, value);
183            yield this;
184         }
185      };
186   }
187
188   /**
189    * Bean property setter:  <property>authorizationCode</property>.
190    *
191    * <p>
192    * Describes the type of items in the array.
193    *
194    * @param value
195    *    The new value for this property.
196    *    <br>Property value is required if <code>type</code> is <js>"array"</js>.
197    *    <br>Can be <jk>null</jk> to unset the property.
198    * @return This object
199    */
200   public OAuthFlows setAuthorizationCode(OAuthFlow value) {
201      authorizationCode = value;
202      return this;
203   }
204
205   /**
206    * Bean property setter:  <property>items</property>.
207    *
208    * <p>
209    * Describes the type of items in the array.
210    *
211    * @param value
212    *    The new value for this property.
213    *    <br>Property value is required if <code>type</code> is <js>"array"</js>.
214    *    <br>Can be <jk>null</jk> to unset the property.
215    * @return This object
216    */
217   public OAuthFlows setClientCredentials(OAuthFlow value) {
218      clientCredentials = value;
219      return this;
220   }
221
222   /**
223    * Bean property setter:  <property>items</property>.
224    *
225    * <p>
226    * Describes the type of items in the array.
227    *
228    * @param value
229    *    The new value for this property.
230    *    <br>Property value is required if <code>type</code> is <js>"array"</js>.
231    *    <br>Can be <jk>null</jk> to unset the property.
232    * @return This object
233    */
234   public OAuthFlows setImplicit(OAuthFlow value) {
235      implicit = value;
236      return this;
237   }
238
239   /**
240    * Bean property setter:  <property>items</property>.
241    *
242    * <p>
243    * Describes the type of items in the array.
244    *
245    * @param value
246    *    The new value for this property.
247    *    <br>Property value is required if <code>type</code> is <js>"array"</js>.
248    *    <br>Can be <jk>null</jk> to unset the property.
249    * @return This object
250    */
251   public OAuthFlows setPassword(OAuthFlow value) {
252      password = value;
253      return this;
254   }
255
256   @Override /* Overridden from OpenApiElement */
257   public OAuthFlows strict(Object value) {
258      super.strict(value);
259      return this;
260   }
261
262   @Override /* Overridden from SwaggerElement */
263   protected OAuthFlows strict() {
264      super.strict();
265      return this;
266   }
267}