diff --git a/api/authentication.go b/api/authentication.go index f70eb50..86fe904 100644 --- a/api/authentication.go +++ b/api/authentication.go @@ -13,6 +13,7 @@ import ( "github.com/tevino/abool" + "github.com/safing/portbase/config" "github.com/safing/portbase/log" "github.com/safing/portbase/modules" "github.com/safing/portbase/rng" @@ -361,15 +362,26 @@ func updateAPIKeys(_ context.Context, _ interface{}) error { delete(apiKeys, k) } + // whether or not we found expired API keys that should be removed + // from the setting + hasExpiredKeys := false + + // a list of valid API keys. Used when hasExpiredKeys is set to true. + // in that case we'll update the setting to only contain validAPIKeys + validAPIKeys := []string{} + // Parse new keys. for _, key := range configuredAPIKeys() { u, err := url.Parse(key) if err != nil { log.Errorf("api: failed to parse configured API key %s: %s", key, err) + continue } + if u.Path == "" { log.Errorf("api: malformed API key %s: missing path section", key) + continue } @@ -403,11 +415,34 @@ func updateAPIKeys(_ context.Context, _ interface{}) error { log.Errorf("api: invalid API key %s: %s", key, err) continue } + + // continue to the next token if this one is already invalid + if time.Now().After(validUntil) { + // mark the key as expired so we'll remove it from the setting afterwards + hasExpiredKeys = true + + continue + } + token.ValidUntil = &validUntil } // Save token. apiKeys[u.Path] = token + validAPIKeys = append(validAPIKeys, key) + } + + if hasExpiredKeys { + name := "api-key-cleanup" + module.StartLowPriorityMicroTask(&name, func(ctx context.Context) error { + if err := config.SetConfigOption(CfgAPIKeys, validAPIKeys); err != nil { + log.Errorf("api: failed to remove expired API keys: %s", err) + } else { + log.Infof("api: removed expired API keys from %s", CfgAPIKeys) + } + + return nil + }) } return nil