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.common.utils.Utils.*;
020import static org.apache.juneau.internal.CollectionUtils.*;
021import static org.apache.juneau.internal.ConverterUtils.*;
022
023import java.util.*;
024
025import org.apache.juneau.internal.*;
026
027/**
028 * Lists the required security schemes for this operation.
029 *
030 * <h5 class='section'>See Also:</h5><ul>
031 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
032 * </ul>
033 */
034public class SecurityRequirement extends OpenApiElement {
035
036   private Map<String,List<String>> requirements;
037
038   /**
039    * Default constructor.
040    */
041   public SecurityRequirement() {}
042
043   /**
044    * Copy constructor.
045    *
046    * @param copyFrom The object to copy.
047    */
048   public SecurityRequirement(SecurityRequirement copyFrom) {
049      super(copyFrom);
050      this.requirements = copyOf(copyFrom.requirements);
051   }
052
053   /**
054    * Makes a copy of this object.
055    *
056    * @return A new copy of this object.
057    */
058   public SecurityRequirement copy() {
059      return new SecurityRequirement(this);
060   }
061
062   /**
063    * Returns the security requirements map.
064    *
065    * @return The security requirements map.
066    */
067   public Map<String,List<String>> getRequirements() {
068      return requirements;
069   }
070
071   /**
072    * Sets the security requirements map.
073    *
074    * @param value The new value for this property.
075    * @return This object.
076    */
077   public SecurityRequirement setRequirements(Map<String,List<String>> value) {
078      this.requirements = value;
079      return this;
080   }
081
082   /**
083    * Adds a security requirement.
084    *
085    * @param schemeName The security scheme name.  Must not be <jk>null</jk>.
086    * @param scopes The required scopes.  Must not be <jk>null</jk>.
087    * @return This object.
088    */
089   public SecurityRequirement addRequirement(String schemeName, String... scopes) {
090      assertArgNotNull("schemeName", schemeName);
091      assertVarargsNotNull("scopes", scopes);
092      if (requirements == null)
093         requirements = new LinkedHashMap<>();
094      requirements.put(schemeName, Arrays.asList(scopes));
095      return this;
096   }
097
098   /**
099    * Adds a security requirement for a scheme that doesn't use scopes.
100    *
101    * <p>
102    * This is a convenience method for adding security schemes that don't use scopes, such as API keys, 
103    * HTTP Basic authentication, or HTTP Bearer tokens. According to the OpenAPI specification, security 
104    * schemes that don't use scopes should have an empty array as the value.
105    *
106    * <p>
107    * This method is equivalent to calling <c>addRequirement(schemeName)</c> with no scopes.
108    *
109    * <h5 class='section'>Example:</h5>
110    * <p class='bjava'>
111    *    <jc>// Add API key authentication requirement</jc>
112    *    SecurityRequirement <jv>requirement</jv> = <jk>new</jk> SecurityRequirement()
113    *       .setApiKeyAuth(<js>"api_key"</js>);
114    *    <jc>// Results in: { "api_key": [] }</jc>
115    * </p>
116    *
117    * <h5 class='section'>See Also:</h5><ul>
118    *    <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#security-requirement-object">OpenAPI Specification &gt; Security Requirement Object</a>
119    *    <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/authentication/">OpenAPI Authentication</a>
120    * </ul>
121    *
122    * @param schemeName The security scheme name.  Must not be <jk>null</jk>.
123    * @return This object.
124    */
125   public SecurityRequirement setApiKeyAuth(String schemeName) {
126      return addRequirement(schemeName);
127   }
128
129   @Override /* Overridden from OpenApiElement */
130   public <T> T get(String property, Class<T> type) {
131      assertArgNotNull("property", property);
132      return switch (property) {
133         case "requirements" -> toType(getRequirements(), type);
134         default -> super.get(property, type);
135      };
136   }
137
138   @Override /* Overridden from OpenApiElement */
139   public SecurityRequirement set(String property, Object value) {
140      assertArgNotNull("property", property);
141      return switch (property) {
142         case "requirements" -> setRequirements((Map<String,List<String>>)value);
143         default -> {
144            super.set(property, value);
145            yield this;
146         }
147      };
148   }
149
150   @Override /* Overridden from OpenApiElement */
151   public Set<String> keySet() {
152      var s = setBuilder(String.class)
153         .addIf(requirements != null, "requirements")
154         .build();
155      return new MultiSet<>(s, super.keySet());
156   }
157
158   @Override /* Overridden from OpenApiElement */
159   public SecurityRequirement strict() {
160      super.strict();
161      return this;
162   }
163
164   @Override /* Overridden from OpenApiElement */
165   public SecurityRequirement strict(Object value) {
166      super.strict(value);
167      return this;
168   }
169
170}