diff --git a/actions_resource.go b/actions_resource.go index fb16e253369848bd1c2ebe3f81cf4222d506baa7..094dc62cd16177d3e8215dae72c2acbf865d1c28 100644 --- a/actions_resource.go +++ b/actions_resource.go @@ -33,6 +33,7 @@ type SearchResourceRequest struct { AdminRequestBase Pattern string `json:"pattern"` + Limit int `json:"limit"` } // Validate the request. @@ -50,7 +51,7 @@ type SearchResourceResponse struct { // Serve the request. func (r *SearchResourceRequest) Serve(rctx *RequestContext) (interface{}, error) { - results, err := rctx.TX.SearchResource(rctx.Context, r.Pattern) + results, err := rctx.TX.SearchResource(rctx.Context, r.Pattern, r.Limit) if err != nil { return nil, err } diff --git a/actions_test.go b/actions_test.go index 20951bdbd54b2a086894dc3690d36bab198dd82a..9681a5df16a4a359e8623c34990a0250f9350cec 100644 --- a/actions_test.go +++ b/actions_test.go @@ -56,7 +56,7 @@ func (b *fakeBackend) GetUser(_ context.Context, username string) (*RawUser, err }, nil } -func (b *fakeBackend) SearchUser(_ context.Context, pattern string) ([]string, error) { +func (b *fakeBackend) SearchUser(_ context.Context, pattern string, limit int) ([]string, error) { var out []string for username := range b.users { if strings.HasPrefix(username, pattern) { @@ -95,7 +95,7 @@ func (b *fakeBackend) FindResource(_ context.Context, req FindResourceRequest) ( return nil, nil } -func (b *fakeBackend) SearchResource(_ context.Context, pattern string) ([]*RawResource, error) { +func (b *fakeBackend) SearchResource(_ context.Context, pattern string, limit int) ([]*RawResource, error) { var out []*RawResource for id, r := range b.resources { owner := strings.Split(id, "/")[0] diff --git a/actions_user.go b/actions_user.go index 34e1f19f9e78d5a7a63232ad95209db62e9b74c6..60071b9e9892f60a4d40310f1c00b96ed0a8c520 100644 --- a/actions_user.go +++ b/actions_user.go @@ -31,6 +31,7 @@ type SearchUserRequest struct { AdminRequestBase Pattern string `json:"pattern"` + Limit int `json:"limit"` } // Validate the request. @@ -48,7 +49,7 @@ type SearchUserResponse struct { // Serve the request. func (r *SearchUserRequest) Serve(rctx *RequestContext) (interface{}, error) { - usernames, err := rctx.TX.SearchUser(rctx.Context, r.Pattern) + usernames, err := rctx.TX.SearchUser(rctx.Context, r.Pattern, r.Limit) if err != nil { return nil, err } diff --git a/backend/ldap/model.go b/backend/ldap/model.go index a0f4ae1a7759e36267bdd1e8c24b2a5db94d34ba..85e749f017077fbadfb2460896b646a6b58bfaf9 100644 --- a/backend/ldap/model.go +++ b/backend/ldap/model.go @@ -348,10 +348,12 @@ func (tx *backendTX) GetUser(ctx context.Context, username string) (*as.RawUser, return user, nil } -func (tx *backendTX) SearchUser(ctx context.Context, pattern string) ([]string, error) { +func (tx *backendTX) SearchUser(ctx context.Context, pattern string, limit int) ([]string, error) { // First of all, find the main user object, and just that one. vars := templateVars{"pattern": rawVariable(pattern)} - result, err := tx.search(ctx, tx.backend.searchUserQuery.query(vars)) + req := tx.backend.searchUserQuery.query(vars) + req.SizeLimit = limit + result, err := tx.search(ctx, req) if err != nil { return nil, err } @@ -493,15 +495,17 @@ func (tx *backendTX) HasAnyResource(ctx context.Context, resourceIDs []as.FindRe return false, nil } -func (tx *backendTX) searchResourcesByType(ctx context.Context, pattern, resourceType string) ([]*as.RawResource, error) { +func (tx *backendTX) searchResourcesByType(ctx context.Context, pattern, resourceType string, limit int) ([]*as.RawResource, error) { tpl, err := tx.backend.resources.SearchQuery(resourceType) if err != nil { return nil, err } - result, err := tx.search(ctx, tpl.query(templateVars{ + req := tpl.query(templateVars{ "resource": rawVariable(pattern), "type": resourceType, - })) + }) + req.SizeLimit = limit + result, err := tx.search(ctx, req) if err != nil { if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) { return nil, nil @@ -528,7 +532,7 @@ func (tx *backendTX) searchResourcesByType(ctx context.Context, pattern, resourc // FindResource fetches a specific resource by type and name. func (tx *backendTX) FindResource(ctx context.Context, spec as.FindResourceRequest) (*as.RawResource, error) { - result, err := tx.searchResourcesByType(ctx, spec.Name, spec.Type) + result, err := tx.searchResourcesByType(ctx, spec.Name, spec.Type, 0) if err != nil { return nil, err } @@ -543,11 +547,11 @@ func (tx *backendTX) FindResource(ctx context.Context, spec as.FindResourceReque } // SearchResource returns all the resources matching the pattern. -func (tx *backendTX) SearchResource(ctx context.Context, pattern string) ([]*as.RawResource, error) { +func (tx *backendTX) SearchResource(ctx context.Context, pattern string, limit int) ([]*as.RawResource, error) { // Aggregate results for all known resource types. var out []*as.RawResource for _, typ := range tx.backend.resources.types { - r, err := tx.searchResourcesByType(ctx, pattern, typ) + r, err := tx.searchResourcesByType(ctx, pattern, typ, limit) if err != nil { return nil, err } diff --git a/backend/ldap/model_test.go b/backend/ldap/model_test.go index 1c461f4da752867b269268efba7f1e3cb2f6db5f..e854ee03105168af0804970fa11fdd5fb1c5738c 100644 --- a/backend/ldap/model_test.go +++ b/backend/ldap/model_test.go @@ -197,7 +197,7 @@ func TestModel_SearchUser(t *testing.T) { stop, b := startServer(t) defer stop() tx, _ := b.NewTransaction() - users, err := tx.SearchUser(context.Background(), "uno") + users, err := tx.SearchUser(context.Background(), "uno", 0) if err != nil { t.Fatal(err) } @@ -288,7 +288,7 @@ func TestModel_SearchResource(t *testing.T) { for _, pattern := range []string{"uno@investici.org", "uno*"} { tx, _ := b.NewTransaction() - resources, err := tx.SearchResource(context.Background(), "uno@investici.org") + resources, err := tx.SearchResource(context.Background(), "uno@investici.org", 0) if err != nil { t.Fatalf("SearchUser(%s): %v", pattern, err) } diff --git a/service.go b/service.go index 450c51e4ca29f4e623ea465c2c560a5aaa961f99..7b01cf2e2648a4ee07f53f42c1b6309819eb11b0 100644 --- a/service.go +++ b/service.go @@ -69,10 +69,10 @@ type TX interface { // Lightweight user search (backend-specific pattern). // Returns list of matching usernames. - SearchUser(context.Context, string) ([]string, error) + SearchUser(context.Context, string, int) ([]string, error) // Resource search (backend-specific pattern). - SearchResource(context.Context, string) ([]*RawResource, error) + SearchResource(context.Context, string, int) ([]*RawResource, error) // Resource ACL check (does not necessarily hit the database). CanAccessResource(context.Context, string, *Resource) bool