Skip to content

Commit

Permalink
feat: login when scopes changed (#261)
Browse files Browse the repository at this point in the history
  • Loading branch information
jfatta authored Apr 23, 2021
1 parent 0ec6677 commit 0f4fee7
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
3 changes: 3 additions & 0 deletions internal/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ var requiredScopes = []string{
"read:client_keys", "read:logs",
}

// RequiredScopes returns the scopes used for login.
func RequiredScopes() []string { return requiredScopes }

// SecretStore provides access to stored sensitive data.
type SecretStore interface {
// Get gets the secret
Expand Down
39 changes: 37 additions & 2 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"os"
"path"
"path/filepath"
"sort"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -43,6 +44,7 @@ type tenant struct {
Name string `json:"name"`
Domain string `json:"domain"`
AccessToken string `json:"access_token,omitempty"`
Scopes []string `json:"scopes,omitempty"`
ExpiresAt time.Time `json:"expires_at"`
Apps map[string]app `json:"apps,omitempty"`
DefaultAppID string `json:"default_app_id,omitempty"`
Expand Down Expand Up @@ -129,8 +131,15 @@ func (c *cli) setup(ctx context.Context) error {
return errUnauthenticated
}

// check if the stored access token is expired:
if isExpired(t.ExpiresAt, accessTokenExpThreshold) {
if scopesChanged(t) {
// required scopes changed,
// a new token is required
err = RunLogin(ctx, c, true)
if err != nil {
return err
}
} else if isExpired(t.ExpiresAt, accessTokenExpThreshold) {
// check if the stored access token is expired:
// use the refresh token to get a new access token:
tr := &auth.TokenRetriever{
Secrets: &auth.Keyring{},
Expand Down Expand Up @@ -179,6 +188,32 @@ func isExpired(t time.Time, threshold time.Duration) bool {
return time.Now().Add(threshold).After(t)
}

// scopesChanged compare the tenant scopes
// with the currently required scopes.
func scopesChanged(t tenant) bool {
want := auth.RequiredScopes()
got := t.Scopes

sort.Strings(want)
sort.Strings(got)

if (want == nil) != (got == nil) {
return true
}

if len(want) != len(got) {
return true
}

for i := range t.Scopes {
if want[i] != got[i] {
return true
}
}

return false
}

// getTenant fetches the default tenant configured (or the tenant specified via
// the --tenant flag).
func (c *cli) getTenant() (tenant, error) {
Expand Down
1 change: 1 addition & 0 deletions internal/cli/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func RunLogin(ctx context.Context, cli *cli, expired bool) error {
ExpiresAt: time.Now().Add(
time.Duration(res.ExpiresIn) * time.Second,
),
Scopes: auth.RequiredScopes(),
})
if err != nil {
return fmt.Errorf("Unexpected error adding tenant to config: %w", err)
Expand Down

0 comments on commit 0f4fee7

Please sign in to comment.