mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 10:06:24 +05:00
Dynamic templates for Radius CoA out of APIOpts
This commit is contained in:
@@ -527,7 +527,12 @@ func (ra *RadiusAgent) V1ReAuthorize(_ *context.Context, cgrEv utils.CGREvent, r
|
||||
if originID == "" {
|
||||
return utils.NewErrMandatoryIeMissing(utils.OriginID)
|
||||
}
|
||||
replyCode, err := ra.sendRadDaReq(radigo.CoARequest, ra.cgrCfg.RadiusAgentCfg().CoATemplate,
|
||||
coaTpl := ra.cgrCfg.RadiusAgentCfg().CoATemplate
|
||||
if optTpl, err := cgrEv.OptAsString(utils.MetaRadCoATemplate); err == nil {
|
||||
coaTpl = optTpl
|
||||
}
|
||||
|
||||
replyCode, err := ra.sendRadDaReq(radigo.CoARequest, coaTpl,
|
||||
originID, utils.MapStorage(cgrEv.Event), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -132,7 +132,7 @@ func TestRadiusCoADisconnect(t *testing.T) {
|
||||
if string(request.AVPs[0].RawValue) != "1001" ||
|
||||
!bytes.Equal(request.AVPs[1].RawValue, decodedNasIPAddr) ||
|
||||
string(request.AVPs[2].RawValue) != "e4921177ab0e3586c37f6a185864b71a@0:0:0:0:0:0:0:0" ||
|
||||
string(request.AVPs[3].RawValue) != "custom_filter" {
|
||||
string(request.AVPs[3].RawValue) != "mycustomvalue" {
|
||||
t.Errorf("unexpected request received: %v", utils.ToJSON(request))
|
||||
reply.Code = radigo.CoANAK
|
||||
} else {
|
||||
@@ -233,11 +233,16 @@ func TestRadiusCoADisconnect(t *testing.T) {
|
||||
}
|
||||
|
||||
var reply string
|
||||
if err := raDiscRPC.Call(context.Background(), utils.SessionSv1ReAuthorize, utils.SessionFilterWithEvent{
|
||||
Event: map[string]any{
|
||||
"CustomFilter": "custom_filter",
|
||||
},
|
||||
}, &reply); err != nil {
|
||||
if err := raDiscRPC.Call(context.Background(), utils.SessionSv1ReAuthorize,
|
||||
utils.SessionFilterWithEvent{
|
||||
SessionFilter: &utils.SessionFilter{
|
||||
APIOpts: map[string]any{
|
||||
utils.MetaRadCoATemplate: "mycoa",
|
||||
}},
|
||||
Event: map[string]any{
|
||||
"CustomFilter": "custom_filter",
|
||||
},
|
||||
}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -1163,42 +1163,42 @@ const CGRATES_CFG_JSON = `
|
||||
|
||||
"templates": {
|
||||
"*err": [
|
||||
{"tag": "SessionId", "path": "*rep.Session-Id", "type": "*variable",
|
||||
"value": "~*req.Session-Id", "mandatory": true},
|
||||
{"tag": "OriginHost", "path": "*rep.Origin-Host", "type": "*variable",
|
||||
"value": "~*vars.OriginHost", "mandatory": true},
|
||||
{"tag": "OriginRealm", "path": "*rep.Origin-Realm", "type": "*variable",
|
||||
{"tag": "SessionId", "path": "*rep.Session-Id", "type": "*variable",
|
||||
"value": "~*req.Session-Id", "mandatory": true},
|
||||
{"tag": "OriginHost", "path": "*rep.Origin-Host", "type": "*variable",
|
||||
"value": "~*vars.OriginHost", "mandatory": true},
|
||||
{"tag": "OriginRealm", "path": "*rep.Origin-Realm", "type": "*variable",
|
||||
"value": "~*vars.OriginRealm", "mandatory": true},
|
||||
],
|
||||
"*cca": [
|
||||
{"tag": "SessionId", "path": "*rep.Session-Id", "type": "*variable",
|
||||
"value": "~*req.Session-Id", "mandatory": true},
|
||||
{"tag": "ResultCode", "path": "*rep.Result-Code", "type": "*constant",
|
||||
"value": "2001"},
|
||||
{"tag": "OriginHost", "path": "*rep.Origin-Host", "type": "*variable",
|
||||
"value": "~*vars.OriginHost", "mandatory": true},
|
||||
{"tag": "OriginRealm", "path": "*rep.Origin-Realm", "type": "*variable",
|
||||
"value": "~*vars.OriginRealm", "mandatory": true},
|
||||
{"tag": "AuthApplicationId", "path": "*rep.Auth-Application-Id", "type": "*variable",
|
||||
"value": "~*vars.*appid", "mandatory": true},
|
||||
{"tag": "CCRequestType", "path": "*rep.CC-Request-Type", "type": "*variable",
|
||||
"value": "~*req.CC-Request-Type", "mandatory": true},
|
||||
{"tag": "CCRequestNumber", "path": "*rep.CC-Request-Number", "type": "*variable",
|
||||
"value": "~*req.CC-Request-Number", "mandatory": true},
|
||||
{"tag": "SessionId", "path": "*rep.Session-Id", "type": "*variable",
|
||||
"value": "~*req.Session-Id", "mandatory": true},
|
||||
{"tag": "ResultCode", "path": "*rep.Result-Code", "type": "*constant",
|
||||
"value": "2001"},
|
||||
{"tag": "OriginHost", "path": "*rep.Origin-Host", "type": "*variable",
|
||||
"value": "~*vars.OriginHost", "mandatory": true},
|
||||
{"tag": "OriginRealm", "path": "*rep.Origin-Realm", "type": "*variable",
|
||||
"value": "~*vars.OriginRealm", "mandatory": true},
|
||||
{"tag": "AuthApplicationId", "path": "*rep.Auth-Application-Id", "type": "*variable",
|
||||
"value": "~*vars.*appid", "mandatory": true},
|
||||
{"tag": "CCRequestType", "path": "*rep.CC-Request-Type", "type": "*variable",
|
||||
"value": "~*req.CC-Request-Type", "mandatory": true},
|
||||
{"tag": "CCRequestNumber", "path": "*rep.CC-Request-Number", "type": "*variable",
|
||||
"value": "~*req.CC-Request-Number", "mandatory": true},
|
||||
],
|
||||
"*asr": [
|
||||
{"tag": "SessionId", "path": "*diamreq.Session-Id", "type": "*variable",
|
||||
"value": "~*req.Session-Id", "mandatory": true},
|
||||
{"tag": "OriginHost", "path": "*diamreq.Origin-Host", "type": "*variable",
|
||||
"value": "~*req.Destination-Host", "mandatory": true},
|
||||
{"tag": "OriginRealm", "path": "*diamreq.Origin-Realm", "type": "*variable",
|
||||
"value": "~*req.Destination-Realm", "mandatory": true},
|
||||
{"tag": "DestinationRealm", "path": "*diamreq.Destination-Realm", "type": "*variable",
|
||||
"value": "~*req.Origin-Realm", "mandatory": true},
|
||||
{"tag": "DestinationHost", "path": "*diamreq.Destination-Host", "type": "*variable",
|
||||
"value": "~*req.Origin-Host", "mandatory": true},
|
||||
{"tag": "AuthApplicationId", "path": "*diamreq.Auth-Application-Id", "type": "*variable",
|
||||
"value": "~*vars.*appid", "mandatory": true},
|
||||
{"tag": "SessionId", "path": "*diamreq.Session-Id", "type": "*variable",
|
||||
"value": "~*req.Session-Id", "mandatory": true},
|
||||
{"tag": "OriginHost", "path": "*diamreq.Origin-Host", "type": "*variable",
|
||||
"value": "~*req.Destination-Host", "mandatory": true},
|
||||
{"tag": "OriginRealm", "path": "*diamreq.Origin-Realm", "type": "*variable",
|
||||
"value": "~*req.Destination-Realm", "mandatory": true},
|
||||
{"tag": "DestinationRealm", "path": "*diamreq.Destination-Realm", "type": "*variable",
|
||||
"value": "~*req.Origin-Realm", "mandatory": true},
|
||||
{"tag": "DestinationHost", "path": "*diamreq.Destination-Host", "type": "*variable",
|
||||
"value": "~*req.Origin-Host", "mandatory": true},
|
||||
{"tag": "AuthApplicationId", "path": "*diamreq.Auth-Application-Id", "type": "*variable",
|
||||
"value": "~*vars.*appid", "mandatory": true},
|
||||
],
|
||||
"*rar": [
|
||||
{"tag": "SessionId", "path": "*diamreq.Session-Id", "type": "*variable",
|
||||
@@ -1216,7 +1216,7 @@ const CGRATES_CFG_JSON = `
|
||||
{"tag": "ReAuthRequestType", "path": "*diamreq.Re-Auth-Request-Type", "type": "*constant",
|
||||
"value": "0"},
|
||||
],
|
||||
"*dmr": [
|
||||
"*dmr": [ // used by RadiusAgent when sending Disconnect message towards the client
|
||||
{"tag": "User-Name", "path": "*radDAReq.User-Name", "type": "*variable",
|
||||
"value": "~*oreq.User-Name"},
|
||||
{"tag": "NAS-IP-Address", "path": "*radDAReq.NAS-IP-Address", "type": "*variable",
|
||||
@@ -1226,7 +1226,7 @@ const CGRATES_CFG_JSON = `
|
||||
{"tag": "Reply-Message", "path": "*radDAReq.Reply-Message", "type": "*variable",
|
||||
"value": "~*vars.DisconnectCause"},
|
||||
],
|
||||
"*coa": [
|
||||
"*coa": [ // used by RadiusAgent when sending ChangeOfAuthorization message towards the client
|
||||
{"tag": "User-Name", "path": "*radDAReq.User-Name", "type": "*variable",
|
||||
"value": "~*oreq.User-Name"},
|
||||
{"tag": "NAS-IP-Address", "path": "*radDAReq.NAS-IP-Address", "type": "*variable",
|
||||
@@ -1237,10 +1237,10 @@ const CGRATES_CFG_JSON = `
|
||||
"value": "~*req.CustomFilter"},
|
||||
],
|
||||
"*errSip": [
|
||||
{"tag": "Request", "path": "*rep.Request", "type": "*constant",
|
||||
"value": "SIP/2.0 500 Internal Server Error", "mandatory": true},
|
||||
{"tag": "Request", "path": "*rep.Request", "type": "*constant",
|
||||
"value": "SIP/2.0 500 Internal Server Error", "mandatory": true},
|
||||
],
|
||||
"*cdrLog": [ // cdrLog template is used in ActionS to build the event that is send to CDRs in case of *cdrLog actionType
|
||||
"*cdrLog": [ // cdrLog template is used in ActionS to build the event that is sent to CDRs in case of *cdrLog actionType
|
||||
{"tag": "ToR", "path": "*cdr.ToR", "type": "*variable",
|
||||
"value": "~*req.BalanceType", "mandatory": true},
|
||||
{"tag": "OriginHost", "path": "*cdr.OriginHost", "type": "*constant",
|
||||
|
||||
19
data/conf/samples/radius_coa_disconnect/templates.json
Normal file
19
data/conf/samples/radius_coa_disconnect/templates.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
|
||||
|
||||
|
||||
"templates": {
|
||||
"mycoa": [ // used by RadiusAgent when sending ChangeOfAuthorization message towards the client
|
||||
{"tag": "User-Name", "path": "*radDAReq.User-Name", "type": "*variable",
|
||||
"value": "~*oreq.User-Name"},
|
||||
{"tag": "NAS-IP-Address", "path": "*radDAReq.NAS-IP-Address", "type": "*variable",
|
||||
"value": "~*oreq.NAS-IP-Address"},
|
||||
{"tag": "Acct-Session-Id", "path": "*radDAReq.Acct-Session-Id", "type": "*variable",
|
||||
"value": "~*oreq.Acct-Session-Id"},
|
||||
{"tag": "Filter-Id", "path": "*radDAReq.Filter-Id", "type": "*variable",
|
||||
"value": "mycustomvalue"},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -4002,7 +4002,7 @@ func (sS *SessionS) BiRPCV1ProcessCDR(ctx *context.Context,
|
||||
rply)
|
||||
}
|
||||
|
||||
func (sS *SessionS) sendRar(ctx *context.Context, s *Session, event map[string]any) (err error) {
|
||||
func (sS *SessionS) sendRar(ctx *context.Context, s *Session, apiOpts map[string]any, event map[string]any) (err error) {
|
||||
clnt := sS.biJClnt(s.ClientConnID)
|
||||
if clnt == nil {
|
||||
return fmt.Errorf("calling %s requires bidirectional JSON connection, connID: <%s>",
|
||||
@@ -4020,9 +4020,10 @@ func (sS *SessionS) sendRar(ctx *context.Context, s *Session, event map[string]a
|
||||
}
|
||||
}
|
||||
args := utils.CGREvent{
|
||||
ID: utils.GenUUID(),
|
||||
Time: utils.TimePointer(time.Now()),
|
||||
Event: event,
|
||||
ID: utils.GenUUID(),
|
||||
Time: utils.TimePointer(time.Now()),
|
||||
APIOpts: apiOpts,
|
||||
Event: event,
|
||||
}
|
||||
|
||||
var rply string
|
||||
@@ -4042,17 +4043,17 @@ func (sS *SessionS) BiRPCv1ReAuthorize(ctx *context.Context,
|
||||
if len(aSs) == 0 {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
cache := utils.NewStringSet(nil)
|
||||
uniqueSIDs := utils.NewStringSet(nil)
|
||||
for _, as := range aSs {
|
||||
if cache.Has(as.CGRID) {
|
||||
if uniqueSIDs.Has(as.CGRID) {
|
||||
continue
|
||||
}
|
||||
cache.Add(as.CGRID)
|
||||
uniqueSIDs.Add(as.CGRID)
|
||||
ss := sS.getSessions(as.CGRID, false)
|
||||
if len(ss) == 0 {
|
||||
continue
|
||||
}
|
||||
if errTerm := sS.sendRar(ctx, ss[0], args.Event); errTerm != nil {
|
||||
if errTerm := sS.sendRar(ctx, ss[0], args.APIOpts, args.Event); errTerm != nil {
|
||||
utils.Logger.Warning(
|
||||
fmt.Sprintf(
|
||||
"<%s> failed sending RAR for session with id: <%s>, err: <%s>",
|
||||
|
||||
@@ -797,6 +797,7 @@ const (
|
||||
TmpSuffix = ".tmp"
|
||||
MetaDiamreq = "*diamreq"
|
||||
MetaRadDAReq = "*radDAReq"
|
||||
MetaRadCoATemplate = "*radCoATemplate"
|
||||
MetaCost = "*cost"
|
||||
MetaGroup = "*group"
|
||||
InternalRPCSet = "InternalRPCSet"
|
||||
|
||||
Reference in New Issue
Block a user