1
21
22 package oauth2
23
24 import (
25 "net/url"
26 "strings"
27 "testing"
28 "time"
29
30 "github.com/stretchr/testify/assert"
31 "github.com/stretchr/testify/require"
32
33 "github.com/ory/fosite"
34 "github.com/ory/fosite/storage"
35 )
36
37 func parseUrl(uu string) *url.URL {
38 u, _ := url.Parse(uu)
39 return u
40 }
41
42 func TestAuthorizeCode_HandleAuthorizeEndpointRequest(t *testing.T) {
43 for k, strategy := range map[string]CoreStrategy{
44 "hmac": &hmacshaStrategy,
45 } {
46 t.Run("strategy="+k, func(t *testing.T) {
47 store := storage.NewMemoryStore()
48 handler := AuthorizeExplicitGrantHandler{
49 CoreStorage: store,
50 AuthorizeCodeStrategy: strategy,
51 ScopeStrategy: fosite.HierarchicScopeStrategy,
52 AudienceMatchingStrategy: fosite.DefaultAudienceMatchingStrategy,
53 }
54 for _, c := range []struct {
55 handler AuthorizeExplicitGrantHandler
56 areq *fosite.AuthorizeRequest
57 description string
58 expectErr error
59 expect func(t *testing.T, areq *fosite.AuthorizeRequest, aresp *fosite.AuthorizeResponse)
60 }{
61 {
62 handler: handler,
63 areq: &fosite.AuthorizeRequest{
64 ResponseTypes: fosite.Arguments{""},
65 Request: *fosite.NewRequest(),
66 },
67 description: "should pass because not responsible for handling an empty response type",
68 },
69 {
70 handler: handler,
71 areq: &fosite.AuthorizeRequest{
72 ResponseTypes: fosite.Arguments{"foo"},
73 Request: *fosite.NewRequest(),
74 },
75 description: "should pass because not responsible for handling an invalid response type",
76 },
77 {
78 handler: handler,
79 areq: &fosite.AuthorizeRequest{
80 ResponseTypes: fosite.Arguments{"code"},
81 Request: fosite.Request{
82 Client: &fosite.DefaultClient{
83 ResponseTypes: fosite.Arguments{"code"},
84 RedirectURIs: []string{"http://asdf.com/cb"},
85 },
86 },
87 RedirectURI: parseUrl("http://asdf.com/cb"),
88 },
89 description: "should fail because redirect uri is not https",
90 expectErr: fosite.ErrInvalidRequest,
91 },
92 {
93 handler: handler,
94 areq: &fosite.AuthorizeRequest{
95 ResponseTypes: fosite.Arguments{"code"},
96 Request: fosite.Request{
97 Client: &fosite.DefaultClient{
98 ResponseTypes: fosite.Arguments{"code"},
99 RedirectURIs: []string{"https://asdf.com/cb"},
100 Audience: []string{"https://www.ory.sh/api"},
101 },
102 RequestedAudience: []string{"https://www.ory.sh/not-api"},
103 },
104 RedirectURI: parseUrl("https://asdf.com/cb"),
105 },
106 description: "should fail because audience doesn't match",
107 expectErr: fosite.ErrInvalidRequest,
108 },
109 {
110 handler: handler,
111 areq: &fosite.AuthorizeRequest{
112 ResponseTypes: fosite.Arguments{"code"},
113 Request: fosite.Request{
114 Client: &fosite.DefaultClient{
115 ResponseTypes: fosite.Arguments{"code"},
116 RedirectURIs: []string{"https://asdf.de/cb"},
117 Audience: []string{"https://www.ory.sh/api"},
118 },
119 RequestedAudience: []string{"https://www.ory.sh/api"},
120 GrantedScope: fosite.Arguments{"a", "b"},
121 Session: &fosite.DefaultSession{
122 ExpiresAt: map[fosite.TokenType]time.Time{fosite.AccessToken: time.Now().UTC().Add(time.Hour)},
123 },
124 RequestedAt: time.Now().UTC(),
125 },
126 State: "superstate",
127 RedirectURI: parseUrl("https://asdf.de/cb"),
128 },
129 description: "should pass",
130 expect: func(t *testing.T, areq *fosite.AuthorizeRequest, aresp *fosite.AuthorizeResponse) {
131 code := aresp.GetParameters().Get("code")
132 assert.NotEmpty(t, code)
133
134 assert.Equal(t, strings.Join(areq.GrantedScope, " "), aresp.GetParameters().Get("scope"))
135 assert.Equal(t, areq.State, aresp.GetParameters().Get("state"))
136 assert.Equal(t, fosite.ResponseModeQuery, areq.GetResponseMode())
137 },
138 },
139 {
140 handler: AuthorizeExplicitGrantHandler{
141 CoreStorage: store,
142 AuthorizeCodeStrategy: strategy,
143 ScopeStrategy: fosite.HierarchicScopeStrategy,
144 AudienceMatchingStrategy: fosite.DefaultAudienceMatchingStrategy,
145 OmitRedirectScopeParam: true,
146 },
147 areq: &fosite.AuthorizeRequest{
148 ResponseTypes: fosite.Arguments{"code"},
149 Request: fosite.Request{
150 Client: &fosite.DefaultClient{
151 ResponseTypes: fosite.Arguments{"code"},
152 RedirectURIs: []string{"https://asdf.de/cb"},
153 Audience: []string{"https://www.ory.sh/api"},
154 },
155 RequestedAudience: []string{"https://www.ory.sh/api"},
156 GrantedScope: fosite.Arguments{"a", "b"},
157 Session: &fosite.DefaultSession{
158 ExpiresAt: map[fosite.TokenType]time.Time{fosite.AccessToken: time.Now().UTC().Add(time.Hour)},
159 },
160 RequestedAt: time.Now().UTC(),
161 },
162 State: "superstate",
163 RedirectURI: parseUrl("https://asdf.de/cb"),
164 },
165 description: "should pass but no scope in redirect uri",
166 expect: func(t *testing.T, areq *fosite.AuthorizeRequest, aresp *fosite.AuthorizeResponse) {
167 code := aresp.GetParameters().Get("code")
168 assert.NotEmpty(t, code)
169
170 assert.Empty(t, aresp.GetParameters().Get("scope"))
171 assert.Equal(t, areq.State, aresp.GetParameters().Get("state"))
172 assert.Equal(t, fosite.ResponseModeQuery, areq.GetResponseMode())
173 },
174 },
175 } {
176 t.Run("case="+c.description, func(t *testing.T) {
177 aresp := fosite.NewAuthorizeResponse()
178 err := c.handler.HandleAuthorizeEndpointRequest(nil, c.areq, aresp)
179 if c.expectErr != nil {
180 require.EqualError(t, err, c.expectErr.Error())
181 } else {
182 require.NoError(t, err)
183 }
184
185 if c.expect != nil {
186 c.expect(t, c.areq, aresp)
187 }
188 })
189 }
190 })
191 }
192 }
193
View as plain text