You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
2.2 KiB
Go

package main
// Queue for pending authentication requests
import (
"crypto/rand"
"math/big"
"sync"
"time"
)
type AuthenticationMap struct {
requestMap map[string]*AuthRequest
app *App
requestMapMutex *sync.RWMutex
}
// Returns empty string when no request by that id is present
func (q *AuthenticationMap) GetRequestByID(ID string) *AuthRequest {
q.requestMapMutex.RLock()
req, ok := q.requestMap[ID]
q.requestMapMutex.RUnlock()
if !ok {
return nil
}
return req
}
func GenerateUniqueID() (string, error) {
length := 64
const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
ret := make([]byte, length)
for i := 0; i < length; i++ {
num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
if err != nil {
return "", err
}
ret[i] = letters[num.Int64()]
}
return string(ret), nil
}
func (q *AuthenticationMap) QueueRequest(r *AuthRequest) error {
var ID string
var err error
for {
ID, err = GenerateUniqueID()
if err != nil {
return err
}
q.requestMapMutex.Lock()
if _, exists := q.requestMap[ID]; exists {
q.requestMapMutex.Unlock()
continue
}
q.requestMapMutex.Unlock()
break
}
err = r.SetId(ID)
if err != nil {
return err
}
r.Queued = time.Now()
q.requestMapMutex.Lock()
q.requestMap[ID] = r
q.requestMapMutex.Unlock()
(*q.app.Logger).Info("Queued request by id: ", ID)
return nil
}
func (q *AuthenticationMap) Init() {
q.requestMap = make(map[string]*AuthRequest)
q.requestMapMutex = &sync.RWMutex{}
q.startRequestMapCleaner()
}
func (q *AuthenticationMap) startRequestMapCleaner() {
go func() {
for _ = range time.Tick(10 * time.Minute) {
q.requestMapMutex.Lock()
for key, req := range q.requestMap {
// If the request has been queued for more than 30
// minutes, it's time to delete it.
if req.Queued.Add(30 * time.Minute).Before(time.Now()) {
(*q.app.Logger).Info("Deleting inactive request with id: ", req.ID)
req.Cancel()
delete(q.requestMap, key)
}
}
q.requestMapMutex.Unlock()
}
}()
}
func (q *AuthenticationMap) Delete(ID string) {
q.requestMapMutex.Lock()
delete(q.requestMap, ID)
q.requestMapMutex.Unlock()
}