Merge branch 'trunk' into bdehamer/att-trusted-root-tenant-aware
This commit is contained in:
commit
5f60b3ca3e
7 changed files with 157 additions and 4 deletions
|
|
@ -52,8 +52,32 @@ func TestTokenFromKeyringForUserErrorsIfUsernameIsBlank(t *testing.T) {
|
|||
require.ErrorContains(t, err, "username cannot be blank")
|
||||
}
|
||||
|
||||
func TestHasActiveToken(t *testing.T) {
|
||||
// Given the user has logged in for a host
|
||||
authCfg := newTestAuthConfig(t)
|
||||
_, err := authCfg.Login("github.com", "test-user", "test-token", "", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
// When we check if that host has an active token
|
||||
hasActiveToken := authCfg.HasActiveToken("github.com")
|
||||
|
||||
// Then there is an active token
|
||||
require.True(t, hasActiveToken, "expected there to be an active token")
|
||||
}
|
||||
|
||||
func TestHasNoActiveToken(t *testing.T) {
|
||||
// Given there are no users logged in for a host
|
||||
authCfg := newTestAuthConfig(t)
|
||||
|
||||
// When we check if any host has an active token
|
||||
hasActiveToken := authCfg.HasActiveToken("github.com")
|
||||
|
||||
// Then there is no active token
|
||||
require.False(t, hasActiveToken, "expected there to be no active token")
|
||||
}
|
||||
|
||||
func TestTokenStoredInConfig(t *testing.T) {
|
||||
// When the user has logged in insecurely
|
||||
// Given the user has logged in insecurely
|
||||
authCfg := newTestAuthConfig(t)
|
||||
_, err := authCfg.Login("github.com", "test-user", "test-token", "", false)
|
||||
require.NoError(t, err)
|
||||
|
|
|
|||
|
|
@ -217,6 +217,12 @@ func (c *AuthConfig) ActiveToken(hostname string) (string, string) {
|
|||
return token, source
|
||||
}
|
||||
|
||||
// HasActiveToken returns true when a token for the hostname is present.
|
||||
func (c *AuthConfig) HasActiveToken(hostname string) bool {
|
||||
token, _ := c.ActiveToken(hostname)
|
||||
return token != ""
|
||||
}
|
||||
|
||||
// HasEnvToken returns true when a token has been specified in an
|
||||
// environment variable, else returns false.
|
||||
func (c *AuthConfig) HasEnvToken() bool {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,9 @@ type Migration interface {
|
|||
// with knowledge on how to access encrypted storage when neccesarry.
|
||||
// Behavior is scoped to authentication specific tasks.
|
||||
type AuthConfig interface {
|
||||
// HasActiveToken returns true when a token for the hostname is present.
|
||||
HasActiveToken(hostname string) bool
|
||||
|
||||
// ActiveToken will retrieve the active auth token for the given hostname, searching environment variables,
|
||||
// general configuration, and finally encrypted storage.
|
||||
ActiveToken(hostname string) (token string, source string)
|
||||
|
|
|
|||
|
|
@ -69,6 +69,15 @@ func NewTrustedRootCmd(f *cmdutil.Factory, runF func(*Options) error) *cobra.Com
|
|||
}
|
||||
|
||||
if ghinstance.IsTenancy(opts.Hostname) {
|
||||
c, err := f.Config()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !c.Authentication().HasActiveToken(opts.Hostname) {
|
||||
return fmt.Errorf("not authenticated with %s", opts.Hostname)
|
||||
}
|
||||
|
||||
hc, err := f.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -94,6 +103,7 @@ func NewTrustedRootCmd(f *cmdutil.Factory, runF func(*Options) error) *cobra.Com
|
|||
},
|
||||
}
|
||||
|
||||
cmdutil.DisableAuthCheck(&trustedRootCmd)
|
||||
trustedRootCmd.Flags().StringVarP(&opts.TufUrl, "tuf-url", "", "", "URL to the TUF repository mirror")
|
||||
trustedRootCmd.Flags().StringVarP(&opts.TufRootPath, "tuf-root", "", "", "Path to the TUF root.json file on disk")
|
||||
trustedRootCmd.MarkFlagsRequiredTogether("tuf-url", "tuf-root")
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package trustedroot
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
|
@ -10,8 +11,13 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cli/cli/v2/internal/config"
|
||||
"github.com/cli/cli/v2/internal/gh"
|
||||
ghmock "github.com/cli/cli/v2/internal/gh/mock"
|
||||
"github.com/cli/cli/v2/pkg/cmd/attestation/api"
|
||||
"github.com/cli/cli/v2/pkg/cmd/attestation/test"
|
||||
"github.com/cli/cli/v2/pkg/cmdutil"
|
||||
"github.com/cli/cli/v2/pkg/httpmock"
|
||||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
)
|
||||
|
||||
|
|
@ -19,6 +25,9 @@ func TestNewTrustedRootCmd(t *testing.T) {
|
|||
testIO, _, _, _ := iostreams.Test()
|
||||
f := &cmdutil.Factory{
|
||||
IOStreams: testIO,
|
||||
Config: func() (gh.Config, error) {
|
||||
return &ghmock.ConfigMock{}, nil
|
||||
},
|
||||
}
|
||||
|
||||
testcases := []struct {
|
||||
|
|
@ -72,6 +81,83 @@ func TestNewTrustedRootCmd(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNewTrustedRootWithTenancy(t *testing.T) {
|
||||
testIO, _, _, _ := iostreams.Test()
|
||||
var testReg httpmock.Registry
|
||||
var metaResp = api.MetaResponse{
|
||||
Domains: api.Domain{
|
||||
ArtifactAttestations: api.ArtifactAttestations{
|
||||
TrustDomain: "foo",
|
||||
},
|
||||
},
|
||||
}
|
||||
testReg.Register(httpmock.REST(http.MethodGet, "meta"),
|
||||
httpmock.StatusJSONResponse(200, &metaResp))
|
||||
|
||||
httpClientFunc := func() (*http.Client, error) {
|
||||
reg := &testReg
|
||||
client := &http.Client{}
|
||||
httpmock.ReplaceTripper(client, reg)
|
||||
return client, nil
|
||||
}
|
||||
|
||||
cli := "--hostname foo-bar.ghe.com"
|
||||
|
||||
t.Run("Host with NO auth configured", func(t *testing.T) {
|
||||
f := &cmdutil.Factory{
|
||||
IOStreams: testIO,
|
||||
Config: func() (gh.Config, error) {
|
||||
return &ghmock.ConfigMock{
|
||||
AuthenticationFunc: func() gh.AuthConfig {
|
||||
return &stubAuthConfig{hasActiveToken: false}
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
cmd := NewTrustedRootCmd(f, func(_ *Options) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
argv := strings.Split(cli, " ")
|
||||
cmd.SetArgs(argv)
|
||||
cmd.SetIn(&bytes.Buffer{})
|
||||
cmd.SetOut(&bytes.Buffer{})
|
||||
cmd.SetErr(&bytes.Buffer{})
|
||||
_, err := cmd.ExecuteC()
|
||||
|
||||
assert.Error(t, err)
|
||||
assert.ErrorContains(t, err, "not authenticated")
|
||||
})
|
||||
|
||||
t.Run("Host with auth configured", func(t *testing.T) {
|
||||
f := &cmdutil.Factory{
|
||||
IOStreams: testIO,
|
||||
Config: func() (gh.Config, error) {
|
||||
return &ghmock.ConfigMock{
|
||||
AuthenticationFunc: func() gh.AuthConfig {
|
||||
return &stubAuthConfig{hasActiveToken: true}
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
HttpClient: httpClientFunc,
|
||||
}
|
||||
|
||||
cmd := NewTrustedRootCmd(f, func(_ *Options) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
argv := strings.Split(cli, " ")
|
||||
cmd.SetArgs(argv)
|
||||
cmd.SetIn(&bytes.Buffer{})
|
||||
cmd.SetOut(&bytes.Buffer{})
|
||||
cmd.SetErr(&bytes.Buffer{})
|
||||
|
||||
_, err := cmd.ExecuteC()
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
var newTUFErrClient tufClientInstantiator = func(o *tuf.Options) (*tuf.Client, error) {
|
||||
return nil, fmt.Errorf("failed to create TUF client")
|
||||
}
|
||||
|
|
@ -99,3 +185,14 @@ func TestGetTrustedRoot(t *testing.T) {
|
|||
})
|
||||
|
||||
}
|
||||
|
||||
type stubAuthConfig struct {
|
||||
config.AuthConfig
|
||||
hasActiveToken bool
|
||||
}
|
||||
|
||||
var _ gh.AuthConfig = (*stubAuthConfig)(nil)
|
||||
|
||||
func (c *stubAuthConfig) HasActiveToken(host string) bool {
|
||||
return c.hasActiveToken
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,9 +280,13 @@ func (m *Manager) installBin(repo ghrepo.Interface, target string) error {
|
|||
}
|
||||
|
||||
if asset == nil {
|
||||
cs := m.io.ColorScheme()
|
||||
errorMessageInRed := fmt.Sprintf(cs.Red("%[1]s unsupported for %[2]s."), repo.RepoName(), platform)
|
||||
issueCreateCommand := generateMissingBinaryIssueCreateCommand(repo.RepoOwner(), repo.RepoName(), platform)
|
||||
|
||||
return fmt.Errorf(
|
||||
"%[1]s unsupported for %[2]s. Open an issue: `gh issue create -R %[3]s/%[1]s -t'Support %[2]s'`",
|
||||
repo.RepoName(), platform, repo.RepoOwner())
|
||||
"%[1]s\n\nTo request support for %[2]s, open an issue on the extension's repo by running the following command:\n\n `%[3]s`",
|
||||
errorMessageInRed, platform, issueCreateCommand)
|
||||
}
|
||||
|
||||
name := repo.RepoName()
|
||||
|
|
@ -334,6 +338,15 @@ func (m *Manager) installBin(repo ghrepo.Interface, target string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func generateMissingBinaryIssueCreateCommand(repoOwner string, repoName string, currentPlatform string) string {
|
||||
issueBody := generateMissingBinaryIssueBody(currentPlatform)
|
||||
return fmt.Sprintf("gh issue create -R %[1]s/%[2]s --title \"Add support for the %[3]s architecture\" --body \"%[4]s\"", repoOwner, repoName, currentPlatform, issueBody)
|
||||
}
|
||||
|
||||
func generateMissingBinaryIssueBody(currentPlatform string) string {
|
||||
return fmt.Sprintf("This extension does not support the %[1]s architecture. I tried to install it on a %[1]s machine, and it failed due to the lack of an available binary. Would you be able to update the extension's build and release process to include the relevant binary? For more details, see <https://docs.github.com/en/github-cli/github-cli/creating-github-cli-extensions>.", currentPlatform)
|
||||
}
|
||||
|
||||
func writeManifest(dir, name string, data []byte) (writeErr error) {
|
||||
path := filepath.Join(dir, name)
|
||||
var f *os.File
|
||||
|
|
|
|||
|
|
@ -906,7 +906,7 @@ func TestManager_Install_binary_unsupported(t *testing.T) {
|
|||
m := newTestManager(tempDir, &client, nil, ios)
|
||||
|
||||
err := m.Install(repo, "")
|
||||
assert.EqualError(t, err, "gh-bin-ext unsupported for windows-amd64. Open an issue: `gh issue create -R owner/gh-bin-ext -t'Support windows-amd64'`")
|
||||
assert.EqualError(t, err, "gh-bin-ext unsupported for windows-amd64.\n\nTo request support for windows-amd64, open an issue on the extension's repo by running the following command:\n\n\t`gh issue create -R owner/gh-bin-ext --title \"Add support for the windows-amd64 architecture\" --body \"This extension does not support the windows-amd64 architecture. I tried to install it on a windows-amd64 machine, and it failed due to the lack of an available binary. Would you be able to update the extension's build and release process to include the relevant binary? For more details, see <https://docs.github.com/en/github-cli/github-cli/creating-github-cli-extensions>.\"`")
|
||||
|
||||
assert.Equal(t, "", stdout.String())
|
||||
assert.Equal(t, "", stderr.String())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue