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

feat(tokens): add bearer token auth support #352

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
28 changes: 19 additions & 9 deletions examples/upcloud-cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import (
"github.com/davecgh/go-spew/spew"
)

var username, password string
var username, password, token string

func init() {
flag.StringVar(&username, "username", "", "UpCloud username")
flag.StringVar(&password, "password", "", "UpCloud password")
flag.StringVar(&password, "token", "", "UpCloud API token")
}

func main() {
Expand All @@ -34,21 +35,30 @@ func run() int {
if username == "" {
username = os.Getenv("UPCLOUD_USERNAME")
}
if token == "" {
token = os.Getenv("UPCLOUD_TOKEN")
}

command := flag.Arg(0)

if len(username) == 0 {
fmt.Fprintln(os.Stderr, "Username must be specified")
return 1
}
var authCfg client.ConfigFn
if len(token) > 0 {
authCfg = client.WithBearerAuth(token)
} else {
if len(username) == 0 {
fmt.Fprintln(os.Stderr, "Username or token must be specified")
return 1
}

if len(password) == 0 {
fmt.Fprintln(os.Stderr, "Password must be specified")
return 2
if len(password) == 0 {
fmt.Fprintln(os.Stderr, "Password or token must be specified")
return 2
}
authCfg = client.WithBasicAuth(username, password)
}

fmt.Println("Creating new client")
c := client.New(username, password)
c := client.New("", "", authCfg)
s := service.New(c)

switch command {
Expand Down
27 changes: 26 additions & 1 deletion upcloud/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type LogFn func(context.Context, string, ...any)
type config struct {
username string
password string
token string
baseURL string
httpClient *http.Client
logger LogFn
Expand Down Expand Up @@ -152,7 +153,11 @@ func (c *Client) addDefaultHeaders(r *http.Request) {
r.Header.Set(userAgent, c.UserAgent)
}
if _, ok := r.Header[authorization]; !ok && strings.HasPrefix(r.URL.String(), c.config.baseURL) {
r.SetBasicAuth(c.config.username, c.config.password)
if c.config.token != "" {
r.Header.Set(authorization, "Bearer "+c.config.token)
} else {
r.SetBasicAuth(c.config.username, c.config.password)
}
}
}

Expand Down Expand Up @@ -248,6 +253,24 @@ func WithHTTPClient(httpClient *http.Client) ConfigFn {
}
}

// WithBasicAuth configures the client to use basic auth credentials for authentication
func WithBasicAuth(username, password string) ConfigFn {
return func(c *config) {
c.username = username
c.password = password
c.token = ""
}
}

// WithBearerAuth configures the client to use bearer token for authentication
func WithBearerAuth(apiToken string) ConfigFn {
return func(c *config) {
c.token = apiToken
c.username = ""
c.password = ""
}
}

// WithTimeout modifies the client's httpClient timeout
func WithTimeout(timeout time.Duration) ConfigFn {
return func(c *config) {
Expand All @@ -264,6 +287,8 @@ func WithLogger(logger LogFn) ConfigFn {

// New creates and returns a new client configured with the specified user and password and optional
// config functions.
// TODO: we should get rid of username, password here, but it's a breaking change. Credentials can be now set with
// configurators client.WithBasicAuth("user", "pass") or client.WithBearerAuth("ucat_token")
func New(username, password string, c ...ConfigFn) *Client {
config := config{
username: username,
Expand Down