mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 10:06:24 +05:00
Added integration test for *stir_authorize
This commit is contained in:
committed by
Dan Christian Bogos
parent
465b0279cd
commit
0fadf12a51
10
data/stir/generate_keys.sh
Executable file
10
data/stir/generate_keys.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
# generate private the key for ES256
|
||||
openssl ecparam -genkey -name prime256v1 -noout -out stir_privatekey.pem
|
||||
|
||||
# generate the public key based on the private key
|
||||
openssl ec -in stir_privatekey.pem -pubout -out stir_pubkey.pem
|
||||
|
||||
#generate the certificate for the private key
|
||||
openssl req -new -x509 -key stir_privatekey.pem -out stir_cert.pem -days 3650 -subj "/C=DE/ST=Bavaria/L=Bad Reichenhall/O=ITsysCOM/OU=root/CN=localhost/emailAddress=contact@itsyscom.com"
|
||||
16
data/stir/stir_cert.pem
Normal file
16
data/stir/stir_cert.pem
Normal file
@@ -0,0 +1,16 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICczCCAhqgAwIBAgIJAMfbYJAZnigjMAoGCCqGSM49BAMCMIGUMQswCQYDVQQG
|
||||
EwJERTEQMA4GA1UECAwHQmF2YXJpYTEYMBYGA1UEBwwPQmFkIFJlaWNoZW5oYWxs
|
||||
MREwDwYDVQQKDAhJVHN5c0NPTTENMAsGA1UECwwEcm9vdDESMBAGA1UEAwwJbG9j
|
||||
YWxob3N0MSMwIQYJKoZIhvcNAQkBFhRjb250YWN0QGl0c3lzY29tLmNvbTAeFw0y
|
||||
MDA0MTYxMTU4MDBaFw0zMDA0MTQxMTU4MDBaMIGUMQswCQYDVQQGEwJERTEQMA4G
|
||||
A1UECAwHQmF2YXJpYTEYMBYGA1UEBwwPQmFkIFJlaWNoZW5oYWxsMREwDwYDVQQK
|
||||
DAhJVHN5c0NPTTENMAsGA1UECwwEcm9vdDESMBAGA1UEAwwJbG9jYWxob3N0MSMw
|
||||
IQYJKoZIhvcNAQkBFhRjb250YWN0QGl0c3lzY29tLmNvbTBZMBMGByqGSM49AgEG
|
||||
CCqGSM49AwEHA0IABI0uM5lqLWKilgdv7J/uL9blKDwENjdmba1LJnsJJdxKwGyK
|
||||
JF0mUq7nCTz7M5QbWG24XJm1wuwyj/bvT6vxp1ajUzBRMB0GA1UdDgQWBBT6VrVO
|
||||
TDbfJs5R/JG8xBTe8O8TkTAfBgNVHSMEGDAWgBT6VrVOTDbfJs5R/JG8xBTe8O8T
|
||||
kTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCID2rMfvx3Qyvvqr2
|
||||
WMz4AgV1Yplp6kI0FDEH2w0GiTjoAiBsIF1TsUAwmmXYW8yaPyCVq7LYK9TUP2bu
|
||||
oa27qsM7gA==
|
||||
-----END CERTIFICATE-----
|
||||
5
data/stir/stir_privatekey.pem
Normal file
5
data/stir/stir_privatekey.pem
Normal file
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEICcL1+2nj9ylMlTKjSpIGx03gALK0cISciviwudQuvb9oAoGCCqGSM49
|
||||
AwEHoUQDQgAEjS4zmWotYqKWB2/sn+4v1uUoPAQ2N2ZtrUsmewkl3ErAbIokXSZS
|
||||
rucJPPszlBtYbbhcmbXC7DKP9u9Pq/GnVg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
4
data/stir/stir_pubkey.pem
Normal file
4
data/stir/stir_pubkey.pem
Normal file
@@ -0,0 +1,4 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjS4zmWotYqKWB2/sn+4v1uUoPAQ2
|
||||
N2ZtrUsmewkl3ErAbIokXSZSrucJPPszlBtYbbhcmbXC7DKP9u9Pq/GnVg==
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -47,6 +47,7 @@ var (
|
||||
testSes2ItLoadFromFolder,
|
||||
testSes2ItInitSession,
|
||||
testSes2ItAsActiveSessions,
|
||||
testSes2StirAuthorize,
|
||||
testSes2ItStopCgrEngine,
|
||||
}
|
||||
)
|
||||
@@ -179,3 +180,41 @@ func testSes2ItStopCgrEngine(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func testSes2StirAuthorize(t *testing.T) {
|
||||
args := &sessions.V1ProcessEventArgs{
|
||||
Flags: []string{"*stir_authorize"},
|
||||
CGREvent: &utils.CGREvent{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "testSes2StirAuthorize",
|
||||
Event: map[string]interface{}{
|
||||
utils.ToR: utils.VOICE,
|
||||
utils.OriginID: "testSes2StirAuthorize",
|
||||
utils.RequestType: utils.META_PREPAID,
|
||||
utils.Account: "1001",
|
||||
utils.Subject: "ANY2CNT",
|
||||
utils.Destination: "1002",
|
||||
utils.Usage: 10 * time.Minute,
|
||||
utils.STIRIdentity: "eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiL3Vzci9zaGFyZS9jZ3JhdGVzL3N0aXIvc3Rpcl9wdWJrZXkucGVtIn0.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMzg4MDIsIm9yaWciOnsidG4iOiIxMDAxIn0sIm9yaWdpZCI6IjEyMzQ1NiJ9.cMEMlFnfyTu8uxfeU4RoZTamA7ifFT9Ibwrvi1_LKwL2xAU6fZ_CSIxKbtyOpNhM_sV03x7CfA_v0T4sHkifzg;info=</usr/share/cgrates/stir/stir_pubkey.pem>;ppt=shaken",
|
||||
},
|
||||
},
|
||||
}
|
||||
var rply sessions.V1ProcessEventReply
|
||||
if err := ses2RPC.Call(utils.SessionSv1ProcessEvent,
|
||||
args, &rply); err != nil { // no error verificated with success
|
||||
t.Error(err)
|
||||
}
|
||||
// altered originator
|
||||
args.CGREvent.Event[utils.STIROriginatorTn] = "1005"
|
||||
if err := ses2RPC.Call(utils.SessionSv1ProcessEvent,
|
||||
args, &rply); err == nil || err.Error() != "*stir_authorize: wrong originatorTn" {
|
||||
t.Errorf("Expected error :%q ,receved: %v", "*stir_authorize: wrong originatorTn", err)
|
||||
}
|
||||
|
||||
// altered identity
|
||||
args.CGREvent.Event[utils.STIRIdentity] = "eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiL3Vzci9zaGFyZS9jZ3JhdGVzL3N0aXIvc3Rpcl9wdWJrZXkucGVtIn0.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMzg4MDIsIm9yaWciOnsidG4iOiIxMDA1In0sIm9yaWdpZCI6IjEyMzQ1NiJ9.cMEMlFnfyTu8uxfeU4RoZTamA7ifFT9Ibwrvi1_LKwL2xAU6fZ_CSIxKbtyOpNhM_sV03x7CfA_v0T4sHkifzg;info=</usr/share/cgrates/stir/stir_pubkey.pem>;ppt=shaken"
|
||||
if err := ses2RPC.Call(utils.SessionSv1ProcessEvent,
|
||||
args, &rply); err == nil || err.Error() != "*stir_authorize: crypto/ecdsa: verification error" {
|
||||
t.Errorf("Expected error :%q ,receved: %v", "*stir_authorize: crypto/ecdsa: verification error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ cgrates (0.11.0~dev) UNRELEASED; urgency=medium
|
||||
* [AgentS] Add ability to inject data in cache from agents
|
||||
* [Config] Config cache format change to include partitions
|
||||
* [ERs] Add *none EventReader type
|
||||
* [SessionS] Added support for *stir_authorize
|
||||
|
||||
-- Alexandru Tripon <alexandru.tripon@itsyscom.com> Wed, 19 Feb 2020 13:25:52 +0200
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
@@ -205,23 +206,19 @@ func (pi *ProcessedStirIdentity) VerifyPayload(originatorTn, originatorURI, dest
|
||||
if hdrMaxDur >= 0 && time.Now().After(time.Unix(pi.Payload.IAT, 0).Add(hdrMaxDur)) {
|
||||
return errors.New("expired payload")
|
||||
}
|
||||
if originatorTn != utils.EmptyString {
|
||||
if originatorTn != pi.Payload.Orig.Tn {
|
||||
return errors.New("wrong originatorTn")
|
||||
}
|
||||
} else {
|
||||
if originatorURI != utils.EmptyString {
|
||||
if originatorURI != pi.Payload.Orig.URI {
|
||||
return errors.New("wrong originatorURI")
|
||||
}
|
||||
} else if originatorTn != pi.Payload.Orig.Tn {
|
||||
return errors.New("wrong originatorTn")
|
||||
}
|
||||
if destinationTn != utils.EmptyString {
|
||||
if !utils.SliceHasMember(pi.Payload.Dest.Tn, destinationTn) {
|
||||
return errors.New("wrong destinationTn")
|
||||
}
|
||||
} else {
|
||||
if destinationURI != utils.EmptyString {
|
||||
if !utils.SliceHasMember(pi.Payload.Dest.URI, destinationURI) {
|
||||
return errors.New("wrong destinationURI")
|
||||
}
|
||||
} else if !utils.SliceHasMember(pi.Payload.Dest.Tn, destinationTn) {
|
||||
return errors.New("wrong destinationTn")
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -258,7 +255,7 @@ func NewIdentity(header *utils.PASSporTHeader, payload *utils.PASSporTPayload, p
|
||||
return
|
||||
}
|
||||
|
||||
func authStirShaken(identity, originatorTn, originatorURI, destinationTn, destinationURI string,
|
||||
func AuthStirShaken(identity, originatorTn, originatorURI, destinationTn, destinationURI string,
|
||||
attest *utils.StringSet, hdrMaxDur time.Duration) (err error) {
|
||||
var pi *ProcessedStirIdentity
|
||||
if pi, err = NewProcessedIdentity(identity); err != nil {
|
||||
@@ -267,8 +264,8 @@ func authStirShaken(identity, originatorTn, originatorURI, destinationTn, destin
|
||||
if !pi.VerifyHeader() {
|
||||
return errors.New("wrong header")
|
||||
}
|
||||
if err = pi.VerifySignature(time.Second); err != nil {
|
||||
if err = pi.VerifySignature(config.CgrConfig().GeneralCfg().ReplyTimeout); err != nil {
|
||||
return
|
||||
}
|
||||
return pi.VerifyPayload(originatorTn, originatorURI, destinationTn, destinationURI, hdrMaxDur, attest) // verificare in lista
|
||||
return pi.VerifyPayload(originatorTn, originatorURI, destinationTn, destinationURI, hdrMaxDur, attest)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
func TestLibSessionSGetSetCGRID(t *testing.T) {
|
||||
@@ -146,3 +147,165 @@ func TestGetFlagIDs(t *testing.T) {
|
||||
t.Errorf("Expected %s , received: %s", utils.ToJSON(eOut), utils.ToJSON(rcv))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewProcessedIdentity(t *testing.T) {
|
||||
if _, err := NewProcessedIdentity(""); err == nil ||
|
||||
err.Error() != "missing parts of the message header" {
|
||||
t.Errorf("Expected %q received: %v", "missing parts of the message header", err)
|
||||
}
|
||||
if _, err := NewProcessedIdentity(";"); err == nil ||
|
||||
err.Error() != "wrong header format" {
|
||||
t.Errorf("Expected %q received: %v", "wrong header format", err)
|
||||
}
|
||||
|
||||
if _, err := NewProcessedIdentity("eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR,5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly93d3cuZXhhbXBsZS5vcmcvY2VydC5jZXIifQ.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMTk4MjIsIm9yaWc,iOnsidG4iOiIxMDAxIn0sIm9yaWdpZCI6IjEyMzQ1NiJ9.4ybtWmgqdkNyJLS9Iv3PuJV8ZxR7yZ_NEBhCpKCEu2WBiTchqwoqoWpI17Q_ALm38tbnpay32t95ZY_LhSgwJg;info=<https://www.example.org/cert.cer>;ppt=shaken"); err == nil {
|
||||
t.Errorf("Expected error")
|
||||
}
|
||||
|
||||
if _, err := NewProcessedIdentity("eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly93d3cuZXhhbXBsZS5vcmcvY2VydC5jZXIifQ.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMTk4MjIsIm9yaWc,iOnsidG4iOiIxMDAxIn0sIm9yaWdpZCI6IjEyMzQ1NiJ9.4ybtWmgqdkNyJLS9Iv3PuJV8ZxR7yZ_NEBhCpKCEu2WBiTchqwoqoWpI17Q_ALm38tbnpay32t95ZY_LhSgwJg;info=<https://www.example.org/cert.cer>;ppt=shaken"); err == nil {
|
||||
t.Errorf("Expected error")
|
||||
}
|
||||
|
||||
expected := &ProcessedStirIdentity{
|
||||
Tokens: []string{"info=<https://www.example.org/cert.cer>", "ppt=shaken"},
|
||||
SigningStr: "eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly93d3cuZXhhbXBsZS5vcmcvY2VydC5jZXIifQ.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMTk4MjIsIm9yaWciOnsidG4iOiIxMDAxIn0sIm9yaWdpZCI6IjEyMzQ1NiJ9",
|
||||
Signature: "4ybtWmgqdkNyJLS9Iv3PuJV8ZxR7yZ_NEBhCpKCEu2WBiTchqwoqoWpI17Q_ALm38tbnpay32t95ZY_LhSgwJg",
|
||||
Header: &utils.PASSporTHeader{
|
||||
Typ: utils.STIRTyp,
|
||||
Alg: utils.STIRAlg,
|
||||
Ppt: utils.STIRPpt,
|
||||
X5u: "https://www.example.org/cert.cer",
|
||||
},
|
||||
Payload: &utils.PASSporTPayload{
|
||||
ATTest: "A",
|
||||
Dest: utils.PASSporTDestinationsIdentity{
|
||||
Tn: []string{"1002"},
|
||||
},
|
||||
IAT: 1587019822,
|
||||
Orig: utils.PASSporTOriginsIdentity{
|
||||
Tn: "1001",
|
||||
},
|
||||
OrigID: "123456",
|
||||
},
|
||||
}
|
||||
if rply, err := NewProcessedIdentity("eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly93d3cuZXhhbXBsZS5vcmcvY2VydC5jZXIifQ.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMTk4MjIsIm9yaWciOnsidG4iOiIxMDAxIn0sIm9yaWdpZCI6IjEyMzQ1NiJ9.4ybtWmgqdkNyJLS9Iv3PuJV8ZxR7yZ_NEBhCpKCEu2WBiTchqwoqoWpI17Q_ALm38tbnpay32t95ZY_LhSgwJg;info=<https://www.example.org/cert.cer>;ppt=shaken"); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expected, rply) {
|
||||
t.Errorf("Expected: %s, received:%s", utils.ToJSON(expected), utils.ToJSON(rply))
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessedIdentityVerifyHeader(t *testing.T) {
|
||||
args := &ProcessedStirIdentity{
|
||||
Tokens: []string{"info=<https://www.example.org/cert.cer>", "ppt=shaken", "extra", "alg=ES256"},
|
||||
Header: &utils.PASSporTHeader{
|
||||
Typ: utils.STIRTyp,
|
||||
Alg: utils.STIRAlg,
|
||||
Ppt: utils.STIRPpt,
|
||||
X5u: "https://www.example.org/cert.cer",
|
||||
},
|
||||
}
|
||||
if !args.VerifyHeader() {
|
||||
t.Errorf("Expected the header to be valid")
|
||||
}
|
||||
args.Header.Typ = "1"
|
||||
if args.VerifyHeader() {
|
||||
t.Errorf("Expected the header to not be valid")
|
||||
}
|
||||
|
||||
args.Tokens = []string{"info=<https://www.example.org/cert.cer>", "ppt=shaken", "alg=wrongArg"}
|
||||
if args.VerifyHeader() {
|
||||
t.Errorf("Expected the header to not be valid")
|
||||
}
|
||||
|
||||
args.Tokens = []string{"info=<https://www.example.org/cert.cer>", "ppt=wrongExtension"}
|
||||
if args.VerifyHeader() {
|
||||
t.Errorf("Expected the header to not be valid")
|
||||
}
|
||||
args.Tokens = []string{"info=<", "ppt=shaken"}
|
||||
if args.VerifyHeader() {
|
||||
t.Errorf("Expected the header to not be valid")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessedIdentityVerifyPayload(t *testing.T) {
|
||||
args := &ProcessedStirIdentity{
|
||||
Payload: &utils.PASSporTPayload{
|
||||
ATTest: "C",
|
||||
Dest: utils.PASSporTDestinationsIdentity{
|
||||
Tn: []string{"1002"},
|
||||
},
|
||||
IAT: 1587019822,
|
||||
Orig: utils.PASSporTOriginsIdentity{
|
||||
Tn: "1001",
|
||||
},
|
||||
OrigID: "123456",
|
||||
},
|
||||
}
|
||||
if err := args.VerifyPayload("1001", "", "1002", "", -1, utils.NewStringSet([]string{utils.META_ANY})); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := args.VerifyPayload("1001", "", "1003", "", -1, utils.NewStringSet([]string{utils.META_ANY})); err == nil ||
|
||||
err.Error() != "wrong destinationTn" {
|
||||
t.Errorf("Expected error: %s,receved %v", "wrong destinationTn", err)
|
||||
}
|
||||
if err := args.VerifyPayload("1001", "", "1003", "1002", -1, utils.NewStringSet([]string{utils.META_ANY})); err == nil ||
|
||||
err.Error() != "wrong destinationURI" {
|
||||
t.Errorf("Expected error: %s,receved %v", "wrong destinationURI", err)
|
||||
}
|
||||
if err := args.VerifyPayload("1002", "", "1003", "1002", -1, utils.NewStringSet([]string{utils.META_ANY})); err == nil ||
|
||||
err.Error() != "wrong originatorTn" {
|
||||
t.Errorf("Expected error: %s,receved %v", "wrong originatorTn", err)
|
||||
}
|
||||
if err := args.VerifyPayload("1002", "1001", "1003", "1002", -1, utils.NewStringSet([]string{utils.META_ANY})); err == nil ||
|
||||
err.Error() != "wrong originatorURI" {
|
||||
t.Errorf("Expected error: %s,receved %v", "wrong originatorURI", err)
|
||||
}
|
||||
if err := args.VerifyPayload("1001", "", "1002", "", time.Second, utils.NewStringSet([]string{utils.META_ANY})); err == nil ||
|
||||
err.Error() != "expired payload" {
|
||||
t.Errorf("Expected error: %s,receved %v", "expired payload", err)
|
||||
}
|
||||
if err := args.VerifyPayload("1001", "", "1002", "", time.Second, utils.NewStringSet([]string{"A"})); err == nil ||
|
||||
err.Error() != "wrong attest level" {
|
||||
t.Errorf("Expected error: %s,receved %v", "wrong attest level", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthStirShaken(t *testing.T) {
|
||||
if err := AuthStirShaken("", "1001", "", "1002", "", utils.NewStringSet([]string{utils.META_ANY}), -1); err == nil {
|
||||
t.Error("Expected invalid identity")
|
||||
}
|
||||
if err := AuthStirShaken(
|
||||
"eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly93d3cuZXhhbXBsZS5vcmcvY2VydC5jZXIifQ.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMTk4MjIsIm9yaWciOnsidG4iOiIxMDAxIn0sIm9yaWdpZCI6IjEyMzQ1NiJ9.4ybtWmgqdkNyJLS9Iv3PuJV8ZxR7yZ_NEBhCpKCEu2WBiTchqwoqoWpI17Q_ALm38tbnpay32t95ZY_LhSgwJg;info=<https://www.example.org/cert.cer2>;ppt=shaken",
|
||||
"1001", "", "1002", "", utils.NewStringSet([]string{utils.META_ANY}), -1); err == nil {
|
||||
t.Error("Expected invalid identity")
|
||||
}
|
||||
engine.Cache.Set(utils.CacheSTIR, "https://www.example.org/cert.cer", nil,
|
||||
nil, true, utils.NonTransactional)
|
||||
if err := AuthStirShaken(
|
||||
"eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly93d3cuZXhhbXBsZS5vcmcvY2VydC5jZXIifQ.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMTk4MjIsIm9yaWciOnsidG4iOiIxMDAxIn0sIm9yaWdpZCI6IjEyMzQ1NiJ9.4ybtWmgqdkNyJLS9Iv3PuJV8ZxR7yZ_NEBhCpKCEu2WBiTchqwoqoWpI17Q_ALm38tbnpay32t95ZY_LhSgwJg;info=<https://www.example.org/cert.cer>;ppt=shaken", "1001", "", "1002", "", utils.NewStringSet([]string{utils.META_ANY}), -1); err == nil {
|
||||
t.Error("Expected invalid identity")
|
||||
}
|
||||
|
||||
pubkeyBuf := []byte(`-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESt8sEh55Yc579vLHjFRWVQO27p4Y
|
||||
aa+jqv4dwkr/FLEcN1zC76Y/IniI65fId55hVJvN3ORuzUqYEtzD3irmsw==
|
||||
-----END PUBLIC KEY-----
|
||||
`)
|
||||
pubKey, err := jwt.ParseECPublicKeyFromPEM(pubkeyBuf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
engine.Cache.Set(utils.CacheSTIR, "https://www.example.org/cert.cer", pubKey,
|
||||
nil, true, utils.NonTransactional)
|
||||
|
||||
if err := AuthStirShaken(
|
||||
"eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly93d3cuZXhhbXBsZS5vcmcvY2VydC5jZXIifQ.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMTk4MjIsIm9yaWciOnsidG4iOiIxMDAxIn0sIm9yaWdpZCI6IjEyMzQ1NiJ9.4ybtWmgqdkNyJLS9Iv3PuJV8ZxR7yZ_NEBhCpKCEu2WBiTchqwoqoWpI17Q_ALm38tbnpay32t95ZY_LhSgwJg;info=<https://www.example.org/cert.cer>;ppt=shaken", "1001", "", "1003", "", utils.NewStringSet([]string{utils.META_ANY}), -1); err == nil {
|
||||
t.Error("Expected invalid identity")
|
||||
}
|
||||
|
||||
if err := AuthStirShaken(
|
||||
"eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly93d3cuZXhhbXBsZS5vcmcvY2VydC5jZXIifQ.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMTk4MjIsIm9yaWciOnsidG4iOiIxMDAxIn0sIm9yaWdpZCI6IjEyMzQ1NiJ9.4ybtWmgqdkNyJLS9Iv3PuJV8ZxR7yZ_NEBhCpKCEu2WBiTchqwoqoWpI17Q_ALm38tbnpay32t95ZY_LhSgwJg;info=<https://www.example.org/cert.cer>;ppt=shaken", "1001", "", "1002", "", utils.NewStringSet([]string{utils.META_ANY}), -1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,12 +361,10 @@ func TestSessionAsCGREvents(t *testing.T) {
|
||||
CGRID: "RandomCGRID",
|
||||
Tenant: "cgrates.org",
|
||||
EventStart: engine.NewMapEvent(startEv),
|
||||
SRuns: []*SRun{
|
||||
&SRun{
|
||||
Event: engine.NewMapEvent(ev),
|
||||
TotalUsage: time.Duration(2 * time.Second),
|
||||
},
|
||||
},
|
||||
SRuns: []*SRun{{
|
||||
Event: engine.NewMapEvent(ev),
|
||||
TotalUsage: time.Duration(2 * time.Second),
|
||||
}},
|
||||
}
|
||||
//check for some fields if populated correct
|
||||
cgrEvs, err := s.asCGREvents()
|
||||
@@ -420,44 +418,40 @@ func TestSessionAsExternalSessions(t *testing.T) {
|
||||
Tenant: "cgrates.org",
|
||||
EventStart: engine.NewMapEvent(startEv),
|
||||
DebitInterval: time.Second,
|
||||
SRuns: []*SRun{
|
||||
&SRun{
|
||||
Event: engine.NewMapEvent(ev),
|
||||
TotalUsage: time.Duration(2 * time.Second),
|
||||
NextAutoDebit: &tTime,
|
||||
},
|
||||
},
|
||||
SRuns: []*SRun{{
|
||||
Event: engine.NewMapEvent(ev),
|
||||
TotalUsage: time.Duration(2 * time.Second),
|
||||
NextAutoDebit: &tTime,
|
||||
}},
|
||||
}
|
||||
exp := []*ExternalSession{
|
||||
&ExternalSession{
|
||||
CGRID: "RandomCGRID",
|
||||
RunID: utils.MetaDefault,
|
||||
ToR: utils.VOICE,
|
||||
OriginID: "123451",
|
||||
// OriginHost: s.EventStart.GetStringIgnoreErrors(utils.OriginHost),
|
||||
Source: utils.SessionS + "_" + "TEST_EVENT",
|
||||
RequestType: utils.META_PREPAID,
|
||||
Tenant: "cgrates.org",
|
||||
Category: "call",
|
||||
Account: "1001",
|
||||
Subject: "1001",
|
||||
Destination: "1004",
|
||||
SetupTime: time.Date(2016, time.January, 5, 18, 30, 59, 0, time.UTC),
|
||||
AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC),
|
||||
Usage: time.Duration(2 * time.Second),
|
||||
ExtraFields: map[string]string{
|
||||
utils.EVENT_NAME: "TEST_EVENT2",
|
||||
},
|
||||
NodeID: "ALL",
|
||||
DebitInterval: time.Second,
|
||||
NextAutoDebit: tTime,
|
||||
// aSs[i].LoopIndex: sr.CD.LoopIndex,
|
||||
// aSs[i].DurationIndex: sr.CD.DurationIndex,
|
||||
// aSs[i].MaxRate: sr.CD.MaxRate,
|
||||
// aSs[i].MaxRateUnit: sr.CD.MaxRateUnit,
|
||||
// aSs[i].MaxCostSoFar: sr.CD.MaxCostSoFar,
|
||||
exp := []*ExternalSession{{
|
||||
CGRID: "RandomCGRID",
|
||||
RunID: utils.MetaDefault,
|
||||
ToR: utils.VOICE,
|
||||
OriginID: "123451",
|
||||
// OriginHost: s.EventStart.GetStringIgnoreErrors(utils.OriginHost),
|
||||
Source: utils.SessionS + "_" + "TEST_EVENT",
|
||||
RequestType: utils.META_PREPAID,
|
||||
Tenant: "cgrates.org",
|
||||
Category: "call",
|
||||
Account: "1001",
|
||||
Subject: "1001",
|
||||
Destination: "1004",
|
||||
SetupTime: time.Date(2016, time.January, 5, 18, 30, 59, 0, time.UTC),
|
||||
AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC),
|
||||
Usage: time.Duration(2 * time.Second),
|
||||
ExtraFields: map[string]string{
|
||||
utils.EVENT_NAME: "TEST_EVENT2",
|
||||
},
|
||||
}
|
||||
NodeID: "ALL",
|
||||
DebitInterval: time.Second,
|
||||
NextAutoDebit: tTime,
|
||||
// aSs[i].LoopIndex: sr.CD.LoopIndex,
|
||||
// aSs[i].DurationIndex: sr.CD.DurationIndex,
|
||||
// aSs[i].MaxRate: sr.CD.MaxRate,
|
||||
// aSs[i].MaxRateUnit: sr.CD.MaxRateUnit,
|
||||
// aSs[i].MaxCostSoFar: sr.CD.MaxCostSoFar,
|
||||
}}
|
||||
//check for some fields if populated correct
|
||||
rply := s.AsExternalSessions("", "ALL")
|
||||
if !reflect.DeepEqual(exp, rply) {
|
||||
@@ -503,49 +497,45 @@ func TestSessionAsExternalSessions2(t *testing.T) {
|
||||
Tenant: "cgrates.org",
|
||||
EventStart: engine.NewMapEvent(startEv),
|
||||
DebitInterval: time.Second,
|
||||
SRuns: []*SRun{
|
||||
&SRun{
|
||||
Event: engine.NewMapEvent(ev),
|
||||
TotalUsage: time.Duration(2 * time.Second),
|
||||
CD: &engine.CallDescriptor{
|
||||
LoopIndex: 10,
|
||||
DurationIndex: 3 * time.Second,
|
||||
MaxRate: 11,
|
||||
MaxRateUnit: 30 * time.Second,
|
||||
MaxCostSoFar: 20,
|
||||
},
|
||||
},
|
||||
SRuns: []*SRun{{
|
||||
Event: engine.NewMapEvent(ev),
|
||||
TotalUsage: time.Duration(2 * time.Second),
|
||||
CD: &engine.CallDescriptor{
|
||||
LoopIndex: 10,
|
||||
DurationIndex: 3 * time.Second,
|
||||
MaxRate: 11,
|
||||
MaxRateUnit: 30 * time.Second,
|
||||
MaxCostSoFar: 20,
|
||||
}},
|
||||
},
|
||||
}
|
||||
exp := []*ExternalSession{
|
||||
&ExternalSession{
|
||||
CGRID: "RandomCGRID",
|
||||
RunID: utils.MetaDefault,
|
||||
ToR: utils.VOICE,
|
||||
OriginID: "123451",
|
||||
// OriginHost: s.EventStart.GetStringIgnoreErrors(utils.OriginHost),
|
||||
Source: utils.SessionS + "_" + "TEST_EVENT",
|
||||
RequestType: utils.META_PREPAID,
|
||||
Tenant: "cgrates.org",
|
||||
Category: "call",
|
||||
Account: "1001",
|
||||
Subject: "1001",
|
||||
Destination: "1004",
|
||||
SetupTime: time.Date(2016, time.January, 5, 18, 30, 59, 0, time.UTC),
|
||||
AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC),
|
||||
Usage: time.Duration(2 * time.Second),
|
||||
ExtraFields: map[string]string{
|
||||
utils.EVENT_NAME: "TEST_EVENT2",
|
||||
},
|
||||
NodeID: "ALL",
|
||||
DebitInterval: time.Second,
|
||||
LoopIndex: 10,
|
||||
DurationIndex: 3 * time.Second,
|
||||
MaxRate: 11,
|
||||
MaxRateUnit: 30 * time.Second,
|
||||
MaxCostSoFar: 20,
|
||||
exp := []*ExternalSession{{
|
||||
CGRID: "RandomCGRID",
|
||||
RunID: utils.MetaDefault,
|
||||
ToR: utils.VOICE,
|
||||
OriginID: "123451",
|
||||
// OriginHost: s.EventStart.GetStringIgnoreErrors(utils.OriginHost),
|
||||
Source: utils.SessionS + "_" + "TEST_EVENT",
|
||||
RequestType: utils.META_PREPAID,
|
||||
Tenant: "cgrates.org",
|
||||
Category: "call",
|
||||
Account: "1001",
|
||||
Subject: "1001",
|
||||
Destination: "1004",
|
||||
SetupTime: time.Date(2016, time.January, 5, 18, 30, 59, 0, time.UTC),
|
||||
AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC),
|
||||
Usage: time.Duration(2 * time.Second),
|
||||
ExtraFields: map[string]string{
|
||||
utils.EVENT_NAME: "TEST_EVENT2",
|
||||
},
|
||||
}
|
||||
NodeID: "ALL",
|
||||
DebitInterval: time.Second,
|
||||
LoopIndex: 10,
|
||||
DurationIndex: 3 * time.Second,
|
||||
MaxRate: 11,
|
||||
MaxRateUnit: 30 * time.Second,
|
||||
MaxCostSoFar: 20,
|
||||
}}
|
||||
//check for some fields if populated correct
|
||||
rply := s.AsExternalSessions("", "ALL")
|
||||
if !reflect.DeepEqual(exp, rply) {
|
||||
@@ -593,20 +583,18 @@ func TestSessionAsExternalSessions3(t *testing.T) {
|
||||
Tenant: "cgrates.org",
|
||||
EventStart: engine.NewMapEvent(startEv),
|
||||
DebitInterval: time.Second,
|
||||
SRuns: []*SRun{
|
||||
&SRun{
|
||||
Event: engine.NewMapEvent(ev),
|
||||
TotalUsage: time.Duration(2 * time.Second),
|
||||
CD: &engine.CallDescriptor{
|
||||
LoopIndex: 10,
|
||||
DurationIndex: 3 * time.Second,
|
||||
MaxRate: 11,
|
||||
MaxRateUnit: 30 * time.Second,
|
||||
MaxCostSoFar: 20,
|
||||
},
|
||||
NextAutoDebit: &tTime,
|
||||
SRuns: []*SRun{{
|
||||
Event: engine.NewMapEvent(ev),
|
||||
TotalUsage: time.Duration(2 * time.Second),
|
||||
CD: &engine.CallDescriptor{
|
||||
LoopIndex: 10,
|
||||
DurationIndex: 3 * time.Second,
|
||||
MaxRate: 11,
|
||||
MaxRateUnit: 30 * time.Second,
|
||||
MaxCostSoFar: 20,
|
||||
},
|
||||
},
|
||||
NextAutoDebit: &tTime,
|
||||
}},
|
||||
}
|
||||
exp := &ExternalSession{
|
||||
CGRID: "RandomCGRID",
|
||||
@@ -663,7 +651,8 @@ func TestSessiontotalUsage(t *testing.T) {
|
||||
EventStart: engine.NewMapEvent(nil),
|
||||
DebitInterval: time.Duration(18),
|
||||
SRuns: []*SRun{
|
||||
{Event: engine.NewMapEvent(nil),
|
||||
{
|
||||
Event: engine.NewMapEvent(nil),
|
||||
CD: &engine.CallDescriptor{Category: "test"},
|
||||
EventCost: &engine.EventCost{CGRID: "testCGRID"},
|
||||
ExtraDuration: time.Duration(1),
|
||||
@@ -671,7 +660,8 @@ func TestSessiontotalUsage(t *testing.T) {
|
||||
TotalUsage: time.Duration(5),
|
||||
NextAutoDebit: &tTime,
|
||||
},
|
||||
{Event: engine.NewMapEvent(nil),
|
||||
{
|
||||
Event: engine.NewMapEvent(nil),
|
||||
CD: &engine.CallDescriptor{Category: "test2"},
|
||||
EventCost: &engine.EventCost{CGRID: "testCGRID2"},
|
||||
ExtraDuration: time.Duration(4),
|
||||
@@ -714,5 +704,73 @@ func TestSessionstopDebitLoops(t *testing.T) {
|
||||
if session.debitStop != nil {
|
||||
t.Errorf("Expecting: nil, received: %s", utils.ToJSON(session.debitStop))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestUpdateSRuns(t *testing.T) {
|
||||
startEv := map[string]interface{}{
|
||||
utils.EVENT_NAME: "TEST_EVENT",
|
||||
utils.ToR: utils.VOICE,
|
||||
utils.OriginID: "123451",
|
||||
utils.Account: "1001",
|
||||
utils.Subject: "1001",
|
||||
utils.Destination: "1004",
|
||||
utils.Category: "call",
|
||||
utils.Tenant: "cgrates.org",
|
||||
utils.RequestType: utils.META_PREPAID,
|
||||
utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 59, 0, time.UTC),
|
||||
utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC),
|
||||
utils.Usage: time.Duration(2 * time.Second),
|
||||
utils.Cost: 12.12,
|
||||
}
|
||||
ev := map[string]interface{}{
|
||||
utils.EVENT_NAME: "TEST_EVENT2",
|
||||
utils.ToR: utils.VOICE,
|
||||
utils.OriginID: "123451",
|
||||
utils.Account: "1001",
|
||||
utils.Subject: "1001",
|
||||
utils.Destination: "1004",
|
||||
utils.Category: "call",
|
||||
utils.RunID: utils.MetaDefault,
|
||||
utils.Tenant: "cgrates.org",
|
||||
utils.RequestType: utils.META_PREPAID,
|
||||
utils.SetupTime: time.Date(2016, time.January, 5, 18, 30, 59, 0, time.UTC),
|
||||
utils.AnswerTime: time.Date(2016, time.January, 5, 18, 31, 05, 0, time.UTC),
|
||||
utils.Usage: time.Duration(2 * time.Second),
|
||||
utils.Cost: 12.13,
|
||||
}
|
||||
s := &Session{
|
||||
CGRID: "RandomCGRID",
|
||||
Tenant: "cgrates.org",
|
||||
EventStart: engine.NewMapEvent(startEv),
|
||||
DebitInterval: time.Second,
|
||||
SRuns: []*SRun{{
|
||||
Event: engine.NewMapEvent(ev),
|
||||
TotalUsage: time.Duration(2 * time.Second),
|
||||
CD: &engine.CallDescriptor{
|
||||
LoopIndex: 10,
|
||||
DurationIndex: 3 * time.Second,
|
||||
MaxRate: 11,
|
||||
MaxRateUnit: 30 * time.Second,
|
||||
MaxCostSoFar: 20,
|
||||
},
|
||||
}},
|
||||
}
|
||||
updEv := map[string]interface{}{
|
||||
utils.EVENT_NAME: "TEST_EVENT2",
|
||||
utils.Tenant: "cgrates.org",
|
||||
utils.RequestType: utils.META_POSTPAID,
|
||||
}
|
||||
s.updateSRuns(updEv, utils.NewStringSet(nil))
|
||||
if s.SRuns[0].Event[utils.RequestType] != utils.META_PREPAID {
|
||||
t.Errorf("Expected session to not change")
|
||||
}
|
||||
s.UpdateSRuns(updEv, utils.NewStringSet(nil))
|
||||
if s.SRuns[0].Event[utils.RequestType] != utils.META_PREPAID {
|
||||
t.Errorf("Expected session to not change")
|
||||
}
|
||||
s.UpdateSRuns(updEv, utils.NewStringSet([]string{utils.RequestType}))
|
||||
if s.SRuns[0].Event[utils.RequestType] != utils.META_POSTPAID {
|
||||
t.Errorf("Expected request type to be: %q, received: %q",
|
||||
utils.META_POSTPAID, s.SRuns[0].Event[utils.RequestType])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2965,7 +2965,7 @@ func (sS *SessionS) BiRPCv1ProcessEvent(clnt rpcclient.ClientConnector,
|
||||
if stirMaxDur, err = ev.GetDuration(utils.STIRPayloadMaxDuration); err != nil {
|
||||
stirMaxDur = sS.cgrCfg.SessionSCfg().STIRPayloadMaxduration
|
||||
}
|
||||
if err = authStirShaken(ev.GetStringIgnoreErrors(utils.STIRIdentity),
|
||||
if err = AuthStirShaken(ev.GetStringIgnoreErrors(utils.STIRIdentity),
|
||||
utils.FirstNonEmpty(ev.GetStringIgnoreErrors(utils.STIROriginatorTn), ev.GetStringIgnoreErrors(utils.Account)),
|
||||
ev.GetStringIgnoreErrors(utils.STIROriginatorURI),
|
||||
utils.FirstNonEmpty(ev.GetStringIgnoreErrors(utils.STIRDestinationTn), ev.GetStringIgnoreErrors(utils.Destination)),
|
||||
|
||||
@@ -30,7 +30,6 @@ import (
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/rpcclient"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
var attrs = &engine.AttrSProcessEventReply{
|
||||
@@ -2209,22 +2208,3 @@ func TestSessionSfilterSessionsCount(t *testing.T) {
|
||||
t.Errorf("Expected %v , received: %s", 2, utils.ToJSON(noSess))
|
||||
}
|
||||
}
|
||||
|
||||
func TestStirShaken(t *testing.T) {
|
||||
pubkeyBuf := []byte(`-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESt8sEh55Yc579vLHjFRWVQO27p4Y
|
||||
aa+jqv4dwkr/FLEcN1zC76Y/IniI65fId55hVJvN3ORuzUqYEtzD3irmsw==
|
||||
-----END PUBLIC KEY-----
|
||||
`)
|
||||
pubKey, err := jwt.ParseECPublicKeyFromPEM(pubkeyBuf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
engine.Cache.Set(utils.CacheSTIR, "https://www.example.org/cert.cer", pubKey,
|
||||
nil, true, utils.NonTransactional)
|
||||
|
||||
if err := authStirShaken(
|
||||
"eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cHM6Ly93d3cuZXhhbXBsZS5vcmcvY2VydC5jZXIifQ.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMDAyIl19LCJpYXQiOjE1ODcwMTk4MjIsIm9yaWciOnsidG4iOiIxMDAxIn0sIm9yaWdpZCI6IjEyMzQ1NiJ9.4ybtWmgqdkNyJLS9Iv3PuJV8ZxR7yZ_NEBhCpKCEu2WBiTchqwoqoWpI17Q_ALm38tbnpay32t95ZY_LhSgwJg;info=<https://www.example.org/cert.cer>;ppt=shaken", "1001", "", "1002", "", utils.NewStringSet([]string{utils.META_ANY}), -1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,5 +264,5 @@ func ErrNotConvertibleTF(from, to string) error {
|
||||
|
||||
// NewSTIRError returns a error with a *stir_authorize prefix
|
||||
func NewSTIRError(reason string) error {
|
||||
return fmt.Errorf("<%s> %s", MetaSTIRAuthorize, reason)
|
||||
return fmt.Errorf("%s: %s", MetaSTIRAuthorize, reason)
|
||||
}
|
||||
|
||||
@@ -230,3 +230,17 @@ func TestErrNotConvertibleTF(t *testing.T) {
|
||||
t.Errorf("Expecting: not convertible : from: test_type1 to:test_type2, received: %+v", rcv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewErrChargerS(t *testing.T) {
|
||||
expected := `CHARGERS_ERROR:NOT_FOUND`
|
||||
if rcv := NewErrChargerS(ErrNotFound); rcv.Error() != expected {
|
||||
t.Errorf("Expecting: %q, received: %q", expected, rcv.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewSTIRError(t *testing.T) {
|
||||
expected := `*stir_authorize: wrong header`
|
||||
if rcv := NewSTIRError("wrong header"); rcv.Error() != expected {
|
||||
t.Errorf("Expecting: %q, received: %q", expected, rcv.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@ type PASSporTOriginsIdentity struct {
|
||||
}
|
||||
|
||||
// NewPASSporTPayload returns an new PASSporTPayload with the given origin and destination
|
||||
func NewPASSporTPayload(attest, originID string, dest PASSporTDestinationsIdentity, orig PASSporTOriginsIdentity) PASSporTPayload {
|
||||
return PASSporTPayload{
|
||||
func NewPASSporTPayload(attest, originID string, dest PASSporTDestinationsIdentity, orig PASSporTOriginsIdentity) *PASSporTPayload {
|
||||
return &PASSporTPayload{
|
||||
ATTest: attest,
|
||||
Dest: dest,
|
||||
IAT: time.Now().Unix(),
|
||||
|
||||
72
utils/stir_shaken_test.go
Normal file
72
utils/stir_shaken_test.go
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewPASSporTHeader(t *testing.T) {
|
||||
expected := &PASSporTHeader{
|
||||
Alg: STIRAlg,
|
||||
Ppt: STIRPpt,
|
||||
Typ: STIRTyp,
|
||||
X5u: "path/to/certificate",
|
||||
}
|
||||
if rply := NewPASSporTHeader("path/to/certificate"); !reflect.DeepEqual(expected, rply) {
|
||||
t.Errorf("Expected: %s,received: %s", ToJSON(expected), ToJSON(rply))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPASSporTDestinationsIdentity(t *testing.T) {
|
||||
expected := &PASSporTDestinationsIdentity{
|
||||
Tn: []string{"1001"},
|
||||
URI: []string{"1002@cgrates.org"},
|
||||
}
|
||||
if rply := NewPASSporTDestinationsIdentity([]string{"1001"}, []string{"1002@cgrates.org"}); !reflect.DeepEqual(expected, rply) {
|
||||
t.Errorf("Expected: %s,received: %s", ToJSON(expected), ToJSON(rply))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPASSporTOriginsIdentity(t *testing.T) {
|
||||
expected := &PASSporTOriginsIdentity{
|
||||
Tn: "1001",
|
||||
}
|
||||
if rply := NewPASSporTOriginsIdentity("1001", ""); !reflect.DeepEqual(expected, rply) {
|
||||
t.Errorf("Expected: %s,received: %s", ToJSON(expected), ToJSON(rply))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPASSporTPayload(t *testing.T) {
|
||||
dst := NewPASSporTDestinationsIdentity([]string{"1001"}, nil)
|
||||
orig := NewPASSporTOriginsIdentity("1002", "")
|
||||
expected := &PASSporTPayload{
|
||||
ATTest: "A",
|
||||
Dest: *dst,
|
||||
IAT: 0,
|
||||
Orig: *orig,
|
||||
OrigID: "123456",
|
||||
}
|
||||
rply := NewPASSporTPayload("A", "123456", *dst, *orig)
|
||||
rply.IAT = 0
|
||||
if !reflect.DeepEqual(expected, rply) {
|
||||
t.Errorf("Expected: %s,received: %s", ToJSON(expected), ToJSON(rply))
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -31,55 +32,67 @@ import (
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
// NewECDSAPrvKey creates a private key from the path
|
||||
func NewECDSAPrvKey(prvKeyPath string, timeout time.Duration) (prvKey *ecdsa.PrivateKey, err error) {
|
||||
// NewECDSAPrvKeyFromReader creates a private key from io.Reader
|
||||
func NewECDSAPrvKeyFromReader(reader io.Reader) (prvKey *ecdsa.PrivateKey, err error) {
|
||||
var prvkeyBuf []byte
|
||||
if prvkeyBuf, err = GetDataAtPath(prvKeyPath, timeout); err != nil {
|
||||
if prvkeyBuf, err = ioutil.ReadAll(reader); err != nil {
|
||||
return
|
||||
}
|
||||
return jwt.ParseECPrivateKeyFromPEM(prvkeyBuf)
|
||||
}
|
||||
|
||||
// NewECDSAPubKey returns a public key from the path
|
||||
func NewECDSAPubKey(pubKeyPath string, timeout time.Duration) (pubKey *ecdsa.PublicKey, err error) {
|
||||
// NewECDSAPubKeyFromReader returns a public key from io.Reader
|
||||
func NewECDSAPubKeyFromReader(reader io.Reader) (pubKey *ecdsa.PublicKey, err error) {
|
||||
var pubkeyBuf []byte
|
||||
if pubkeyBuf, err = GetDataAtPath(pubKeyPath, timeout); err != nil {
|
||||
if pubkeyBuf, err = ioutil.ReadAll(reader); err != nil {
|
||||
return
|
||||
}
|
||||
return jwt.ParseECPublicKeyFromPEM(pubkeyBuf)
|
||||
}
|
||||
|
||||
// getURLFile returns the file from URL
|
||||
func getURLFile(urlVal string, timeout time.Duration) (body []byte, err error) {
|
||||
// NewECDSAPrvKey creates a private key from the path
|
||||
func NewECDSAPrvKey(prvKeyPath string, timeout time.Duration) (prvKey *ecdsa.PrivateKey, err error) {
|
||||
var prvKeyBuf io.ReadCloser
|
||||
if prvKeyBuf, err = GetReaderFromPath(prvKeyPath, timeout); err != nil {
|
||||
return
|
||||
}
|
||||
prvKey, err = NewECDSAPrvKeyFromReader(prvKeyBuf)
|
||||
prvKeyBuf.Close()
|
||||
return
|
||||
}
|
||||
|
||||
// NewECDSAPubKey returns a public key from the path
|
||||
func NewECDSAPubKey(pubKeyPath string, timeout time.Duration) (pubKey *ecdsa.PublicKey, err error) {
|
||||
var pubKeyBuf io.ReadCloser
|
||||
if pubKeyBuf, err = GetReaderFromPath(pubKeyPath, timeout); err != nil {
|
||||
return
|
||||
}
|
||||
pubKey, err = NewECDSAPubKeyFromReader(pubKeyBuf)
|
||||
pubKeyBuf.Close()
|
||||
return
|
||||
}
|
||||
|
||||
// GetReaderFromPath returns the reader at the given path
|
||||
func GetReaderFromPath(path string, timeout time.Duration) (r io.ReadCloser, err error) {
|
||||
if !IsURL(path) {
|
||||
return os.Open(path)
|
||||
}
|
||||
httpClient := http.Client{
|
||||
Timeout: timeout,
|
||||
}
|
||||
var resp *http.Response
|
||||
if resp, err = httpClient.Get(urlVal); err != nil {
|
||||
if resp, err = httpClient.Get(path); err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
resp.Body.Close()
|
||||
err = fmt.Errorf("http status error: %v", resp.StatusCode)
|
||||
return
|
||||
}
|
||||
return ioutil.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
func GetDataAtPath(path string, timeout time.Duration) (body []byte, err error) {
|
||||
if IsURL(path) {
|
||||
return getURLFile(path, timeout)
|
||||
}
|
||||
var file *os.File
|
||||
if file, err = os.Open(path); err != nil {
|
||||
return
|
||||
}
|
||||
body, err = ioutil.ReadAll(file)
|
||||
file.Close()
|
||||
return
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
||||
// EncodeBase64JSON encodes the structure in json and then the string in base64
|
||||
func EncodeBase64JSON(val interface{}) (enc string, err error) {
|
||||
var b []byte
|
||||
if b, err = json.Marshal(val); err != nil {
|
||||
@@ -89,6 +102,7 @@ func EncodeBase64JSON(val interface{}) (enc string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeBase64JSON decodes the base64 json string in the given interface
|
||||
func DecodeBase64JSON(data string, val interface{}) (err error) {
|
||||
var b []byte
|
||||
if b, err = jwt.DecodeSegment(data); err != nil {
|
||||
@@ -97,6 +111,7 @@ func DecodeBase64JSON(data string, val interface{}) (err error) {
|
||||
return json.Unmarshal(b, val)
|
||||
}
|
||||
|
||||
// RemoveWhiteSpaces removes white spaces from string
|
||||
func RemoveWhiteSpaces(str string) string {
|
||||
rout := make([]rune, 0, len(str))
|
||||
for _, r := range str {
|
||||
|
||||
93
utils/stir_shaken_utils_test.go
Normal file
93
utils/stir_shaken_utils_test.go
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRemoveWhiteSpaces(t *testing.T) {
|
||||
strWithWS := ` A String
|
||||
With White Spaces`
|
||||
expected := `AStringWithWhiteSpaces`
|
||||
if rply := RemoveWhiteSpaces(strWithWS); rply != expected {
|
||||
t.Errorf("Expected: %q, received: %q", expected, rply)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeBase64JSON(t *testing.T) {
|
||||
var args interface{}
|
||||
args = math.NaN()
|
||||
if _, err := EncodeBase64JSON(args); err == nil {
|
||||
t.Errorf("Expected error")
|
||||
}
|
||||
args = map[string]interface{}{"Q": 1}
|
||||
expected := `eyJRIjoxfQ`
|
||||
if rply, err := EncodeBase64JSON(args); err != nil {
|
||||
t.Error(err)
|
||||
} else if rply != expected {
|
||||
t.Errorf("Expected: %q,received: %q", expected, rply)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeBase64JSON(t *testing.T) {
|
||||
args := `eyJRIjoxfQ`
|
||||
var rply1 string
|
||||
if err := DecodeBase64JSON(args, &rply1); err == nil {
|
||||
t.Errorf("Expected error")
|
||||
}
|
||||
var rply2 map[string]interface{}
|
||||
expected := map[string]interface{}{"Q": 1.}
|
||||
if err := DecodeBase64JSON(args, &rply2); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expected, rply2) {
|
||||
t.Errorf("Expected: %s,received: %s", ToJSON(expected), ToJSON(rply2))
|
||||
}
|
||||
args = `eyJRIjoxfQ,`
|
||||
if err := DecodeBase64JSON(args, &rply2); err == nil {
|
||||
t.Errorf("Expected error")
|
||||
}
|
||||
}
|
||||
|
||||
type testErrReader struct{}
|
||||
|
||||
func (testErrReader) Read([]byte) (int, error) { return 0, ErrNotFound }
|
||||
|
||||
func TestNewECDSAPrvKeyFromReader(t *testing.T) {
|
||||
if _, err := NewECDSAPrvKeyFromReader(new(testErrReader)); err == nil {
|
||||
t.Errorf("Expected error")
|
||||
}
|
||||
r := bytes.NewBuffer([]byte("invalid certificate"))
|
||||
if _, err := NewECDSAPrvKeyFromReader(r); err == nil {
|
||||
t.Errorf("Expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewECDSAPubKeyFromReader(t *testing.T) {
|
||||
if _, err := NewECDSAPubKeyFromReader(new(testErrReader)); err == nil {
|
||||
t.Errorf("Expected error")
|
||||
}
|
||||
r := bytes.NewBuffer([]byte("invalid certificate"))
|
||||
if _, err := NewECDSAPubKeyFromReader(r); err == nil {
|
||||
t.Errorf("Expected error")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user