Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

client: functional opts for constructor #54

Merged
merged 7 commits into from
Dec 21, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 32 additions & 14 deletions v2/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,37 @@ const DefaultUserAgent = "voucher-client/2"

// NewClient creates a new Client set to connect to the passed
// hostname.
func NewClient(voucherURL string) (*Client, error) {
return newClient(voucherURL, &http.Client{})
func NewClient(voucherURL string, opts ...Option) (*Client, error) {
thepwagner marked this conversation as resolved.
Show resolved Hide resolved
return newClient(voucherURL, &http.Client{}, opts...)
}

type Option func(*Client)

// WithHTTPClient sets the http.Client to use for the client.
func WithHTTPClient(httpClient *http.Client) Option {
return func(c *Client) {
c.httpClient = httpClient
}
}

// WithUserAgent sets the User-Agent header for the client.
func WithUserAgent(userAgent string) Option {
return func(c *Client) {
c.userAgent = userAgent
}
}

// WithBasicAuth sets the username and password to use for the client.
func WithBasicAuth(username, password string) Option {
return func(c *Client) {
c.username = username
c.password = password
}
}

// NewAuthClient creates a new auth Client set to connect to the passed
// hostname using tokens.
// Deprecated: use the WithHTTPClient option instead
thepwagner marked this conversation as resolved.
Show resolved Hide resolved
func NewAuthClient(voucherURL string) (*Client, error) {
authClient, err := idtoken.NewClient(context.Background(), voucherURL)
if err != nil {
Expand All @@ -45,23 +70,13 @@ func NewAuthClient(voucherURL string) (*Client, error) {
return newClient(voucherURL, authClient)
}

// NewCustomClient creates a new Client set to connect to passed
// hostname using a passed http client
func NewCustomClient(voucherURL string, client *http.Client) (*Client, error) {
return newClient(voucherURL, client)
}

// SetBasicAuth adds the username and password to the Client struct
// Deprecated: use the WithBasicAuth option instead
func (c *Client) SetBasicAuth(username, password string) {
c.username = username
c.password = password
}

// SetUserAgent customizes the user agent used by the client
func (c *Client) SetUserAgent(userAgent string) {
c.userAgent = userAgent
}

// CopyURL returns a copy of this client's URL
func (c *Client) CopyURL() *url.URL {
urlCopy := (*c.url)
Expand Down Expand Up @@ -117,7 +132,7 @@ func (c *Client) doVoucherRequest(ctx context.Context, url string, image referen
return &voucherResp, nil
}

func newClient(voucherURL string, httpClient *http.Client) (*Client, error) {
func newClient(voucherURL string, httpClient *http.Client, options ...Option) (*Client, error) {
if voucherURL == "" {
return nil, errNoHost
}
Expand All @@ -135,5 +150,8 @@ func newClient(voucherURL string, httpClient *http.Client) (*Client, error) {
httpClient: httpClient,
userAgent: DefaultUserAgent,
}
for _, opt := range options {
opt(client)
}
return client, nil
}
3 changes: 1 addition & 2 deletions v2/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ func TestVoucher_CustomUserAgent(t *testing.T) {
srv := httptest.NewServer(v)
defer srv.Close()

c, err := client.NewClient(srv.URL)
c.SetUserAgent(customUserAgent)
c, err := client.NewClient(srv.URL, client.WithUserAgent(customUserAgent))
require.NoError(t, err)
res, err := c.Check(context.Background(), "diy", canonical(t, image))
require.NoError(t, err)
Expand Down
28 changes: 17 additions & 11 deletions v2/cmd/voucher_client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

voucher "github.com/grafeas/voucher/v2"
"github.com/grafeas/voucher/v2/client"
"google.golang.org/api/idtoken"
)

type config struct {
Expand All @@ -26,30 +27,35 @@ func getCheck() string {
}

func getVoucherClient() (voucher.Interface, error) {
var newClient *client.Client
var err error
options := []client.Option{
client.WithUserAgent(fmt.Sprintf("voucher-client/%s", version)),
}
switch strings.ToLower(defaultConfig.Auth) {
case "idtoken":
newClient, err = client.NewAuthClient(defaultConfig.Server)
if err != nil {
return nil, err
}
case "basic":
newClient, err = client.NewClient(defaultConfig.Server)
options = append(options, client.WithBasicAuth(defaultConfig.Username, defaultConfig.Password))

case "idtoken":
idClient, err := idtoken.NewClient(context.Background(), defaultConfig.Server)
if err != nil {
return nil, err
}
newClient.SetBasicAuth(defaultConfig.Username, defaultConfig.Password)
options = append(options, client.WithHTTPClient(idClient))

case "default-access-token":
newClient, err = NewAuthClientWithToken(context.Background(), defaultConfig.Server)
tokenClient, err := getDefaultTokenSourceClient(context.Background())
if err != nil {
return nil, err
}
options = append(options, client.WithHTTPClient(tokenClient))

default:
return nil, fmt.Errorf("invalid auth value: %q", defaultConfig.Auth)
}

newClient.SetUserAgent(fmt.Sprintf("voucher-client/%s", version))
newClient, err := client.NewClient(defaultConfig.Server, options...)
if err != nil {
return nil, err
}
return newClient, nil
}

Expand Down
24 changes: 3 additions & 21 deletions v2/cmd/voucher_client/defaultclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"net/http"

"github.com/grafeas/voucher/v2/client"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/option"
Expand Down Expand Up @@ -39,33 +38,16 @@ func (s *idTokenSource) Token() (*oauth2.Token, error) {
}, nil
}

// NewAuthClientWithToken creates an auth client using the token created from ADC
func NewAuthClientWithToken(ctx context.Context, voucherURL string) (*client.Client, error) {
ts, err := getDefaultTokenSource(ctx)
if err != nil {
return nil, err
}

c, err := newHTTPClient(ctx, ts)
if err != nil {
return nil, err
}
return client.NewCustomClient(voucherURL, c)
}

func getDefaultTokenSource(ctx context.Context) (oauth2.TokenSource, error) {
func getDefaultTokenSourceClient(ctx context.Context) (*http.Client, error) {
src, err := google.DefaultTokenSource(ctx)
if err != nil {
return nil, fmt.Errorf("error creating token source: %w", err)
}
ts := oauth2.ReuseTokenSource(nil, &idTokenSource{TokenSource: src})
return ts, nil
}

func newHTTPClient(ctx context.Context, ts oauth2.TokenSource) (*http.Client, error) {
t, err := htransport.NewTransport(ctx, http.DefaultTransport, option.WithTokenSource(ts))
transport, err := htransport.NewTransport(ctx, http.DefaultTransport, option.WithTokenSource(ts))
if err != nil {
return nil, fmt.Errorf("error creating client: %w", err)
}
return &http.Client{Transport: t}, nil
return &http.Client{Transport: transport}, nil
}