mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-08-17 16:07:18 +02:00
94 lines
2.9 KiB
Go
94 lines
2.9 KiB
Go
package service
|
|
|
|
import (
|
|
"net/url"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/phishingclub/phishingclub/data"
|
|
"github.com/phishingclub/phishingclub/utils"
|
|
)
|
|
|
|
// decryptState pulls the state parameter out of a built flow url and decrypts it back to
|
|
// the page type it encodes, so the test can assert the url points at the right stage.
|
|
func decryptState(t *testing.T, rawURL string, stateKey string, secret string) string {
|
|
t.Helper()
|
|
parsed, err := url.Parse(rawURL)
|
|
if err != nil {
|
|
t.Fatalf("failed to parse url %q: %v", rawURL, err)
|
|
}
|
|
state := parsed.Query().Get(stateKey)
|
|
if state == "" {
|
|
t.Fatalf("url %q has no %q state param", rawURL, stateKey)
|
|
}
|
|
page, err := utils.Decrypt(state, secret)
|
|
if err != nil {
|
|
t.Fatalf("failed to decrypt state %q: %v", state, err)
|
|
}
|
|
return page
|
|
}
|
|
|
|
func TestBuildFlowPageURLs(t *testing.T) {
|
|
campaignID := uuid.New()
|
|
secret := utils.UUIDToSecret(&campaignID)
|
|
crid := uuid.New().String()
|
|
|
|
base := FlowPageURLParams{
|
|
BaseURL: "https://example.test",
|
|
URLPath: "/login",
|
|
URLIdentifier: "id",
|
|
StateIdentifier: "state",
|
|
CampaignRecipientID: crid,
|
|
CampaignID: campaignID,
|
|
}
|
|
|
|
t.Run("all stages present", func(t *testing.T) {
|
|
p := base
|
|
p.HasBeforePage = true
|
|
p.HasAfterPage = true
|
|
before, landing, after := BuildFlowPageURLs(p)
|
|
|
|
for name, u := range map[string]string{"before": before, "landing": landing, "after": after} {
|
|
if u == "" {
|
|
t.Fatalf("%s url is empty, expected a value", name)
|
|
}
|
|
parsed, err := url.Parse(u)
|
|
if err != nil {
|
|
t.Fatalf("%s url %q did not parse: %v", name, u, err)
|
|
}
|
|
if got := parsed.Query().Get("id"); got != crid {
|
|
t.Errorf("%s url id param = %q, want %q", name, got, crid)
|
|
}
|
|
if parsed.Path != "/login" {
|
|
t.Errorf("%s url path = %q, want /login", name, parsed.Path)
|
|
}
|
|
}
|
|
|
|
if got := decryptState(t, before, "state", secret); got != data.PAGE_TYPE_BEFORE {
|
|
t.Errorf("before state = %q, want %q", got, data.PAGE_TYPE_BEFORE)
|
|
}
|
|
if got := decryptState(t, landing, "state", secret); got != data.PAGE_TYPE_LANDING {
|
|
t.Errorf("landing state = %q, want %q", got, data.PAGE_TYPE_LANDING)
|
|
}
|
|
if got := decryptState(t, after, "state", secret); got != data.PAGE_TYPE_AFTER {
|
|
t.Errorf("after state = %q, want %q", got, data.PAGE_TYPE_AFTER)
|
|
}
|
|
})
|
|
|
|
t.Run("no before or after stage renders empty", func(t *testing.T) {
|
|
before, landing, after := BuildFlowPageURLs(base)
|
|
if before != "" {
|
|
t.Errorf("before url = %q, want empty when stage absent", before)
|
|
}
|
|
if after != "" {
|
|
t.Errorf("after url = %q, want empty when stage absent", after)
|
|
}
|
|
if landing == "" {
|
|
t.Fatal("landing url is empty, want a value since landing is always present")
|
|
}
|
|
if got := decryptState(t, landing, "state", secret); got != data.PAGE_TYPE_LANDING {
|
|
t.Errorf("landing state = %q, want %q", got, data.PAGE_TYPE_LANDING)
|
|
}
|
|
})
|
|
}
|