radius: support reading vendor-specific attributes

handles paths with 2 elements the same way radAppendAttributes does
e.g. *req.Microsoft.MS-CHAP2-Response

Ref: #4962
This commit is contained in:
ionutboangiu
2026-02-19 20:11:43 +02:00
committed by Dan Christian Bogos
parent 51943cb387
commit 137e81b89c
2 changed files with 35 additions and 6 deletions

View File

@@ -72,7 +72,7 @@ func (pk *radiusDP) String() string {
// FieldAsInterface is part of utils.DataProvider interface
func (pk *radiusDP) FieldAsInterface(fldPath []string) (data any, err error) {
if len(fldPath) != 1 {
if len(fldPath) == 0 || len(fldPath) > 2 {
return nil, utils.ErrNotFound
}
if data, err = pk.cache.FieldAsInterface(fldPath); err != nil {
@@ -83,8 +83,14 @@ func (pk *radiusDP) FieldAsInterface(fldPath []string) (data any, err error) {
} else {
return // data found in cache
}
if attrs := pk.req.AttributesWithName(fldPath[0], ""); len(attrs) != 0 {
data = attrs[0].GetStringValue()
var attrName, vendorName string
if len(fldPath) == 2 {
vendorName, attrName = fldPath[0], fldPath[1]
} else {
attrName = fldPath[0]
}
if avps := pk.req.AttributesWithName(attrName, vendorName); len(avps) != 0 {
data = avps[0].GetStringValue()
}
pk.cache.Set(fldPath, data)
return

View File

@@ -155,7 +155,6 @@ func TestRadiusDPFieldAsInterfaceCached(t *testing.T) {
}
dp := newRADataProvider(pkt)
if data, err := dp.FieldAsInterface([]string{"User-Name"}); err != nil {
t.Error(err)
} else if data != "cgr1" {
@@ -180,8 +179,32 @@ func TestRadiusDPFieldAsInterfaceCached(t *testing.T) {
t.Errorf("Expecting: nil, received: <%v>", data)
}
if _, err := dp.FieldAsInterface([]string{"Field1", "Field2"}); err != utils.ErrNotFound {
if _, err := dp.FieldAsInterface([]string{"vendor", "attribute", "extra"}); err != utils.ErrNotFound {
t.Errorf("Expecting: ErrNotFound, received: <%v>", err)
}
}
func TestRadiusDPFieldAsInterfaceVSA(t *testing.T) {
pkt := radigo.NewPacket(radigo.AccountingRequest, 1, dictRad, coder, "CGRateS.org")
if err := pkt.AddAVPWithName("Cisco-NAS-Port", "CGR1", "Cisco"); err != nil {
t.Fatal(err)
}
dp := newRADataProvider(pkt)
if data, err := dp.FieldAsInterface([]string{"Cisco", "Cisco-NAS-Port"}); err != nil {
t.Error(err)
} else if data != "CGR1" {
t.Errorf("Expected CGR1, got: %v", data)
}
}
func TestLibradFieldAsInterfaceWithInvalidPathLength(t *testing.T) {
pk := &radiusDP{}
fldPath := []string{"vendor", "attribute", "extra"}
data, err := pk.FieldAsInterface(fldPath)
if err != utils.ErrNotFound {
t.Errorf("Expected ErrNotFound error, got: %v", err)
}
if data != nil {
t.Errorf("Expected nil data, got: %v", data)
}
}