From 947362c60b5bd195089b4276687841d4b5e778e5 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Mon, 27 Jul 2020 15:42:08 +0300 Subject: [PATCH] Added check for empty path before AttributeProfile set --- apier/v1/attributes.go | 19 ++++++++++--------- apier/v1/attributes_it_test.go | 24 ++++++++++++++++++++++++ engine/libattributes.go | 7 +++++++ engine/model_helpers.go | 4 ++++ engine/tpreader.go | 6 ++++++ migrator/alias.go | 2 ++ migrator/attributes.go | 6 ++++++ migrator/derived_chargers.go | 5 +++-- migrator/filters.go | 10 ++++++++++ migrator/user.go | 2 ++ 10 files changed, 74 insertions(+), 11 deletions(-) diff --git a/apier/v1/attributes.go b/apier/v1/attributes.go index 420396078..d93c9e62d 100644 --- a/apier/v1/attributes.go +++ b/apier/v1/attributes.go @@ -91,15 +91,16 @@ func (apierSv1 *APIerSv1) SetAttributeProfile(alsWrp *AttributeWithCache, reply if missing := utils.MissingStructFields(alsWrp.AttributeProfile, []string{"Tenant", "ID", "Attributes"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } - if len(alsWrp.Attributes) != 0 { - for _, attr := range alsWrp.Attributes { - for _, sub := range attr.Value { - if sub.Rules == "" { - return utils.NewErrMandatoryIeMissing("Rules") - } - if err := sub.Compile(); err != nil { - return utils.NewErrServerError(err) - } + for _, attr := range alsWrp.Attributes { + if attr.Path == utils.EmptyString { + return utils.NewErrMandatoryIeMissing("Path") + } + for _, sub := range attr.Value { + if sub.Rules == utils.EmptyString { + return utils.NewErrMandatoryIeMissing("Rules") + } + if err := sub.Compile(); err != nil { + return utils.NewErrServerError(err) } } } diff --git a/apier/v1/attributes_it_test.go b/apier/v1/attributes_it_test.go index 2efbc3a56..ed927a75a 100644 --- a/apier/v1/attributes_it_test.go +++ b/apier/v1/attributes_it_test.go @@ -71,6 +71,7 @@ var ( testAttributeSProcessWithMultipleRuns, testAttributeSProcessWithMultipleRuns2, testAttributeSGetAttributeProfileIDsCount, + testAttributeSSetAttributeWithEmptyPath, testAttributeSKillEngine, //start test for cache options testAttributeSInitCfg, @@ -1716,3 +1717,26 @@ func testAttributeSCachingMetaRemove(t *testing.T) { } } + +func testAttributeSSetAttributeWithEmptyPath(t *testing.T) { + eAttrPrf2 := &AttributeWithCache{ + AttributeProfile: &engine.AttributeProfile{ + Tenant: "cgrates.org", + ID: "ATTR_3", + FilterIDs: []string{"*string:~*req.Account:dan"}, + Contexts: []string{utils.MetaSessionS}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 1, 14, 0, 0, 0, 0, time.UTC)}, + Attributes: []*engine.Attribute{ + { + Value: config.NewRSRParsersMustCompile("1001", utils.INFIELD_SEP), + }, + }, + Weight: 10.0, + }, + } + var result string + if err := attrSRPC.Call(utils.APIerSv1SetAttributeProfile, eAttrPrf2, &result); err == nil { + t.Errorf("Expected error received nil") + } +} diff --git a/engine/libattributes.go b/engine/libattributes.go index 32186c63e..0bdb919cc 100644 --- a/engine/libattributes.go +++ b/engine/libattributes.go @@ -108,6 +108,9 @@ func (ext *ExternalAttributeProfile) AsAttributeProfile() (attr *AttributeProfil } attr.Attributes = make([]*Attribute, len(ext.Attributes)) for i, extAttr := range ext.Attributes { + if extAttr.Path == utils.EmptyString { + return nil, utils.NewErrMandatoryIeMissing("Path") + } if len(extAttr.Value) == 0 { return nil, utils.NewErrMandatoryIeMissing("Value") } @@ -145,6 +148,10 @@ func NewAttributeFromInline(tenant, inlnRule string) (attr *AttributeProfile, er if vals, err = config.NewRSRParsers(ruleSplt[2], utils.PipeSep); err != nil { return nil, err } + if len(ruleSplt[1]) == 0 { + err = fmt.Errorf("empty path in inline AttributeProfile <%s>", inlnRule) + return + } attr.Attributes = append(attr.Attributes, &Attribute{ Path: ruleSplt[1], Type: ruleSplt[0], diff --git a/engine/model_helpers.go b/engine/model_helpers.go index 3be57fdf8..ce9b525e0 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -2322,6 +2322,10 @@ func APItoAttributeProfile(tpAttr *utils.TPAttributeProfile, timezone string) (a attrPrf.Contexts[i] = context } for i, reqAttr := range tpAttr.Attributes { + if reqAttr.Path == utils.EmptyString { // we do not suppot empty Path in Attributes + err = fmt.Errorf("empty path in AttributeProfile <%s>", attrPrf.TenantID()) + return + } sbstPrsr, err := config.NewRSRParsers(reqAttr.Value, config.CgrConfig().GeneralCfg().RSRSep) if err != nil { return nil, err diff --git a/engine/tpreader.go b/engine/tpreader.go index c73a21d4a..933513bb7 100644 --- a/engine/tpreader.go +++ b/engine/tpreader.go @@ -1206,6 +1206,12 @@ func (tpr *TpReader) LoadAttributeProfilesFiltered(tag string) (err error) { if err = verifyInlineFilterS(attr.FilterIDs); err != nil { return } + for _, at := range attr.Attributes { + if at.Path == utils.EmptyString { // we do not suppot empty Path in Attributes + err = fmt.Errorf("empty path in AttributeProfile <%s>", utils.ConcatenatedKey(attr.Tenant, attr.ID)) + return + } + } mapAttrPfls[utils.TenantID{Tenant: attr.Tenant, ID: attr.ID}] = attr } tpr.attributeProfiles = mapAttrPfls diff --git a/migrator/alias.go b/migrator/alias.go index a5a11091e..d848e6ee0 100644 --- a/migrator/alias.go +++ b/migrator/alias.go @@ -111,6 +111,8 @@ func alias2AtttributeProfile(alias *v1Alias, defaultTenant string) *engine.Attri fld = utils.MetaTenant } else if fieldName != utils.EmptyString { fld = utils.MetaReq + utils.NestingSep + fieldName + } else { + continue // ignore empty fieldNames } attr := &engine.Attribute{ Path: fld, diff --git a/migrator/attributes.go b/migrator/attributes.go index 141143418..0bc5aeff8 100644 --- a/migrator/attributes.go +++ b/migrator/attributes.go @@ -237,6 +237,12 @@ func (m *Migrator) migrateAttributeProfile() (err error) { } if !m.dryRun { + for _, attr := range v6Attr.Attributes { + if attr.Path == utils.EmptyString { // we do not suppot empty Path in Attributes + err = fmt.Errorf("the AttributeProfile <%s> was not migrated corectly", v6Attr.TenantID()) + return + } + } if vrs[utils.Attributes] == 1 { if err = m.dmOut.DataManager().DataDB().SetAttributeProfileDrv(v6Attr); err != nil { return diff --git a/migrator/derived_chargers.go b/migrator/derived_chargers.go index 530bc1b50..1db5ee390 100644 --- a/migrator/derived_chargers.go +++ b/migrator/derived_chargers.go @@ -83,9 +83,10 @@ func fieldinfo2Attribute(attr []*engine.Attribute, fieldName, fieldInfo string) return attr } var path string - if fieldName != utils.EmptyString { - path = utils.MetaReq + utils.NestingSep + fieldName + if fieldName == utils.EmptyString { + return attr // do not append attribute if fieldName is empty } + path = utils.MetaReq + utils.NestingSep + fieldName return append(attr, &engine.Attribute{ Path: path, Value: rp, diff --git a/migrator/filters.go b/migrator/filters.go index d5ff9c0bc..e9734812a 100644 --- a/migrator/filters.go +++ b/migrator/filters.go @@ -499,6 +499,11 @@ func (m *Migrator) migrateAttributeProfileFiltersV1() (err error) { attrPrf.FilterIDs[i] = migrateInlineFilter(fl) } for i, attr := range attrPrf.Attributes { + if attr.Path == utils.EmptyString { + // in case of older version of attributes we do not have Path + // stop the inline migration until the attributes are migrated + return fmt.Errorf("error: when migrating filter for attribute profile: <%s>", attrPrf.TenantID()) + } for j, fl := range attr.FilterIDs { attrPrf.Attributes[i].FilterIDs[j] = migrateInlineFilter(fl) } @@ -712,6 +717,11 @@ func (m *Migrator) migrateAttributeProfileFiltersV2() (err error) { attrPrf.FilterIDs[i] = migrateInlineFilterV2(fl) } for i, attr := range attrPrf.Attributes { + if attr.Path == utils.EmptyString { + // in case of older version of attributes we do not have Path + // stop the inline migration until the attributes are migrated + return fmt.Errorf("error: when migrating filter for attribute profile: <%s>", attrPrf.TenantID()) + } for j, fl := range attr.FilterIDs { attrPrf.Attributes[i].FilterIDs[j] = migrateInlineFilterV2(fl) } diff --git a/migrator/user.go b/migrator/user.go index 3657b5c1c..1ab8faed5 100644 --- a/migrator/user.go +++ b/migrator/user.go @@ -79,6 +79,8 @@ func userProfile2attributeProfile(user *v1UserProfile) (attr *engine.AttributePr var path string if fieldName != utils.EmptyString { path = utils.MetaReq + utils.NestingSep + fieldName + } else { + continue // ignore empty filedNames } attr.Attributes = append(attr.Attributes, &engine.Attribute{ Path: path,