Skip to content

Commit

Permalink
feat(#246): allow searching for a small list of identity_subjects
Browse files Browse the repository at this point in the history
  • Loading branch information
Jumpy-Squirrel committed Dec 17, 2024
1 parent c9bba4e commit f30c836
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 3 deletions.
15 changes: 15 additions & 0 deletions api/openapi-spec/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2231,6 +2231,21 @@ components:
sponsor-items: 1
key-hand-out: 0
overdue: 1
identity_subjects:
description: |-
exact match to search for a set of OIDC subjects as cached in registrations. No condition if left empty.
IMPORTANT: Use of this field is limited to 8 identities, any additional identities in you list will be silently ignored!
If you need to check a large number of identities, please request the identity_subject search result field,
and filter on your end!
Note that caching of identities is configuration dependent, if disabled, no registrations will ever match if this is set.
type: array
maxItems: 8
items:
type: string
example:
- '1234567890'
ChoiceStateCondition:
type: integer
format: int64
Expand Down
1 change: 1 addition & 0 deletions internal/api/v1/attendee/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type AttendeeSearchSingleCriterion struct {
Permissions map[string]int8 `json:"permissions"`
AdminComments string `json:"admin_comments"`
AddInfo map[string]int8 `json:"add_info"` // can only search for presence of a value for each area, Note: special area 'overdue'
IdentitySubjects []string `json:"identity_subjects"`
}

// --- search result ---
Expand Down
11 changes: 10 additions & 1 deletion internal/repository/database/inmemorydb/match.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/eurofurence/reg-attendee-service/internal/repository/config"
"github.com/eurofurence/reg-attendee-service/internal/web/util/validation"
"github.com/ryanuber/go-glob"
"slices"
"strconv"
"strings"
)
Expand Down Expand Up @@ -48,7 +49,8 @@ func (r *InMemoryRepository) matches(cond *attendee.AttendeeSearchSingleCriterio
matchesSubstringGlobOrEmpty(cond.AdminComments, adm.AdminComments) &&
matchesAddInfoPresence(cond.AddInfo, addInf) &&
matchesOverdue(cond.AddInfo, a.CacheDueDate, r.Now().Format(config.IsoDateFormat), st.Status) &&
matchesIsoDateRange(cond.BirthdayFrom, cond.BirthdayTo, a.Birthday)
matchesIsoDateRange(cond.BirthdayFrom, cond.BirthdayTo, a.Birthday) &&
matchesIdentitySubjects(cond.IdentitySubjects, a.Identity)
}

func matchesUintSliceOrEmpty(cond []uint, value uint) bool {
Expand Down Expand Up @@ -183,3 +185,10 @@ func matchesIsoDateRange(condFrom string, condTo string, value string) bool {
}
return true
}

func matchesIdentitySubjects(cond []string, value string) bool {
if len(cond) > 8 {
cond = cond[:8]
}
return len(cond) == 0 || slices.Contains(cond, value)
}
20 changes: 20 additions & 0 deletions internal/repository/database/mysqldb/searchquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@ func (r *MysqlRepository) addSingleCondition(cond *attendee.AttendeeSearchSingle
if cond.BirthdayTo != "" {
query.WriteString(stringLessThanOrEqual("a.birthday", cond.BirthdayTo, params, paramBaseName, &paramNo))
}
if len(cond.IdentitySubjects) > 0 {
query.WriteString(stringSliceMatch("a.identity", cond.IdentitySubjects, params, paramBaseName, &paramNo))
}

return query.String()
}
Expand Down Expand Up @@ -315,6 +318,23 @@ func safeStatusSliceMatch(field string, values []status.Status) string {
return fmt.Sprintf(" AND ( %s IN (%s) )\n", field, strings.Join(mappedValues, ","))
}

func stringSliceMatch(field string, values []string, params map[string]interface{}, paramBaseName string, idx *int) string {
var result strings.Builder
result.WriteString(fmt.Sprintf(" AND ( %s IN ( ", field))
cond := make([]string, 0)
for i, v := range values {
if i < 8 {
pName := fmt.Sprintf("%s_%d_%d", paramBaseName, *idx, i+1)
params[pName] = v
cond = append(cond, "@"+pName)
}
}
*idx++
result.WriteString(strings.Join(cond, " , "))
result.WriteString(" ) )\n")
return result.String()
}

func substringMatch(field string, condition string, params map[string]interface{}, paramBaseName string, idx *int) string {
return fullstringMatch(field, "*"+condition+"*", params, paramBaseName, idx)
}
Expand Down
8 changes: 6 additions & 2 deletions internal/repository/database/mysqldb/searchquery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,9 @@ func TestTwoFullSearchQueries(t *testing.T) {
"overdue": 1,
"sponsor-items": 1,
},
BirthdayFrom: "1970-10-24",
BirthdayTo: "1980-12-24",
BirthdayFrom: "1970-10-24",
BirthdayTo: "1980-12-24",
IdentitySubjects: []string{"Q1E4D2", "R1E5DD"},
},
},
MinId: 1,
Expand Down Expand Up @@ -158,6 +159,8 @@ func TestTwoFullSearchQueries(t *testing.T) {
"param_2_1": "small%bird",
"param_2_2": "Johnny",
"param_2_20": "1980-12-24",
"param_2_21_1": "Q1E4D2",
"param_2_21_2": "R1E5DD",
"param_2_3": "%Berlin%",
"param_2_4": "CH",
"param_2_5": "%gg@hh%",
Expand Down Expand Up @@ -238,6 +241,7 @@ WHERE (
AND ( ( SELECT COUNT(*) FROM att_additional_infos WHERE attendee_id = a.id AND area = @param_2_18_2 ) > 0 )
AND ( STRCMP(a.birthday,@param_2_19) >= 0 )
AND ( STRCMP(a.birthday,@param_2_20) <= 0 )
AND ( a.identity IN ( @param_2_21_1 , @param_2_21_2 ) )
)
) AND a.id >= @param_0_1 AND a.id <= @param_0_2 ORDER BY CONCAT(a.first_name, ' ', a.last_name) DESC`

Expand Down

0 comments on commit f30c836

Please sign in to comment.