github.com/zak-blake/goa@v1.4.1/design/security.go (about)

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