A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.

move packages out of token that are not related to docker jwt token

evan.jarrett.net 7f2d780b 8956568e

verified
+21 -22
+2 -2
pkg/appview/middleware/registry.go
··· 339 339 "pullerDID", pullerDID, 340 340 "cacheKey", cacheKey) 341 341 342 - token, err := token.GetOrFetchServiceTokenWithAppPassword(ctx, pullerDID, holdDID, pullerPDSEndpoint) 342 + token, err := auth.GetOrFetchServiceTokenWithAppPassword(ctx, pullerDID, holdDID, pullerPDSEndpoint) 343 343 if err != nil { 344 344 slog.Error("Failed to get service token with app-password", 345 345 "component", "registry/middleware", ··· 357 357 "pullerDID", pullerDID, 358 358 "cacheKey", cacheKey) 359 359 360 - token, err := token.GetOrFetchServiceToken(ctx, nr.refresher, pullerDID, holdDID, pullerPDSEndpoint) 360 + token, err := auth.GetOrFetchServiceToken(ctx, nr.refresher, pullerDID, holdDID, pullerPDSEndpoint) 361 361 if err != nil { 362 362 slog.Error("Failed to get service token with OAuth", 363 363 "component", "registry/middleware",
+2 -2
pkg/appview/storage/crew.go
··· 9 9 "time" 10 10 11 11 "atcr.io/pkg/atproto" 12 + "atcr.io/pkg/auth" 12 13 "atcr.io/pkg/auth/oauth" 13 - "atcr.io/pkg/auth/token" 14 14 ) 15 15 16 16 // EnsureCrewMembership attempts to register the user as a crew member on their default hold. ··· 39 39 } 40 40 41 41 // Wrap the refresher to match OAuthSessionRefresher interface 42 - serviceToken, err := token.GetOrFetchServiceToken(ctx, refresher, client.DID(), holdDID, client.PDSEndpoint()) 42 + serviceToken, err := auth.GetOrFetchServiceToken(ctx, refresher, client.DID(), holdDID, client.PDSEndpoint()) 43 43 if err != nil { 44 44 slog.Warn("failed to get service token", "holdDID", holdDID, "error", err) 45 45 return
+11 -11
pkg/appview/storage/proxy_blob_store_test.go
··· 12 12 "time" 13 13 14 14 "atcr.io/pkg/atproto" 15 - "atcr.io/pkg/auth/token" 15 + "atcr.io/pkg/auth" 16 16 "github.com/opencontainers/go-digest" 17 17 ) 18 18 ··· 22 22 holdDID := "did:web:hold.example.com" 23 23 24 24 // Test 1: Empty cache - invalidate any existing token 25 - token.InvalidateServiceToken(userDID, holdDID) 26 - cachedToken, _ := token.GetServiceToken(userDID, holdDID) 25 + auth.InvalidateServiceToken(userDID, holdDID) 26 + cachedToken, _ := auth.GetServiceToken(userDID, holdDID) 27 27 if cachedToken != "" { 28 28 t.Error("Expected empty cache at start") 29 29 } ··· 34 34 testPayload := fmt.Sprintf(`{"exp":%d}`, time.Now().Add(50*time.Second).Unix()) 35 35 testToken := "eyJhbGciOiJIUzI1NiJ9." + base64URLEncode(testPayload) + ".signature" 36 36 37 - err := token.SetServiceToken(userDID, holdDID, testToken) 37 + err := auth.SetServiceToken(userDID, holdDID, testToken) 38 38 if err != nil { 39 39 t.Fatalf("Failed to set service token: %v", err) 40 40 } 41 41 42 42 // Test 3: Retrieve from cache 43 - cachedToken, expiresAt := token.GetServiceToken(userDID, holdDID) 43 + cachedToken, expiresAt := auth.GetServiceToken(userDID, holdDID) 44 44 if cachedToken == "" { 45 45 t.Fatal("Expected token to be in cache") 46 46 } ··· 56 56 // Test 4: Expired token - GetServiceToken automatically removes it 57 57 expiredPayload := fmt.Sprintf(`{"exp":%d}`, time.Now().Add(-1*time.Hour).Unix()) 58 58 expiredToken := "eyJhbGciOiJIUzI1NiJ9." + base64URLEncode(expiredPayload) + ".signature" 59 - token.SetServiceToken(userDID, holdDID, expiredToken) 59 + auth.SetServiceToken(userDID, holdDID, expiredToken) 60 60 61 61 // GetServiceToken should return empty string for expired token 62 - cachedToken, _ = token.GetServiceToken(userDID, holdDID) 62 + cachedToken, _ = auth.GetServiceToken(userDID, holdDID) 63 63 if cachedToken != "" { 64 64 t.Error("Expected expired token to be removed from cache") 65 65 } ··· 234 234 // Insert expired token 235 235 expiredPayload := fmt.Sprintf(`{"exp":%d}`, time.Now().Add(-1*time.Hour).Unix()) 236 236 expiredToken := "eyJhbGciOiJIUzI1NiJ9." + base64URLEncode(expiredPayload) + ".signature" 237 - token.SetServiceToken(userDID, holdDID, expiredToken) 237 + auth.SetServiceToken(userDID, holdDID, expiredToken) 238 238 239 239 // GetServiceToken should automatically remove expired tokens 240 - cachedToken, expiresAt := token.GetServiceToken(userDID, holdDID) 240 + cachedToken, expiresAt := auth.GetServiceToken(userDID, holdDID) 241 241 242 242 // Should return empty string for expired token 243 243 if cachedToken != "" { ··· 310 310 311 311 testPayload := fmt.Sprintf(`{"exp":%d}`, time.Now().Add(50*time.Second).Unix()) 312 312 testTokenStr := "eyJhbGciOiJIUzI1NiJ9." + base64URLEncode(testPayload) + ".signature" 313 - token.SetServiceToken(userDID, holdDID, testTokenStr) 313 + auth.SetServiceToken(userDID, holdDID, testTokenStr) 314 314 315 315 for b.Loop() { 316 - cachedToken, expiresAt := token.GetServiceToken(userDID, holdDID) 316 + cachedToken, expiresAt := auth.GetServiceToken(userDID, holdDID) 317 317 318 318 if cachedToken == "" || time.Now().After(expiresAt) { 319 319 b.Error("Cache miss in benchmark")
+1 -1
pkg/auth/token/cache.go pkg/auth/cache.go
··· 2 2 // Service tokens are JWTs issued by a user's PDS to authorize AppView to 3 3 // act on their behalf when communicating with hold services. Tokens are 4 4 // cached with automatic expiry parsing and 10-second safety margins. 5 - package token 5 + package auth 6 6 7 7 import ( 8 8 "encoding/base64"
+1 -1
pkg/auth/token/cache_test.go pkg/auth/cache_test.go
··· 1 - package token 1 + package auth 2 2 3 3 import ( 4 4 "testing"
+3 -4
pkg/auth/token/servicetoken.go pkg/auth/servicetoken.go
··· 1 - package token 1 + package auth 2 2 3 3 import ( 4 4 "context" ··· 12 12 "time" 13 13 14 14 "atcr.io/pkg/atproto" 15 - "atcr.io/pkg/auth" 16 15 "atcr.io/pkg/auth/oauth" 17 16 "github.com/bluesky-social/indigo/atproto/atclient" 18 17 indigo_oauth "github.com/bluesky-social/indigo/atproto/auth/oauth" ··· 267 266 } 268 267 269 268 // Get app-password access token from cache 270 - accessToken, ok := auth.GetGlobalTokenCache().Get(did) 269 + accessToken, ok := GetGlobalTokenCache().Get(did) 271 270 if !ok { 272 271 InvalidateServiceToken(did, holdDID) 273 272 slog.Error("No app-password access token found in cache", ··· 314 313 315 314 if resp.StatusCode == http.StatusUnauthorized { 316 315 // App-password token is invalid or expired - clear from cache 317 - auth.GetGlobalTokenCache().Delete(did) 316 + GetGlobalTokenCache().Delete(did) 318 317 InvalidateServiceToken(did, holdDID) 319 318 slog.Error("App-password token rejected by PDS", 320 319 "component", "token/servicetoken",
+1 -1
pkg/auth/token/servicetoken_test.go pkg/auth/servicetoken_test.go
··· 1 - package token 1 + package auth 2 2 3 3 import ( 4 4 "context"