test
0

Configure Feed

Select the types of activity you want to include in your feed.

auth: iterate on purge codepath error handling

+19 -17
+19 -17
atproto/auth/jwt.go
··· 47 47 } 48 48 49 49 token, err := jwt.ParseWithClaims(tokenString, &serviceAuthClaims{}, s.fetchIssuerKeyFunc(ctx), opts...) 50 + 51 + // if signature validation fails, purge the directory and try again 52 + // TODO: probably need to cache or rate-limit this? 50 53 if err != nil && errors.Is(err, jwt.ErrTokenSignatureInvalid) { 51 - // if signature validation fails, purge the directory and try again 52 - // TODO: probably need to cache or rate-limit this? 53 54 54 55 // do an unvalidated extraction of 'iss' from JWT 55 56 insecure := jwt.NewParser(jwt.WithoutClaimsValidation()) 56 - t, _, err := insecure.ParseUnverified(tokenString, &jwt.MapClaims{}) 57 - if err != nil { 58 - return "", fmt.Errorf("parse unverified %q: %w", tokenString, err) 57 + t, _, purgeErr := insecure.ParseUnverified(tokenString, &jwt.MapClaims{}) 58 + if purgeErr != nil { 59 + return "", purgeErr 59 60 } 60 61 claims, ok := t.Claims.(*jwt.MapClaims) 61 62 if !ok { 62 63 return "", jwt.ErrTokenInvalidClaims 63 64 } 64 - iss, err := claims.GetIssuer() 65 - if err != nil { 66 - return "", err 65 + iss, purgeErr := claims.GetIssuer() 66 + if purgeErr != nil { 67 + return "", purgeErr 67 68 } 68 - did, err := syntax.ParseDID(iss) 69 - if err != nil { 70 - return "", fmt.Errorf("%w: invalid DID: %w", jwt.ErrTokenInvalidIssuer, err) 69 + did, purgeErr := syntax.ParseDID(iss) 70 + if purgeErr != nil { 71 + return "", fmt.Errorf("%w: invalid DID: %w", jwt.ErrTokenInvalidIssuer, purgeErr) 71 72 } 72 73 73 74 slog.Info("purging directory and retrying service auth signature validation", "did", did) 74 - err = s.Dir.Purge(ctx, did.AtIdentifier()) 75 - if err != nil { 76 - slog.Error("purging identity directory", "did", did, "err", err) 75 + purgeErr = s.Dir.Purge(ctx, did.AtIdentifier()) 76 + if purgeErr != nil { 77 + slog.Error("purging identity directory", "did", did, "err", purgeErr) 77 78 } 78 79 token, err = jwt.ParseWithClaims(tokenString, &serviceAuthClaims{}, s.fetchIssuerKeyFunc(ctx), opts...) 79 - if err != nil { 80 - return "", fmt.Errorf("parse with claims %q: %w", tokenString, err) 81 - } 80 + // 'err' checked again just below 82 81 } 82 + 83 + // all other errors (or second signature error) 83 84 if err != nil { 84 85 return "", err 85 86 } 87 + 86 88 claims, ok := token.Claims.(*serviceAuthClaims) 87 89 if !ok { 88 90 // TODO: is the error message returned descriptive enough?