clean up duplicate functions

This commit is contained in:
Evan Jarrett
2025-10-28 09:43:43 -05:00
parent 4cfe6f221d
commit e62ebdaa53
8 changed files with 23 additions and 52 deletions
+5 -12
View File
@@ -1,7 +1,6 @@
package handlers
import (
"context"
"database/sql"
"encoding/json"
"errors"
@@ -37,7 +36,7 @@ func (h *StarRepositoryHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
repository := chi.URLParam(r, "repository")
// Resolve owner's handle to DID
ownerDID, err := resolveIdentityToDID(r.Context(), h.Directory, handle)
ownerDID, err := atproto.ResolveHandleToDID(r.Context(), handle)
if err != nil {
slog.Warn("Failed to resolve handle for star", "handle", handle, "error", err)
http.Error(w, fmt.Sprintf("Failed to resolve handle: %v", err), http.StatusBadRequest)
@@ -95,7 +94,7 @@ func (h *UnstarRepositoryHandler) ServeHTTP(w http.ResponseWriter, r *http.Reque
repository := chi.URLParam(r, "repository")
// Resolve owner's handle to DID
ownerDID, err := resolveIdentityToDID(r.Context(), h.Directory, handle)
ownerDID, err := atproto.ResolveHandleToDID(r.Context(), handle)
if err != nil {
slog.Warn("Failed to resolve handle for unstar", "handle", handle, "error", err)
http.Error(w, fmt.Sprintf("Failed to resolve handle: %v", err), http.StatusBadRequest)
@@ -156,7 +155,7 @@ func (h *CheckStarHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
repository := chi.URLParam(r, "repository")
// Resolve owner's handle to DID
ownerDID, err := resolveIdentityToDID(r.Context(), h.Directory, handle)
ownerDID, err := atproto.ResolveHandleToDID(r.Context(), handle)
if err != nil {
slog.Warn("Failed to resolve handle for check star", "handle", handle, "error", err)
http.Error(w, fmt.Sprintf("Failed to resolve handle: %v", err), http.StatusBadRequest)
@@ -200,7 +199,7 @@ func (h *GetStatsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
repository := chi.URLParam(r, "repository")
// Resolve owner's handle to DID
ownerDID, err := resolveIdentityToDID(r.Context(), h.Directory, handle)
ownerDID, err := atproto.ResolveHandleToDID(r.Context(), handle)
if err != nil {
http.Error(w, "Failed to resolve handle", http.StatusBadRequest)
return
@@ -231,7 +230,7 @@ func (h *ManifestDetailHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
digest := chi.URLParam(r, "digest")
// Resolve owner's handle to DID
ownerDID, err := resolveIdentityToDID(r.Context(), h.Directory, handle)
ownerDID, err := atproto.ResolveHandleToDID(r.Context(), handle)
if err != nil {
http.Error(w, "Failed to resolve handle", http.StatusBadRequest)
return
@@ -253,9 +252,3 @@ func (h *ManifestDetailHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(manifest)
}
// resolveIdentityToDID is a helper function that resolves a handle or DID to a DID
func resolveIdentityToDID(ctx context.Context, directory identity.Directory, identityStr string) (string, error) {
// Resolve to DID via directory (handles both handles and DIDs)
return atproto.ResolveHandleToDID(ctx, identityStr)
}
+3 -1
View File
@@ -6,6 +6,8 @@ import (
"net/http/httptest"
"testing"
"time"
"atcr.io/pkg/atproto"
)
func TestNewChecker(t *testing.T) {
@@ -317,7 +319,7 @@ func TestNormalizeHoldEndpoint(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := normalizeHoldEndpoint(tt.input)
result := atproto.ResolveHoldDIDFromURL(tt.input)
if result != tt.expected {
t.Errorf("normalizeHoldEndpoint(%q) = %q, want %q", tt.input, result, tt.expected)
}
+3 -28
View File
@@ -5,9 +5,10 @@ import (
"database/sql"
"fmt"
"log/slog"
"strings"
"sync"
"time"
"atcr.io/pkg/atproto"
)
// DBQuerier interface for database queries (allows mocking in tests)
@@ -129,7 +130,7 @@ func (w *Worker) refreshAllHolds(ctx context.Context) {
for _, endpoint := range endpoints {
// Normalize to canonical DID format
normalizedDID := normalizeHoldEndpoint(endpoint)
normalizedDID := atproto.ResolveHoldDIDFromURL(endpoint)
// Skip if we've already seen this normalized DID
if seen[normalizedDID] {
@@ -219,29 +220,3 @@ func (a *DBAdapter) GetUniqueHoldEndpoints() ([]string, error) {
return endpoints, nil
}
// normalizeHoldEndpoint converts a hold endpoint (URL or DID) to canonical DID format
// This ensures that different representations of the same hold are deduplicated:
// - http://172.28.0.3:8080 → did:web:172.28.0.3:8080
// - http://hold01.atcr.io → did:web:hold01.atcr.io
// - https://hold01.atcr.io → did:web:hold01.atcr.io
// - did:web:hold01.atcr.io → did:web:hold01.atcr.io (passthrough)
func normalizeHoldEndpoint(endpoint string) string {
// Strip protocol and trailing slashes
normalized := endpoint
normalized = strings.TrimPrefix(normalized, "http://")
normalized = strings.TrimPrefix(normalized, "https://")
normalized = strings.TrimSuffix(normalized, "/")
// If already a DID, return as-is
if strings.HasPrefix(endpoint, "did:") {
return endpoint
}
// Extract hostname (remove path if present)
parts := strings.Split(normalized, "/")
hostname := parts[0]
// Convert to did:web
return "did:web:" + hostname
}
+2 -2
View File
@@ -25,8 +25,8 @@ type Processor struct {
// useCache: true for Worker (live streaming), false for Backfill (batch processing)
func NewProcessor(database *sql.DB, useCache bool) *Processor {
p := &Processor{
db: database,
useCache: useCache,
db: database,
useCache: useCache,
}
if useCache {
-1
View File
@@ -525,7 +525,6 @@ func TestTemplates(t *testing.T) {
// Test that all expected templates are loaded
expectedTemplates := []string{
"base.html",
"nav",
"repo-card",
"repository",
+6 -3
View File
@@ -406,8 +406,11 @@ func ParseStarRecordKey(rkey string) (ownerDID, repository string, err error) {
}
// ResolveHoldDIDFromURL converts a hold endpoint URL to a did:web DID
// For did:web holds: https://hold01.atcr.io → did:web:hold01.atcr.io
// If input is already a DID, returns it as-is
// This ensures that different representations of the same hold are deduplicated:
// - http://172.28.0.3:8080 → did:web:172.28.0.3:8080
// - http://hold01.atcr.io → did:web:hold01.atcr.io
// - https://hold01.atcr.io → did:web:hold01.atcr.io
// - did:web:hold01.atcr.io → did:web:hold01.atcr.io (passthrough)
func ResolveHoldDIDFromURL(holdURL string) string {
// Handle empty URLs
if holdURL == "" {
@@ -415,7 +418,7 @@ func ResolveHoldDIDFromURL(holdURL string) string {
}
// If already a DID, return as-is
if strings.HasPrefix(holdURL, "did:") {
if IsDID(holdURL) {
return holdURL
}
+2 -3
View File
@@ -20,7 +20,6 @@ import (
type App struct {
clientApp *oauth.ClientApp
baseURL string
directory identity.Directory
}
// NewApp creates a new OAuth app for ATCR with default scopes
@@ -32,11 +31,11 @@ func NewApp(baseURL string, store oauth.ClientAuthStore, holdDid string, testMod
func NewAppWithScopes(baseURL string, store oauth.ClientAuthStore, scopes []string) (*App, error) {
config := NewClientConfigWithScopes(baseURL, scopes)
clientApp := oauth.NewClientApp(&config, store)
clientApp.Dir = atproto.GetDirectory()
return &App{
clientApp: clientApp,
baseURL: baseURL,
directory: atproto.GetDirectory(),
}, nil
}
@@ -102,7 +101,7 @@ func (a *App) GetClientApp() *oauth.ClientApp {
// Directory returns the identity directory used by the OAuth app
func (a *App) Directory() identity.Directory {
return a.directory
return a.clientApp.Dir
}
// ClientIDWithScopes generates a client ID with custom scopes
+2 -2
View File
@@ -263,7 +263,7 @@ func (h *XRPCHandler) HandleGetProfile(w http.ResponseWriter, r *http.Request) {
// Normalize actor to DID
actorDID := actor
if !strings.HasPrefix(actor, "did:") {
if !atproto.IsDID(actor) {
// It's a handle, resolve to DID
expectedHandle := strings.TrimPrefix(h.pds.DID(), "did:web:")
if actor == expectedHandle {
@@ -306,7 +306,7 @@ func (h *XRPCHandler) HandleGetProfiles(w http.ResponseWriter, r *http.Request)
for _, actor := range actors {
// Normalize actor to DID
actorDID := actor
if !strings.HasPrefix(actor, "did:") {
if !atproto.IsDID(actor) {
// It's a handle, check if it matches
if actor == expectedHandle {
actorDID = h.pds.DID()