Skip to content

Commit ea5fb34

Browse files
committed
untested merge conflict resolved
2 parents 90ac1cc + a3a85ea commit ea5fb34

37 files changed

+1698
-879
lines changed

.circleci/config.yml

-13
This file was deleted.

.github/renovate.json5

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": [
3+
"config:base"
4+
],
5+
"packageRules": [
6+
{
7+
"updateTypes": ["minor", "patch", "digest"],
8+
"automerge": true
9+
}
10+
],
11+
"postUpdateOptions": [
12+
"gomodTidy"
13+
]
14+
}

.github/workflows/go.yaml

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: go
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- .github/workflows/go.yaml
7+
- '**/*.go'
8+
- go.*
9+
push:
10+
paths:
11+
- .github/workflows/go.yaml
12+
- '**/*.go'
13+
- go.*
14+
branches:
15+
- master
16+
17+
jobs:
18+
lint:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v2
22+
- uses: actions/setup-go@v2
23+
with:
24+
go-version: 1.16
25+
- uses: golangci/golangci-lint-action@v2
26+
with:
27+
version: v1.38.0
28+
29+
test:
30+
runs-on: ubuntu-latest
31+
steps:
32+
- uses: actions/checkout@v2
33+
- uses: actions/setup-go@v2
34+
with:
35+
go-version: 1.16
36+
- uses: actions/cache@v2
37+
with:
38+
path: ~/go/pkg/mod
39+
key: go-linux-amd64-${{ hashFiles('**/go.sum') }}
40+
restore-keys: |
41+
go-linux-amd64-
42+
- run: go test -v -race ./...

Makefile

-5
This file was deleted.

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
# oauth2cli [![CircleCI](https://circleci.com/gh/int128/oauth2cli.svg?style=shield)](https://circleci.com/gh/int128/oauth2cli) [![GoDoc](https://godoc.org/github.com/int128/oauth2cli?status.svg)](https://godoc.org/github.com/int128/oauth2cli)
1+
# oauth2cli ![test](https://github.com/int128/oauth2cli/workflows/test/badge.svg) [![GoDoc](https://godoc.org/github.com/int128/oauth2cli?status.svg)](https://godoc.org/github.com/int128/oauth2cli)
22

33
This is a Go package for OAuth 2.0 authorization in a command line interface (CLI) tool.
44
You can create a CLI tool with the simple authorization flow for better UX.
55

6-
Take a look at the demo movie running [the example application](example/).
6+
Take a look at the screencast of [the example application](example/).
77

8-
<img alt="example" src="https://user-images.githubusercontent.com/321266/67554896-35e02280-f74b-11e9-8d32-392c13b4804a.gif" width="650" height="470">
8+
<img src="https://user-images.githubusercontent.com/321266/87224372-c2a53c00-c3bf-11ea-8419-74380a9e681e.gif" width="572" height="391">
99

1010

1111
## Purpose

e2e_test/authserver/handler.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
package authserver
55

66
import (
7+
"errors"
8+
"fmt"
79
"net/http"
810
"net/url"
911
"testing"
10-
11-
"golang.org/x/xerrors"
1212
)
1313

1414
// AuthorizationRequest represents an authorization request described as:
@@ -55,13 +55,13 @@ func (h *Handler) serveHTTP(w http.ResponseWriter, r *http.Request) error {
5555
q := r.URL.Query()
5656
scope, state, redirectURI := q.Get("scope"), q.Get("state"), q.Get("redirect_uri")
5757
if scope == "" {
58-
return xerrors.New("scope is missing")
58+
return errors.New("scope is missing")
5959
}
6060
if state == "" {
61-
return xerrors.New("state is missing")
61+
return errors.New("state is missing")
6262
}
6363
if redirectURI == "" {
64-
return xerrors.New("redirect_uri is missing")
64+
return errors.New("redirect_uri is missing")
6565
}
6666
to := h.NewAuthorizationResponse(AuthorizationRequest{
6767
Scope: scope,
@@ -73,14 +73,14 @@ func (h *Handler) serveHTTP(w http.ResponseWriter, r *http.Request) error {
7373

7474
case r.Method == "POST" && r.URL.Path == "/token":
7575
if err := r.ParseForm(); err != nil {
76-
return xerrors.Errorf("error while parsing form: %w", err)
76+
return fmt.Errorf("error while parsing form: %w", err)
7777
}
7878
code, redirectURI := r.Form.Get("code"), r.Form.Get("redirect_uri")
7979
if code == "" {
80-
return xerrors.New("code is missing")
80+
return errors.New("code is missing")
8181
}
8282
if redirectURI == "" {
83-
return xerrors.New("redirect_uri is missing")
83+
return errors.New("redirect_uri is missing")
8484
}
8585
status, b := h.NewTokenResponse(TokenRequest{
8686
Code: code,
@@ -89,7 +89,7 @@ func (h *Handler) serveHTTP(w http.ResponseWriter, r *http.Request) error {
8989
w.Header().Add("Content-Type", "application/json")
9090
w.WriteHeader(status)
9191
if _, err := w.Write([]byte(b)); err != nil {
92-
return xerrors.Errorf("error while writing response body: %w", err)
92+
return fmt.Errorf("error while writing response body: %w", err)
9393
}
9494

9595
default:

e2e_test/client/client.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package client
2+
3+
import (
4+
"crypto/tls"
5+
"crypto/x509"
6+
"fmt"
7+
"io/ioutil"
8+
"net/http"
9+
"testing"
10+
11+
"github.com/google/go-cmp/cmp"
12+
)
13+
14+
var certPool = x509.NewCertPool()
15+
16+
func init() {
17+
data, err := ioutil.ReadFile("testdata/ca.crt")
18+
if err != nil {
19+
panic(err)
20+
}
21+
if !certPool.AppendCertsFromPEM(data) {
22+
panic("could not append certificate data")
23+
}
24+
}
25+
26+
func Get(url string) (int, string, error) {
27+
client := http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{RootCAs: certPool}}}
28+
resp, err := client.Get(url)
29+
if err != nil {
30+
return 0, "", fmt.Errorf("could not send a request: %w", err)
31+
}
32+
defer resp.Body.Close()
33+
b, err := ioutil.ReadAll(resp.Body)
34+
if err != nil {
35+
return resp.StatusCode, "", fmt.Errorf("could not read response body: %w", err)
36+
}
37+
return resp.StatusCode, string(b), nil
38+
}
39+
40+
func GetAndVerify(t *testing.T, url string, code int, body string) {
41+
gotCode, gotBody, err := Get(url)
42+
if err != nil {
43+
t.Errorf("could not open browser request: %s", err)
44+
return
45+
}
46+
if gotCode != code {
47+
t.Errorf("status wants %d but %d", code, gotCode)
48+
}
49+
if gotBody != body {
50+
t.Errorf("response body did not match: %s", cmp.Diff(gotBody, body))
51+
}
52+
}

e2e_test/context_test.go

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package e2e_test
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"net/http/httptest"
8+
"testing"
9+
"time"
10+
11+
"github.com/int128/oauth2cli"
12+
"github.com/int128/oauth2cli/e2e_test/authserver"
13+
"golang.org/x/oauth2"
14+
)
15+
16+
func TestContextCancelOnWaitingForBrowser(t *testing.T) {
17+
ctx, cancel := context.WithTimeout(context.TODO(), 100*time.Millisecond)
18+
defer cancel()
19+
s := httptest.NewServer(&authserver.Handler{
20+
T: t,
21+
NewAuthorizationResponse: func(r authserver.AuthorizationRequest) string {
22+
return fmt.Sprintf("%s?error=server_error", r.RedirectURI)
23+
},
24+
NewTokenResponse: func(r authserver.TokenRequest) (int, string) {
25+
return 500, "should not reach here"
26+
},
27+
})
28+
defer s.Close()
29+
cfg := oauth2cli.Config{
30+
OAuth2Config: oauth2.Config{
31+
ClientID: "YOUR_CLIENT_ID",
32+
ClientSecret: "YOUR_CLIENT_SECRET",
33+
Scopes: []string{"email", "profile"},
34+
Endpoint: oauth2.Endpoint{
35+
AuthURL: s.URL + "/auth",
36+
TokenURL: s.URL + "/token",
37+
},
38+
},
39+
Logf: t.Logf,
40+
}
41+
_, err := oauth2cli.GetToken(ctx, cfg)
42+
if err == nil {
43+
t.Errorf("GetToken wants error but was nil")
44+
return
45+
}
46+
if !errors.Is(err, context.DeadlineExceeded) {
47+
t.Errorf("err wants DeadlineExceeded but %+v", err)
48+
}
49+
}
50+
51+
func TestContextCancelOnLocalServerReadyChan(t *testing.T) {
52+
ctx, cancel := context.WithTimeout(context.TODO(), 100*time.Millisecond)
53+
defer cancel()
54+
openBrowserCh := make(chan string)
55+
defer close(openBrowserCh)
56+
s := httptest.NewServer(&authserver.Handler{
57+
T: t,
58+
NewAuthorizationResponse: func(r authserver.AuthorizationRequest) string {
59+
return fmt.Sprintf("%s?error=server_error", r.RedirectURI)
60+
},
61+
NewTokenResponse: func(r authserver.TokenRequest) (int, string) {
62+
return 500, "should not reach here"
63+
},
64+
})
65+
defer s.Close()
66+
cfg := oauth2cli.Config{
67+
OAuth2Config: oauth2.Config{
68+
ClientID: "YOUR_CLIENT_ID",
69+
ClientSecret: "YOUR_CLIENT_SECRET",
70+
Scopes: []string{"email", "profile"},
71+
Endpoint: oauth2.Endpoint{
72+
AuthURL: s.URL + "/auth",
73+
TokenURL: s.URL + "/token",
74+
},
75+
},
76+
LocalServerReadyChan: openBrowserCh,
77+
Logf: t.Logf,
78+
}
79+
_, err := oauth2cli.GetToken(ctx, cfg)
80+
if err == nil {
81+
t.Errorf("GetToken wants error but was nil")
82+
return
83+
}
84+
if !errors.Is(err, context.DeadlineExceeded) {
85+
t.Errorf("err wants DeadlineExceeded but %+v", err)
86+
}
87+
}

0 commit comments

Comments
 (0)