case 4717 - KPI interval accepted only as a known date unit
Six KPIs put the request's interval criterion into the query as
DATE_TRUNC('<interval>', ...) unchecked, reachable by staff down to
TechRestricted (security review F26). New KPIFetcher.DateTruncUnitOrNull
accepts only PostgreSQL's date_trunc unit names (any case); the seven KPIs that
read interval refuse anything else with "Invalid 'interval' criteria", the same
form as their existing missing-criteria errors. The client only sends day or
month. (WorkOrderByStatusList reads interval without using it; checked too.)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,19 @@ namespace AyaNova.KPI
|
||||
internal static class KPIFetcher
|
||||
{
|
||||
|
||||
//case 4717: the date_trunc field names PostgreSQL accepts; anything else in a KPI interval is refused
|
||||
private static readonly System.Collections.Generic.HashSet<string> DateTruncUnits = new System.Collections.Generic.HashSet<string> {
|
||||
"microseconds", "milliseconds", "second", "minute", "hour", "day", "week",
|
||||
"month", "quarter", "year", "decade", "century", "millennium" };
|
||||
|
||||
internal static string DateTruncUnitOrNull(string unit)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(unit))
|
||||
return null;
|
||||
unit = unit.Trim().ToLowerInvariant();
|
||||
return DateTruncUnits.Contains(unit) ? unit : null;
|
||||
}
|
||||
|
||||
#if (AYSHOWKPIQUERYINFO)
|
||||
#if (DEBUG)
|
||||
#warning FYI AYSHOWKPIQUERYINFO is defined
|
||||
|
||||
@@ -55,7 +55,13 @@ namespace AyaNova.KPI
|
||||
}
|
||||
|
||||
var timeSpan = (string)options.Criteria["timeSpan"];
|
||||
var interval = (string)options.Criteria["interval"];
|
||||
//case 4717: interval goes into DATE_TRUNC in the query, so only PostgreSQL's own unit names are accepted
|
||||
var interval = KPIFetcher.DateTruncUnitOrNull((string)options.Criteria["interval"]);
|
||||
if (interval == null)
|
||||
{
|
||||
_errorMessage = "Invalid 'interval' criteria";
|
||||
return;
|
||||
}
|
||||
var dateWhere = DataListSqlFilterCriteriaBuilder.DataFilterToColumnCriteria("aworkorder.createddate", UiFieldDataType.DateTime, "no-operator", timeSpan, options.ClientTimeStamp);
|
||||
|
||||
var wotags = options.Criteria["wotags"].ToObject<List<string>>();
|
||||
|
||||
@@ -41,7 +41,13 @@ AuthorizationRoles.Accounting;
|
||||
}
|
||||
|
||||
var timeSpan = (string)options.Criteria["timeSpan"];
|
||||
var interval = (string)options.Criteria["interval"];
|
||||
//case 4717: interval goes into DATE_TRUNC in the query, so only PostgreSQL's own unit names are accepted
|
||||
var interval = KPIFetcher.DateTruncUnitOrNull((string)options.Criteria["interval"]);
|
||||
if (interval == null)
|
||||
{
|
||||
_errorMessage = "Invalid 'interval' criteria";
|
||||
return;
|
||||
}
|
||||
var dateWhere = DataListSqlFilterCriteriaBuilder.DataFilterToColumnCriteria("aworkorder.createddate", UiFieldDataType.DateTime, "no-operator", timeSpan, options.ClientTimeStamp);
|
||||
var wotags = options.Criteria["wotags"].ToObject<List<string>>();
|
||||
bool wotagsany = options.Criteria["wotagsany"].ToObject<bool>();
|
||||
|
||||
@@ -41,7 +41,13 @@ AuthorizationRoles.Accounting;
|
||||
}
|
||||
|
||||
var timeSpan = (string)options.Criteria["timeSpan"];
|
||||
var interval = (string)options.Criteria["interval"];
|
||||
//case 4717: interval goes into DATE_TRUNC in the query, so only PostgreSQL's own unit names are accepted
|
||||
var interval = KPIFetcher.DateTruncUnitOrNull((string)options.Criteria["interval"]);
|
||||
if (interval == null)
|
||||
{
|
||||
_errorMessage = "Invalid 'interval' criteria";
|
||||
return;
|
||||
}
|
||||
var dateWhere = DataListSqlFilterCriteriaBuilder.DataFilterToColumnCriteria("aworkorder.createddate", UiFieldDataType.DateTime, "no-operator", timeSpan, options.ClientTimeStamp);
|
||||
var wotags = options.Criteria["wotags"].ToObject<List<string>>();
|
||||
bool wotagsany = options.Criteria["wotagsany"].ToObject<bool>();
|
||||
|
||||
@@ -42,7 +42,13 @@ AuthorizationRoles.Accounting;
|
||||
userWhere = $"AND aworkorderitemlabor.userid = {userid}";
|
||||
}
|
||||
var timeSpan = (string)options.Criteria["timeSpan"];
|
||||
var interval = (string)options.Criteria["interval"];
|
||||
//case 4717: interval goes into DATE_TRUNC in the query, so only PostgreSQL's own unit names are accepted
|
||||
var interval = KPIFetcher.DateTruncUnitOrNull((string)options.Criteria["interval"]);
|
||||
if (interval == null)
|
||||
{
|
||||
_errorMessage = "Invalid 'interval' criteria";
|
||||
return;
|
||||
}
|
||||
var dateWhere = DataListSqlFilterCriteriaBuilder.DataFilterToColumnCriteria("aworkorderitemlabor.servicestopdate", UiFieldDataType.DateTime, "no-operator", timeSpan, options.ClientTimeStamp);
|
||||
var techtags = options.Criteria["techtags"].ToObject<List<string>>();
|
||||
bool techtagsany = options.Criteria["techtagsany"].ToObject<bool>();
|
||||
|
||||
@@ -34,7 +34,13 @@ namespace AyaNova.KPI
|
||||
}
|
||||
|
||||
var timeSpan = (string)options.Criteria["timeSpan"];
|
||||
var interval = (string)options.Criteria["interval"];
|
||||
//case 4717: interval goes into DATE_TRUNC in the query, so only PostgreSQL's own unit names are accepted
|
||||
var interval = KPIFetcher.DateTruncUnitOrNull((string)options.Criteria["interval"]);
|
||||
if (interval == null)
|
||||
{
|
||||
_errorMessage = "Invalid 'interval' criteria";
|
||||
return;
|
||||
}
|
||||
var dateWhere = DataListSqlFilterCriteriaBuilder.DataFilterToColumnCriteria("aworkorderitemlabor.servicestopdate", UiFieldDataType.DateTime, "no-operator", timeSpan, options.ClientTimeStamp);
|
||||
var wotags = options.Criteria["wotags"].ToObject<List<string>>();
|
||||
bool wotagsany = options.Criteria["wotagsany"].ToObject<bool>();
|
||||
|
||||
@@ -41,7 +41,13 @@ namespace AyaNova.KPI
|
||||
}
|
||||
|
||||
var timeSpan = (string)options.Criteria["timeSpan"];
|
||||
var interval = (string)options.Criteria["interval"];
|
||||
//case 4717: interval goes into DATE_TRUNC in the query, so only PostgreSQL's own unit names are accepted
|
||||
var interval = KPIFetcher.DateTruncUnitOrNull((string)options.Criteria["interval"]);
|
||||
if (interval == null)
|
||||
{
|
||||
_errorMessage = "Invalid 'interval' criteria";
|
||||
return;
|
||||
}
|
||||
var dateWhere = DataListSqlFilterCriteriaBuilder.DataFilterToColumnCriteria("aworkorder.createddate", UiFieldDataType.DateTime, "no-operator", timeSpan, options.ClientTimeStamp);
|
||||
var wotags = options.Criteria["wotags"].ToObject<List<string>>();
|
||||
bool wotagsany = options.Criteria["wotagsany"].ToObject<bool>();
|
||||
|
||||
@@ -41,7 +41,13 @@ namespace AyaNova.KPI
|
||||
}
|
||||
|
||||
var timeSpan = (string)options.Criteria["timeSpan"];
|
||||
var interval = (string)options.Criteria["interval"];
|
||||
//case 4717: interval goes into DATE_TRUNC in the query, so only PostgreSQL's own unit names are accepted
|
||||
var interval = KPIFetcher.DateTruncUnitOrNull((string)options.Criteria["interval"]);
|
||||
if (interval == null)
|
||||
{
|
||||
_errorMessage = "Invalid 'interval' criteria";
|
||||
return;
|
||||
}
|
||||
var dateWhere = DataListSqlFilterCriteriaBuilder.DataFilterToColumnCriteria("aworkorder.createddate", UiFieldDataType.DateTime, "no-operator", timeSpan, options.ClientTimeStamp);
|
||||
var wotags = options.Criteria["wotags"].ToObject<List<string>>();
|
||||
bool wotagsany = options.Criteria["wotagsany"].ToObject<bool>();
|
||||
|
||||
Reference in New Issue
Block a user