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

Activate auth command #275

Merged
merged 5 commits into from
Nov 12, 2024
Merged
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
7 changes: 3 additions & 4 deletions internal/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"strings"

"github.com/debricked/cli/internal/client"
"github.com/golang-jwt/jwt"
"github.com/zalando/go-keyring"
"golang.org/x/oauth2"
Expand Down Expand Up @@ -50,7 +49,7 @@ func (dsc DebrickedSecretClient) Delete(service string) error {
return keyring.Delete(service, dsc.User)
}

func NewDebrickedAuthenticator(client client.IDebClient) Authenticator {
func NewDebrickedAuthenticator(host string) Authenticator {
return Authenticator{
SecretClient: DebrickedSecretClient{
User: "DebrickedCLI",
Expand All @@ -59,8 +58,8 @@ func NewDebrickedAuthenticator(client client.IDebClient) Authenticator {
ClientID: "01919462-7d6e-78e8-aa24-ba779213c90f",
ClientSecret: "",
Endpoint: oauth2.Endpoint{
AuthURL: client.Host() + "/app/oauth/authorize",
TokenURL: client.Host() + "/app/oauth/token",
AuthURL: host + "/app/oauth/authorize",
TokenURL: host + "/app/oauth/token",
},
RedirectURL: "http://localhost:9096/callback",
Scopes: []string{"select", "profile", "basicRepo", "fullApi"},
Expand Down
3 changes: 1 addition & 2 deletions internal/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"testing"

"github.com/debricked/cli/internal/auth/testdata"
clientTestdata "github.com/debricked/cli/internal/client/testdata"
"github.com/stretchr/testify/assert"
"github.com/zalando/go-keyring"
"golang.org/x/oauth2"
Expand All @@ -15,7 +14,7 @@ const windowsOS = "windows"
const macOS = "darwin"

func TestNewAuthenticator(t *testing.T) {
res := NewDebrickedAuthenticator(clientTestdata.NewDebClientMock())
res := NewDebrickedAuthenticator("")
assert.NotNil(t, res)
}

Expand Down
34 changes: 16 additions & 18 deletions internal/client/deb_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"net/http"
"os"

"github.com/debricked/cli/internal/auth"

"github.com/fatih/color"
)

Expand All @@ -23,13 +25,15 @@ type IDebClient interface {
SetAccessToken(accessToken *string)
IsEnterpriseCustomer(silent bool) bool
Host() string
Authenticator() auth.IAuthenticator
}

type DebClient struct {
host *string
httpClient IClient
accessToken *string
jwtToken string
host *string
httpClient IClient
accessToken *string
jwtToken string
authenticator auth.IAuthenticator
}

func NewDebClient(accessToken *string, httpClient IClient) *DebClient {
Expand All @@ -39,10 +43,11 @@ func NewDebClient(accessToken *string, httpClient IClient) *DebClient {
}

return &DebClient{
host: &host,
httpClient: httpClient,
accessToken: initAccessToken(accessToken),
jwtToken: "",
host: &host,
httpClient: httpClient,
accessToken: accessToken,
jwtToken: "",
authenticator: auth.NewDebrickedAuthenticator(host),
}
}

Expand All @@ -63,18 +68,11 @@ func (debClient *DebClient) Get(uri string, format string) (*http.Response, erro
}

func (debClient *DebClient) SetAccessToken(accessToken *string) {
debClient.accessToken = initAccessToken(accessToken)
debClient.accessToken = accessToken
}

func initAccessToken(accessToken *string) *string {
if accessToken == nil {
accessToken = new(string)
}
if len(*accessToken) == 0 {
*accessToken = os.Getenv("DEBRICKED_TOKEN")
}

return accessToken
func (debClient *DebClient) Authenticator() auth.IAuthenticator {
return debClient.authenticator
}

type BillingPlan struct {
Expand Down
59 changes: 29 additions & 30 deletions internal/client/deb_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"
"testing"

testdataAuth "github.com/debricked/cli/internal/auth/testdata"
testdataClient "github.com/debricked/cli/internal/client/testdata/client"
"github.com/stretchr/testify/assert"
)
Expand All @@ -33,35 +34,6 @@ func TestNewDebClientWithNilToken(t *testing.T) {
if *debClient.host != DefaultDebrickedUri {
t.Error("failed to assert that host was set properly")
}
if debClient.accessToken == nil {
t.Error("failed to assert that access token was set properly")
}
}

const debrickedTknEnvVar = "DEBRICKED_TOKEN"

func TestNewDebClientWithTokenEnvVariable(t *testing.T) {
envVarTkn := "env-tkn"
oldEnvValue := os.Getenv(debrickedTknEnvVar)
err := os.Setenv(debrickedTknEnvVar, "env-tkn")
if err != nil {
t.Fatalf("failed to set env var %s", debrickedTknEnvVar)
}
defer func(key, value string) {
err := os.Setenv(key, value)
if err != nil {
t.Fatalf("failed to reset env var %s", debrickedTknEnvVar)
}
}(debrickedTknEnvVar, oldEnvValue)

accessToken := ""
debClient := NewDebClient(&accessToken, nil)
if *debClient.host != DefaultDebrickedUri {
t.Error("failed to assert that host was set properly")
}
if *debClient.accessToken != envVarTkn {
t.Errorf("failed to assert that access token was set to %s. Got %s", envVarTkn, *debClient.accessToken)
}
}

func TestNewDebClientWithWithURI(t *testing.T) {
Expand Down Expand Up @@ -95,6 +67,16 @@ func TestClientUnauthorized(t *testing.T) {
}
}

func TestHost(t *testing.T) {
debClient := NewDebClient(&tkn, nil)
assert.Equal(t, *debClient.host, debClient.Host())
}

func TestAuthenticator(t *testing.T) {
debClient := NewDebClient(&tkn, nil)
assert.NotNil(t, debClient.Authenticator())
}

func TestGet(t *testing.T) {
clientMock := testdataClient.NewMock()
clientMock.AddMockResponse(testdataClient.MockResponse{
Expand Down Expand Up @@ -172,7 +154,7 @@ func TestPostWithTimeout(t *testing.T) {
}
}

func TestAuthenticate(t *testing.T) {
func TestAuthenticateExplicitToken(t *testing.T) {
tkn = "0501ac404fd1823d0d4c047f957637a912d3b94713ee32a6"
jwtTkn := "jwt-tkn"
clientMock := testdataClient.NewMock()
Expand All @@ -191,6 +173,23 @@ func TestAuthenticate(t *testing.T) {
}
}

func TestAuthenticateCachedToken(t *testing.T) {
clientMock := testdataClient.NewMock()
client = NewDebClient(nil, clientMock)
client = &DebClient{
host: nil,
accessToken: nil,
httpClient: clientMock,
jwtToken: "",
authenticator: testdataAuth.MockAuthenticator{},
}

err := client.authenticate()
if err != nil {
t.Fatal("failed to assert that no error occurred")
}
}

func TestSetAccessToken(t *testing.T) {
debClient := NewDebClient(nil, testdataClient.NewMock())
debClient.accessToken = nil
Expand Down
19 changes: 19 additions & 0 deletions internal/client/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,25 @@ type errorMessage struct {
}

func (debClient *DebClient) authenticate() error {
if debClient.accessToken != nil { // To avoid segfault
if len(*debClient.accessToken) != 0 {
return debClient.authenticateExplicitToken()
}
}

return debClient.authenticateCachedToken()
}

func (debClient *DebClient) authenticateCachedToken() error {
token, err := debClient.authenticator.Token()
if err == nil {
debClient.jwtToken = token.AccessToken
}

return err
}

func (debClient *DebClient) authenticateExplicitToken() error {
uri := "/api/login_refresh"

data := map[string]string{"refresh_token": *debClient.accessToken}
Expand Down
9 changes: 9 additions & 0 deletions internal/client/testdata/deb_client_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"net/http"
"net/url"

"github.com/debricked/cli/internal/auth"
authTestdata "github.com/debricked/cli/internal/auth/testdata"
"github.com/debricked/cli/internal/client"
)

Expand Down Expand Up @@ -146,3 +148,10 @@ func (mock *DebClientMock) IsEnterpriseCustomer(silent bool) bool {

return mock.isEnterprise
}

func (mock *DebClientMock) Authenticator() auth.IAuthenticator {
return auth.Authenticator{
SecretClient: authTestdata.MockInvalidSecretClient{},
OAuthConfig: nil,
}
}
5 changes: 1 addition & 4 deletions internal/cmd/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ import (
"testing"

"github.com/debricked/cli/internal/auth"
"github.com/debricked/cli/internal/client"
"github.com/stretchr/testify/assert"
)

func TestNewAuthCmd(t *testing.T) {
token := "token"
deb_client := client.NewDebClient(&token, nil)
authenticator := auth.NewDebrickedAuthenticator(deb_client)
authenticator := auth.NewDebrickedAuthenticator("")
cmd := NewAuthCmd(authenticator)
commands := cmd.Commands()
nbrOfCommands := 3
Expand Down
5 changes: 1 addition & 4 deletions internal/cmd/auth/login/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ import (

"github.com/debricked/cli/internal/auth"
"github.com/debricked/cli/internal/auth/testdata"
"github.com/debricked/cli/internal/client"
"github.com/stretchr/testify/assert"
)

func TestNewLoginCmd(t *testing.T) {
token := "token"
deb_client := client.NewDebClient(&token, nil)
authenticator := auth.NewDebrickedAuthenticator(deb_client)
authenticator := auth.NewDebrickedAuthenticator("")
cmd := NewLoginCmd(authenticator)
commands := cmd.Commands()
nbrOfCommands := 0
Expand Down
5 changes: 1 addition & 4 deletions internal/cmd/auth/logout/logout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ import (

"github.com/debricked/cli/internal/auth"
"github.com/debricked/cli/internal/auth/testdata"
"github.com/debricked/cli/internal/client"
"github.com/stretchr/testify/assert"
)

func TestNewLogoutCmd(t *testing.T) {
token := "token"
deb_client := client.NewDebClient(&token, nil)
authenticator := auth.NewDebrickedAuthenticator(deb_client)
authenticator := auth.NewDebrickedAuthenticator("")
cmd := NewLogoutCmd(authenticator)
commands := cmd.Commands()
nbrOfCommands := 0
Expand Down
15 changes: 11 additions & 4 deletions internal/cmd/auth/token/token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@ import (

"github.com/debricked/cli/internal/auth"
"github.com/debricked/cli/internal/auth/testdata"
"github.com/debricked/cli/internal/client"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
)

func TestNewTokenCmd(t *testing.T) {
token := "token"
deb_client := client.NewDebClient(&token, nil)
authenticator := auth.NewDebrickedAuthenticator(deb_client)
authenticator := auth.NewDebrickedAuthenticator("")
cmd := NewTokenCmd(authenticator)
commands := cmd.Commands()
nbrOfCommands := 0
Expand Down Expand Up @@ -57,6 +54,16 @@ func TestRunE(t *testing.T) {
assert.NoError(t, err)
}

func TestRunEJSONFlag(t *testing.T) {
a := testdata.MockAuthenticator{}
jsonFormat = true
runE := RunE(a)

err := runE(nil, []string{})

assert.NoError(t, err)
}

func TestRunEError(t *testing.T) {
a := testdata.ErrorMockAuthenticator{}
runE := RunE(a)
Expand Down
9 changes: 6 additions & 3 deletions internal/cmd/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import (

var accessToken string

const AccessTokenFlag = "access-token"
const AccessTokenFlag = "token"
const OldAccessTokenFlag = "access-token"

func NewRootCmd(version string, container *wire.CliContainer) *cobra.Command {
rootCmd := &cobra.Command{
Expand All @@ -29,12 +30,14 @@ Complete documentation is available at https://docs.debricked.com/tools-and-inte
Version: version,
}
viper.SetEnvPrefix("DEBRICKED")
viper.AutomaticEnv()
viper.MustBindEnv(AccessTokenFlag)

rootCmd.PersistentFlags().StringVarP(
&accessToken,
AccessTokenFlag,
OldAccessTokenFlag,
"t",
"",
viper.GetString(AccessTokenFlag),
`Debricked access token.
Read more: https://docs.debricked.com/product/administration/generate-access-token`,
)
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/root/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestNewRootCmd(t *testing.T) {
}

flags := cmd.PersistentFlags()
flag := flags.Lookup(AccessTokenFlag)
flag := flags.Lookup(OldAccessTokenFlag)
assert.NotNil(t, flag)
assert.Equal(t, "t", flag.Shorthand)

Expand All @@ -34,7 +34,7 @@ func TestNewRootCmd(t *testing.T) {
break
}
}
assert.Truef(t, match, "failed to assert that flag was present: "+AccessTokenFlag)
assert.Truef(t, match, "failed to assert that flag was present: "+OldAccessTokenFlag)
assert.Len(t, viperKeys, 22)
}

Expand Down
5 changes: 5 additions & 0 deletions internal/file/finder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"strings"
"testing"

"github.com/debricked/cli/internal/auth"
"github.com/debricked/cli/internal/client/testdata"
ioFs "github.com/debricked/cli/internal/io"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -68,6 +69,10 @@ func (mock *debClientMock) IsEnterpriseCustomer(silent bool) bool {
return true
}

func (mock *debClientMock) Authenticator() auth.IAuthenticator {
return nil
}

var finder *Finder

func setUp(auth bool) {
Expand Down
Loading
Loading