package sign import ( "crypto/rsa" "math/rand" "strings" "testing" "time" ) var testSignTime = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) var testSignURL = []struct { u string p *Policy t time.Time customPolicy bool expectErr bool out string }{ { "http://example.com/a", NewCannedPolicy("http://example.com/a", testSignTime), time.Time{}, true, false, "http://example.com/a?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2V4YW1wbGUuY29tL2EiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjEyNTc4OTQwMDB9fX1dfQ__&Signature=Y6qvWOZNl99uNPMGprvrKXEmXpLWJ-xXKVHL~nmF0BR1jPb2XA2jor0MUYKBE4ViTkWZZ1dz46zSFMsEEfw~n6-SVYXZ2QHBBTkSAoxGtH6dH33Ph9pz~f9Wy7aYXq~9I-Ah0E6yC~BMiQuXe5qAOucuMPorKgPfC0dvLMw2EF0_&Key-Pair-Id=KeyID", }, { "http://example.com/a", nil, testSignTime, false, false, "http://example.com/a?Expires=1257894000&Signature=Y6qvWOZNl99uNPMGprvrKXEmXpLWJ-xXKVHL~nmF0BR1jPb2XA2jor0MUYKBE4ViTkWZZ1dz46zSFMsEEfw~n6-SVYXZ2QHBBTkSAoxGtH6dH33Ph9pz~f9Wy7aYXq~9I-Ah0E6yC~BMiQuXe5qAOucuMPorKgPfC0dvLMw2EF0_&Key-Pair-Id=KeyID", }, { "http://example.com/Ƿ", nil, testSignTime, false, true, "http://example.com/Ƿ?Expires=1257894000&Signature=Y6qvWOZNl99uNPMGprvrKXEmXpLWJ-xXKVHL~nmF0BR1jPb2XA2jor0MUYKBE4ViTkWZZ1dz46zSFMsEEfw~n6-SVYXZ2QHBBTkSAoxGtH6dH33Ph9pz~f9Wy7aYXq~9I-Ah0E6yC~BMiQuXe5qAOucuMPorKgPfC0dvLMw2EF0_&Key-Pair-Id=KeyID", }, { "http://example.com/a", &Policy{}, time.Time{}, true, true, "http://example.com/a?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2V4YW1wbGUuY29tL2EiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjEyNTc4OTQwMDB9fX1dfQ__&Signature=Y6qvWOZNl99uNPMGprvrKXEmXpLWJ-xXKVHL~nmF0BR1jPb2XA2jor0MUYKBE4ViTkWZZ1dz46zSFMsEEfw~n6-SVYXZ2QHBBTkSAoxGtH6dH33Ph9pz~f9Wy7aYXq~9I-Ah0E6yC~BMiQuXe5qAOucuMPorKgPfC0dvLMw2EF0_&Key-Pair-Id=KeyID", }, { "http://example.com/a", NewCannedPolicy("", testSignTime), time.Time{}, true, true, "http://example.com/a?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2V4YW1wbGUuY29tL2EiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjEyNTc4OTQwMDB9fX1dfQ__&Signature=Y6qvWOZNl99uNPMGprvrKXEmXpLWJ-xXKVHL~nmF0BR1jPb2XA2jor0MUYKBE4ViTkWZZ1dz46zSFMsEEfw~n6-SVYXZ2QHBBTkSAoxGtH6dH33Ph9pz~f9Wy7aYXq~9I-Ah0E6yC~BMiQuXe5qAOucuMPorKgPfC0dvLMw2EF0_&Key-Pair-Id=KeyID", }, { "rtmp://example.com/a", nil, testSignTime, false, false, "a?Expires=1257894000&Signature=Ds9NbpGwIcDKG1iZDyjfPXp0ZFYSIzfvGzJj-x28XlXfrarHrJbTOQj3bec~aAyb8NAqghBYRdKF9~RdjNrdyxyiequo-SCjFgFHnRNIk0FiqH0fVt2NO63f0X8-Kbur9cPtJoHR9Jzk0I1CQnECqhL6A0OgPhijTfKUITocmzA_&Key-Pair-Id=KeyID", }, { "rtmp://example.com/a", NewCannedPolicy("a", testSignTime), time.Time{}, true, false, "a?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiYSIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI1Nzg5NDAwMH19fV19&Signature=Ds9NbpGwIcDKG1iZDyjfPXp0ZFYSIzfvGzJj-x28XlXfrarHrJbTOQj3bec~aAyb8NAqghBYRdKF9~RdjNrdyxyiequo-SCjFgFHnRNIk0FiqH0fVt2NO63f0X8-Kbur9cPtJoHR9Jzk0I1CQnECqhL6A0OgPhijTfKUITocmzA_&Key-Pair-Id=KeyID", }, } // TODO Sign URL HTTP // TODO Sign URL RMTP func TestSignURL(t *testing.T) { origRandReader := randReader randReader = newRandomReader(rand.New(rand.NewSource(1))) defer func() { randReader = origRandReader }() privKey, err := rsa.GenerateKey(randReader, 1024) if err != nil { t.Fatalf("Unexpected priv key error, %#v", err) } s := NewURLSigner("KeyID", privKey) for i, v := range testSignURL { var u string var err error if v.customPolicy { u, err = s.SignWithPolicy(v.u, v.p) } else { u, err = s.Sign(v.u, v.t) } if err != nil { if v.expectErr { continue } t.Errorf("%d, Unexpected error, %s", i, err.Error()) continue } else if v.expectErr { t.Errorf("%d Expected error, but got none", i) continue } if u != v.out { t.Errorf("%d, Unexpected URL\nexpect: %s\nactual: %s\n", i, v.out, u) } } } var testBuildSignedURL = []struct { u, keyID string p *Policy customPolicy bool b64Policy, b64Sig []byte out string }{ { "https://example.com/a?b=1", "KeyID", NewCannedPolicy("", testSignTime), true, []byte("b64Policy"), []byte("b64Sig"), "https://example.com/a?b=1&Policy=b64Policy&Signature=b64Sig&Key-Pair-Id=KeyID", }, { "https://example.com/a", "KeyID", NewCannedPolicy("", testSignTime), true, []byte("b64Policy"), []byte("b64Sig"), "https://example.com/a?Policy=b64Policy&Signature=b64Sig&Key-Pair-Id=KeyID", }, { "https://example.com/a?b=1", "KeyID", NewCannedPolicy("https://example.com/a?b=1", testSignTime), false, []byte("b64Policy"), []byte("b64Sig"), "https://example.com/a?b=1&Expires=1257894000&Signature=b64Sig&Key-Pair-Id=KeyID", }, } func TestBuildSignedURL(t *testing.T) { for i, v := range testBuildSignedURL { u := buildSignedURL(v.u, v.keyID, v.p, v.customPolicy, v.b64Policy, v.b64Sig) if u != v.out { t.Errorf("%d, Unexpected URL\nexpect: %s\nactual: %s\n", i, v.out, u) } } } var testValidURL = []struct { in, errPrefix string }{ {"https://example.com/a?b=1&else=b", ""}, {"https://example.com/a?b=1&Policy=something&else=b", "Policy"}, {"https://example.com/a?b=1&Signature=something&else=b", "Signature"}, {"https://example.com/a?b=1&Key-Pair-Id=something&else=b", "Key-Pair-Id"}, {"http?://example.com/a?b=1", "URL missing valid scheme"}, } func TestValidateURL(t *testing.T) { for i, v := range testValidURL { err := validateURL(v.in) if err != nil { if v.errPrefix == "" { t.Errorf("%d, Unexpected error %s", i, err.Error()) } if !strings.HasPrefix(err.Error(), v.errPrefix) { t.Errorf("%d, Expected to find prefix\nexpect: %s\nactual: %s", i, v.errPrefix, err.Error()) } } else if v.errPrefix != "" { t.Errorf("%d, Expected error %s", i, v.errPrefix) } } }