diff --git a/cmd/cosign/cli/clean.go b/cmd/cosign/cli/clean.go index 16815be4b51..33ae67af7ba 100644 --- a/cmd/cosign/cli/clean.go +++ b/cmd/cosign/cli/clean.go @@ -16,13 +16,11 @@ package cli import ( - "bufio" "context" "errors" "fmt" "net/http" "os" - "strings" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1/remote" @@ -30,6 +28,7 @@ import ( "github.com/spf13/cobra" "github.com/sigstore/cosign/cmd/cosign/cli/options" + "github.com/sigstore/cosign/pkg/cosign" ociremote "github.com/sigstore/cosign/pkg/oci/remote" ) @@ -50,27 +49,13 @@ func Clean() *cobra.Command { return cmd } -// confirmPromptDestructive prompts the user for confirmation for an action. Ignores -// skipConfirmation. -func confirmPromptDestructive(msg string) (bool, error) { - fmt.Fprintf(os.Stderr, "%s\n\nAre you sure you want to continue? (y/[N]): ", msg) - reader := bufio.NewReader(os.Stdin) - r, err := reader.ReadString('\n') +func CleanCmd(ctx context.Context, regOpts options.RegistryOptions, cleanType, imageRef string, force bool) error { + ok, err := cosign.ConfirmPrompt(prompt(cleanType), force) if err != nil { - return false, err + return err } - return strings.Trim(r, "\n") == "Y" || strings.Trim(r, "\n") == "y", nil -} - -func CleanCmd(ctx context.Context, regOpts options.RegistryOptions, cleanType, imageRef string, force bool) error { - if !force { - ok, err := confirmPromptDestructive(prompt(cleanType)) - if err != nil { - return err - } - if !ok { - return nil - } + if !ok { + return nil } ref, err := name.ParseReference(imageRef) diff --git a/cmd/cosign/cli/fulcio/fulcio.go b/cmd/cosign/cli/fulcio/fulcio.go index bb6fa6ea9b4..68c01f99cee 100644 --- a/cmd/cosign/cli/fulcio/fulcio.go +++ b/cmd/cosign/cli/fulcio/fulcio.go @@ -39,15 +39,15 @@ import ( ) const ( - FlowNormal = "normal" - FlowDevice = "device" - FlowToken = "token" + flowNormal = "normal" + flowDevice = "device" + flowToken = "token" // spacing is intentional to have this indented - PrivacyStatement = ` + privacyStatement = ` Note that there may be personally identifiable information associated with this signed artifact. This may include the email address associated with the account with which you authenticate. This information will be used for signing this artifact and will be stored in public transparency logs and cannot be removed later.` - PrivacyStatementConfirmation = " By typing 'y', you attest that you grant (or have permission to grant) and agree to have this information stored permanently in transparency logs." + privacyStatementConfirmation = " By typing 'y', you attest that you grant (or have permission to grant) and agree to have this information stored permanently in transparency logs." ) type oidcConnector interface { @@ -95,12 +95,12 @@ func getCertForOauthID(priv *ecdsa.PrivateKey, fc api.Client, connector oidcConn func GetCert(ctx context.Context, priv *ecdsa.PrivateKey, idToken, flow, oidcIssuer, oidcClientID, oidcClientSecret, oidcRedirectURL string, fClient api.Client) (*api.CertificateResponse, error) { c := &realConnector{} switch flow { - case FlowDevice: + case flowDevice: c.flow = oauthflow.NewDeviceFlowTokenGetter( oidcIssuer, oauthflow.SigstoreDeviceURL, oauthflow.SigstoreTokenURL) - case FlowNormal: + case flowNormal: c.flow = oauthflow.DefaultIDTokenGetter - case FlowToken: + case flowToken: c.flow = &oauthflow.StaticTokenGetter{RawToken: idToken} default: return nil, fmt.Errorf("unsupported oauth flow: %s", flow) @@ -151,7 +151,7 @@ func NewSigner(ctx context.Context, ko options.KeyOpts) (*Signer, error) { } fmt.Fprintln(os.Stderr, "Retrieving signed certificate...") - fmt.Fprintln(os.Stderr, PrivacyStatement) + fmt.Fprintln(os.Stderr, privacyStatement) var flow string switch { @@ -159,19 +159,19 @@ func NewSigner(ctx context.Context, ko options.KeyOpts) (*Signer, error) { // Caller manually set flow option. flow = ko.FulcioAuthFlow case idToken != "": - flow = FlowToken + flow = flowToken case !term.IsTerminal(0): fmt.Fprintln(os.Stderr, "Non-interactive mode detected, using device flow.") - flow = FlowDevice + flow = flowDevice default: - ok, err := cosign.ConfirmPrompt(PrivacyStatementConfirmation, ko.SkipConfirmation) + ok, err := cosign.ConfirmPrompt(privacyStatementConfirmation, ko.SkipConfirmation) if err != nil { return nil, err } if !ok { return nil, errors.New("no confirmation") } - flow = FlowNormal + flow = flowNormal } Resp, err := GetCert(ctx, priv, idToken, flow, ko.OIDCIssuer, ko.OIDCClientID, ko.OIDCClientSecret, ko.OIDCRedirectURL, fClient) // TODO, use the chain. if err != nil { diff --git a/cmd/cosign/cli/options/clean.go b/cmd/cosign/cli/options/clean.go index 32b4907b479..3bda7b0e206 100644 --- a/cmd/cosign/cli/options/clean.go +++ b/cmd/cosign/cli/options/clean.go @@ -27,5 +27,6 @@ var _ Interface = (*CleanOptions)(nil) func (c *CleanOptions) AddFlags(cmd *cobra.Command) { c.Registry.AddFlags(cmd) cmd.Flags().StringVarP(&c.CleanType, "type", "", "all", "a type of clean: (default: all)") + // TODO: Rename to --skip-confirmation for consistency? cmd.Flags().BoolVarP(&c.Force, "force", "f", false, "do not prompt for confirmation") }