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 }