diff --git a/go.mod b/go.mod
index c99919b..ddd8e29 100644
--- a/go.mod
+++ b/go.mod
@@ -3,9 +3,9 @@ module source.toby3d.me/website/oauth
go 1.16
require (
- github.com/brianvoe/gofakeit v3.18.0+incompatible
github.com/fasthttp/router v1.4.1
github.com/goccy/go-json v0.7.6
+ github.com/google/go-cmp v0.5.6 // indirect
github.com/pkg/errors v0.9.1
github.com/spf13/viper v1.8.1
github.com/stretchr/testify v1.7.0
@@ -15,6 +15,7 @@ require (
go.etcd.io/bbolt v1.3.6
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf // indirect
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f
+ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
google.golang.org/protobuf v1.27.1 // indirect
willnorris.com/go/microformats v1.1.1
diff --git a/go.sum b/go.sum
index 266b4a9..9d5db08 100644
--- a/go.sum
+++ b/go.sum
@@ -50,8 +50,6 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
-github.com/brianvoe/gofakeit v3.18.0+incompatible h1:wDOmHc9DLG4nRjUVVaxA+CEglKOW72Y5+4WNxUIkjM8=
-github.com/brianvoe/gofakeit v3.18.0+incompatible/go.mod h1:kfwdRA90vvNhPutZWfH7WPaDzUjz+CZFqG+rPkOjGOc=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
@@ -128,8 +126,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -440,8 +439,9 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/internal/client/repository/http/http_client_test.go b/internal/client/repository/http/http_client_test.go
index ee5ee8f..d7efd64 100644
--- a/internal/client/repository/http/http_client_test.go
+++ b/internal/client/repository/http/http_client_test.go
@@ -2,80 +2,46 @@ package http_test
import (
"context"
- "net"
"testing"
- "github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
http "github.com/valyala/fasthttp"
- httputil "github.com/valyala/fasthttp/fasthttputil"
repository "source.toby3d.me/website/oauth/internal/client/repository/http"
"source.toby3d.me/website/oauth/internal/common"
"source.toby3d.me/website/oauth/internal/domain"
+ "source.toby3d.me/website/oauth/internal/util"
)
-const testBody string = `
-
-
-
-
-
- Example App
-
-
-
-
-
-
-`
-
func TestGet(t *testing.T) {
t.Parallel()
- ln := httputil.NewInmemoryListener()
- u := http.AcquireURI()
- u.SetScheme("http")
- u.SetHost(ln.Addr().String())
-
- t.Cleanup(func() {
- http.ReleaseURI(u)
- assert.NoError(t, ln.Close())
+ httpClient, _, cleanup := util.TestServe(t, func(ctx *http.RequestCtx) {
+ ctx.SuccessString(common.MIMETextHTML, `
+
+
+
+
+
+ Example App
+
+
+
+
+
+
+ `)
+ ctx.Response.Header.Set(http.HeaderLink, `; rel="redirect_uri">`)
})
+ t.Cleanup(cleanup)
- go func(t *testing.T) {
- t.Helper()
- require.NoError(t, http.Serve(ln, func(ctx *http.RequestCtx) {
- ctx.SuccessString(common.MIMETextHTML, testBody)
- ctx.Response.Header.Set(http.HeaderLink,
- `; rel="redirect_uri">`)
- }))
- }(t)
+ client := domain.TestClient(t)
- client := new(http.Client)
- client.Dial = func(addr string) (net.Conn, error) {
- conn, err := ln.Dial()
- if err != nil {
- return nil, errors.Wrap(err, "failed to dial the address")
- }
-
- return conn, nil
- }
-
- result, err := repository.NewHTTPClientRepository(client).Get(context.TODO(), u.String())
+ result, err := repository.NewHTTPClientRepository(httpClient).Get(context.TODO(), client.ID)
require.NoError(t, err)
- assert.Equal(t, &domain.Client{
- ID: u.String(),
- Name: "Example App",
- Logo: u.String() + "logo.png",
- URL: u.String(),
- RedirectURI: []string{
- "https://app.example.com/redirect",
- u.String() + "redirect",
- },
- }, result)
+ assert.Equal(t, client, result)
}
diff --git a/internal/domain/client.go b/internal/domain/client.go
index 21b9741..224a56a 100644
--- a/internal/domain/client.go
+++ b/internal/domain/client.go
@@ -21,13 +21,13 @@ func TestClient(tb testing.TB) *Client {
tb.Helper()
return &Client{
- ID: "http://127.0.0.1:2368/",
+ ID: "http://app.example.com/",
Name: "Example App",
- Logo: "http://127.0.0.1:2368/logo.png",
- URL: "http://127.0.0.1:2368/",
+ Logo: "http://app.example.com/logo.png",
+ URL: "http://app.example.com/",
RedirectURI: []string{
- "https://app.example.com/redirect",
- "http://127.0.0.1:2368/redirect",
+ "http://app.example.com/redirect",
+ "http://app.example.com/redirect",
},
}
}
diff --git a/internal/domain/login.go b/internal/domain/login.go
index 6893dbd..fab0c09 100644
--- a/internal/domain/login.go
+++ b/internal/domain/login.go
@@ -23,13 +23,13 @@ func TestLogin(tb testing.TB) *Login {
tb.Helper()
return &Login{
- ClientID: "https://app.example.com/",
+ ClientID: "http://app.example.com/",
Code: random.New().String(16),
CodeChallenge: "OfYAxt8zU2dAPDWQxTAUIteRzMsoj9QBdMIVEDOErUo",
CodeChallengeMethod: PKCEMethodS256,
CodeVerifier: "a6128783714cfda1d388e2e98b6ae8221ac31aca31959e59512c59f5",
- Me: "https://user.example.net/",
- RedirectURI: "https://app.example.com/redirect",
+ Me: "http://user.example.net/",
+ RedirectURI: "http://app.example.com/redirect",
Scopes: []string{"profile", "create", "update", "delete"},
State: "1234567890",
}
diff --git a/internal/domain/profile.go b/internal/domain/profile.go
index 00d9877..142432a 100644
--- a/internal/domain/profile.go
+++ b/internal/domain/profile.go
@@ -14,8 +14,8 @@ func TestProfile(tb testing.TB) *Profile {
return &Profile{
Name: "Example User",
- URL: "https://user.example.net/",
- Photo: "https://user.example.net/photo.jpg",
+ URL: "http://user.example.net/",
+ Photo: "http://user.example.net/photo.jpg",
Email: "user@example.net",
}
}
diff --git a/internal/domain/token.go b/internal/domain/token.go
index 66195a5..9de9b58 100644
--- a/internal/domain/token.go
+++ b/internal/domain/token.go
@@ -28,8 +28,8 @@ func TestToken(tb testing.TB) *Token {
return &Token{
AccessToken: random.New().String(32),
- ClientID: "https://app.example.com/",
- Me: "https://user.example.net/",
+ ClientID: "http://app.example.com/",
+ Me: "http://user.example.net/",
Profile: TestProfile(tb),
Scopes: []string{"create", "update", "delete"},
Type: "Bearer",
diff --git a/internal/token/delivery/http/token_http_test.go b/internal/token/delivery/http/token_http_test.go
index d4e7cc6..404aac6 100644
--- a/internal/token/delivery/http/token_http_test.go
+++ b/internal/token/delivery/http/token_http_test.go
@@ -22,24 +22,26 @@ import (
func TestVerification(t *testing.T) {
t.Parallel()
- store := new(sync.Map)
- repo := repository.NewMemoryTokenRepository(store)
+ repo := repository.NewMemoryTokenRepository(new(sync.Map))
accessToken := domain.TestToken(t)
require.NoError(t, repo.Create(context.TODO(), accessToken))
+ client, _, cleanup := util.TestServe(t, delivery.NewRequestHandler(usecase.NewTokenUseCase(repo)).Read)
+ t.Cleanup(cleanup)
+
req := http.AcquireRequest()
defer http.ReleaseRequest(req)
-
req.Header.SetMethod(http.MethodGet)
- req.SetRequestURI("http://localhost/token")
+ req.SetRequestURI("http://app.example.com/token")
req.Header.Set(http.HeaderAccept, common.MIMEApplicationJSON)
req.Header.Set(http.HeaderAuthorization, "Bearer "+accessToken.AccessToken)
resp := http.AcquireResponse()
defer http.ReleaseResponse(resp)
- require.NoError(t, util.Serve(delivery.NewRequestHandler(usecase.NewTokenUseCase(repo)).Read, req, resp))
+ require.NoError(t, client.Do(req, resp))
+
assert.Equal(t, http.StatusOK, resp.StatusCode())
token := new(delivery.VerificationResponse)
@@ -54,17 +56,18 @@ func TestVerification(t *testing.T) {
func TestRevocation(t *testing.T) {
t.Parallel()
- store := new(sync.Map)
- repo := repository.NewMemoryTokenRepository(store)
+ repo := repository.NewMemoryTokenRepository(new(sync.Map))
accessToken := domain.TestToken(t)
require.NoError(t, repo.Create(context.TODO(), domain.TestToken(t)))
+ client, _, cleanup := util.TestServe(t, delivery.NewRequestHandler(usecase.NewTokenUseCase(repo)).Update)
+ t.Cleanup(cleanup)
+
req := http.AcquireRequest()
defer http.ReleaseRequest(req)
-
req.Header.SetMethod(http.MethodPost)
- req.SetRequestURI("http://localhost/token")
+ req.SetRequestURI("http://app.example.com/token")
req.Header.SetContentType(common.MIMEApplicationXWWWFormUrlencoded)
req.Header.Set(http.HeaderAccept, common.MIMEApplicationJSON)
req.PostArgs().Set("action", "revoke")
@@ -73,7 +76,8 @@ func TestRevocation(t *testing.T) {
resp := http.AcquireResponse()
defer http.ReleaseResponse(resp)
- require.NoError(t, util.Serve(delivery.NewRequestHandler(usecase.NewTokenUseCase(repo)).Update, req, resp))
+ require.NoError(t, client.Do(req, resp))
+
assert.Equal(t, http.StatusOK, resp.StatusCode())
assert.Equal(t, `{}`, strings.TrimSpace(string(resp.Body())))
diff --git a/internal/token/repository/bolt/bolt_token_test.go b/internal/token/repository/bolt/bolt_token_test.go
index c539ad7..acb1aec 100644
--- a/internal/token/repository/bolt/bolt_token_test.go
+++ b/internal/token/repository/bolt/bolt_token_test.go
@@ -6,6 +6,7 @@ import (
"log"
"os"
"path/filepath"
+ "strings"
"testing"
json "github.com/goccy/go-json"
@@ -49,73 +50,60 @@ func TestMain(m *testing.M) {
func TestGet(t *testing.T) {
t.Parallel()
- accessToken := random.New().String(32)
+ accessToken := domain.TestToken(t)
+ accessToken.Profile = nil
t.Cleanup(func() {
_ = db.Update(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
- return tx.Bucket(bolt.Token{}.Bucket()).Delete([]byte(accessToken))
+ return tx.Bucket(bolt.Token{}.Bucket()).Delete([]byte(accessToken.AccessToken))
})
})
src, err := json.Marshal(&bolt.Token{
- AccessToken: accessToken,
- ClientID: "https://app.example.com/",
- Me: "https://toby3d.me/",
- Scope: "read update delete",
- Type: "Bearer",
+ AccessToken: accessToken.AccessToken,
+ ClientID: accessToken.ClientID,
+ Me: accessToken.Me,
+ Scope: strings.Join(accessToken.Scopes, " "),
+ Type: accessToken.Type,
})
require.NoError(t, err)
require.NoError(t, db.Update(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
- return tx.Bucket(bolt.Token{}.Bucket()).Put([]byte(accessToken), src)
+ return tx.Bucket(bolt.Token{}.Bucket()).Put([]byte(accessToken.AccessToken), src)
}))
- tkn, err := repo.Get(context.TODO(), accessToken)
+ tkn, err := repo.Get(context.TODO(), accessToken.AccessToken)
require.NoError(t, err)
- assert.Equal(t, &domain.Token{
- AccessToken: accessToken,
- ClientID: "https://app.example.com/",
- Me: "https://toby3d.me/",
- Scopes: []string{"read", "update", "delete"},
- Type: "Bearer",
- Profile: nil,
- }, tkn)
+ assert.Equal(t, accessToken, tkn)
}
func TestCreate(t *testing.T) {
t.Parallel()
- accessToken := random.New().String(32)
+ accessToken := domain.TestToken(t)
+ accessToken.Profile = nil
t.Cleanup(func() {
_ = db.Update(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
- return tx.Bucket(bolt.Token{}.Bucket()).Delete([]byte(accessToken))
+ return tx.Bucket(bolt.Token{}.Bucket()).Delete([]byte(accessToken.AccessToken))
})
})
- tkn := &domain.Token{
- AccessToken: accessToken,
- ClientID: "https://app.example.com/",
- Me: "https://toby3d.me/",
- Scopes: []string{"read", "update", "delete"},
- Type: "Bearer",
- Profile: nil,
- }
+ require.NoError(t, repo.Create(context.TODO(), accessToken))
- require.NoError(t, repo.Create(context.TODO(), tkn))
-
- result := domain.NewToken()
+ result := new(domain.Token)
require.NoError(t, db.View(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
- return new(bolt.Token).Bind(tx.Bucket(bolt.Token{}.Bucket()).Get([]byte(tkn.AccessToken)), result)
+ return new(bolt.Token).Bind(tx.Bucket(bolt.Token{}.Bucket()).Get([]byte(accessToken.AccessToken)),
+ result)
}))
- assert.Equal(t, tkn, result)
- assert.EqualError(t, repo.Create(context.TODO(), tkn), token.ErrExist.Error())
+ assert.Equal(t, accessToken, result)
+ assert.EqualError(t, repo.Create(context.TODO(), accessToken), token.ErrExist.Error())
}
func TestUpdate(t *testing.T) {
diff --git a/internal/util/util.go b/internal/util/util.go
index 6e4c467..11be78a 100644
--- a/internal/util/util.go
+++ b/internal/util/util.go
@@ -2,26 +2,41 @@ package util
import (
"net"
+ "testing"
+ "github.com/pkg/errors"
+ "github.com/stretchr/testify/assert"
http "github.com/valyala/fasthttp"
httputil "github.com/valyala/fasthttp/fasthttputil"
)
-func Serve(handler http.RequestHandler, req *http.Request, res *http.Response) error {
+//nolint: exhaustivestruct
+func TestServe(tb testing.TB, handler http.RequestHandler) (*http.Client, *http.Server, func()) {
+ tb.Helper()
+
ln := httputil.NewInmemoryListener()
- defer ln.Close()
+ server := &http.Server{
+ Handler: handler,
+ DisableKeepalive: true,
+ CloseOnShutdown: true,
+ }
go func() {
- if err := http.Serve(ln, handler); err != nil {
- panic(err)
- }
+ assert.NoError(tb, server.Serve(ln))
}()
- client := http.Client{
- Dial: func(addr string) (net.Conn, error) {
- return ln.Dial()
+ client := &http.Client{
+ Dial: func(_ string) (net.Conn, error) {
+ conn, err := ln.Dial()
+ if err != nil {
+ return nil, errors.Wrap(err, "cannot dial to address")
+ }
+
+ return conn, nil
},
}
- return client.Do(req, res)
+ return client, server, func() {
+ assert.NoError(tb, server.Shutdown())
+ }
}