Skip to content

Commit f0cb3f3

Browse files
authored
feat: added support for returning total number of results in new Audit.SearchAll method (#493)
* feat: added support for returning total number of results in new SearchAll method feat: renamed option to set paging size by using the Limit option instead of the Size option (breaking but not in use yet by clients so not worth "dirtying" the API with unneeded aliases) chore: added files generated by running the local example to be ignored by gitleaks to avoid false leaks from appearing in pre-commit hooks * build: re-added test that calls the Deprecated Audit.Search method directly
1 parent b5970dd commit f0cb3f3

File tree

7 files changed

+56
-28
lines changed

7 files changed

+56
-28
lines changed

descope/internal/mgmt/audit.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type audit struct {
1717

1818
var _ sdk.Audit = &audit{}
1919

20-
func (a *audit) Search(ctx context.Context, options *descope.AuditSearchOptions) ([]*descope.AuditRecord, error) {
20+
func (a *audit) SearchAll(ctx context.Context, options *descope.AuditSearchOptions) ([]*descope.AuditRecord, int, error) {
2121
body := map[string]any{
2222
"userIds": options.UserIDs,
2323
"actions": options.Actions,
@@ -32,16 +32,22 @@ func (a *audit) Search(ctx context.Context, options *descope.AuditSearchOptions)
3232
"tenants": options.Tenants,
3333
"noTenants": options.NoTenants,
3434
"text": options.Text,
35-
"size": options.Size,
35+
"size": options.Limit,
3636
"page": options.Page,
3737
}
3838
res, err := a.client.DoPostRequest(ctx, api.Routes.ManagementAuditSearch(), body, nil, a.conf.ManagementKey)
3939
if err != nil {
40-
return nil, err
40+
return nil, 0, err
4141
}
4242
return unmarshalAuditRecords(res)
4343
}
4444

45+
// Deprecated: replaced by audit.SearchAll
46+
func (a *audit) Search(ctx context.Context, options *descope.AuditSearchOptions) ([]*descope.AuditRecord, error) {
47+
records, _, err := a.SearchAll(ctx, options)
48+
return records, err
49+
}
50+
4551
func (a *audit) CreateEvent(ctx context.Context, options *descope.AuditCreateOptions) error {
4652
if options.Action == "" {
4753
return utils.NewInvalidArgumentError("Action")
@@ -88,20 +94,21 @@ type apiAuditRecord struct {
8894

8995
type apiSearchAuditResponse struct {
9096
Audits []*apiAuditRecord
97+
Total int
9198
}
9299

93-
func unmarshalAuditRecords(res *api.HTTPResponse) ([]*descope.AuditRecord, error) {
100+
func unmarshalAuditRecords(res *api.HTTPResponse) ([]*descope.AuditRecord, int, error) {
94101
var auditRes *apiSearchAuditResponse
95102
err := utils.Unmarshal([]byte(res.BodyStr), &auditRes)
96103
if err != nil {
97104
// notest
98-
return nil, err
105+
return nil, 0, err
99106
}
100107
var records []*descope.AuditRecord
101108
for _, rec := range auditRes.Audits {
102109
occurred, err := strconv.ParseInt(rec.Occurred, 10, 64)
103110
if err != nil {
104-
return nil, err
111+
return nil, 0, err
105112
}
106113
records = append(records, &descope.AuditRecord{
107114
ProjectID: rec.ProjectID,
@@ -119,5 +126,5 @@ func unmarshalAuditRecords(res *api.HTTPResponse) ([]*descope.AuditRecord, error
119126
Type: rec.Type,
120127
})
121128
}
122-
return records, nil
129+
return records, auditRes.Total, nil
123130
}

descope/internal/mgmt/audit_test.go

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ func TestAuditSearch(t *testing.T) {
4242
Tenants: []string{"t1"},
4343
Data: map[string]interface{}{"x": "y1", "z": 2},
4444
},
45-
}}
45+
},
46+
Total: 2,
47+
}
4648
searchOptions := &descope.AuditSearchOptions{
4749
UserIDs: []string{"u1", "u2"},
4850
Actions: []string{"a1", "a2"},
@@ -56,7 +58,7 @@ func TestAuditSearch(t *testing.T) {
5658
Tenants: []string{"t1"},
5759
NoTenants: true,
5860
Text: "kuku",
59-
Size: 10,
61+
Limit: 10,
6062
Page: 1,
6163
}
6264
mgmt := newTestMgmt(nil, helpers.DoOkWithBody(func(r *http.Request) {
@@ -77,24 +79,32 @@ func TestAuditSearch(t *testing.T) {
7779
require.EqualValues(t, []interface{}{searchOptions.Tenants[0]}, req["tenants"])
7880
require.EqualValues(t, searchOptions.NoTenants, req["noTenants"])
7981
require.EqualValues(t, searchOptions.Text, req["text"])
80-
require.EqualValues(t, searchOptions.Size, req["size"])
82+
require.EqualValues(t, searchOptions.Limit, req["size"])
8183
require.EqualValues(t, searchOptions.Page, req["page"])
8284
}, response))
85+
doAsserts := func(res []*descope.AuditRecord, err error) {
86+
require.NoError(t, err)
87+
require.Len(t, res, 2)
88+
assert.Equal(t, response.Audits[0].ProjectID, res[0].ProjectID)
89+
assert.Equal(t, response.Audits[0].UserID, res[0].UserID)
90+
assert.Equal(t, response.Audits[0].Action, res[0].Action)
91+
assert.Equal(t, response.Audits[0].Occurred, strconv.FormatInt(res[0].Occurred.UnixMilli(), 10))
92+
assert.Equal(t, response.Audits[0].Device, res[0].Device)
93+
assert.Equal(t, response.Audits[0].Method, res[0].Method)
94+
assert.Equal(t, response.Audits[0].Geo, res[0].Geo)
95+
assert.Equal(t, response.Audits[0].RemoteAddress, res[0].RemoteAddress)
96+
assert.EqualValues(t, response.Audits[0].ExternalIDs, res[0].LoginIDs)
97+
assert.EqualValues(t, response.Audits[0].Tenants, res[0].Tenants)
98+
assert.EqualValues(t, response.Audits[0].Data["x"], res[0].Data["x"])
99+
assert.True(t, called)
100+
}
101+
//run test for Deprecated Search API
83102
res, err := mgmt.Audit().Search(context.Background(), searchOptions)
84-
require.NoError(t, err)
85-
require.Len(t, res, 2)
86-
assert.Equal(t, response.Audits[0].ProjectID, res[0].ProjectID)
87-
assert.Equal(t, response.Audits[0].UserID, res[0].UserID)
88-
assert.Equal(t, response.Audits[0].Action, res[0].Action)
89-
assert.Equal(t, response.Audits[0].Occurred, strconv.FormatInt(res[0].Occurred.UnixMilli(), 10))
90-
assert.Equal(t, response.Audits[0].Device, res[0].Device)
91-
assert.Equal(t, response.Audits[0].Method, res[0].Method)
92-
assert.Equal(t, response.Audits[0].Geo, res[0].Geo)
93-
assert.Equal(t, response.Audits[0].RemoteAddress, res[0].RemoteAddress)
94-
assert.EqualValues(t, response.Audits[0].ExternalIDs, res[0].LoginIDs)
95-
assert.EqualValues(t, response.Audits[0].Tenants, res[0].Tenants)
96-
assert.EqualValues(t, response.Audits[0].Data["x"], res[0].Data["x"])
97-
assert.True(t, called)
103+
doAsserts(res, err)
104+
//run test for SearchAll API, and also assert the value of the "total" return value
105+
res, total, err := mgmt.Audit().SearchAll(context.Background(), searchOptions)
106+
doAsserts(res, err)
107+
assert.Equal(t, 2, total)
98108
}
99109

100110
func TestAuditCreate(t *testing.T) {

descope/sdk/mgmt.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,8 @@ type Project interface {
742742

743743
// Provides search project audit trail
744744
type Audit interface {
745-
Search(ctx context.Context, options *descope.AuditSearchOptions) ([]*descope.AuditRecord, error)
745+
Search(ctx context.Context, options *descope.AuditSearchOptions) ([]*descope.AuditRecord, error) // Deprecated: replaced by Audit.SearchAll
746+
SearchAll(ctx context.Context, options *descope.AuditSearchOptions) ([]*descope.AuditRecord, int, error)
746747
CreateEvent(ctx context.Context, options *descope.AuditCreateOptions) error
747748
}
748749

descope/tests/mocks/mgmt/managementmock.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,7 @@ func (m *MockProject) ListProjects(_ context.Context) ([]*descope.Project, error
12901290
type MockAudit struct {
12911291
SearchAssert func(*descope.AuditSearchOptions)
12921292
SearchResponse []*descope.AuditRecord
1293+
SearchTotal int
12931294
SearchError error
12941295

12951296
CreateEventAssert func(*descope.AuditCreateOptions)
@@ -1303,6 +1304,13 @@ func (m *MockAudit) Search(_ context.Context, options *descope.AuditSearchOption
13031304
return m.SearchResponse, m.SearchError
13041305
}
13051306

1307+
func (m *MockAudit) SearchAll(_ context.Context, options *descope.AuditSearchOptions) ([]*descope.AuditRecord, int, error) {
1308+
if m.SearchAssert != nil {
1309+
m.SearchAssert(options)
1310+
}
1311+
return m.SearchResponse, m.SearchTotal, m.SearchError
1312+
}
1313+
13061314
func (m *MockAudit) CreateEvent(_ context.Context, options *descope.AuditCreateOptions) error {
13071315
if m.CreateEventAssert != nil {
13081316
m.CreateEventAssert(options)

descope/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ type AuditSearchOptions struct {
870870
Tenants []string `json:"tenants"` // List of tenants to filter by
871871
NoTenants bool `json:"noTenants"` // Should audits without any tenants always be included
872872
Text string `json:"text"` // Free text search across all fields
873-
Size int32 `json:"size,omitempty"` // Number of results to include per retrived page. Current default, and max value, is 1000.
873+
Limit int32 `json:"limit,omitempty"` // Number of results to include per retrieved page. Current default, and max value, is 1000
874874
Page int32 `json:"page,omitempty"` // Page number of results to retrieve, zero-based. Default is 0.
875875
}
876876

examples/webapp/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,11 +565,11 @@ func handleStepupStepupVerify(w http.ResponseWriter, r *http.Request) {
565565

566566
func handleAuditSearch(w http.ResponseWriter, r *http.Request) {
567567
searchOptions := &descope.AuditSearchOptions{}
568-
auditSearchRes, err := descopeClient.Management.Audit().Search(r.Context(), searchOptions)
568+
auditSearchRes, total, err := descopeClient.Management.Audit().SearchAll(r.Context(), searchOptions)
569569
if err != nil {
570570
setError(w, err.Error())
571571
} else {
572-
helpTxt := fmt.Sprintf("Audit Search Results (%d Results Returned):\n", len(auditSearchRes))
572+
helpTxt := fmt.Sprintf("Audit Search Results (%d Results Returned, %d Total):\n", len(auditSearchRes), total)
573573
mr, _ := json.MarshalIndent(auditSearchRes, "", "\t")
574574
helpTxt += string(mr) + "\n"
575575
setResponse(w, http.StatusOK, helpTxt)

scripts/lint/gitleaks.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,4 +651,6 @@ paths = [
651651
'''(.*?)(jpg|gif|doc|pdf|bin|svg|socket)$''',
652652
'''(go.mod|go.sum)$''',
653653
"vendor/",
654+
"examples/key.pem",
655+
"examples/cert.pem",
654656
]

0 commit comments

Comments
 (0)