A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go
73
fork

Configure Feed

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

at refactor 87 lines 2.9 kB view raw
1package auth 2 3import ( 4 "context" 5 "fmt" 6 "log/slog" 7 8 "atcr.io/pkg/atproto" 9) 10 11// HoldAuthorizer checks if a DID has read/write access to a hold 12// Implementations can query local PDS (hold service) or remote XRPC (appview) 13type HoldAuthorizer interface { 14 // CheckReadAccess checks if userDID can read from holdDID 15 // Returns: (allowed bool, error) 16 CheckReadAccess(ctx context.Context, holdDID, userDID string) (bool, error) 17 18 // CheckWriteAccess checks if userDID can write to holdDID 19 // Returns: (allowed bool, error) 20 CheckWriteAccess(ctx context.Context, holdDID, userDID string) (bool, error) 21 22 // GetCaptainRecord retrieves the captain record for a hold 23 // Used to check public flag and allowAllCrew settings 24 GetCaptainRecord(ctx context.Context, holdDID string) (*atproto.CaptainRecord, error) 25 26 // IsCrewMember checks if userDID is a crew member of holdDID 27 IsCrewMember(ctx context.Context, holdDID, userDID string) (bool, error) 28} 29 30// CheckReadAccessWithCaptain implements the standard read authorization logic 31// This is shared across all HoldAuthorizer implementations 32// Read access rules: 33// - Public hold: allow anyone (even anonymous) 34// - Private hold: require authentication (any authenticated user) 35func CheckReadAccessWithCaptain(captain *atproto.CaptainRecord, userDID string) bool { 36 if captain.Public { 37 // Public hold - allow anyone (even anonymous) 38 return true 39 } 40 41 // Private hold - require authentication 42 // Any authenticated user with a DID can read 43 if userDID == "" { 44 // Anonymous user trying to access private hold 45 return false 46 } 47 48 // For MVP: assume DID presence means they have sailor.profile 49 // Future: could query PDS to verify sailor.profile exists 50 return true 51} 52 53// CheckWriteAccessWithCaptain implements the standard write authorization logic 54// This is shared across all HoldAuthorizer implementations 55// Write access rules: 56// - Must be authenticated 57// - Must be hold owner OR crew member 58func CheckWriteAccessWithCaptain(captain *atproto.CaptainRecord, userDID string, isCrew bool) bool { 59 slog.Debug("Checking write access", "userDID", userDID, "owner", captain.Owner, "isCrew", isCrew) 60 61 if userDID == "" { 62 // Anonymous writes not allowed 63 slog.Debug("Write access denied: anonymous user") 64 return false 65 } 66 67 // Check if DID is the hold owner 68 if userDID == captain.Owner { 69 // Owner always has write access 70 slog.Debug("Write access allowed: user is hold owner") 71 return true 72 } 73 74 // Check if DID is a crew member 75 if isCrew { 76 slog.Debug("Write access allowed: user is crew member") 77 } else { 78 slog.Debug("Write access denied: user is not owner or crew") 79 } 80 return isCrew 81} 82 83// ErrHoldNotFound is returned when a hold's captain record cannot be found 84var ErrHoldNotFound = fmt.Errorf("hold not found") 85 86// ErrUnauthorized is returned when access is denied 87var ErrUnauthorized = fmt.Errorf("unauthorized")