1
21
22 package openid
23
24 import (
25 "fmt"
26 "net/url"
27 "testing"
28 "time"
29
30 "github.com/golang/mock/gomock"
31 "github.com/stretchr/testify/assert"
32
33 "github.com/ory/fosite"
34 "github.com/ory/fosite/handler/oauth2"
35 "github.com/ory/fosite/internal"
36 "github.com/ory/fosite/storage"
37 "github.com/ory/fosite/token/jwt"
38 )
39
40 func makeOpenIDConnectImplicitHandler(minParameterEntropy int) OpenIDConnectImplicitHandler {
41 var idStrategy = &DefaultStrategy{
42 JWTStrategy: &jwt.RS256JWTStrategy{
43 PrivateKey: internal.MustRSAKey(),
44 },
45 MinParameterEntropy: minParameterEntropy,
46 }
47
48 var j = &DefaultStrategy{
49 JWTStrategy: &jwt.RS256JWTStrategy{
50 PrivateKey: key,
51 },
52 MinParameterEntropy: minParameterEntropy,
53 }
54
55 return OpenIDConnectImplicitHandler{
56 AuthorizeImplicitGrantTypeHandler: &oauth2.AuthorizeImplicitGrantTypeHandler{
57 AccessTokenLifespan: time.Hour,
58 AccessTokenStrategy: hmacStrategy,
59 AccessTokenStorage: storage.NewMemoryStore(),
60 },
61 IDTokenHandleHelper: &IDTokenHandleHelper{
62 IDTokenStrategy: idStrategy,
63 },
64 ScopeStrategy: fosite.HierarchicScopeStrategy,
65 OpenIDConnectRequestValidator: NewOpenIDConnectRequestValidator(nil, j.JWTStrategy),
66 MinParameterEntropy: minParameterEntropy,
67 }
68 }
69
70 func TestImplicit_HandleAuthorizeEndpointRequest(t *testing.T) {
71 ctrl := gomock.NewController(t)
72 defer ctrl.Finish()
73
74 aresp := fosite.NewAuthorizeResponse()
75 areq := fosite.NewAuthorizeRequest()
76 areq.Session = new(fosite.DefaultSession)
77
78 for k, c := range []struct {
79 description string
80 setup func() OpenIDConnectImplicitHandler
81 expectErr error
82 check func()
83 }{
84 {
85 description: "should not do anything because request requirements are not met",
86 setup: func() OpenIDConnectImplicitHandler {
87 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
88 },
89 },
90 {
91 description: "should not do anything because request requirements are not met",
92 setup: func() OpenIDConnectImplicitHandler {
93 areq.ResponseTypes = fosite.Arguments{"id_token"}
94 areq.State = "foostate"
95 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
96 },
97 },
98 {
99 description: "should not do anything because request requirements are not met",
100 setup: func() OpenIDConnectImplicitHandler {
101 areq.ResponseTypes = fosite.Arguments{"token", "id_token"}
102 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
103 },
104 },
105 {
106 description: "should not do anything because request requirements are not met",
107 setup: func() OpenIDConnectImplicitHandler {
108 areq.ResponseTypes = fosite.Arguments{}
109 areq.GrantedScope = fosite.Arguments{"openid"}
110 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
111 },
112 },
113 {
114 description: "should not do anything because request requirements are not met",
115 setup: func() OpenIDConnectImplicitHandler {
116 areq.ResponseTypes = fosite.Arguments{"token", "id_token"}
117 areq.RequestedScope = fosite.Arguments{"openid"}
118 areq.Client = &fosite.DefaultClient{
119 GrantTypes: fosite.Arguments{},
120 ResponseTypes: fosite.Arguments{},
121 Scopes: []string{"openid", "fosite"},
122 }
123 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
124 },
125 expectErr: fosite.ErrInvalidGrant,
126 },
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 {
143 description: "should not do anything because request requirements are not met",
144 setup: func() OpenIDConnectImplicitHandler {
145 areq.ResponseTypes = fosite.Arguments{"id_token"}
146 areq.RequestedScope = fosite.Arguments{"openid"}
147 areq.Client = &fosite.DefaultClient{
148 GrantTypes: fosite.Arguments{"implicit"},
149
150 Scopes: []string{"openid", "fosite"},
151 }
152 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
153 },
154 expectErr: fosite.ErrInvalidRequest,
155 },
156 {
157 description: "should not do anything because request requirements are not met",
158 setup: func() OpenIDConnectImplicitHandler {
159 areq.Form = url.Values{"nonce": {"short"}}
160 areq.ResponseTypes = fosite.Arguments{"id_token"}
161 areq.RequestedScope = fosite.Arguments{"openid"}
162 areq.Client = &fosite.DefaultClient{
163 GrantTypes: fosite.Arguments{"implicit"},
164 ResponseTypes: fosite.Arguments{"token", "id_token"},
165 Scopes: []string{"openid", "fosite"},
166 }
167 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
168 },
169 expectErr: fosite.ErrInsufficientEntropy,
170 },
171 {
172 description: "should fail because session not set",
173 setup: func() OpenIDConnectImplicitHandler {
174 areq.Form = url.Values{"nonce": {"long-enough"}}
175 areq.ResponseTypes = fosite.Arguments{"id_token"}
176 areq.RequestedScope = fosite.Arguments{"openid"}
177 areq.Client = &fosite.DefaultClient{
178 GrantTypes: fosite.Arguments{"implicit"},
179 ResponseTypes: fosite.Arguments{"token", "id_token"},
180 Scopes: []string{"openid", "fosite"},
181 }
182 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
183 },
184 expectErr: ErrInvalidSession,
185 },
186 {
187 description: "should pass because nonce set",
188 setup: func() OpenIDConnectImplicitHandler {
189 areq.Session = &DefaultSession{
190 Claims: &jwt.IDTokenClaims{
191 Subject: "peter",
192 },
193 Headers: &jwt.Headers{},
194 Subject: "peter",
195 }
196 areq.Form.Add("nonce", "some-random-foo-nonce-wow")
197 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
198 },
199 },
200 {
201 description: "should pass",
202 setup: func() OpenIDConnectImplicitHandler {
203 areq.ResponseTypes = fosite.Arguments{"id_token"}
204 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
205 },
206 check: func() {
207 assert.NotEmpty(t, aresp.GetParameters().Get("id_token"))
208 assert.NotEmpty(t, aresp.GetParameters().Get("state"))
209 assert.Empty(t, aresp.GetParameters().Get("access_token"))
210 },
211 },
212 {
213 description: "should pass",
214 setup: func() OpenIDConnectImplicitHandler {
215 areq.ResponseTypes = fosite.Arguments{"token", "id_token"}
216 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
217 },
218 check: func() {
219 assert.NotEmpty(t, aresp.GetParameters().Get("id_token"))
220 assert.NotEmpty(t, aresp.GetParameters().Get("state"))
221 assert.NotEmpty(t, aresp.GetParameters().Get("access_token"))
222 },
223 },
224 {
225 description: "should pass",
226 setup: func() OpenIDConnectImplicitHandler {
227 areq.ResponseTypes = fosite.Arguments{"id_token", "token"}
228 areq.RequestedScope = fosite.Arguments{"fosite", "openid"}
229 return makeOpenIDConnectImplicitHandler(fosite.MinParameterEntropy)
230 },
231 check: func() {
232 assert.NotEmpty(t, aresp.GetParameters().Get("id_token"))
233 assert.NotEmpty(t, aresp.GetParameters().Get("state"))
234 assert.NotEmpty(t, aresp.GetParameters().Get("access_token"))
235 assert.Equal(t, fosite.ResponseModeFragment, areq.GetResponseMode())
236 },
237 },
238 {
239 description: "should pass with low min entropy",
240 setup: func() OpenIDConnectImplicitHandler {
241 areq.Form.Set("nonce", "short")
242 return makeOpenIDConnectImplicitHandler(4)
243 },
244 check: func() {
245 assert.NotEmpty(t, aresp.GetParameters().Get("id_token"))
246 assert.NotEmpty(t, aresp.GetParameters().Get("state"))
247 assert.NotEmpty(t, aresp.GetParameters().Get("access_token"))
248 },
249 },
250 } {
251 t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) {
252 h := c.setup()
253 err := h.HandleAuthorizeEndpointRequest(nil, areq, aresp)
254
255 if c.expectErr != nil {
256 assert.EqualError(t, err, c.expectErr.Error())
257 } else {
258 assert.NoError(t, err)
259 if c.check != nil {
260 c.check()
261 }
262 }
263 })
264 }
265 }
266
View as plain text