Skip to content

Commit

Permalink
Implement token refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
efirs committed Mar 16, 2022
1 parent 05fe0ef commit 5472e8f
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 41 deletions.
47 changes: 37 additions & 10 deletions client/driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
Expand Down Expand Up @@ -295,25 +296,25 @@ func testTxBasic(t *testing.T, c Driver, mc *mockServer) {
}

func TestGRPCDriver(t *testing.T) {
client, mockServer, cancel := setupGRPCTests(t, &Config{})
client, mockServer, cancel := setupGRPCTests(t, &Config{Token: "aaa"})
defer cancel()
testDriverBasic(t, client, mockServer)
}

func TestHTTPDriver(t *testing.T) {
client, mockServer, cancel := setupHTTPTests(t, &Config{})
client, mockServer, cancel := setupHTTPTests(t, &Config{Token: "aaa"})
defer cancel()
testDriverBasic(t, client, mockServer)
}

func TestTxGRPCDriver(t *testing.T) {
client, mockServer, cancel := setupGRPCTests(t, &Config{})
client, mockServer, cancel := setupGRPCTests(t, &Config{Token: "aaa"})
defer cancel()
testTxBasic(t, client, mockServer)
}

func TestTxHTTPDriver(t *testing.T) {
client, mockServer, cancel := setupHTTPTests(t, &Config{})
client, mockServer, cancel := setupHTTPTests(t, &Config{Token: "aaa"})
defer cancel()
testTxBasic(t, client, mockServer)
}
Expand Down Expand Up @@ -391,6 +392,13 @@ func setupTests(t *testing.T) (*mockServer, func()) {
r.HandleFunc(apiPathPrefix+documentPathPattern, func(w http.ResponseWriter, r *http.Request) {
mux.ServeHTTP(w, r)
})
r.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) {
b, err := ioutil.ReadAll(r.Body)
require.NoError(t, err)
require.Equal(t, []byte(`grant_type=refresh_token&refresh_token=refresh_token_123`), b)
_, err = w.Write([]byte(`access_token=refreshed_token_config_123`))
require.NoError(t, err)
})

var wg sync.WaitGroup

Expand Down Expand Up @@ -438,48 +446,67 @@ func testDriverAuth(t *testing.T, d Driver, mc *mockServer, token string) {

func TestGRPCDriverAuth(t *testing.T) {
t.Run("config", func(t *testing.T) {
client, mockServer, cancel := setupGRPCTests(t, &Config{AuthToken: "token_config_123"})
client, mockServer, cancel := setupGRPCTests(t, &Config{Token: "token_config_123"})
defer cancel()

testDriverAuth(t, client, mockServer, "token_config_123")
})

t.Run("env", func(t *testing.T) {
err := os.Setenv(AUTH_TOKEN_ENV, "token_env_567")
err := os.Setenv(TOKEN_ENV, "token_env_567")
require.NoError(t, err)

client, mockServer, cancel := setupGRPCTests(t, &Config{})
defer cancel()

testDriverAuth(t, client, mockServer, "token_env_567")

err = os.Unsetenv(AUTH_TOKEN_ENV)
err = os.Unsetenv(TOKEN_ENV)
require.NoError(t, err)
})
}

func TestHTTPDriverAuth(t *testing.T) {
t.Run("config", func(t *testing.T) {
client, mockServer, cancel := setupHTTPTests(t, &Config{AuthToken: "token_config_123"})
client, mockServer, cancel := setupHTTPTests(t, &Config{Token: "token_config_123"})
defer cancel()

testDriverAuth(t, client, mockServer, "token_config_123")
})

t.Run("env", func(t *testing.T) {
err := os.Setenv(AUTH_TOKEN_ENV, "token_env_567")
err := os.Setenv(TOKEN_ENV, "token_env_567")
require.NoError(t, err)

client, mockServer, cancel := setupHTTPTests(t, &Config{})
defer cancel()

testDriverAuth(t, client, mockServer, "token_env_567")

err = os.Unsetenv(AUTH_TOKEN_ENV)
err = os.Unsetenv(TOKEN_ENV)
require.NoError(t, err)
})
}

func TestGRPCTokenRefresh(t *testing.T) {
t.Skip("TODO: implement")
client, mockServer, cancel := setupGRPCTests(t, &Config{Token: "token_config_123:refresh_token_123"})
defer cancel()

TOKEN_REFRESH_URL = TestHTTPURL + "/token"

testDriverAuth(t, client, mockServer, "refreshed_token_config_123")
}

func TestHTTPTokenRefresh(t *testing.T) {
TOKEN_REFRESH_URL = TestHTTPURL + "/token"

client, mockServer, cancel := setupHTTPTests(t, &Config{Token: "token_config_123:refresh_token_123"})
defer cancel()

testDriverAuth(t, client, mockServer, "refreshed_token_config_123")
}

var testServerKey = `
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALmad2p/jWwu6Wbc
Expand Down
3 changes: 1 addition & 2 deletions client/driver/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"unsafe"

api "github.com/tigrisdata/tigrisdb-client-go/api/server/v1"
"golang.org/x/oauth2"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/oauth"
Expand All @@ -32,7 +31,7 @@ type grpcDriver struct {
}

func NewGRPCClient(_ context.Context, url string, config *Config) (Driver, error) {
rpcCreds := oauth.NewOauthAccess(&oauth2.Token{AccessToken: getAuthToken(config)})
rpcCreds := oauth.NewOauthAccess(getAuthToken(config))
conn, err := grpc.Dial(url,
grpc.WithTransportCredentials(credentials.NewTLS(config.TLS)),
grpc.WithPerRPCCredentials(rpcCreds),
Expand Down
16 changes: 7 additions & 9 deletions client/driver/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import (
"net/http"
"unsafe"

"github.com/deepmap/oapi-codegen/pkg/securityprovider"
"golang.org/x/oauth2"

userHTTP "github.com/tigrisdata/tigrisdb-client-go/api/client/v1/user"
)

Expand All @@ -30,21 +31,18 @@ type httpDriver struct {
*httpCRUD
}

func NewHTTPClient(_ context.Context, url string, config *Config) (Driver, error) {
auth, err := securityprovider.NewSecurityProviderBearerToken(getAuthToken(config))
if err != nil {
return nil, err
}
func NewHTTPClient(ctx context.Context, url string, config *Config) (Driver, error) {
token := getAuthToken(config)

t := &http.Transport{
TLSClientConfig: config.TLS,
}

hc := http.Client{Transport: t}
ocfg := oauth2.Config{Endpoint: oauth2.Endpoint{TokenURL: TOKEN_REFRESH_URL}}
hc := ocfg.Client(context.WithValue(ctx, oauth2.HTTPClient, &http.Client{Transport: t}), token)

c, err := userHTTP.NewClientWithResponses(url,
userHTTP.WithRequestEditorFn(auth.Intercept),
userHTTP.WithHTTPClient(&hc),
userHTTP.WithHTTPClient(hc),
)
return &driver{driverWithOptions: &httpDriver{httpCRUD: &httpCRUD{api: c}}}, err
}
Expand Down
29 changes: 24 additions & 5 deletions client/driver/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ package driver
import (
"context"
"os"
"strings"
"time"

"golang.org/x/oauth2"
)

type driverWithOptions interface {
Expand Down Expand Up @@ -31,10 +35,25 @@ type txWithOptions interface {
Rollback(ctx context.Context) error
}

func getAuthToken(config *Config) string {
token := config.AuthToken
if os.Getenv(AUTH_TOKEN_ENV) != "" {
token = os.Getenv(AUTH_TOKEN_ENV)
func getAuthToken(config *Config) *oauth2.Token {
token := config.Token
if os.Getenv(TOKEN_ENV) != "" {
token = os.Getenv(TOKEN_ENV)
}

parts := strings.Split(token, ":")

t := oauth2.Token{}

if len(parts) > 0 {
t.AccessToken = parts[0]
}

if len(parts) > 1 {
t.RefreshToken = parts[1]
// So as we have refresh token, just disregard current access token and refresh immediately
t.Expiry = time.Now()
}
return token

return &t
}
16 changes: 10 additions & 6 deletions client/driver/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ import (
)

const (
GRPC = iota
HTTP = iota
DefaultProtocol = GRPC
GRPC = iota
HTTP = iota

AUTH_TOKEN_ENV = "TIGRISDB_AUTH_TOKEN"
TOKEN_ENV = "TIGRISDB_TOKEN"
)

var (
DefaultProtocol = GRPC
TOKEN_REFRESH_URL = "https://tigrisdata-dev.us.auth0.com/oauth/token"
)

type Document json.RawMessage
Expand All @@ -36,6 +40,6 @@ type UpdateResponse *api.UpdateResponse
type DeleteResponse *api.DeleteResponse

type Config struct {
AuthToken string `json:"auth_token"`
TLS *tls.Config `json:"tls"`
TLS *tls.Config `json:"tls,omitempty"`
Token string `json:",omitempty"`
}
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e // indirect
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
golang.org/x/text v0.3.7 // indirect
Expand Down
8 changes: 0 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo/v4 v4.6.3 h1:VhPuIZYxsbPmo4m9KAkMU/el2442eB7EBFFhNTTT9ac=
github.com/labstack/echo/v4 v4.6.3/go.mod h1:Hk5OiHj0kDqmFq7aHe7eDqI7CUhuCrfpupQtLGGLm7A=
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
Expand All @@ -204,10 +202,8 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
Expand Down Expand Up @@ -242,9 +238,7 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand All @@ -269,8 +263,6 @@ golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU=
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down

0 comments on commit 5472e8f

Please sign in to comment.