Skip to content

Commit 25591ee

Browse files
authored
Add support to PKCE in OIDC connector (#3777)
Signed-off-by: johnvan7 <giovanni.vella98@gmail.com> Signed-off-by: Giovanni Vella <giovanni.vella98@gmail.com>
1 parent 5d27abc commit 25591ee

File tree

20 files changed

+208
-64
lines changed

20 files changed

+208
-64
lines changed

connector/bitbucketcloud/bitbucketcloud.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,12 @@ func (b *bitbucketConnector) oauth2Config(scopes connector.Scopes) *oauth2.Confi
111111
}
112112
}
113113

114-
func (b *bitbucketConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) {
114+
func (b *bitbucketConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, []byte, error) {
115115
if b.redirectURI != callbackURL {
116-
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, b.redirectURI)
116+
return "", nil, fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, b.redirectURI)
117117
}
118118

119-
return b.oauth2Config(scopes).AuthCodeURL(state), nil
119+
return b.oauth2Config(scopes).AuthCodeURL(state), nil, nil
120120
}
121121

122122
type oauth2Error struct {
@@ -131,7 +131,7 @@ func (e *oauth2Error) Error() string {
131131
return e.error + ": " + e.errorDescription
132132
}
133133

134-
func (b *bitbucketConnector) HandleCallback(s connector.Scopes, r *http.Request) (identity connector.Identity, err error) {
134+
func (b *bitbucketConnector) HandleCallback(s connector.Scopes, connData []byte, r *http.Request) (identity connector.Identity, err error) {
135135
q := r.URL.Query()
136136
if errType := q.Get("error"); errType != "" {
137137
return identity, &oauth2Error{errType, q.Get("error_description")}

connector/bitbucketcloud/bitbucketcloud_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func TestUsernameIncludedInFederatedIdentity(t *testing.T) {
102102
expectNil(t, err)
103103

104104
bitbucketConnector := bitbucketConnector{apiURL: s.URL, hostName: hostURL.Host, httpClient: newClient()}
105-
identity, err := bitbucketConnector.HandleCallback(connector.Scopes{}, req)
105+
identity, err := bitbucketConnector.HandleCallback(connector.Scopes{}, nil, req)
106106

107107
expectNil(t, err)
108108
expectEquals(t, identity.Username, "some-login")

connector/connector.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ type CallbackConnector interface {
6363
// requested if one has already been issues. There's no good general answer
6464
// for these kind of restrictions, and may require this package to become more
6565
// aware of the global set of user/connector interactions.
66-
LoginURL(s Scopes, callbackURL, state string) (string, error)
66+
LoginURL(s Scopes, callbackURL, state string) (string, []byte, error)
6767

6868
// Handle the callback to the server and return an identity.
69-
HandleCallback(s Scopes, r *http.Request) (identity Identity, err error)
69+
HandleCallback(s Scopes, connData []byte, r *http.Request) (identity Identity, err error)
7070
}
7171

7272
// SAMLConnector represents SAML connectors which implement the HTTP POST binding.

connector/gitea/gitea.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ func (c *giteaConnector) oauth2Config(_ connector.Scopes) *oauth2.Config {
102102
}
103103
}
104104

105-
func (c *giteaConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) {
105+
func (c *giteaConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, []byte, error) {
106106
if c.redirectURI != callbackURL {
107-
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", c.redirectURI, callbackURL)
107+
return "", nil, fmt.Errorf("expected callback URL %q did not match the URL in the config %q", c.redirectURI, callbackURL)
108108
}
109-
return c.oauth2Config(scopes).AuthCodeURL(state), nil
109+
return c.oauth2Config(scopes).AuthCodeURL(state), nil, nil
110110
}
111111

112112
type oauth2Error struct {
@@ -121,7 +121,7 @@ func (e *oauth2Error) Error() string {
121121
return e.error + ": " + e.errorDescription
122122
}
123123

124-
func (c *giteaConnector) HandleCallback(s connector.Scopes, r *http.Request) (identity connector.Identity, err error) {
124+
func (c *giteaConnector) HandleCallback(s connector.Scopes, connData []byte, r *http.Request) (identity connector.Identity, err error) {
125125
q := r.URL.Query()
126126
if errType := q.Get("error"); errType != "" {
127127
return identity, &oauth2Error{errType, q.Get("error_description")}

connector/gitea/gitea_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ func TestUsernameIncludedInFederatedIdentity(t *testing.T) {
3030
expectNil(t, err)
3131

3232
c := giteaConnector{baseURL: s.URL, httpClient: newClient()}
33-
identity, err := c.HandleCallback(connector.Scopes{}, req)
33+
identity, err := c.HandleCallback(connector.Scopes{}, nil, req)
3434

3535
expectNil(t, err)
3636
expectEquals(t, identity.Username, "some@email.com")
3737
expectEquals(t, identity.UserID, "12345678")
3838

3939
c = giteaConnector{baseURL: s.URL, httpClient: newClient()}
40-
identity, err = c.HandleCallback(connector.Scopes{}, req)
40+
identity, err = c.HandleCallback(connector.Scopes{}, nil, req)
4141

4242
expectNil(t, err)
4343
expectEquals(t, identity.Username, "some@email.com")

connector/github/github.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,12 @@ func (c *githubConnector) oauth2Config(scopes connector.Scopes) *oauth2.Config {
194194
}
195195
}
196196

197-
func (c *githubConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) {
197+
func (c *githubConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, []byte, error) {
198198
if c.redirectURI != callbackURL {
199-
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, c.redirectURI)
199+
return "", nil, fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, c.redirectURI)
200200
}
201201

202-
return c.oauth2Config(scopes).AuthCodeURL(state), nil
202+
return c.oauth2Config(scopes).AuthCodeURL(state), nil, nil
203203
}
204204

205205
type oauth2Error struct {
@@ -214,7 +214,7 @@ func (e *oauth2Error) Error() string {
214214
return e.error + ": " + e.errorDescription
215215
}
216216

217-
func (c *githubConnector) HandleCallback(s connector.Scopes, r *http.Request) (identity connector.Identity, err error) {
217+
func (c *githubConnector) HandleCallback(s connector.Scopes, connData []byte, r *http.Request) (identity connector.Identity, err error) {
218218
q := r.URL.Query()
219219
if errType := q.Get("error"); errType != "" {
220220
return identity, &oauth2Error{errType, q.Get("error_description")}

connector/github/github_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,15 @@ func TestUsernameIncludedInFederatedIdentity(t *testing.T) {
152152
expectNil(t, err)
153153

154154
c := githubConnector{apiURL: s.URL, hostName: hostURL.Host, httpClient: newClient()}
155-
identity, err := c.HandleCallback(connector.Scopes{Groups: true}, req)
155+
identity, err := c.HandleCallback(connector.Scopes{Groups: true}, nil, req)
156156

157157
expectNil(t, err)
158158
expectEquals(t, identity.Username, "some-login")
159159
expectEquals(t, identity.UserID, "12345678")
160160
expectEquals(t, 0, len(identity.Groups))
161161

162162
c = githubConnector{apiURL: s.URL, hostName: hostURL.Host, httpClient: newClient(), loadAllGroups: true}
163-
identity, err = c.HandleCallback(connector.Scopes{Groups: true}, req)
163+
identity, err = c.HandleCallback(connector.Scopes{Groups: true}, nil, req)
164164

165165
expectNil(t, err)
166166
expectEquals(t, identity.Username, "some-login")
@@ -193,7 +193,7 @@ func TestLoginUsedAsIDWhenConfigured(t *testing.T) {
193193
expectNil(t, err)
194194

195195
c := githubConnector{apiURL: s.URL, hostName: hostURL.Host, httpClient: newClient(), useLoginAsID: true}
196-
identity, err := c.HandleCallback(connector.Scopes{Groups: true}, req)
196+
identity, err := c.HandleCallback(connector.Scopes{Groups: true}, nil, req)
197197

198198
expectNil(t, err)
199199
expectEquals(t, identity.UserID, "some-login")

connector/gitlab/gitlab.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,11 @@ func (c *gitlabConnector) oauth2Config(scopes connector.Scopes) *oauth2.Config {
122122
}
123123
}
124124

125-
func (c *gitlabConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, error) {
125+
func (c *gitlabConnector) LoginURL(scopes connector.Scopes, callbackURL, state string) (string, []byte, error) {
126126
if c.redirectURI != callbackURL {
127-
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", c.redirectURI, callbackURL)
127+
return "", nil, fmt.Errorf("expected callback URL %q did not match the URL in the config %q", c.redirectURI, callbackURL)
128128
}
129-
return c.oauth2Config(scopes).AuthCodeURL(state), nil
129+
return c.oauth2Config(scopes).AuthCodeURL(state), nil, nil
130130
}
131131

132132
type oauth2Error struct {
@@ -141,7 +141,7 @@ func (e *oauth2Error) Error() string {
141141
return e.error + ": " + e.errorDescription
142142
}
143143

144-
func (c *gitlabConnector) HandleCallback(s connector.Scopes, r *http.Request) (identity connector.Identity, err error) {
144+
func (c *gitlabConnector) HandleCallback(s connector.Scopes, connData []byte, r *http.Request) (identity connector.Identity, err error) {
145145
q := r.URL.Query()
146146
if errType := q.Get("error"); errType != "" {
147147
return identity, &oauth2Error{errType, q.Get("error_description")}

connector/gitlab/gitlab_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -247,15 +247,15 @@ func TestUsernameIncludedInFederatedIdentity(t *testing.T) {
247247
expectNil(t, err)
248248

249249
c := gitlabConnector{baseURL: s.URL, httpClient: newClient()}
250-
identity, err := c.HandleCallback(connector.Scopes{Groups: false}, req)
250+
identity, err := c.HandleCallback(connector.Scopes{Groups: false}, nil, req)
251251

252252
expectNil(t, err)
253253
expectEquals(t, identity.Username, "some@email.com")
254254
expectEquals(t, identity.UserID, "12345678")
255255
expectEquals(t, 0, len(identity.Groups))
256256

257257
c = gitlabConnector{baseURL: s.URL, httpClient: newClient()}
258-
identity, err = c.HandleCallback(connector.Scopes{Groups: true}, req)
258+
identity, err = c.HandleCallback(connector.Scopes{Groups: true}, nil, req)
259259

260260
expectNil(t, err)
261261
expectEquals(t, identity.Username, "some@email.com")
@@ -283,7 +283,7 @@ func TestLoginUsedAsIDWhenConfigured(t *testing.T) {
283283
expectNil(t, err)
284284

285285
c := gitlabConnector{baseURL: s.URL, httpClient: newClient(), useLoginAsID: true}
286-
identity, err := c.HandleCallback(connector.Scopes{Groups: true}, req)
286+
identity, err := c.HandleCallback(connector.Scopes{Groups: true}, nil, req)
287287

288288
expectNil(t, err)
289289
expectEquals(t, identity.UserID, "joebloggs")
@@ -310,7 +310,7 @@ func TestLoginWithTeamWhitelisted(t *testing.T) {
310310
expectNil(t, err)
311311

312312
c := gitlabConnector{baseURL: s.URL, httpClient: newClient(), groups: []string{"team-1"}}
313-
identity, err := c.HandleCallback(connector.Scopes{Groups: true}, req)
313+
identity, err := c.HandleCallback(connector.Scopes{Groups: true}, nil, req)
314314

315315
expectNil(t, err)
316316
expectEquals(t, identity.UserID, "12345678")
@@ -337,7 +337,7 @@ func TestLoginWithTeamNonWhitelisted(t *testing.T) {
337337
expectNil(t, err)
338338

339339
c := gitlabConnector{baseURL: s.URL, httpClient: newClient(), groups: []string{"team-2"}}
340-
_, err = c.HandleCallback(connector.Scopes{Groups: true}, req)
340+
_, err = c.HandleCallback(connector.Scopes{Groups: true}, nil, req)
341341

342342
expectNotNil(t, err, "HandleCallback error")
343343
expectEquals(t, err.Error(), "gitlab: get groups: gitlab: user \"joebloggs\" is not in any of the required groups")
@@ -371,7 +371,7 @@ func TestRefresh(t *testing.T) {
371371
})
372372
expectNil(t, err)
373373

374-
identity, err := c.HandleCallback(connector.Scopes{OfflineAccess: true}, req)
374+
identity, err := c.HandleCallback(connector.Scopes{OfflineAccess: true}, nil, req)
375375
expectNil(t, err)
376376
expectEquals(t, identity.Username, "some@email.com")
377377
expectEquals(t, identity.UserID, "12345678")
@@ -435,7 +435,7 @@ func TestGroupsWithPermission(t *testing.T) {
435435
expectNil(t, err)
436436

437437
c := gitlabConnector{baseURL: s.URL, httpClient: newClient(), getGroupsPermission: true}
438-
identity, err := c.HandleCallback(connector.Scopes{Groups: true}, req)
438+
identity, err := c.HandleCallback(connector.Scopes{Groups: true}, nil, req)
439439
expectNil(t, err)
440440

441441
expectEquals(t, identity.Groups, []string{

connector/google/google.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,9 @@ func (c *googleConnector) Close() error {
168168
return nil
169169
}
170170

171-
func (c *googleConnector) LoginURL(s connector.Scopes, callbackURL, state string) (string, error) {
171+
func (c *googleConnector) LoginURL(s connector.Scopes, callbackURL, state string) (string, []byte, error) {
172172
if c.redirectURI != callbackURL {
173-
return "", fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, c.redirectURI)
173+
return "", nil, fmt.Errorf("expected callback URL %q did not match the URL in the config %q", callbackURL, c.redirectURI)
174174
}
175175

176176
var opts []oauth2.AuthCodeOption
@@ -186,7 +186,7 @@ func (c *googleConnector) LoginURL(s connector.Scopes, callbackURL, state string
186186
opts = append(opts, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", c.promptType))
187187
}
188188

189-
return c.oauth2Config.AuthCodeURL(state, opts...), nil
189+
return c.oauth2Config.AuthCodeURL(state, opts...), nil, nil
190190
}
191191

192192
type oauth2Error struct {
@@ -201,7 +201,7 @@ func (e *oauth2Error) Error() string {
201201
return e.error + ": " + e.errorDescription
202202
}
203203

204-
func (c *googleConnector) HandleCallback(s connector.Scopes, r *http.Request) (identity connector.Identity, err error) {
204+
func (c *googleConnector) HandleCallback(s connector.Scopes, connData []byte, r *http.Request) (identity connector.Identity, err error) {
205205
q := r.URL.Query()
206206
if errType := q.Get("error"); errType != "" {
207207
return identity, &oauth2Error{errType, q.Get("error_description")}

0 commit comments

Comments
 (0)