1package openapi3 2 3import ( 4 "context" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8) 9 10type securitySchemeExample struct { 11 title string 12 raw []byte 13 valid bool 14} 15 16func TestSecuritySchemaExample(t *testing.T) { 17 for _, example := range securitySchemeExamples { 18 t.Run(example.title, testSecuritySchemaExample(t, example)) 19 } 20} 21 22func testSecuritySchemaExample(t *testing.T, e securitySchemeExample) func(*testing.T) { 23 return func(t *testing.T) { 24 var err error 25 ss := &SecurityScheme{} 26 err = ss.UnmarshalJSON(e.raw) 27 require.NoError(t, err) 28 err = ss.Validate(context.Background()) 29 if e.valid { 30 require.NoError(t, err) 31 } else { 32 require.Error(t, err) 33 } 34 } 35} 36 37// from https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#fixed-fields-23 38var securitySchemeExamples = []securitySchemeExample{ 39 { 40 title: "Basic Authentication Sample", 41 raw: []byte(` 42{ 43 "type": "http", 44 "scheme": "basic" 45} 46`), 47 valid: true, 48 }, 49 { 50 title: "Negotiate Authentication Sample", 51 raw: []byte(` 52{ 53 "type": "http", 54 "scheme": "negotiate" 55} 56`), 57 valid: true, 58 }, 59 { 60 title: "Unknown http Authentication Sample", 61 raw: []byte(` 62{ 63 "type": "http", 64 "scheme": "notvalid" 65} 66`), 67 valid: false, 68 }, 69 { 70 title: "API Key Sample", 71 raw: []byte(` 72{ 73 "type": "apiKey", 74 "name": "api_key", 75 "in": "header" 76} 77`), 78 valid: true, 79 }, 80 { 81 title: "apiKey with bearerFormat", 82 raw: []byte(` 83{ 84 "type": "apiKey", 85 "in": "header", 86 "name": "X-API-KEY", 87 "bearerFormat": "Arbitrary text" 88} 89`), 90 valid: false, 91 }, 92 { 93 title: "Bearer Sample with arbitrary format", 94 raw: []byte(` 95{ 96 "type": "http", 97 "scheme": "bearer", 98 "bearerFormat": "Arbitrary text" 99} 100`), 101 valid: true, 102 }, 103 { 104 title: "Implicit OAuth2 Sample", 105 raw: []byte(` 106{ 107 "type": "oauth2", 108 "flows": { 109 "implicit": { 110 "authorizationUrl": "https://example.com/api/oauth/dialog", 111 "scopes": { 112 "write:pets": "modify pets in your account", 113 "read:pets": "read your pets" 114 } 115 } 116 } 117} 118`), 119 valid: true, 120 }, 121 { 122 title: "OAuth Flow Object Sample", 123 raw: []byte(` 124{ 125 "type": "oauth2", 126 "flows": { 127 "implicit": { 128 "authorizationUrl": "https://example.com/api/oauth/dialog", 129 "scopes": { 130 "write:pets": "modify pets in your account", 131 "read:pets": "read your pets" 132 } 133 }, 134 "authorizationCode": { 135 "authorizationUrl": "https://example.com/api/oauth/dialog", 136 "tokenUrl": "https://example.com/api/oauth/token", 137 "scopes": { 138 "write:pets": "modify pets in your account", 139 "read:pets": "read your pets" 140 } 141 } 142 } 143} 144`), 145 valid: true, 146 }, 147 { 148 title: "OAuth Flow Object clientCredentials/password", 149 raw: []byte(` 150{ 151 "type": "oauth2", 152 "flows": { 153 "clientCredentials": { 154 "tokenUrl": "https://example.com/api/oauth/token", 155 "scopes": { 156 "write:pets": "modify pets in your account" 157 } 158 }, 159 "password": { 160 "tokenUrl": "https://example.com/api/oauth/token", 161 "scopes": { 162 "read:pets": "read your pets" 163 } 164 } 165 } 166} 167`), 168 valid: true, 169 }, 170 { 171 title: "Invalid Basic", 172 raw: []byte(` 173{ 174 "type": "https", 175 "scheme": "basic" 176} 177`), 178 valid: false, 179 }, 180 { 181 title: "Apikey Cookie", 182 raw: []byte(` 183{ 184 "type": "apiKey", 185 "in": "cookie", 186 "name": "somecookie" 187} 188`), 189 valid: true, 190 }, 191 192 { 193 title: "OAuth Flow Object with no scopes", 194 raw: []byte(` 195{ 196 "type": "oauth2", 197 "flows": { 198 "password": { 199 "tokenUrl": "https://example.com/api/oauth/token" 200 } 201 } 202} 203`), 204 valid: false, 205 }, 206 { 207 title: "OAuth Flow Object with empty scopes", 208 raw: []byte(` 209{ 210 "type": "oauth2", 211 "flows": { 212 "password": { 213 "tokenUrl": "https://example.com/api/oauth/token", 214 "scopes": {} 215 } 216 } 217} 218`), 219 valid: true, 220 }, 221 { 222 title: "OIDC Type With URL", 223 raw: []byte(` 224{ 225 "type": "openIdConnect", 226 "openIdConnectUrl": "https://example.com/.well-known/openid-configuration" 227} 228`), 229 valid: true, 230 }, 231 { 232 title: "OIDC Type Without URL", 233 raw: []byte(` 234{ 235 "type": "openIdConnect", 236 "openIdConnectUrl": "" 237} 238`), 239 valid: false, 240 }, 241} 242