feat(auth): enforce vehicle grant time boundaries
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package platform
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@@ -455,6 +457,7 @@ func buildDailyMileageSQL(query url.Values) SQLQuery {
|
||||
}
|
||||
where, args = appendVINListFilter(where, args, "m.vin", query.Get("vins"))
|
||||
where, args = appendVINListFilter(where, args, "m.vin", query.Get("scopeVins"))
|
||||
where, args = appendVehicleDateScope(where, args, "m.vin", "m.stat_date", query.Get("scopeVehicleFrom"))
|
||||
protocols := parseMileageProtocols(query.Get("protocols"))
|
||||
if len(protocols) > 0 {
|
||||
where, args = appendMileageProtocolFilter(where, args, "m.protocol", protocols)
|
||||
@@ -517,6 +520,7 @@ func buildMileageSummarySQL(query url.Values) SQLQuery {
|
||||
}
|
||||
where, args = appendVINListFilter(where, args, "m.vin", query.Get("vins"))
|
||||
where, args = appendVINListFilter(where, args, "m.vin", query.Get("scopeVins"))
|
||||
where, args = appendVehicleDateScope(where, args, "m.vin", "m.stat_date", query.Get("scopeVehicleFrom"))
|
||||
if protocols := parseMileageProtocols(query.Get("protocols")); len(protocols) > 0 {
|
||||
where, args = appendMileageProtocolFilter(where, args, "m.protocol", protocols)
|
||||
} else if protocol := strings.TrimSpace(query.Get("protocol")); protocol != "" {
|
||||
@@ -552,6 +556,7 @@ func buildMileageStatisticsWhere(query url.Values) (string, []any) {
|
||||
}
|
||||
where, args = appendVINListFilter(where, args, "m.vin", query.Get("vins"))
|
||||
where, args = appendVINListFilter(where, args, "m.vin", query.Get("scopeVins"))
|
||||
where, args = appendVehicleDateScope(where, args, "m.vin", "m.stat_date", query.Get("scopeVehicleFrom"))
|
||||
if protocols := parseMileageProtocols(query.Get("protocols")); len(protocols) > 0 {
|
||||
where, args = appendMileageProtocolFilter(where, args, "m.protocol", protocols)
|
||||
} else if protocol := strings.TrimSpace(query.Get("protocol")); protocol != "" {
|
||||
@@ -700,6 +705,40 @@ func appendVINListFilter(where []string, args []any, column string, raw string)
|
||||
return append(where, column+" IN ("+strings.Join(placeholders, ",")+")"), args
|
||||
}
|
||||
|
||||
func appendVehicleDateScope(where []string, args []any, vinColumn, dateColumn, raw string) ([]string, []any) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
return where, args
|
||||
}
|
||||
var parsed map[string]string
|
||||
if err := json.Unmarshal([]byte(raw), &parsed); err != nil || len(parsed) == 0 {
|
||||
return append(where, "1 = 0"), args
|
||||
}
|
||||
cutoffs := make(map[string]string, len(parsed))
|
||||
for vin, cutoff := range parsed {
|
||||
vin = strings.ToUpper(strings.TrimSpace(vin))
|
||||
cutoff = strings.TrimSpace(cutoff)
|
||||
if vin == "" || cutoff == "" {
|
||||
continue
|
||||
}
|
||||
cutoffs[vin] = cutoff
|
||||
}
|
||||
if len(cutoffs) == 0 {
|
||||
return append(where, "1 = 0"), args
|
||||
}
|
||||
vins := make([]string, 0, len(cutoffs))
|
||||
for vin := range cutoffs {
|
||||
vins = append(vins, vin)
|
||||
}
|
||||
sort.Strings(vins)
|
||||
predicates := make([]string, 0, len(vins))
|
||||
for _, vin := range vins {
|
||||
predicates = append(predicates, "("+vinColumn+" = ? AND "+dateColumn+" >= ?)")
|
||||
args = append(args, vin, cutoffs[vin])
|
||||
}
|
||||
return append(where, "("+strings.Join(predicates, " OR ")+")"), args
|
||||
}
|
||||
|
||||
func buildLimitOffset(query url.Values) (int, int) {
|
||||
return parseSQLPageSize(query.Get("limit"), 20), parsePositive(query.Get("offset"), 0)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user