github.com/brycereitano/goa@v0.0.0-20170315073847-8ffa6c85e265/design/apidsl/security_test.go (about)

     1  package apidsl_test
     2  
     3  import (
     4  	. "github.com/goadesign/goa/design"
     5  	. "github.com/goadesign/goa/design/apidsl"
     6  	"github.com/goadesign/goa/dslengine"
     7  	. "github.com/onsi/ginkgo"
     8  	. "github.com/onsi/gomega"
     9  )
    10  
    11  var _ = Describe("Security", func() {
    12  	BeforeEach(func() {
    13  		dslengine.Reset()
    14  	})
    15  
    16  	It("should have no security DSL when none are defined", func() {
    17  		API("secure", nil)
    18  		dslengine.Run()
    19  		Ω(Design.SecuritySchemes).Should(BeNil())
    20  		Ω(dslengine.Errors).ShouldNot(HaveOccurred())
    21  	})
    22  
    23  	It("should be the fully valid and well defined, live on the happy path", func() {
    24  		API("secure", func() {
    25  			Host("example.com")
    26  			Scheme("http")
    27  
    28  			BasicAuthSecurity("basic_authz", func() {
    29  				Description("desc")
    30  			})
    31  
    32  			OAuth2Security("googAuthz", func() {
    33  				Description("desc")
    34  				AccessCodeFlow("/auth", "/token")
    35  				Scope("user:read", "Read users")
    36  			})
    37  
    38  			APIKeySecurity("a_key", func() {
    39  				Description("desc")
    40  				Query("access_token")
    41  			})
    42  
    43  			JWTSecurity("jwt", func() {
    44  				Description("desc")
    45  				Header("Authorization")
    46  				TokenURL("/token")
    47  				Scope("user:read", "Read users")
    48  				Scope("user:write", "Write users")
    49  			})
    50  		})
    51  
    52  		dslengine.Run()
    53  
    54  		Ω(dslengine.Errors).ShouldNot(HaveOccurred())
    55  		Ω(Design.SecuritySchemes).Should(HaveLen(4))
    56  
    57  		Ω(Design.SecuritySchemes[0].Kind).Should(Equal(BasicAuthSecurityKind))
    58  		Ω(Design.SecuritySchemes[0].Description).Should(Equal("desc"))
    59  
    60  		Ω(Design.SecuritySchemes[1].Kind).Should(Equal(OAuth2SecurityKind))
    61  		Ω(Design.SecuritySchemes[1].AuthorizationURL).Should(Equal("http://example.com/auth"))
    62  		Ω(Design.SecuritySchemes[1].TokenURL).Should(Equal("http://example.com/token"))
    63  		Ω(Design.SecuritySchemes[1].Flow).Should(Equal("accessCode"))
    64  
    65  		Ω(Design.SecuritySchemes[2].Kind).Should(Equal(APIKeySecurityKind))
    66  		Ω(Design.SecuritySchemes[2].In).Should(Equal("query"))
    67  		Ω(Design.SecuritySchemes[2].Name).Should(Equal("access_token"))
    68  
    69  		Ω(Design.SecuritySchemes[3].Kind).Should(Equal(JWTSecurityKind))
    70  		Ω(Design.SecuritySchemes[3].TokenURL).Should(Equal("http://example.com/token"))
    71  		Ω(Design.SecuritySchemes[3].Scopes).Should(HaveLen(2))
    72  	})
    73  
    74  	Context("with basic security", func() {
    75  		It("should fail because of duplicate In declaration", func() {
    76  			API("", func() {
    77  				BasicAuthSecurity("broken_basic_authz", func() {
    78  					Description("desc")
    79  					Header("Authorization")
    80  					Query("access_token")
    81  				})
    82  			})
    83  			dslengine.Run()
    84  			Ω(dslengine.Errors).Should(HaveOccurred())
    85  		})
    86  
    87  		It("should fail because of invalid declaration of OAuth2Flow", func() {
    88  			API("", func() {
    89  				BasicAuthSecurity("broken_basic_authz", func() {
    90  					Description("desc")
    91  					ImplicitFlow("invalid")
    92  				})
    93  			})
    94  			dslengine.Run()
    95  			Ω(dslengine.Errors).Should(HaveOccurred())
    96  		})
    97  
    98  		It("should fail because of invalid declaration of TokenURL", func() {
    99  			API("", func() {
   100  				BasicAuthSecurity("broken_basic_authz", func() {
   101  					Description("desc")
   102  					TokenURL("/token")
   103  				})
   104  			})
   105  			dslengine.Run()
   106  			Ω(dslengine.Errors).Should(HaveOccurred())
   107  		})
   108  
   109  		It("should fail because of invalid declaration of TokenURL", func() {
   110  			API("", func() {
   111  				BasicAuthSecurity("broken_basic_authz", func() {
   112  					Description("desc")
   113  					TokenURL("in valid")
   114  				})
   115  			})
   116  			dslengine.Run()
   117  			Ω(dslengine.Errors).Should(HaveOccurred())
   118  		})
   119  
   120  		It("should fail because of invalid declaration of Header", func() {
   121  			API("", func() {
   122  				BasicAuthSecurity("broken_basic_authz", func() {
   123  					Description("desc")
   124  					Header("invalid")
   125  				})
   126  			})
   127  			dslengine.Run()
   128  			Ω(dslengine.Errors).Should(HaveOccurred())
   129  		})
   130  	})
   131  
   132  	Context("with oauth2 security", func() {
   133  		It("should pass with valid values when well defined", func() {
   134  			API("", func() {
   135  				Host("example.com")
   136  				Scheme("http")
   137  				OAuth2Security("googAuthz", func() {
   138  					Description("Use Goog's Auth")
   139  					AccessCodeFlow("/auth", "/token")
   140  					Scope("scope:1", "Desc 1")
   141  					Scope("scope:2", "Desc 2")
   142  				})
   143  			})
   144  			Resource("one", func() {
   145  				Action("first", func() {
   146  					Routing(GET("/first"))
   147  					Security("googAuthz", func() {
   148  						Scope("scope:1")
   149  					})
   150  				})
   151  			})
   152  
   153  			dslengine.Run()
   154  
   155  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   156  			Ω(Design.SecuritySchemes).Should(HaveLen(1))
   157  			scheme := Design.SecuritySchemes[0]
   158  			Ω(scheme.Description).Should(Equal("Use Goog's Auth"))
   159  			Ω(scheme.AuthorizationURL).Should(Equal("http://example.com/auth"))
   160  			Ω(scheme.TokenURL).Should(Equal("http://example.com/token"))
   161  			Ω(scheme.Flow).Should(Equal("accessCode"))
   162  			Ω(scheme.Scopes["scope:1"]).Should(Equal("Desc 1"))
   163  			Ω(scheme.Scopes["scope:2"]).Should(Equal("Desc 2"))
   164  		})
   165  
   166  		It("should fail because of invalid declaration of Header", func() {
   167  			API("", func() {
   168  				OAuth2Security("googAuthz", func() {
   169  					Header("invalid")
   170  				})
   171  			})
   172  			dslengine.Run()
   173  			Ω(dslengine.Errors).Should(HaveOccurred())
   174  		})
   175  
   176  	})
   177  
   178  	Context("with resources and actions", func() {
   179  		It("should fallback properly to lower-level security", func() {
   180  			API("", func() {
   181  				JWTSecurity("jwt", func() {
   182  					TokenURL("/token")
   183  					Scope("read", "Read")
   184  					Scope("write", "Write")
   185  				})
   186  				BasicAuthSecurity("password")
   187  
   188  				Security("jwt")
   189  			})
   190  			Resource("one", func() {
   191  				Action("first", func() {
   192  					Routing(GET("/first"))
   193  					NoSecurity()
   194  				})
   195  				Action("second", func() {
   196  					Routing(GET("/second"))
   197  				})
   198  			})
   199  			Resource("two", func() {
   200  				Security("password")
   201  
   202  				Action("third", func() {
   203  					Routing(GET("/third"))
   204  				})
   205  				Action("fourth", func() {
   206  					Routing(GET("/fourth"))
   207  					Security("jwt")
   208  				})
   209  			})
   210  			Resource("three", func() {
   211  				Action("fifth", func() {
   212  					Routing(GET("/fifth"))
   213  				})
   214  			})
   215  			Resource("auth", func() {
   216  				NoSecurity()
   217  
   218  				Action("auth", func() {
   219  					Routing(GET("/auth"))
   220  				})
   221  				Action("refresh", func() {
   222  					Routing(GET("/refresh"))
   223  					Security("jwt")
   224  				})
   225  			})
   226  
   227  			dslengine.Run()
   228  
   229  			Ω(dslengine.Errors).ShouldNot(HaveOccurred())
   230  			Ω(Design.SecuritySchemes).Should(HaveLen(2))
   231  			Ω(Design.Resources["one"].Actions["first"].Security).Should(BeNil())
   232  			Ω(Design.Resources["one"].Actions["second"].Security.Scheme.SchemeName).Should(Equal("jwt"))
   233  			Ω(Design.Resources["two"].Actions["third"].Security.Scheme.SchemeName).Should(Equal("password"))
   234  			Ω(Design.Resources["two"].Actions["fourth"].Security.Scheme.SchemeName).Should(Equal("jwt"))
   235  			Ω(Design.Resources["three"].Actions["fifth"].Security.Scheme.SchemeName).Should(Equal("jwt"))
   236  			Ω(Design.Resources["auth"].Actions["auth"].Security).Should(BeNil())
   237  			Ω(Design.Resources["auth"].Actions["refresh"].Security.Scheme.SchemeName).Should(Equal("jwt"))
   238  		})
   239  	})
   240  })