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