44 lines
1.6 KiB
Go
44 lines
1.6 KiB
Go
package ports
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"galaxy/authsession/internal/domain/challenge"
|
|
"galaxy/authsession/internal/domain/common"
|
|
)
|
|
|
|
// ChallengeStore provides source-of-truth persistence for auth confirmation
|
|
// challenges without exposing storage-specific primitives.
|
|
type ChallengeStore interface {
|
|
// Get returns the stored challenge for challengeID. Implementations must
|
|
// wrap ErrNotFound when challengeID does not exist.
|
|
Get(ctx context.Context, challengeID common.ChallengeID) (challenge.Challenge, error)
|
|
|
|
// Create persists record as a new challenge. Implementations must wrap
|
|
// ErrConflict when record.ID already exists.
|
|
Create(ctx context.Context, record challenge.Challenge) error
|
|
|
|
// CompareAndSwap replaces previous with next when the currently stored
|
|
// challenge matches previous exactly. Implementations must wrap ErrConflict
|
|
// when the stored challenge differs from previous and wrap ErrNotFound when
|
|
// previous.ID does not exist.
|
|
CompareAndSwap(ctx context.Context, previous challenge.Challenge, next challenge.Challenge) error
|
|
}
|
|
|
|
// ValidateComparableChallenges reports whether previous and next are suitable
|
|
// for one ChallengeStore compare-and-swap call.
|
|
func ValidateComparableChallenges(previous challenge.Challenge, next challenge.Challenge) error {
|
|
if err := previous.Validate(); err != nil {
|
|
return fmt.Errorf("previous challenge: %w", err)
|
|
}
|
|
if err := next.Validate(); err != nil {
|
|
return fmt.Errorf("next challenge: %w", err)
|
|
}
|
|
if previous.ID != next.ID {
|
|
return fmt.Errorf("challenge compare-and-swap ids must match: %q != %q", previous.ID, next.ID)
|
|
}
|
|
|
|
return nil
|
|
}
|