forked from goadesign/goa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
security.go
133 lines (119 loc) · 4.17 KB
/
security.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package design
import (
"fmt"
"net/url"
"github.com/goadesign/goa/dslengine"
)
// SecuritySchemeKind is a type of security scheme, according to the
// swagger specs.
type SecuritySchemeKind int
const (
// OAuth2SecurityKind means "oauth2" security type.
OAuth2SecurityKind SecuritySchemeKind = iota + 1
// BasicAuthSecurityKind means "basic" security type.
BasicAuthSecurityKind
// APIKeySecurityKind means "apiKey" security type.
APIKeySecurityKind
// JWTSecurityKind means an "apiKey" security type, with support for TokenPath and Scopes.
JWTSecurityKind
// NoSecurityKind means to have no security for this endpoint.
NoSecurityKind
)
// SecurityDefinition defines security requirements for an Action
type SecurityDefinition struct {
// Scheme defines the Security Scheme used for this action.
Scheme *SecuritySchemeDefinition
// Scopes are scopes required for this action
Scopes []string `json:"scopes,omitempty"`
}
// Context returns the generic definition name used in error messages.
func (s *SecurityDefinition) Context() string { return "Security" }
// SecuritySchemeDefinition defines a security scheme used to
// authenticate against the API being designed. See
// http://swagger.io/specification/#securityDefinitionsObject for more
// information.
type SecuritySchemeDefinition struct {
// Kind is the sort of security scheme this object represents
Kind SecuritySchemeKind
// DSLFunc is an optional DSL function
DSLFunc func()
// Scheme is the name of the security scheme, referenced in
// Security() declarations. Ex: "googAuth", "my_big_token", "jwt".
SchemeName string `json:"scheme"`
// Type is one of "apiKey", "oauth2" or "basic", according to the
// Swagger specs. We also support "jwt".
Type string `json:"type"`
// Description describes the security scheme. Ex: "Google OAuth2"
Description string `json:"description"`
// In determines whether it is in the "header" or in the "query"
// string that we will find an `apiKey`.
In string `json:"in,omitempty"`
// Name refers to a header or parameter name, based on In's value.
Name string `json:"name,omitempty"`
// Scopes is a list of available scopes for this scheme, along
// with their textual description.
Scopes map[string]string `json:"scopes,omitempty"`
// Flow determines the oauth2 flow to use for this scheme.
Flow string `json:"flow,omitempty"`
// TokenURL holds the URL for refreshing tokens with oauth2 or JWT
TokenURL string `json:"token_url,omitempty"`
// AuthorizationURL holds URL for retrieving authorization codes with oauth2
AuthorizationURL string `json:"authorization_url,omitempty"`
// Metadata is a list of key/value pairs
Metadata dslengine.MetadataDefinition
}
// DSL returns the DSL function
func (s *SecuritySchemeDefinition) DSL() func() {
return s.DSLFunc
}
// Context returns the generic definition name used in error messages.
func (s *SecuritySchemeDefinition) Context() string {
dslFunc := "[unknown]"
switch s.Kind {
case OAuth2SecurityKind:
dslFunc = "OAuth2Security"
case BasicAuthSecurityKind:
dslFunc = "BasicAuthSecurity"
case APIKeySecurityKind:
dslFunc = "APIKeySecurity"
case JWTSecurityKind:
dslFunc = "JWTSecurity"
}
return dslFunc
}
// Validate ensures that TokenURL and AuthorizationURL are valid URLs.
func (s *SecuritySchemeDefinition) Validate() error {
_, err := url.Parse(s.TokenURL)
if err != nil {
return fmt.Errorf("invalid token URL %#v: %s", s.TokenURL, err)
}
_, err = url.Parse(s.AuthorizationURL)
if err != nil {
return fmt.Errorf("invalid authorization URL %#v: %s", s.AuthorizationURL, err)
}
return nil
}
// Finalize makes the TokenURL and AuthorizationURL complete if needed.
func (s *SecuritySchemeDefinition) Finalize() {
tu, _ := url.Parse(s.TokenURL) // validated in Validate
au, _ := url.Parse(s.AuthorizationURL) // validated in Validate
tokenOK := s.TokenURL == "" || tu.IsAbs()
authOK := s.AuthorizationURL == "" || au.IsAbs()
if tokenOK && authOK {
return
}
var scheme string
if len(Design.Schemes) > 0 {
scheme = Design.Schemes[0]
}
if !tokenOK {
tu.Scheme = scheme
tu.Host = Design.Host
s.TokenURL = tu.String()
}
if !authOK {
au.Scheme = scheme
au.Host = Design.Host
s.AuthorizationURL = au.String()
}
}