From e20deaa3944cfdc3c7dfd940fc56e106fd8a24ff Mon Sep 17 00:00:00 2001 From: stgarf Date: Tue, 5 Mar 2024 11:20:04 -0800 Subject: [PATCH] Add config options for Autoclose and AutocloseTimeout (#466) * Add autoclose after auth feature Add the ability to have the window `autoclose` after the specified `autocloseTimeout`. If the go template cannot be rendered the page will fallback to the original static html page. Signed-off-by: Steve Garf * Update README and default values Signed-off-by: Steve Garf * Update README.md Co-authored-by: Billy Lynch <1844673+wlynch@users.noreply.github.com> Signed-off-by: stgarf --------- Signed-off-by: Steve Garf Signed-off-by: stgarf Co-authored-by: Billy Lynch <1844673+wlynch@users.noreply.github.com> --- README.md | 4 ++++ internal/config/config.go | 22 +++++++++++++++++++++- internal/config/config_test.go | 10 ++++++---- internal/fulcio/identity.go | 10 +++++----- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d65b354e..2ec2338e 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,8 @@ The following config options are supported: | tokenProvider | | Optional OIDC token provider to use to fetch tokens. If not set, any available providers are used. valid values are:
- `interactive`
- `spiffe`
- `google-workload-identity`
- `google-impersonation`
- `github-actions`
- `filesystem`
- `buildkite-agent` | | timestampServerURL | | Address of timestamping authority. If set, a trusted timestamp will be included in the signature. | | timestampCertChain | | Path to PEM encoded certificate chain for RFC3161 Timestamp Authority verification. | +| autoclose | true | If true, autoclose the browser window after `autocloseTimeout`. In order for autoclose to work you must also set `connectorID`. | +| autocloseTimeout | 6 | If `autoclose` is true, this is how long to wait until the window is closed. | ### Environment Variables @@ -93,6 +95,8 @@ The following config options are supported: | GITSIGN_TIMESTAMP_CERT_CHAIN | ✅ | | Path to PEM encoded certificate chain for RFC3161 Timestamp Authority verification. | | GITSIGN_FULCIO_ROOT | ✅ | | Path to PEM encoded certificate for Fulcio CA (additional alias: SIGSTORE_ROOT_FILE) | | GITSIGN_REKOR_MODE | ❌ | online | Rekor storage mode to operate in. One of [online, offline] (default: online)
online - Commit SHAs are stored in Rekor, requiring online verification for all commit objects.
offline - Hashed commit content is stored in Rekor, with Rekor attributes necessary for offline verification being stored in the commit itself.
Note: online verification will be deprecated in favor of offline in the future. | +| GITSIGN_AUTOCLOSE | ❌ | true | If true, autoclose the browser window after `GITSIGN_AUTOCLOSE_TIME`. | +| GITSIGN_AUTOCLOSE_TIMEOUT | ❌ | 6 | If `GITSIGN_AUTOCLOSE` is true, this is how long to wait until the window is closed. | For environment variables that support `Sigstore Prefix`, the values may be provided with either a `GITSIGN_` or `SIGSTORE_` prefix - e.g. diff --git a/internal/config/config.go b/internal/config/config.go index 84490093..62d81028 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -19,8 +19,10 @@ import ( "bytes" "fmt" "io" + "log" "os" "os/exec" + "strconv" "strings" ) @@ -80,6 +82,11 @@ type Config struct { CommitterName string CommitterEmail string MatchCommitter bool + + // Autoclose specifies whether to close window after successful authentication + Autoclose bool + // AutocloseTimeout specifies the time to wait before closing the window + AutocloseTimeout int } // Get fetches the gitsign config options for the repo in the current working @@ -98,7 +105,9 @@ func Get() (*Config, error) { ClientID: "sigstore", Issuer: "https://oauth2.sigstore.dev/auth", // TODO: default to offline - RekorMode: "online", + RekorMode: "online", + Autoclose: true, + AutocloseTimeout: 6, } // Get values from config file. @@ -124,6 +133,8 @@ func Get() (*Config, error) { out.TokenProvider = envOrValue(fmt.Sprintf("%s_TOKEN_PROVIDER", prefix), out.TokenProvider) out.TimestampURL = envOrValue(fmt.Sprintf("%s_TIMESTAMP_SERVER_URL", prefix), out.TimestampURL) out.TimestampCert = envOrValue(fmt.Sprintf("%s_TIMESTAMP_CERT_CHAIN", prefix), out.TimestampCert) + out.Autoclose = envOrValue(fmt.Sprintf("%s_AUTOCLOSE", prefix), fmt.Sprintf("%t", out.Autoclose)) == "true" + out.AutocloseTimeout, _ = strconv.Atoi(envOrValue(fmt.Sprintf("%s_AUTOCLOSE_TIMEOUT", prefix), fmt.Sprintf("%d", out.AutocloseTimeout))) } out.LogPath = envOrValue("GITSIGN_LOG", out.LogPath) @@ -203,6 +214,15 @@ func applyGitOptions(out *Config, cfg map[string]string) { out.TimestampCert = v case strings.EqualFold(k, "gitsign.matchCommitter"): out.MatchCommitter = strings.EqualFold(v, "true") + case strings.EqualFold(k, "gitsign.autoclose"): + out.Autoclose = strings.EqualFold(v, "true") + case strings.EqualFold(k, "gitsign.autocloseTimeout"): + if i, err := strconv.Atoi(v); err == nil && i > 0 { + out.AutocloseTimeout = i + } else { + log.Printf("invalid gitsign.autocloseTimeout value %q, defaulting to 6", v) + out.AutocloseTimeout = 6 + } } } } diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 1598677d..b63bcaca 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -82,10 +82,12 @@ func TestGet(t *testing.T) { // Default value ClientID: "sigstore", // Overridden by env var - Issuer: "tacocat", - RedirectURL: "example.com", - ConnectorID: "bar", - RekorMode: "online", + Issuer: "tacocat", + RedirectURL: "example.com", + ConnectorID: "bar", + RekorMode: "online", + Autoclose: true, + AutocloseTimeout: 6, } execFn = func() (io.Reader, error) { diff --git a/internal/fulcio/identity.go b/internal/fulcio/identity.go index 583a4057..fbc901b7 100644 --- a/internal/fulcio/identity.go +++ b/internal/fulcio/identity.go @@ -197,13 +197,13 @@ func (f *IdentityFactory) NewIdentity(ctx context.Context, cfg *config.Config) ( // Autoclose only works if we don't go through the identity selection page // (otherwise it'll show a countdown timer that doesn't work) - autoclose := false - if cfg.ConnectorID != "" { - autoclose = true + if cfg.ConnectorID == "" { + cfg.Autoclose = false } - html, err := oauth.GetInteractiveSuccessHTML(autoclose, 6) + html, err := oauth.GetInteractiveSuccessHTML(cfg.Autoclose, cfg.AutocloseTimeout) if err != nil { - return nil, fmt.Errorf("error generating interactive HTML: %w", err) + fmt.Println("error getting interactive success html, using static default", err) + html = oauth.InteractiveSuccessHTML } defaultFlow := &oauthflow.InteractiveIDTokenGetter{ HTMLPage: html,