go-captiveportal/registry.go

119 lines
1.7 KiB
Go

package captiveportal
import (
"sync"
)
type Client struct {
ID string
Captive bool
Lying bool
OS OS
}
type Registry struct {
mutex sync.RWMutex
clients map[string]*Client
}
func (r *Registry) Touch(id string, os OS) {
r.mutex.Lock()
defer r.mutex.Unlock()
client := r.upsert(id)
client.OS = os
}
func (r *Registry) Lie(id string) {
r.mutex.Lock()
defer r.mutex.Unlock()
client := r.upsert(id)
client.Lying = true
}
func (r *Registry) Release(id string) {
r.mutex.Lock()
defer r.mutex.Unlock()
client := r.upsert(id)
client.Captive = false
}
func (r *Registry) IsCaptive(id string) bool {
r.mutex.RLock()
defer r.mutex.RUnlock()
client, exists := r.clients[id]
if !exists {
return false
}
return client.Captive
}
func (r *Registry) ClientOS(id string) OS {
r.mutex.RLock()
defer r.mutex.RUnlock()
client, exists := r.clients[id]
if !exists {
return OSUnknown
}
return client.OS
}
func (r *Registry) IsLying(id string) bool {
r.mutex.RLock()
defer r.mutex.RUnlock()
client, exists := r.clients[id]
if !exists {
return false
}
return client.Lying
}
func (r *Registry) Delete(id string) {
r.mutex.Lock()
defer r.mutex.Unlock()
delete(r.clients, id)
}
func (r *Registry) Clients() []Client {
r.mutex.RLock()
defer r.mutex.RUnlock()
clients := make([]Client, 0, len(r.clients))
for _, c := range r.clients {
clients = append(clients, *c)
}
return clients
}
func (r *Registry) upsert(id string) *Client {
client, exists := r.clients[id]
if !exists {
client = &Client{
ID: id,
Captive: true,
Lying: false,
OS: OSUnknown,
}
r.clients[id] = client
}
return client
}
func NewRegistry() *Registry {
return &Registry{
clients: make(map[string]*Client),
}
}