A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
1package handlers
2
3import (
4 "context"
5 "log/slog"
6 "strings"
7
8 "atcr.io/pkg/auth/oauth"
9)
10
11// isOAuthError checks if an error indicates OAuth authentication failure
12// These errors indicate the OAuth session is invalid and should be cleaned up
13func isOAuthError(err error) bool {
14 if err == nil {
15 return false
16 }
17 errStr := strings.ToLower(err.Error())
18 return strings.Contains(errStr, "401") ||
19 strings.Contains(errStr, "403") ||
20 strings.Contains(errStr, "invalid_token") ||
21 strings.Contains(errStr, "invalid_grant") ||
22 strings.Contains(errStr, "use_dpop_nonce") ||
23 strings.Contains(errStr, "unauthorized") ||
24 strings.Contains(errStr, "token") && strings.Contains(errStr, "expired") ||
25 strings.Contains(errStr, "authentication failed")
26}
27
28// handleOAuthError checks if an error is OAuth-related and invalidates UI sessions if so
29// Returns true if the error was an OAuth error (caller should return early)
30func handleOAuthError(ctx context.Context, refresher *oauth.Refresher, did string, err error) bool {
31 if !isOAuthError(err) {
32 return false
33 }
34
35 slog.Warn("OAuth error detected, invalidating sessions",
36 "component", "handlers",
37 "did", did,
38 "error", err)
39
40 // Invalidate all UI sessions for this DID
41 if delErr := refresher.DeleteSession(ctx, did); delErr != nil {
42 slog.Warn("Failed to delete OAuth session after error",
43 "component", "handlers",
44 "did", did,
45 "error", delErr)
46 }
47
48 return true
49}