in lib/auditlogsapi/filters.go [56:123]
func parseExp(s string) (*exp, error) {
s = strings.TrimSpace(s)
matches := expRE.FindAllStringSubmatch(s, -1)
if len(matches) == 0 {
return nil, status.Errorf(codes.InvalidArgument, "unknown expression format")
}
ss := matches[0][1:]
var field expField
for _, f := range allowFields {
if ss[0] == string(f) {
field = f
}
}
if len(field) == 0 {
return nil, status.Errorf(codes.InvalidArgument, "unknown expression field: %s", ss[0])
}
switch field {
case fieldTime:
// time allows >= and <=
if ss[1] != string(gte) && ss[1] != string(lte) {
return nil, status.Errorf(codes.InvalidArgument, "not allowed op for time field: %s", ss[1])
}
case fieldType:
// type allows =
if ss[1] != string(equals) {
return nil, status.Errorf(codes.InvalidArgument, "not allowed op for type field: %s", ss[1])
}
case fieldText:
// text allows : and =
if ss[1] != string(equals) && ss[1] != string(contains) {
return nil, status.Errorf(codes.InvalidArgument, "not allowed op for text field: %s", ss[1])
}
case fieldDecision:
// decision allows =
if ss[1] != string(equals) {
return nil, status.Errorf(codes.InvalidArgument, "not allowed op for decision field: %s", ss[1])
}
default:
return nil, status.Errorf(codes.Internal, "unknown expression field in op checker: %s", field)
}
op := expOp(ss[1])
value := strings.Trim(ss[2], `"`)
if field == fieldTime {
if _, err := time.Parse(time.RFC3339, value); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "time value not in RFC3339 format: %s", value)
}
}
if field == fieldType {
if value != apb.LogType_REQUEST.String() && value != apb.LogType_POLICY.String() {
return nil, status.Errorf(codes.InvalidArgument, "type value not allowed: %s", value)
}
}
if field == fieldDecision {
value = strings.ToUpper(value)
if value != apb.Decision_PASS.String() && value != apb.Decision_FAIL.String() {
return nil, status.Errorf(codes.InvalidArgument, "decision value not allowed: %s", value)
}
}
return &exp{field: field, op: op, value: value}, nil
}