feat: authsession service
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
package testkit
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"galaxy/authsession/internal/domain/common"
|
||||
"galaxy/authsession/internal/ports"
|
||||
)
|
||||
|
||||
// SequenceIDGenerator is a deterministic IDGenerator double that consumes
|
||||
// queued identifiers before falling back to monotonic generated ids.
|
||||
type SequenceIDGenerator struct {
|
||||
mu sync.Mutex
|
||||
|
||||
// ChallengeIDs stores queued challenge identifiers returned by
|
||||
// NewChallengeID before generated ids are used.
|
||||
ChallengeIDs []common.ChallengeID
|
||||
|
||||
// DeviceSessionIDs stores queued device-session identifiers returned by
|
||||
// NewDeviceSessionID before generated ids are used.
|
||||
DeviceSessionIDs []common.DeviceSessionID
|
||||
|
||||
// ChallengeErr is returned directly from NewChallengeID when set.
|
||||
ChallengeErr error
|
||||
|
||||
// DeviceSessionErr is returned directly from NewDeviceSessionID when set.
|
||||
DeviceSessionErr error
|
||||
|
||||
ChallengePrefix string
|
||||
DeviceSessionPrefix string
|
||||
nextChallengeNumber int
|
||||
nextSessionNumber int
|
||||
}
|
||||
|
||||
// NewChallengeID returns the next deterministic challenge identifier.
|
||||
func (g *SequenceIDGenerator) NewChallengeID() (common.ChallengeID, error) {
|
||||
if g.ChallengeErr != nil {
|
||||
return "", g.ChallengeErr
|
||||
}
|
||||
|
||||
g.mu.Lock()
|
||||
defer g.mu.Unlock()
|
||||
|
||||
if len(g.ChallengeIDs) > 0 {
|
||||
id := g.ChallengeIDs[0]
|
||||
g.ChallengeIDs = g.ChallengeIDs[1:]
|
||||
if err := id.Validate(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
g.nextChallengeNumber++
|
||||
prefix := g.ChallengePrefix
|
||||
if prefix == "" {
|
||||
prefix = "challenge-"
|
||||
}
|
||||
|
||||
id := common.ChallengeID(fmt.Sprintf("%s%d", prefix, g.nextChallengeNumber))
|
||||
if err := id.Validate(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
// NewDeviceSessionID returns the next deterministic device-session
|
||||
// identifier.
|
||||
func (g *SequenceIDGenerator) NewDeviceSessionID() (common.DeviceSessionID, error) {
|
||||
if g.DeviceSessionErr != nil {
|
||||
return "", g.DeviceSessionErr
|
||||
}
|
||||
|
||||
g.mu.Lock()
|
||||
defer g.mu.Unlock()
|
||||
|
||||
if len(g.DeviceSessionIDs) > 0 {
|
||||
id := g.DeviceSessionIDs[0]
|
||||
g.DeviceSessionIDs = g.DeviceSessionIDs[1:]
|
||||
if err := id.Validate(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
g.nextSessionNumber++
|
||||
prefix := g.DeviceSessionPrefix
|
||||
if prefix == "" {
|
||||
prefix = "device-session-"
|
||||
}
|
||||
|
||||
id := common.DeviceSessionID(fmt.Sprintf("%s%d", prefix, g.nextSessionNumber))
|
||||
if err := id.Validate(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
var _ ports.IDGenerator = (*SequenceIDGenerator)(nil)
|
||||
Reference in New Issue
Block a user