From cab720ed47f91af98bb3ec61b2fee92694ee25b6 Mon Sep 17 00:00:00 2001 From: Andrew Martinez Date: Mon, 1 Feb 2021 09:24:46 -0500 Subject: [PATCH] limit public query options to 500 whe "none" is specified --- controller/internal/routes/base_router.go | 12 +++--- .../routes/current_api_session_router.go | 2 +- .../current_identity_authenticator_router.go | 2 +- .../internal/routes/posture_check_router.go | 2 +- controller/internal/routes/query_options.go | 37 ++++--------------- .../internal/routes/role_attributes_router.go | 2 +- controller/internal/routes/routes.go | 4 +- controller/internal/routes/service_router.go | 2 +- controller/internal/routes/session_router.go | 2 +- 9 files changed, 21 insertions(+), 44 deletions(-) diff --git a/controller/internal/routes/base_router.go b/controller/internal/routes/base_router.go index 38b02d36b..60243963b 100644 --- a/controller/internal/routes/base_router.go +++ b/controller/internal/routes/base_router.go @@ -139,7 +139,7 @@ type ApiListEnvelopeFactory func(data []interface{}, meta *rest_model.Meta) inte type ApiEntityEnvelopeFactory func(data interface{}, meta *rest_model.Meta) interface{} func ListWithQueryFAndCollector(ae *env.AppEnv, rc *response.RequestContext, lister models.EntityRetriever, mapper ModelToApiMapper, toEnvelope ApiListEnvelopeFactory, qf queryF) { - ListWithEnvelopeFactory(rc, toEnvelope, func(rc *response.RequestContext, queryOptions *QueryOptions) (*QueryResult, error) { + ListWithEnvelopeFactory(rc, toEnvelope, func(rc *response.RequestContext, queryOptions *PublicQueryOptions) (*QueryResult, error) { // validate that the submitted query is only using public symbols. The query options may contain an final // query which has been modified with additional filters query, err := queryOptions.getFullQuery(lister.GetStore()) @@ -161,7 +161,7 @@ func ListWithQueryFAndCollector(ae *env.AppEnv, rc *response.RequestContext, lis }) } -type modelListF func(rc *response.RequestContext, queryOptions *QueryOptions) (*QueryResult, error) +type modelListF func(rc *response.RequestContext, queryOptions *PublicQueryOptions) (*QueryResult, error) func List(rc *response.RequestContext, f modelListF) { ListWithEnvelopeFactory(rc, defaultToListEnvelope, f) @@ -446,10 +446,10 @@ func listWithId(rc *response.RequestContext, f func(id string) ([]interface{}, e } // type ListAssocF func(string, func(models.Entity)) error -type listAssocF func(rc *response.RequestContext, id string, queryOptions *QueryOptions) (*QueryResult, error) +type listAssocF func(rc *response.RequestContext, id string, queryOptions *PublicQueryOptions) (*QueryResult, error) func ListAssociationsWithFilter(ae *env.AppEnv, rc *response.RequestContext, filterTemplate string, entityController models.EntityRetriever, mapper ModelToApiMapper) { - ListAssociations(rc, func(rc *response.RequestContext, id string, queryOptions *QueryOptions) (*QueryResult, error) { + ListAssociations(rc, func(rc *response.RequestContext, id string, queryOptions *PublicQueryOptions) (*QueryResult, error) { query, err := queryOptions.getFullQuery(entityController.GetStore()) if err != nil { return nil, err @@ -479,7 +479,7 @@ func ListAssociationsWithFilter(ae *env.AppEnv, rc *response.RequestContext, fil } func ListAssociationWithHandler(ae *env.AppEnv, rc *response.RequestContext, lister models.EntityRetriever, associationLoader models.EntityRetriever, mapper ModelToApiMapper) { - ListAssociations(rc, func(rc *response.RequestContext, id string, queryOptions *QueryOptions) (*QueryResult, error) { + ListAssociations(rc, func(rc *response.RequestContext, id string, queryOptions *PublicQueryOptions) (*QueryResult, error) { // validate that the submitted query is only using public symbols. The query options may contain an final // query which has been modified with additional filters query, err := queryOptions.getFullQuery(associationLoader.GetStore()) @@ -513,7 +513,7 @@ func ListAssociations(rc *response.RequestContext, listF listAssocF) { } filter := rc.Request.URL.Query().Get("filter") - queryOptions := &QueryOptions{ + queryOptions := &PublicQueryOptions{ Predicate: filter, } diff --git a/controller/internal/routes/current_api_session_router.go b/controller/internal/routes/current_api_session_router.go index 0f358e6ce..cb6e0e114 100644 --- a/controller/internal/routes/current_api_session_router.go +++ b/controller/internal/routes/current_api_session_router.go @@ -90,7 +90,7 @@ func (router *CurrentSessionRouter) Delete(ae *env.AppEnv, rc *response.RequestC } func (router *CurrentSessionRouter) ListCertificates(ae *env.AppEnv, rc *response.RequestContext) { - ListWithEnvelopeFactory(rc, defaultToListEnvelope, func(rc *response.RequestContext, queryOptions *QueryOptions) (*QueryResult, error) { + ListWithEnvelopeFactory(rc, defaultToListEnvelope, func(rc *response.RequestContext, queryOptions *PublicQueryOptions) (*QueryResult, error) { query, err := queryOptions.getFullQuery(ae.GetStores().ApiSessionCertificate) if err != nil { return nil, err diff --git a/controller/internal/routes/current_identity_authenticator_router.go b/controller/internal/routes/current_identity_authenticator_router.go index 13ed38cde..fd0d69722 100644 --- a/controller/internal/routes/current_identity_authenticator_router.go +++ b/controller/internal/routes/current_identity_authenticator_router.go @@ -60,7 +60,7 @@ func (r *CurrentIdentityAuthenticatorRouter) Register(ae *env.AppEnv) { } func (r *CurrentIdentityAuthenticatorRouter) List(ae *env.AppEnv, rc *response.RequestContext) { - List(rc, func(rc *response.RequestContext, queryOptions *QueryOptions) (*QueryResult, error) { + List(rc, func(rc *response.RequestContext, queryOptions *PublicQueryOptions) (*QueryResult, error) { query, err := queryOptions.getFullQuery(ae.Handlers.Authenticator.GetStore()) if err != nil { return nil, err diff --git a/controller/internal/routes/posture_check_router.go b/controller/internal/routes/posture_check_router.go index 725b4e800..4dc795f84 100644 --- a/controller/internal/routes/posture_check_router.go +++ b/controller/internal/routes/posture_check_router.go @@ -68,7 +68,7 @@ func (r *PostureCheckRouter) Register(ae *env.AppEnv) { } func (r *PostureCheckRouter) List(ae *env.AppEnv, rc *response.RequestContext) { - List(rc, func(rc *response.RequestContext, queryOptions *QueryOptions) (*QueryResult, error) { + List(rc, func(rc *response.RequestContext, queryOptions *PublicQueryOptions) (*QueryResult, error) { query, err := queryOptions.getFullQuery(ae.Handlers.PostureCheck.GetStore()) if err != nil { return nil, err diff --git a/controller/internal/routes/query_options.go b/controller/internal/routes/query_options.go index afc0f0869..e1835dd6e 100644 --- a/controller/internal/routes/query_options.go +++ b/controller/internal/routes/query_options.go @@ -31,46 +31,22 @@ const ( OffsetDefault = 0 ) -type QueryOptions struct { +// Represents external query options, which limits some query options (i.e. return all vs max limit). PublicQueryOptions +// can be used internally as long as the public option limitations are fitting. +type PublicQueryOptions struct { Predicate string Sort string Paging *Paging } -func (qo *QueryOptions) String() string { +func (qo *PublicQueryOptions) String() string { if qo == nil { return "nil" } return fmt.Sprintf("[QueryOption Predicate: '%v', Sort: '%v', Paging: '%v']", qo.Predicate, qo.Sort, qo.Paging) } -func (qo *QueryOptions) ValidateAndCorrect() { - // Sort limit is handled in ScanEntityImpl.NewScanner - if qo.Paging == nil { - qo.Paging = &Paging{ - Limit: LimitDefault, - Offset: OffsetDefault, - } - } else { - if qo.Paging.Limit > LimitMax { - qo.Paging.Limit = LimitMax - } - - if qo.Paging.Limit <= 0 { - qo.Paging.Limit = LimitDefault - } - - if qo.Paging.Offset > OffsetMax { - qo.Paging.Offset = OffsetMax - } - - if qo.Paging.Offset <= 0 { - qo.Paging.Offset = OffsetDefault - } - } -} - -func (qo *QueryOptions) getFullQuery(store boltz.ListStore) (ast.Query, error) { +func (qo *PublicQueryOptions) getFullQuery(store boltz.ListStore) (ast.Query, error) { if qo.Predicate == "" { qo.Predicate = "true" } @@ -89,7 +65,8 @@ func (qo *QueryOptions) getFullQuery(store boltz.ListStore) (ast.Query, error) { if qo.Paging != nil { if query.GetLimit() == nil { if qo.Paging.ReturnAll { - query.SetLimit(-1) + //public external queries cannot be "return all" + query.SetLimit(LimitMax) } else { query.SetLimit(qo.Paging.Limit) } diff --git a/controller/internal/routes/role_attributes_router.go b/controller/internal/routes/role_attributes_router.go index d31770005..c9501ba76 100644 --- a/controller/internal/routes/role_attributes_router.go +++ b/controller/internal/routes/role_attributes_router.go @@ -64,7 +64,7 @@ func (r *RoleAttributesRouter) listServiceRoleAttributes(ae *env.AppEnv, rc *res } func (r *RoleAttributesRouter) listRoleAttributes(rc *response.RequestContext, queryable roleAttributeQueryable) { - List(rc, func(rc *response.RequestContext, queryOptions *QueryOptions) (*QueryResult, error) { + List(rc, func(rc *response.RequestContext, queryOptions *PublicQueryOptions) (*QueryResult, error) { results, qmd, err := queryable.QueryRoleAttributes(queryOptions.Predicate) if err != nil { return nil, err diff --git a/controller/internal/routes/routes.go b/controller/internal/routes/routes.go index 70468e1ed..707d2c389 100644 --- a/controller/internal/routes/routes.go +++ b/controller/internal/routes/routes.go @@ -60,7 +60,7 @@ type ReadUpdateRouter interface { type ModelToApiMapper func(*env.AppEnv, *response.RequestContext, models.Entity) (interface{}, error) -func GetModelQueryOptionsFromRequest(r *http.Request) (*QueryOptions, error) { +func GetModelQueryOptionsFromRequest(r *http.Request) (*PublicQueryOptions, error) { filter := r.URL.Query().Get("filter") sort := r.URL.Query().Get("sort") @@ -70,7 +70,7 @@ func GetModelQueryOptionsFromRequest(r *http.Request) (*QueryOptions, error) { return nil, err } - return &QueryOptions{ + return &PublicQueryOptions{ Predicate: filter, Sort: sort, Paging: pg, diff --git a/controller/internal/routes/service_router.go b/controller/internal/routes/service_router.go index 216c54bda..9a648e63a 100644 --- a/controller/internal/routes/service_router.go +++ b/controller/internal/routes/service_router.go @@ -104,7 +104,7 @@ func (r *ServiceRouter) Register(ae *env.AppEnv) { func (r *ServiceRouter) List(ae *env.AppEnv, rc *response.RequestContext) { start := time.Now() // ListWithHandler won't do search limiting by logged in user - List(rc, func(rc *response.RequestContext, queryOptions *QueryOptions) (*QueryResult, error) { + List(rc, func(rc *response.RequestContext, queryOptions *PublicQueryOptions) (*QueryResult, error) { identity := rc.Identity if rc.Identity.IsAdmin { if asId := rc.Request.URL.Query().Get("asIdentity"); asId != "" { diff --git a/controller/internal/routes/session_router.go b/controller/internal/routes/session_router.go index 6758ea8f3..173456a63 100644 --- a/controller/internal/routes/session_router.go +++ b/controller/internal/routes/session_router.go @@ -64,7 +64,7 @@ func (r *SessionRouter) Register(ae *env.AppEnv) { func (r *SessionRouter) List(ae *env.AppEnv, rc *response.RequestContext) { // ListWithHandler won't do search limiting by logged in user - List(rc, func(rc *response.RequestContext, queryOptions *QueryOptions) (*QueryResult, error) { + List(rc, func(rc *response.RequestContext, queryOptions *PublicQueryOptions) (*QueryResult, error) { query, err := queryOptions.getFullQuery(ae.Handlers.Session.GetStore()) if err != nil { return nil, err