Skip to content

Commit

Permalink
Add support for ADC using voucher_client (#53)
Browse files Browse the repository at this point in the history
* Add support of auth using ADC
* fix lint + cleanup
* Use passed in context
* Remove unused audience
* Update readme
  • Loading branch information
rxbchen authored Dec 16, 2021
1 parent 3536639 commit 509de80
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 8 deletions.
6 changes: 6 additions & 0 deletions v2/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ 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
func (c *Client) SetBasicAuth(username, password string) {
c.username = username
Expand Down
14 changes: 7 additions & 7 deletions v2/cmd/voucher_client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ The configuration for Voucher Client can be written as a toml, json, or yaml fil

Below are the configuration options for Voucher Client:

| Key | Description |
| :---------- | :----------------------------------------------------------------------------------------- |
| `server` | The Voucher server to connect to. |
| `timeout` | The number of seconds to wait before failing (defaults to 240). |
| `username` | Username to authenticate against Voucher with. (When auth = basic) |
| `password` | Password to authenticate against Voucher with. (When auth = basic) |
| `auth` | The method to authenticate against Voucher with. (defaults to basic) |
| Key | Description |
| :---------- | :------------------------------------------------------------------------------------------------------------------------------ |
| `server` | The Voucher server to connect to. |
| `timeout` | The number of seconds to wait before failing (defaults to 240). |
| `username` | Username to authenticate against Voucher with. (When auth = basic) |
| `password` | Password to authenticate against Voucher with. (When auth = basic) |
| `auth` | The method to authenticate against Voucher with. (defaults to basic). Possible values: basic, idtoken, default-access-token |

Configuration options can be overridden at runtime by setting the appropriate flag. For example, if you set the "port" flag when running `voucher_server`, that value will override whatever is in the configuration.

Expand Down
6 changes: 6 additions & 0 deletions v2/cmd/voucher_client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ func getVoucherClient() (voucher.Interface, error) {
newClient.SetBasicAuth(defaultConfig.Username, defaultConfig.Password)
}
return newClient, err
case "default-access-token":
newClient, err := NewAuthClientWithToken(context.Background(), defaultConfig.Server)
if err != nil {
return nil, err
}
return newClient, err
default:
return nil, fmt.Errorf("invalid auth value: %q", defaultConfig.Auth)
}
Expand Down
71 changes: 71 additions & 0 deletions v2/cmd/voucher_client/defaultclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package main

import (
"context"
"fmt"
"net/http"

"github.com/grafeas/voucher/v2/client"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/option"
htransport "google.golang.org/api/transport/http"
)

const idTokenKey = "id_token"

// idTokenSource is an oauth2.TokenSource that wraps another
// It takes the id_token from TokenSource and passes that on as a bearer token
// Implementation from: https://github.com/googleapis/google-api-go-client/issues/873
type idTokenSource struct {
TokenSource oauth2.TokenSource
}

func (s *idTokenSource) Token() (*oauth2.Token, error) {
token, err := s.TokenSource.Token()
if err != nil {
return nil, err
}

idToken, ok := token.Extra(idTokenKey).(string)
if !ok {
return nil, fmt.Errorf("token did not contain an id_token")
}

return &oauth2.Token{
AccessToken: idToken,
TokenType: "Bearer",
Expiry: token.Expiry,
}, 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) {
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))
if err != nil {
return nil, fmt.Errorf("error creating client: %w", err)
}
return &http.Client{Transport: t}, nil
}
2 changes: 1 addition & 1 deletion v2/cmd/voucher_client/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func init() {
viper.BindPFlag("timeout", rootCmd.Flags().Lookup("timeout"))
rootCmd.Flags().StringVarP(&defaultConfig.Check, "check", "c", "all", "the name of the checks to run against Voucher with")
viper.BindPFlag("check", rootCmd.Flags().Lookup("check"))
rootCmd.Flags().StringVarP(&defaultConfig.Auth, "auth", "a", "basic", "the method to authenticate against Voucher with. Supported types: basic, idtoken")
rootCmd.Flags().StringVarP(&defaultConfig.Auth, "auth", "a", "basic", "the method to authenticate against Voucher with. Supported types: basic, idtoken, default-access-token")
viper.BindPFlag("auth", rootCmd.Flags().Lookup("auth"))
}

Expand Down

0 comments on commit 509de80

Please sign in to comment.