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