84 lines
2.0 KiB
Go
84 lines
2.0 KiB
Go
package sloppy
|
|
|
|
import (
|
|
"slices"
|
|
"sync"
|
|
"time"
|
|
|
|
"fiskerinc.com/modules/logger"
|
|
"fiskerinc.com/modules/utils/whereami"
|
|
)
|
|
|
|
var vinblocker *VINBlocker
|
|
var vinblockerOnce sync.Once
|
|
|
|
// VIN Blocker fetches the list of allowed vins once per day, and stores them locally to check against
|
|
func GetVINBlocker() *VINBlocker {
|
|
vinblockerOnce.Do(func() {
|
|
vinblocker = newVINBlocker()
|
|
})
|
|
return vinblocker
|
|
}
|
|
|
|
type VINBlocker struct {
|
|
allowedList []string // The list of vins to allow
|
|
allowAll bool // Should we allow all vins to be used
|
|
sync.RWMutex // Control overwriting the allowed list
|
|
}
|
|
|
|
func newVINBlocker() (vb *VINBlocker) {
|
|
vb = &VINBlocker{}
|
|
vb.allowAll = true // This will for half a second allow all cars to access cloud
|
|
// create a new thread to get the list of vins everyday
|
|
//On dev, always allow all connections
|
|
if whereami.Environment != whereami.DEVELOPMENT {
|
|
vb.updateVINList() // Run in thread, so no sneaks can happen
|
|
go vb.autoUpdate()
|
|
}
|
|
return vb
|
|
}
|
|
|
|
func (vb *VINBlocker) IsVINAllowed(vin string) (allow bool) {
|
|
// We are allowing all vins to connect
|
|
if vb.allowAll {
|
|
return true
|
|
}
|
|
|
|
vb.RLock()
|
|
defer vb.RUnlock()
|
|
// Returns the index of where the string might be, annoying
|
|
_, allow = slices.BinarySearch(vb.allowedList, vin)
|
|
return allow
|
|
}
|
|
|
|
func (vb *VINBlocker) autoUpdate() {
|
|
vb.updateVINList()
|
|
// Going to be pretty actively changed, so should change this to more detect when vin list is diff
|
|
nextRun := time.Now().Add(1 * time.Hour)
|
|
time.AfterFunc(time.Until(nextRun), vb.autoUpdate)
|
|
}
|
|
|
|
func (vb *VINBlocker) updateVINList() {
|
|
tempList := fetchVINList()
|
|
vb.Lock()
|
|
defer vb.Unlock()
|
|
if len(tempList) == 0 {
|
|
vb.allowAll = true
|
|
} else {
|
|
vb.allowAll = false
|
|
}
|
|
vb.allowedList = tempList
|
|
}
|
|
|
|
func fetchVINList() (vinList []string) {
|
|
carsDB := GetCarsDB()
|
|
var err error
|
|
vinList, err = carsDB.GetWhiteListCars()
|
|
if err != nil {
|
|
logger.Err(err).Msg("Failed to vinBlocker list")
|
|
}
|
|
// making sure the results are sorted
|
|
slices.Sort(vinList)
|
|
return
|
|
}
|