001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.dto.swagger;
014
015import static org.apache.juneau.internal.BeanPropertyUtils.*;
016import static org.apache.juneau.internal.ArrayUtils.*;
017
018import java.util.*;
019
020import org.apache.juneau.*;
021import org.apache.juneau.annotation.*;
022
023/**
024 * Allows the definition of a security scheme that can be used by the operations.
025 * 
026 * <p>
027 * Supported schemes are basic authentication, an API key (either as a header or as a query parameter) and OAuth2's
028 * common flows (implicit, password, application and access code).
029 * 
030 * <h5 class='section'>Example:</h5>
031 * <p class='bcode'>
032 *    <jc>// Basic authentication sample</jc>
033 *    {
034 *       <js>"type"</js>: <js>"basic"</js>
035 *    }
036 * 
037 *    <jc>// API key sample</jc>
038 *    {
039 *       <js>"type"</js>: <js>"apiKey"</js>,
040 *       <js>"name"</js>: <js>"api_key"</js>,
041 *       <js>"in"</js>: <js>"header"</js>
042 *    }
043 * 
044 *    <jc>// Implicit OAuth2 sample</jc>
045 *    {
046 *       <js>"type"</js>: <js>"oauth2"</js>,
047 *       <js>"authorizationUrl"</js>: <js>"http://swagger.io/api/oauth/dialog"</js>,
048 *       <js>"flow"</js>: <js>"implicit"</js>,
049 *       <js>"scopes"</js>: {
050 *          <js>"write:pets"</js>: <js>"modify pets in your account"</js>,
051 *          <js>"read:pets"</js>: <js>"read your pets"</js>
052 *       }
053 *    }
054 * </p>
055 * 
056 * <h5 class='section'>See Also:</h5>
057 * <ul class='doctree'>
058 *    <li class='link'><a class='doclink' href='../../../../../overview-summary.html#juneau-dto.Swagger'>Overview &gt; juneau-dto &gt; Swagger</a>
059 * </ul>
060 */
061@Bean(properties="type,description,name,in,flow,authorizationUrl,tokenUrl,scopes,*")
062public class SecurityScheme extends SwaggerElement {
063
064   private static final String[] VALID_TYPES = {"basic", "apiKey", "oauth2"};
065
066   private String 
067      type,
068      description,
069      name,
070      in,
071      flow,
072      authorizationUrl,
073      tokenUrl;
074   private Map<String,String> scopes;
075
076   @Override /* SwaggerElement */
077   protected SecurityScheme strict() {
078      super.strict();
079      return this;
080   }
081
082   /**
083    * Bean property getter:  <property>type</property>.
084    * 
085    * <p>
086    * The type of the security scheme.
087    * 
088    * @return The property value, or <jk>null</jk> if it is not set.
089    */
090   public String getType() {
091      return type;
092   }
093
094   /**
095    * Bean property setter:  <property>type</property>.
096    * 
097    * <p>
098    * The type of the security scheme.
099    * 
100    * <p>
101    * Valid values are .
102    * 
103    * @param value 
104    *    The new value for this property.
105    *    <br>Valid values:
106    *    <ul>  
107    *       <li><js>"basic"</js>
108    *       <li><js>"apiKey"</js>
109    *       <li><js>"oauth2"</js>
110    *    </ul>
111    *    <br>Property value is required.
112    * @return This object (for method chaining).
113    */
114   public SecurityScheme setType(String value) {
115      if (isStrict() && ! contains(value, VALID_TYPES))
116         throw new FormattedRuntimeException(
117            "Invalid value passed in to setType(String).  Value=''{0}'', valid values={1}",
118            value, VALID_TYPES
119         );
120      type = value;
121      return this;
122   }
123
124   /**
125    * Same as {@link #setType(String)}.
126    * 
127    * @param value
128    *    The new value for this property.
129    *    <br>Non-String values will be converted to String using <code>toString()</code>.
130    *    <br>Valid values:
131    *    <ul>  
132    *       <li><js>"basic"</js>
133    *       <li><js>"apiKey"</js>
134    *       <li><js>"oauth2"</js>
135    *    </ul>
136    *    <br>Can be <jk>null</jk> to unset the property.
137    * @return This object (for method chaining).
138    */
139   public SecurityScheme type(Object value) {
140      return setType(toStringVal(value));
141   }
142
143   /**
144    * Bean property getter:  <property>description</property>.
145    * 
146    * <p>
147    * A short description for security scheme.
148    * 
149    * @return The property value, or <jk>null</jk> if it is not set.
150    */
151   public String getDescription() {
152      return description;
153   }
154
155   /**
156    * Bean property setter:  <property>description</property>.
157    * 
158    * <p>
159    * A short description for security scheme.
160    * 
161    * @param value 
162    *    The new value for this property.
163    *    <br>Can be <jk>null</jk> to unset the property.
164    * @return This object (for method chaining).
165    */
166   public SecurityScheme setDescription(String value) {
167      description = value;
168      return this;
169   }
170
171   /**
172    * Same as {@link #setDescription(String)}.
173    * 
174    * @param value
175    *    The new value for this property.
176    *    <br>Non-String values will be converted to String using <code>toString()</code>.
177    *    <br>Can be <jk>null</jk> to unset the property.
178    * @return This object (for method chaining).
179    */
180   public SecurityScheme description(Object value) {
181      return setDescription(toStringVal(value));
182   }
183
184   /**
185    * Bean property getter:  <property>name</property>.
186    * 
187    * <p>
188    * The name of the header or query parameter to be used.
189    * 
190    * @return The property value, or <jk>null</jk> if it is not set.
191    */
192   public String getName() {
193      return name;
194   }
195
196   /**
197    * Bean property setter:  <property>name</property>.
198    * 
199    * <p>
200    * The name of the header or query parameter to be used.
201    * 
202    * @param value 
203    *    The new value for this property.
204    *    <br>Can be <jk>null</jk> to unset the property.
205    * @return This object (for method chaining).
206    */
207   public SecurityScheme setName(String value) {
208      name = value;
209      return this;
210   }
211
212   /**
213    * Same as {@link #setName(String)}.
214    * 
215    * @param value
216    *    The new value for this property.
217    *    <br>Non-String values will be converted to String using <code>toString()</code>.
218    *    <br>Can be <jk>null</jk> to unset the property.
219    * @return This object (for method chaining).
220    */
221   public SecurityScheme name(Object value) {
222      return setName(toStringVal(value));
223   }
224
225   /**
226    * Bean property getter:  <property>in</property>.
227    * 
228    * <p>
229    * The location of the API key.
230    * 
231    * @return The property value, or <jk>null</jk> if it is not set.
232    */
233   public String getIn() {
234      return in;
235   }
236
237   /**
238    * Bean property setter:  <property>in</property>.
239    * 
240    * <p>
241    * The location of the API key.
242    * 
243    * @param value 
244    *    The new value for this property.
245    *    <br>Valid values:
246    *    <ul>  
247    *       <li><js>"query"</js>
248    *       <li><js>"header"</js>
249    *    </ul>
250    *    <br>Can be <jk>null</jk> to unset the property.
251    * @return This object (for method chaining).
252    */
253   public SecurityScheme setIn(String value) {
254      in = value;
255      return this;
256   }
257
258   /**
259    * Same as {@link #setIn(String)}.
260    * 
261    * @param value
262    *    The new value for this property.
263    *    <br>Non-String values will be converted to String using <code>toString()</code>.
264    *    <br>Valid values:
265    *    <ul>  
266    *       <li><js>"query"</js>
267    *       <li><js>"header"</js>
268    *    </ul>
269    *    <br>Can be <jk>null</jk> to unset the property.
270    * @return This object (for method chaining).
271    */
272   public SecurityScheme in(Object value) {
273      return setIn(toStringVal(value));
274   }
275
276   /**
277    * Bean property getter:  <property>flow</property>.
278    * 
279    * <p>
280    * The flow used by the OAuth2 security scheme.
281    * 
282    * @return The property value, or <jk>null</jk> if it is not set.
283    */
284   public String getFlow() {
285      return flow;
286   }
287
288   /**
289    * Bean property setter:  <property>flow</property>.
290    * 
291    * <p>
292    * The flow used by the OAuth2 security scheme.
293    * 
294    * @param value 
295    *    The new value for this property.
296    *    <br>Valid values:
297    *    <ul>  
298    *       <li><js>"implicit"</js>
299    *       <li><js>"password"</js>
300    *       <li><js>"application"</js>
301    *       <li><js>"accessCode"</js>
302    *    </ul>
303    *    <br>Can be <jk>null</jk> to unset the property.
304    * @return This object (for method chaining).
305    */
306   public SecurityScheme setFlow(String value) {
307      flow = value;
308      return this;
309   }
310
311   /**
312    * Same as {@link #setFlow(String)}.
313    * 
314    * @param value
315    *    The new value for this property.
316    *    <br>Non-String values will be converted to String using <code>toString()</code>.
317    *    <br>Valid values:
318    *    <ul>  
319    *       <li><js>"implicit"</js>
320    *       <li><js>"password"</js>
321    *       <li><js>"application"</js>
322    *       <li><js>"accessCode"</js>
323    *    </ul>
324    *    <br>Can be <jk>null</jk> to unset the property.
325    * @return This object (for method chaining).
326    */
327   public SecurityScheme flow(Object value) {
328      return setFlow(toStringVal(value));
329   }
330
331   /**
332    * Bean property getter:  <property>authorizationUrl</property>.
333    * 
334    * <p>
335    * The authorization URL to be used for this flow.
336    * 
337    * @return The property value, or <jk>null</jk> if it is not set.
338    */
339   public String getAuthorizationUrl() {
340      return authorizationUrl;
341   }
342
343   /**
344    * Bean property setter:  <property>authorizationUrl</property>.
345    * 
346    * <p>
347    * The authorization URL to be used for this flow.
348    * 
349    * @param value 
350    *    The new value for this property.
351    *    <br>This SHOULD be in the form of a URL.
352    *    <br>Can be <jk>null</jk> to unset the property.
353    * @return This object (for method chaining).
354    */
355   public SecurityScheme setAuthorizationUrl(String value) {
356      authorizationUrl = value;
357      return this;
358   }
359
360   /**
361    * Same as {@link #setAuthorizationUrl(String)}.
362    * 
363    * @param value
364    *    The new value for this property.
365    *    <br>Non-String values will be converted to String using <code>toString()</code>.
366    *    <br>This SHOULD be in the form of a URL.
367    *    <br>Can be <jk>null</jk> to unset the property.
368    * @return This object (for method chaining).
369    */
370   public SecurityScheme authorizationUrl(Object value) {
371      return setAuthorizationUrl(toStringVal(value));
372   }
373
374   /**
375    * Bean property getter:  <property>tokenUrl</property>.
376    * 
377    * <p>
378    * The token URL to be used for this flow.
379    * 
380    * @return The property value, or <jk>null</jk> if it is not set.
381    */
382   public String getTokenUrl() {
383      return tokenUrl;
384   }
385
386   /**
387    * Bean property setter:  <property>tokenUrl</property>.
388    * 
389    * <p>
390    * The token URL to be used for this flow.
391    * 
392    * @param value 
393    *    The new value for this property.
394    *    <br>This SHOULD be in the form of a URL.
395    *    <br>Can be <jk>null</jk> to unset the property.
396    * @return This object (for method chaining).
397    */
398   public SecurityScheme setTokenUrl(String value) {
399      tokenUrl = value;
400      return this;
401   }
402
403   /**
404    * Same as {@link #setTokenUrl(String)}.
405    * 
406    * @param value
407    *    The new value for this property.
408    *    <br>Non-String values will be converted to String using <code>toString()</code>.
409    *    <br>This SHOULD be in the form of a URL.
410    *    <br>Can be <jk>null</jk> to unset the property.
411    * @return This object (for method chaining).
412    */
413   public SecurityScheme tokenUrl(Object value) {
414      return setTokenUrl(toStringVal(value));
415   }
416
417   /**
418    * Bean property getter:  <property>scopes</property>.
419    * 
420    * <p>
421    * The available scopes for the OAuth2 security scheme.
422    * 
423    * @return The property value, or <jk>null</jk> if it is not set.
424    */
425   public Map<String,String> getScopes() {
426      return scopes;
427   }
428
429   /**
430    * Bean property setter:  <property>scopes</property>.
431    * 
432    * <p>
433    * The available scopes for the OAuth2 security scheme.
434    * 
435    * @param value 
436    *    The new value for this property.
437    *    <br>Can be <jk>null</jk> to unset the property.
438    * @return This object (for method chaining).
439    */
440   public SecurityScheme setScopes(Map<String,String> value) {
441      scopes = newMap(value);
442      return this;
443   }
444
445   /**
446    * Adds one or more values to the <property>scopes</property> property.
447    * 
448    * @param values
449    *    The values to add to this property.
450    *    <br>Ignored if <jk>null</jk>.
451    * @return This object (for method chaining).
452    */
453   public SecurityScheme addScopes(Map<String,String> values) {
454      scopes = addToMap(scopes, values);
455      return this;
456   }
457   
458   /**
459    * Adds one or more values to the <property>enum</property> property.
460    * 
461    * @param values
462    *    The values to add to this property.
463    *    <br>Valid types:
464    *    <ul>
465    *       <li><code>Map&lt;String,{@link HeaderInfo}|String&gt;</code>
466    *       <li><code>String</code> - JSON object representation of <code>Map&lt;String,{@link HeaderInfo}&gt;</code>
467    *          <h5 class='figure'>Example:</h5>
468    *          <p class='bcode'>
469    *    scopes(<js>"{name:'value'}"</js>);
470    *          </p>
471    *    </ul>
472    *    <br>Ignored if <jk>null</jk>.
473    * @return This object (for method chaining).
474    */
475   public SecurityScheme scopes(Object...values) {
476      scopes = addToMap(scopes, values, String.class, String.class);
477      return this;
478   }
479
480   @Override /* SwaggerElement */
481   public <T> T get(String property, Class<T> type) {
482      if (property == null)
483         return null;
484      switch (property) {
485         case "type": return toType(getType(), type);
486         case "description": return toType(getDescription(), type);
487         case "name": return toType(getName(), type);
488         case "in": return toType(getIn(), type);
489         case "flow": return toType(getFlow(), type);
490         case "authorizationUrl": return toType(getAuthorizationUrl(), type);
491         case "tokenUrl": return toType(getTokenUrl(), type);
492         case "scopes": return toType(getScopes(), type);
493         default: return super.get(property, type);
494      }
495   }
496
497   @Override /* SwaggerElement */
498   public SecurityScheme set(String property, Object value) {
499      if (property == null)
500         return this;
501      switch (property) {
502         case "type": return type(value);
503         case "description": return description(value);
504         case "name": return name(value);
505         case "in": return in(value);
506         case "flow": return flow(value);
507         case "authorizationUrl": return authorizationUrl(value);
508         case "tokenUrl": return tokenUrl(value);
509         case "scopes": return setScopes(null).scopes(value);
510         default: 
511            super.set(property, value);
512            return this;
513      }
514   }
515}