Skip to content

Commit

Permalink
Add support for PKCE (#136)
Browse files Browse the repository at this point in the history
* Adds PKCE params to fetch code-path, using helper function from pkce.go.
* Updates go mod version to 1.16 since the latest version of oauth2 core lib has a dependency on 1.16 API. Update vendors.
* Ensure hostname is fully specified (i.e. localhost:8080 instead of :8080) in cli_test.go and loopback.go, to avoid a MacOS security pop-up.
  • Loading branch information
andyrzhao authored Jul 6, 2022
1 parent c142cd9 commit 0d7480f
Show file tree
Hide file tree
Showing 456 changed files with 176,811 additions and 1,353 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Go
name: Integration Test

on:
push:
Expand All @@ -16,7 +16,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.13
go-version: 1.16

- name: Build
run: go build -v ./...
Expand Down
28 changes: 0 additions & 28 deletions .travis.yml

This file was deleted.

10 changes: 7 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
module github.com/google/oauth2l

go 1.13
go 1.16

require (
github.com/jessevdk/go-flags v1.4.0
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
cloud.google.com/go/compute v1.7.0 // indirect
github.com/google/uuid v1.3.0
github.com/jessevdk/go-flags v1.5.0
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
golang.org/x/oauth2 v0.0.0-20220628200809-02e64fa58f26
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b // indirect
)
290 changes: 290 additions & 0 deletions go.sum

Large diffs are not rendered by default.

19 changes: 16 additions & 3 deletions integration/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ func runTestScenariosWithInputAndProcessedOutput(t *testing.T, tests []testCase,
}
}

// Helper for removing the randomly generated code_challenge string from comparison.
func removeCodeChallenge(s string) string {
re := regexp.MustCompile("code_challenge=.*code_challenge_method")
match := re.FindString(s)
if match == "" {
return s
}
return strings.Replace(s, match, "code_challenge_method", 1)
}

// Test base-case scenarios
func TestCLI(t *testing.T) {
tests := []testCase{
Expand Down Expand Up @@ -290,7 +300,10 @@ func Test3LOFlow(t *testing.T) {
false,
},
}
runTestScenariosWithInput(t, tests, newFixture(t, "fake-verification-code.fixture").asFile())
process3LOOutput := func(output string) string {
return removeCodeChallenge(output)
}
runTestScenariosWithInputAndProcessedOutput(t, tests, newFixture(t, "fake-verification-code.fixture").asFile(), process3LOOutput)
}

// TODO: Enhance tests so that the entire loopback flow can be tested
Expand Down Expand Up @@ -381,7 +394,7 @@ func Test3LOLoopbackFlow(t *testing.T) {
re := regexp.MustCompile("redirect_uri=http%3A%2F%2Flocalhost%3A\\d+")
match := re.FindString(output)
output = strings.Replace(output, match, "redirect_uri=http%3A%2F%2Flocalhost", 1)
return output
return removeCodeChallenge(output)
}

runTestScenariosWithInputAndProcessedOutput(t, tests, nil, process3LOOutput)
Expand Down Expand Up @@ -579,7 +592,7 @@ func TestMain(m *testing.M) {
// Start mock server
go func() {
mux := http.NewServeMux()
server := http.Server{Addr: ":8080", Handler: mux}
server := http.Server{Addr: "localhost:8080", Handler: mux}
mux.HandleFunc("/token", MockTokenApi)
mux.HandleFunc("/expiredtoken", MockExpiredTokenApi)
mux.HandleFunc("/curl", MockCurlApi)
Expand Down
2 changes: 1 addition & 1 deletion integration/golden/curl-3lo-loopback.golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Go to the following link in your browser:

https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
Authorization code not yet set.
2 changes: 1 addition & 1 deletion integration/golden/curl-3lo.golden
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Go to the following link in your browser:

https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&code_challenge_method=S256&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state

Enter authorization code:
{}
2 changes: 1 addition & 1 deletion integration/golden/fetch-3lo-loopback-refresh-token.golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Go to the following link in your browser:

https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
Authorization code not yet set.
2 changes: 1 addition & 1 deletion integration/golden/fetch-3lo-loopback-userinfo.golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Go to the following link in your browser:

https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&state=state
https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&state=state
Authorization code not yet set.
2 changes: 1 addition & 1 deletion integration/golden/fetch-3lo-loopback.golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Go to the following link in your browser:

https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
Authorization code not yet set.
2 changes: 1 addition & 1 deletion integration/golden/fetch-3lo-openid.golden
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Go to the following link in your browser:

https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=openid+profile+email&state=state
https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&code_challenge_method=S256&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=openid+profile+email&state=state

Enter authorization code:
ya29.GltDB_y4Oz8lVB5diZu9YVMgHuXoSVBXx6jt7WU9n8IaXk63RejERFtx2LfrH-VL51CbaAxKsC8EoMZXg50h2QvOcUQ-YZTvFnKtIJpLj_Zj68M56_VagXpZkZd7
2 changes: 1 addition & 1 deletion integration/golden/fetch-3lo-refresh-token.golden
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Go to the following link in your browser:

https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&code_challenge_method=S256&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state

Enter authorization code:
{"client_id":"144169.apps.googleusercontent.com","client_secret":"awesomesecret","token_uri":"http://localhost:8080/token","auth_uri":"https://accounts.google.com/o/oauth2/auth","refresh_token":"1/q8uQkblGs0Zzpe1LtpDtBLKsyf_NlEnPOxo1DcTR27U","type":"authorized_user"}
2 changes: 1 addition & 1 deletion integration/golden/fetch-3lo-userinfo.golden
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Go to the following link in your browser:

https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&state=state
https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&code_challenge_method=S256&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&state=state

Enter authorization code:
ya29.GltDB_y4Oz8lVB5diZu9YVMgHuXoSVBXx6jt7WU9n8IaXk63RejERFtx2LfrH-VL51CbaAxKsC8EoMZXg50h2QvOcUQ-YZTvFnKtIJpLj_Zj68M56_VagXpZkZd7
2 changes: 1 addition & 1 deletion integration/golden/fetch-3lo.golden
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Go to the following link in your browser:

https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&code_challenge_method=S256&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state

Enter authorization code:
ya29.GltDB_y4Oz8lVB5diZu9YVMgHuXoSVBXx6jt7WU9n8IaXk63RejERFtx2LfrH-VL51CbaAxKsC8EoMZXg50h2QvOcUQ-YZTvFnKtIJpLj_Zj68M56_VagXpZkZd7
2 changes: 1 addition & 1 deletion integration/golden/header-3lo-loopback.golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Go to the following link in your browser:

https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
Authorization code not yet set.
2 changes: 1 addition & 1 deletion integration/golden/header-3lo.golden
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Go to the following link in your browser:

https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state
https://accounts.google.com/o/oauth2/auth?client_id=144169.apps.googleusercontent.com&code_challenge_method=S256&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fpubsub&state=state

Enter authorization code:
Authorization: Bearer ya29.GltDB_y4Oz8lVB5diZu9YVMgHuXoSVBXx6jt7WU9n8IaXk63RejERFtx2LfrH-VL51CbaAxKsC8EoMZXg50h2QvOcUQ-YZTvFnKtIJpLj_Zj68M56_VagXpZkZd7
1 change: 1 addition & 0 deletions util/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ func FindJSONCredentials(ctx context.Context, settings *Settings) (*google.Crede
params.State = "state"
params.AuthHandler = settings.AuthHandler
params.Subject = settings.Email
params.PKCE = GeneratePKCEParams()
if settings.CredentialsJSON != "" {
return google.CredentialsFromJSONWithParams(ctx, []byte(settings.CredentialsJSON),
params)
Expand Down
4 changes: 2 additions & 2 deletions util/loopback.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,10 @@ func getListener(address string) (listener *net.Listener, serverAddress string,

if match == "" { // Case: No given port provided for localhost
// Creating a listener on the next available port
l, err = net.Listen("tcp", ":0")
l, err = net.Listen("tcp", "localhost:0")
} else { // Case: Port provided for localhost
// Creating a listener on the provided port
l, err = net.Listen("tcp", strings.Replace(match, "localhost", "", 1))
l, err = net.Listen("tcp", match)
}

if err != nil {
Expand Down
37 changes: 37 additions & 0 deletions util/pkce.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// Copyright 2022 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package util

import (
"crypto/sha256"
"encoding/base64"

"github.com/google/uuid"
"golang.org/x/oauth2/authhandler"
)

// GeneratePKCEParams generates a unique PKCE challenge and verifier combination,
// using UUID, SHA256 encryption, and base64 URL encoding with no padding.
func GeneratePKCEParams() *authhandler.PKCEParams {
verifier := uuid.New().String()
sha := sha256.Sum256([]byte(verifier))
challenge := base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(sha[:])

return &authhandler.PKCEParams{
Challenge: challenge,
ChallengeMethod: "S256",
Verifier: verifier,
}
}
File renamed without changes.
50 changes: 36 additions & 14 deletions vendor/cloud.google.com/go/compute/metadata/metadata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0d7480f

Please sign in to comment.