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.Shorts.*;
020import static org.apache.juneau.marshall.internal.ConverterUtils.*;
021import static org.apache.juneau.bean.openapi3.OpenApiCopyUtils.*;
022
023import java.util.*;
024
025import org.apache.juneau.commons.collections.*;
026
027/**
028 * Allows configuration of the supported OAuth Flows.
029 *
030 * <p>
031 * The OAuthFlows Object allows configuration of the supported OAuth Flows. This object contains the configuration
032 * for different OAuth 2.0 flows that can be used to secure the API. Each flow type has its own specific configuration
033 * requirements and use cases.
034 *
035 * <h5 class='section'>OpenAPI Specification:</h5>
036 * <p>
037 * The OAuthFlows Object is composed of the following fields:
038 * <ul class='spaced-list'>
039 *    <li><c>implicit</c> ({@link OAuthFlow}) - Configuration for the OAuth Implicit flow
040 *    <li><c>password</c> ({@link OAuthFlow}) - Configuration for the OAuth Resource Owner Password flow
041 *    <li><c>clientCredentials</c> ({@link OAuthFlow}) - Configuration for the OAuth Client Credentials flow
042 *    <li><c>authorizationCode</c> ({@link OAuthFlow}) - Configuration for the OAuth Authorization Code flow
043 * </ul>
044 *
045 * <h5 class='section'>Example:</h5>
046 * <p class='bcode'>
047 *    <jc>// Construct using SwaggerBuilder.</jc>
048 *    OAuthFlows <jv>x</jv> = <jsm>oauthFlows</jsm>()
049 *       .setAuthorizationCode(<jsm>oauthFlow</jsm>()
050 *          .setAuthorizationUrl(<js>"https://example.com/oauth/authorize"</js>)
051 *          .setTokenUrl(<js>"https://example.com/oauth/token"</js>));
052 *
053 *    <jc>// Serialize using JsonSerializer.</jc>
054 *    String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>x</jv>);
055 *
056 *    <jc>// Or just use toString() which does the same as above.</jc>
057 *    <jv>json</jv> = <jv>x</jv>.toString();
058 * </p>
059 * <p class='bcode'>
060 *    <jc>// Output</jc>
061 *    {
062 *       <js>"authorizationCode"</js>: {
063 *          <js>"authorizationUrl"</js>: <js>"https://example.com/oauth/authorize"</js>,
064 *          <js>"tokenUrl"</js>: <js>"https://example.com/oauth/token"</js>
065 *       }
066 *    }
067 * </p>
068 *
069 * <h5 class='section'>See Also:</h5><ul>
070 *    <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>
071 *    <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/authentication/oauth2/">OpenAPI OAuth2 Authentication</a>
072 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
073 * </ul>
074 */
075@SuppressWarnings({
076   "java:S1192" // Duplicated literals (argument/property names) read more clearly inline than as constants
077})
078public class OAuthFlows extends OpenApiElement {
079
080   private OAuthFlow implicit;
081   private OAuthFlow password;
082   private OAuthFlow clientCredentials;
083   private OAuthFlow authorizationCode;
084
085   /**
086    * Default constructor.
087    */
088   public OAuthFlows() {}
089
090   /**
091    * Copy constructor.
092    *
093    * @param copyFrom The object to copy.
094    */
095   public OAuthFlows(OAuthFlows copyFrom) {
096      super(copyFrom);
097
098      this.implicit = copyOf(copyFrom.implicit);
099      this.password = copyOf(copyFrom.password);
100      this.clientCredentials = copyOf(copyFrom.clientCredentials);
101      this.authorizationCode = copyOf(copyFrom.authorizationCode);
102   }
103
104   /**
105    * Make a deep copy of this object.
106    *
107    * @return A deep copy of this object.
108    */
109   public OAuthFlows copy() {
110      return new OAuthFlows(this);
111   }
112
113   @Override /* Overridden from SwaggerElement */
114   public <T> T get(String property, Class<T> type) {
115      reqnn("property", property);
116      return switch (property) {
117         case "implicit" -> toType(getImplicit(), type);
118         case "password" -> toType(getPassword(), type);
119         case "clientCredentials" -> toType(getClientCredentials(), type);
120         case "authorizationCode" -> toType(getAuthorizationCode(), type);
121         default -> super.get(property, type);
122      };
123   }
124
125   /**
126    * Bean property getter:  <property>authorizationCode</property>.
127    *
128    * <p>
129    * Configuration for the OAuth Authorization Code flow.
130    *
131    * @return The property value, or <jk>null</jk> if it is not set.
132    */
133   public OAuthFlow getAuthorizationCode() { return authorizationCode; }
134
135   /**
136    * Bean property getter:  <property>clientCredentials</property>.
137    *
138    * <p>
139    * Configuration for the OAuth Client Credentials flow.
140    *
141    * @return The property value, or <jk>null</jk> if it is not set.
142    */
143   public OAuthFlow getClientCredentials() { return clientCredentials; }
144
145   /**
146    * Bean property getter:  <property>implicit</property>.
147    *
148    * <p>
149    * Configuration for the OAuth Implicit flow.
150    *
151    * @return The property value, or <jk>null</jk> if it is not set.
152    */
153   public OAuthFlow getImplicit() { return implicit; }
154
155   /**
156    * Bean property getter:  <property>password</property>.
157    *
158    * <p>
159    * Configuration for the OAuth Resource Owner Password flow.
160    *
161    * @return The property value, or <jk>null</jk> if it is not set.
162    */
163   public OAuthFlow getPassword() { return password; }
164
165   @Override /* Overridden from SwaggerElement */
166   public Set<String> keySet() {
167      // @formatter:off
168      var s = stb(String.class)
169         .addIf(nn(authorizationCode), "authorizationCode")
170         .addIf(nn(clientCredentials), "clientCredentials")
171         .addIf(nn(implicit), "implicit")
172         .addIf(nn(password), "password")
173         .build();
174      // @formatter:on
175      return new MultiSet<>(s, super.keySet());
176   }
177
178   @Override /* Overridden from SwaggerElement */
179   public OAuthFlows set(String property, Object value) {
180      reqnn("property", property);
181      return switch (property) {
182         case "authorizationCode" -> setAuthorizationCode(toType(value, OAuthFlow.class));
183         case "clientCredentials" -> setClientCredentials(toType(value, OAuthFlow.class));
184         case "implicit" -> setImplicit(toType(value, OAuthFlow.class));
185         case "password" -> setPassword(toType(value, OAuthFlow.class));
186         default -> {
187            super.set(property, value);
188            yield this;
189         }
190      };
191   }
192
193   /**
194    * Bean property setter:  <property>authorizationCode</property>.
195    *
196    * <p>
197    * Configuration for the OAuth Authorization Code flow.
198    *
199    * @param value
200    *    The new value for this property.
201    *    <br>Can be <jk>null</jk> to unset the property.
202    * @return This object
203    */
204   public OAuthFlows setAuthorizationCode(OAuthFlow value) {
205      authorizationCode = value;
206      return this;
207   }
208
209   /**
210    * Bean property setter:  <property>clientCredentials</property>.
211    *
212    * <p>
213    * Configuration for the OAuth Client Credentials flow.
214    *
215    * @param value
216    *    The new value for this property.
217    *    <br>Can be <jk>null</jk> to unset the property.
218    * @return This object
219    */
220   public OAuthFlows setClientCredentials(OAuthFlow value) {
221      clientCredentials = value;
222      return this;
223   }
224
225   /**
226    * Bean property setter:  <property>implicit</property>.
227    *
228    * <p>
229    * Configuration for the OAuth Implicit flow.
230    *
231    * @param value
232    *    The new value for this property.
233    *    <br>Can be <jk>null</jk> to unset the property.
234    * @return This object
235    */
236   public OAuthFlows setImplicit(OAuthFlow value) {
237      implicit = value;
238      return this;
239   }
240
241   /**
242    * Bean property setter:  <property>password</property>.
243    *
244    * <p>
245    * Configuration for the OAuth Resource Owner Password flow.
246    *
247    * @param value
248    *    The new value for this property.
249    *    <br>Can be <jk>null</jk> to unset the property.
250    * @return This object
251    */
252   public OAuthFlows setPassword(OAuthFlow value) {
253      password = value;
254      return this;
255   }
256
257   @Override /* Overridden from OpenApiElement */
258   public OAuthFlows strict(Object value) {
259      super.strict(value);
260      return this;
261   }
262
263   @Override /* Overridden from SwaggerElement */
264   protected OAuthFlows strict() {
265      super.strict();
266      return this;
267   }
268}