mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-08-30 12:46:57 +00:00
96 lines
2.9 KiB
Go
96 lines
2.9 KiB
Go
package atproto
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
// Profile record key is always "self" per lexicon
|
|
const ProfileRKey = "self"
|
|
|
|
// EnsureProfile checks if a user's profile exists and creates it if needed
|
|
// This should be called during authentication (OAuth exchange or token service)
|
|
// If defaultHoldEndpoint is provided and profile doesn't exist, creates profile with that default
|
|
func EnsureProfile(ctx context.Context, client *Client, defaultHoldEndpoint string) error {
|
|
// Check if profile already exists
|
|
profile, err := client.GetRecord(ctx, SailorProfileCollection, ProfileRKey)
|
|
if err == nil && profile != nil {
|
|
// Profile exists, nothing to do
|
|
return nil
|
|
}
|
|
|
|
// Profile doesn't exist
|
|
// Only create if we have a default hold endpoint to set
|
|
if defaultHoldEndpoint == "" {
|
|
// No default configured, don't create empty profile
|
|
return nil
|
|
}
|
|
|
|
// Create new profile with default hold
|
|
newProfile := NewSailorProfileRecord(defaultHoldEndpoint)
|
|
|
|
_, err = client.PutRecord(ctx, SailorProfileCollection, ProfileRKey, newProfile)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create sailor profile: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetProfile retrieves the user's profile from their PDS
|
|
// Returns nil if profile doesn't exist
|
|
func GetProfile(ctx context.Context, client *Client) (*SailorProfileRecord, error) {
|
|
record, err := client.GetRecord(ctx, SailorProfileCollection, ProfileRKey)
|
|
if err != nil {
|
|
// Check if it's a 404 (profile doesn't exist)
|
|
if isNotFoundError(err) {
|
|
return nil, nil
|
|
}
|
|
return nil, fmt.Errorf("failed to get profile: %w", err)
|
|
}
|
|
|
|
// Parse the profile record
|
|
var profile SailorProfileRecord
|
|
if err := json.Unmarshal(record.Value, &profile); err != nil {
|
|
return nil, fmt.Errorf("failed to parse profile: %w", err)
|
|
}
|
|
|
|
return &profile, nil
|
|
}
|
|
|
|
// UpdateProfile updates the user's profile
|
|
func UpdateProfile(ctx context.Context, client *Client, profile *SailorProfileRecord) error {
|
|
_, err := client.PutRecord(ctx, SailorProfileCollection, ProfileRKey, profile)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to update profile: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// isNotFoundError checks if an error is a 404 not found error
|
|
func isNotFoundError(err error) bool {
|
|
// This is a simple check - in practice, you might need to parse the error more carefully
|
|
if err == nil {
|
|
return false
|
|
}
|
|
errStr := err.Error()
|
|
return contains(errStr, "404") || contains(errStr, "not found") || contains(errStr, "RecordNotFound")
|
|
}
|
|
|
|
// contains checks if a string contains a substring (case-insensitive helper)
|
|
func contains(s, substr string) bool {
|
|
return len(s) >= len(substr) && (s == substr || len(s) > len(substr) &&
|
|
(s[:len(substr)] == substr || s[len(s)-len(substr):] == substr ||
|
|
findSubstring(s, substr)))
|
|
}
|
|
|
|
func findSubstring(s, substr string) bool {
|
|
for i := 0; i <= len(s)-len(substr); i++ {
|
|
if s[i:i+len(substr)] == substr {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|