diff --git a/engine/attributes.go b/engine/attributes.go index 3917505a7..7aec88c2d 100644 --- a/engine/attributes.go +++ b/engine/attributes.go @@ -163,6 +163,16 @@ func (alS *AttributeS) processEvent(ctx *context.Context, tnt string, args *util continue } } + if attribute.Type == utils.MetaPassword { + password := attribute.Value.GetRule(config.CgrConfig().GeneralCfg().RSRSep) + if password, err = utils.ComputeHash(password); err != nil { + return + } + if attribute.Value, err = config.NewRSRParsers(password, config.CgrConfig().GeneralCfg().RSRSep); err != nil { + return + } + attribute.Type = utils.MetaConstant + } var out interface{} if out, err = ParseAttribute(dynDP, utils.FirstNonEmpty(attribute.Type, utils.MetaVariable), utils.DynamicDataPrefix+attribute.Path, attribute.Value, alS.cfg.GeneralCfg().RoundingDecimals, alS.cfg.GeneralCfg().DefaultTimezone, time.RFC3339, alS.cfg.GeneralCfg().RSRSep); err != nil { rply = nil diff --git a/engine/z_attributes_test.go b/engine/z_attributes_test.go index ef657095a..26ae105ae 100644 --- a/engine/z_attributes_test.go +++ b/engine/z_attributes_test.go @@ -4708,3 +4708,99 @@ func TestAttributesParseAttributeError(t *testing.T) { t.Errorf("Expected %q, Received %q", "unsupported type: ", err) } } + +func TestAttributesProcessEventPasswordAttribute(t *testing.T) { + tmp := Cache + tmpC := config.CgrConfig() + defer func() { + Cache = tmp + config.SetCgrConfig(tmpC) + }() + + cfg := config.NewDefaultCGRConfig() + data := NewInternalDB(nil, nil, cfg.DataDbCfg().Items) + dm := NewDataManager(data, cfg.CacheCfg(), nil) + Cache = NewCacheS(cfg, dm, nil) + filterS := NewFilterS(cfg, nil, dm) + attrS := NewAttributeService(dm, filterS, cfg) + + value := config.NewRSRParsersMustCompile("abcd123", config.CgrConfig().GeneralCfg().RSRSep) + + attrPrf := &AttributeProfile{ + Tenant: "cgrates.org", + ID: "ATTR_TEST", + Attributes: []*Attribute{ + { + Path: "*req.Password", + Type: utils.MetaPassword, + Value: value, + }, + }, + Weight: 10, + } + + if err := dm.SetAttributeProfile(context.Background(), attrPrf, true); err != nil { + t.Fatal(err) + } + + cgrEv := &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "EventHashPw", + Event: map[string]interface{}{ + "Password": "321dcba", + }, + } + + exp := AttrSProcessEventReply{ + MatchedProfiles: []string{"cgrates.org:ATTR_TEST"}, + AlteredFields: []string{"*req.Password"}, + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "EventHashPw", + Event: map[string]interface{}{ + "Password": "abcd123", + }, + APIOpts: map[string]interface{}{}, + }, + } + var hashedPw string + var reply AttrSProcessEventReply + if err := attrS.V1ProcessEvent(context.Background(), cgrEv, &reply); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(reply.MatchedProfiles, exp.MatchedProfiles) || + !reflect.DeepEqual(reply.AlteredFields, exp.AlteredFields) { + t.Fatalf("expected: Matched Profiles:<%+v> \nAltered Fields<%+v>,\nreceived: Matched Profiles:<%+v>\nAltered Fields<%+v>", + utils.ToJSON(exp.MatchedProfiles), utils.ToJSON(exp.AlteredFields), + utils.ToJSON(reply.MatchedProfiles), utils.ToJSON(reply.AlteredFields)) + } else { + hashedPw = utils.IfaceAsString(reply.Event["Password"]) + if !utils.VerifyHash(hashedPw, "abcd123") { + t.Fatalf("expected: <%+v>, \nreceived: <%+v>", "abcd123", hashedPw) + } + exp.Event["Password"] = hashedPw + if !reflect.DeepEqual(reply.CGREvent, exp.CGREvent) { + t.Fatalf("expected: <%+v>, \nreceived: <%+v>", + utils.ToJSON(exp.CGREvent), utils.ToJSON(reply.CGREvent)) + } + } + + value = config.NewRSRParsersMustCompile(hashedPw, config.CgrConfig().GeneralCfg().RSRSep) + expAttrPrf := &AttributeProfile{ + Tenant: "cgrates.org", + ID: "ATTR_TEST", + Attributes: []*Attribute{ + { + Path: "*req.Password", + Type: utils.MetaConstant, + Value: value, + }, + }, + Weight: 10, + } + if rcvAttrPrf, err := dm.GetAttributeProfile(context.Background(), attrPrf.Tenant, attrPrf.ID, true, true, + utils.NonTransactional); err != nil { + t.Fatal(err) + } else if !reflect.DeepEqual(rcvAttrPrf, expAttrPrf) { + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(expAttrPrf), utils.ToJSON(rcvAttrPrf)) + } +} diff --git a/utils/consts.go b/utils/consts.go index 092037a12..f14bd749f 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -284,6 +284,7 @@ const ( CreateTariffPlanTablesSQL = "create_tariffplan_tables.sql" TestSQL = "TEST_SQL" MetaConstant = "*constant" + MetaPassword = "*password" MetaFiller = "*filler" MetaHTTPPost = "*httpPost" MetaHTTPjsonCDR = "*http_json_cdr"