package asterisk import ( "encoding/json" "strings" "testing" "git.ipao.vip/rogee/go-sip/internal/configread" ) func testSIP(t *testing.T) configread.SIP { t.Helper() var sip configread.SIP if err := json.Unmarshal([]byte(`{"resource":"sip_config","dispatcher_id":"c046b893-8628-4589-ae50-619d049248a6","revision":9,"trunks":[{"trunk_id":"trunk-shuqi","provider_id":"shuqi","codec":"PCMA","dial_prefix":"7089","enabled":true,"server_host":"61.132.228.221","server_port":5060,"transport":"udp","auth_mode":"ip","registration_required":false,"max_concurrent_calls":1,"caller_id":"BD93205882","schedule":{"time_zone":"Asia/Shanghai","weekly_windows":{"monday":[{"start":"09:00","end":"20:00"}],"tuesday":[],"wednesday":[],"thursday":[],"friday":[],"saturday":[],"sunday":[]}}}]}`), &sip); err != nil { t.Fatal(err) } return sip } func TestRenderApprovedIPTrunk(t *testing.T) { text, err := Render(testSIP(t)) if err != nil { t.Fatal(err) } for _, want := range []string{"[trunk-shuqi]", "type=endpoint", "transport=go-sip-udp", "allow=alaw", "aors=trunk-shuqi-aor", "contact=sip:61.132.228.221:5060", "from_user=BD93205882", "callerid=\"BD93205882\" "} { if !strings.Contains(text, want) { t.Errorf("rendered SIP is missing %q", want) } } if strings.Contains(text, "type=transport") || strings.Contains(text, "7089") || strings.Contains(text, "register=") { t.Fatal("per-call prefix or registration leaked into static endpoint") } } func TestRenderKeepsDistinctTrunkCallerIdentities(t *testing.T) { sip := testSIP(t) var trunks []map[string]any if err := json.Unmarshal(sip.Trunks, &trunks); err != nil { t.Fatal(err) } second := make(map[string]any, len(trunks[0])) for key, value := range trunks[0] { second[key] = value } second["trunk_id"], second["caller_id"] = "trunk-zhongding", "mbkq" trunks = append(trunks, second) var err error sip.Trunks, err = json.Marshal(trunks) if err != nil { t.Fatal(err) } text, err := Render(sip) if err != nil { t.Fatal(err) } for _, want := range []string{"[trunk-shuqi]\ntype=endpoint", "from_user=BD93205882\ncallerid=\"BD93205882\" ", "[trunk-zhongding]\ntype=endpoint", "from_user=mbkq\ncallerid=\"mbkq\" "} { if !strings.Contains(text, want) { t.Fatalf("missing separately approved line identity %q in %s", want, text) } } } func TestRenderRejectsUnsupportedOrAmbiguousSIP(t *testing.T) { for _, mutation := range []struct{ name, from, to string }{ {"digest", `"auth_mode":"ip"`, `"auth_mode":"digest"`}, {"register", `"registration_required":false`, `"registration_required":true`}, {"tcp", `"transport":"udp"`, `"transport":"tcp"`}, {"missing_transport", `"transport":"udp"`, `"transport":null`}, {"missing_auth", `"auth_mode":"ip"`, `"auth_mode":null`}, {"bad_id", `"trunk_id":"trunk-shuqi"`, `"trunk_id":"bad]\n[attacker"`}, {"bad_host", `"server_host":"61.132.228.221"`, `"server_host":"oops\npassword=bad"`}, {"missing_caller", `"caller_id":"BD93205882"`, `"caller_id":""`}, {"unsafe_caller", `"caller_id":"BD93205882"`, `"caller_id":"BD93205882\nfrom_user=anonymous"`}, } { t.Run(mutation.name, func(t *testing.T) { sip := testSIP(t) sip.Trunks = []byte(strings.Replace(string(sip.Trunks), mutation.from, mutation.to, 1)) if _, err := Render(sip); err == nil { t.Fatal("unsupported SIP configuration was accepted") } }) } }