1// Copyright 2015 go-swagger maintainers 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package spec 16 17import ( 18 "encoding/json" 19 20 "github.com/go-openapi/jsonpointer" 21 "github.com/go-openapi/swag" 22) 23 24const ( 25 basic = "basic" 26 apiKey = "apiKey" 27 oauth2 = "oauth2" 28 implicit = "implicit" 29 password = "password" 30 application = "application" 31 accessCode = "accessCode" 32) 33 34// BasicAuth creates a basic auth security scheme 35func BasicAuth() *SecurityScheme { 36 return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{Type: basic}} 37} 38 39// APIKeyAuth creates an api key auth security scheme 40func APIKeyAuth(fieldName, valueSource string) *SecurityScheme { 41 return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{Type: apiKey, Name: fieldName, In: valueSource}} 42} 43 44// OAuth2Implicit creates an implicit flow oauth2 security scheme 45func OAuth2Implicit(authorizationURL string) *SecurityScheme { 46 return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{ 47 Type: oauth2, 48 Flow: implicit, 49 AuthorizationURL: authorizationURL, 50 }} 51} 52 53// OAuth2Password creates a password flow oauth2 security scheme 54func OAuth2Password(tokenURL string) *SecurityScheme { 55 return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{ 56 Type: oauth2, 57 Flow: password, 58 TokenURL: tokenURL, 59 }} 60} 61 62// OAuth2Application creates an application flow oauth2 security scheme 63func OAuth2Application(tokenURL string) *SecurityScheme { 64 return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{ 65 Type: oauth2, 66 Flow: application, 67 TokenURL: tokenURL, 68 }} 69} 70 71// OAuth2AccessToken creates an access token flow oauth2 security scheme 72func OAuth2AccessToken(authorizationURL, tokenURL string) *SecurityScheme { 73 return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{ 74 Type: oauth2, 75 Flow: accessCode, 76 AuthorizationURL: authorizationURL, 77 TokenURL: tokenURL, 78 }} 79} 80 81// SecuritySchemeProps describes a swagger security scheme in the securityDefinitions section 82type SecuritySchemeProps struct { 83 Description string `json:"description,omitempty"` 84 Type string `json:"type"` 85 Name string `json:"name,omitempty"` // api key 86 In string `json:"in,omitempty"` // api key 87 Flow string `json:"flow,omitempty"` // oauth2 88 AuthorizationURL string `json:"authorizationUrl"` // oauth2 89 TokenURL string `json:"tokenUrl,omitempty"` // oauth2 90 Scopes map[string]string `json:"scopes,omitempty"` // oauth2 91} 92 93// AddScope adds a scope to this security scheme 94func (s *SecuritySchemeProps) AddScope(scope, description string) { 95 if s.Scopes == nil { 96 s.Scopes = make(map[string]string) 97 } 98 s.Scopes[scope] = description 99} 100 101// SecurityScheme allows the definition of a security scheme that can be used by the operations. 102// Supported schemes are basic authentication, an API key (either as a header or as a query parameter) 103// and OAuth2's common flows (implicit, password, application and access code). 104// 105// For more information: http://goo.gl/8us55a#securitySchemeObject 106type SecurityScheme struct { 107 VendorExtensible 108 SecuritySchemeProps 109} 110 111// JSONLookup implements an interface to customize json pointer lookup 112func (s SecurityScheme) JSONLookup(token string) (interface{}, error) { 113 if ex, ok := s.Extensions[token]; ok { 114 return &ex, nil 115 } 116 117 r, _, err := jsonpointer.GetForToken(s.SecuritySchemeProps, token) 118 return r, err 119} 120 121// MarshalJSON marshal this to JSON 122func (s SecurityScheme) MarshalJSON() ([]byte, error) { 123 var ( 124 b1 []byte 125 err error 126 ) 127 128 if s.Type == oauth2 && (s.Flow == "implicit" || s.Flow == "accessCode") { 129 // when oauth2 for implicit or accessCode flows, empty AuthorizationURL is added as empty string 130 b1, err = json.Marshal(s.SecuritySchemeProps) 131 } else { 132 // when not oauth2, empty AuthorizationURL should be omitted 133 b1, err = json.Marshal(struct { 134 Description string `json:"description,omitempty"` 135 Type string `json:"type"` 136 Name string `json:"name,omitempty"` // api key 137 In string `json:"in,omitempty"` // api key 138 Flow string `json:"flow,omitempty"` // oauth2 139 AuthorizationURL string `json:"authorizationUrl,omitempty"` // oauth2 140 TokenURL string `json:"tokenUrl,omitempty"` // oauth2 141 Scopes map[string]string `json:"scopes,omitempty"` // oauth2 142 }{ 143 Description: s.Description, 144 Type: s.Type, 145 Name: s.Name, 146 In: s.In, 147 Flow: s.Flow, 148 AuthorizationURL: s.AuthorizationURL, 149 TokenURL: s.TokenURL, 150 Scopes: s.Scopes, 151 }) 152 } 153 if err != nil { 154 return nil, err 155 } 156 157 b2, err := json.Marshal(s.VendorExtensible) 158 if err != nil { 159 return nil, err 160 } 161 return swag.ConcatJSON(b1, b2), nil 162} 163 164// UnmarshalJSON marshal this from JSON 165func (s *SecurityScheme) UnmarshalJSON(data []byte) error { 166 if err := json.Unmarshal(data, &s.SecuritySchemeProps); err != nil { 167 return err 168 } 169 return json.Unmarshal(data, &s.VendorExtensible) 170} 171