safing-portmaster/spn/access/token/registry.go

116 lines
2.4 KiB
Go

package token
import "sync"
// Handler represents a token handling system.
type Handler interface {
// Zone returns the zone name.
Zone() string
// ShouldRequest returns whether the new tokens should be requested.
ShouldRequest() bool
// Amount returns the current amount of tokens in this handler.
Amount() int
// IsFallback returns whether this handler should only be used as a fallback.
IsFallback() bool
// GetToken returns a token.
GetToken() (token *Token, err error)
// Verify verifies the given token.
Verify(token *Token) error
// Save serializes and returns the current tokens.
Save() ([]byte, error)
// Load loads the given tokens into the handler.
Load(data []byte) error
// Clear clears all the tokens in the handler.
Clear()
}
var (
registry map[string]Handler
pblindRegistry []*PBlindHandler
scrambleRegistry []*ScrambleHandler
registryLock sync.RWMutex
)
func init() {
initRegistry()
}
func initRegistry() {
registry = make(map[string]Handler)
pblindRegistry = make([]*PBlindHandler, 0, 1)
scrambleRegistry = make([]*ScrambleHandler, 0, 1)
}
// RegisterPBlindHandler registers a pblind handler with the registry.
func RegisterPBlindHandler(h *PBlindHandler) error {
registryLock.Lock()
defer registryLock.Unlock()
if err := registerHandler(h, h.opts.Zone); err != nil {
return err
}
pblindRegistry = append(pblindRegistry, h)
return nil
}
// RegisterScrambleHandler registers a scramble handler with the registry.
func RegisterScrambleHandler(h *ScrambleHandler) error {
registryLock.Lock()
defer registryLock.Unlock()
if err := registerHandler(h, h.opts.Zone); err != nil {
return err
}
scrambleRegistry = append(scrambleRegistry, h)
return nil
}
func registerHandler(h Handler, zone string) error {
if zone == "" {
return ErrNoZone
}
_, ok := registry[zone]
if ok {
return ErrZoneTaken
}
registry[zone] = h
return nil
}
// GetHandler returns the handler of the given zone.
func GetHandler(zone string) (handler Handler, ok bool) {
registryLock.RLock()
defer registryLock.RUnlock()
handler, ok = registry[zone]
return
}
// ResetRegistry resets the token handler registry.
func ResetRegistry() {
registryLock.Lock()
defer registryLock.Unlock()
initRegistry()
}
// RegistrySize returns the amount of handler registered.
func RegistrySize() int {
registryLock.Lock()
defer registryLock.Unlock()
return len(registry)
}