package handlers import ( "context" "encoding/json" "net/http" "slices" "strings" "otaupdate/services" "github.com/fiskerinc/cloud-services/pkg/common" "github.com/fiskerinc/cloud-services/pkg/logger" "github.com/fiskerinc/cloud-services/pkg/loggerdataresp" "github.com/fiskerinc/cloud-services/pkg/tmobile" ) // FIX BUG: current system allows for vins to be tmobile activated, // but because we don't have them, we don't get them in response list // HandleCarsAllowedAccess godoc // @Summary Fetch the list of VINs that can connect to fisker cloud // @Description Note: when a VIN is added or removed, changes will take time to propagate to the network filters // @Accept json // @Produce json // @Param Authorization header string false "Bearer " // @Param Api-Key header string false "" // @Success 200 {object} HandleCarsAllowedAccessResponse // @Failure 400 {object} common.JSONError "Bad request" // @Failure 401 {object} common.JSONError "Unauthorized" // @Failure 503 {object} common.JSONError "Service unavailable" // @Router /cars/allowed_access [get] func HandleCarsAllowedAccess(w http.ResponseWriter, r *http.Request) { var err error res := HandleCarsAllowedAccessResponse{} res.AllowedVINs, err = fetchVINList() if loggerdataresp.BadDataErrorResp(w, err, http.StatusBadRequest) { return } res.AllowAll = len(res.AllowedVINs) == 0 err = json.NewEncoder(w).Encode(res) loggerdataresp.BadDataErrorResp(w, err, http.StatusInternalServerError) } type HandleCarsAllowedAccessResponse struct { AllowAll bool `json:"allow_all"` AllowedVINs []string `json:"allowed_vins"` } func fetchVINList() (vins []string, err error) { vins, err = services.GetDB().GetCars().GetWhiteListCars() return } // HandleCarsAllowedAccess godoc // @Summary Check if a single VIN has cloud and t-mobile access // @Description // @Accept json // @Produce json // @Param Authorization header string false "Bearer " // @Param Api-Key header string false "" // @Param VINList body HandleAccessCheckInput true "List of VINs to check" // @Success 200 {object} HandleAccessCheckResponse // @Failure 400 {object} common.JSONError "Bad request" // @Failure 401 {object} common.JSONError "Unauthorized" // @Failure 503 {object} common.JSONError "Service unavailable" // @Router /cars/allowed_access [post] func HandleCarAllowedAccess(w http.ResponseWriter, r *http.Request) { vinput := HandleAccessCheckInput{} err := json.NewDecoder(r.Body).Decode(&vinput) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } results, err := CarAllowedAccess(vinput.VINs) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } res := HandleAccessCheckResponse{ VINStatuses: results, } err = json.NewEncoder(w).Encode(res) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } } func CarAllowedAccess(vins []string) (results []AllowedStruct, err error) { var allowedVINs []string allowedVINs, err = fetchVINList() if err != nil { return } slices.Sort(allowedVINs) carDB := services.GetDB().GetCars() tmobileClient, err := tmobile.NewTMobileMiniClient() if err != nil { return } results = make([]AllowedStruct, 0, len(vins)) for _, v := range vins { temp := AllowedStruct{} temp.VIN = v temp.CloudAccess = slices.Contains(allowedVINs, v) // Slow but I dont give a damn var car *common.Car car, err = carDB.SelectByVIN(v) if err != nil { logger.Err(err).Msg("failed to select car by vin") } else if car.ICCID != "" && car.ICCID != "N/A" { car.ICCID = strings.TrimSuffix(car.ICCID, "F") var details *tmobile.DeviceDetailsResponse input := tmobile.DeviceDetailsRequest{ ICCID: car.ICCID, } details, err = tmobileClient.DeviceDetails(context.Background(), &input) if err != nil { break } temp.TMobileStatus = string(details.Status) } else { temp.TMobileStatus = "INVALID ICCID" } results = append(results, temp) } return } type HandleAccessCheckInput struct { VINs []string `json:"vins"` } type HandleAccessCheckResponse struct { VINStatuses []AllowedStruct `json:"vin_statuses"` } type AllowedStruct struct { VIN string `json:"vin"` CloudAccess bool `json:"cloud_access"` TMobileStatus string `json:"tmobile_access"` }