@@ -16,67 +16,72 @@ import (
1616 "net/url"
1717 "testing"
1818
19+ "github.com/google/go-cmp/cmp"
1920 "github.com/stretchr/testify/assert"
2021 "github.com/vouch/vouch-proxy/pkg/cfg"
2122)
2223
2324func Test_normalizeLoginURL (t * testing.T ) {
2425 setUp ("/config/testing/handler_login_url.yml" )
2526 tests := []struct {
26- name string
27- url string
28- want string
29- wantErr bool
27+ name string
28+ url string
29+ want string
30+ wantStray []string
31+ wantErr bool
3032 }{
3133 // This is not an RFC-compliant URL because it does not encode :// in the url param; we accept it anyway
32- {"extra params" , "http://host/login?url=http://host/path?p2=2" , "http://host/path?p2=2" , false },
33- {"extra params (blank)" , "http://host/login?url=http://host/path?p2=" , "http://host/path?p2=" , false },
34+ {"extra params" , "http://host/login?url=http://host/path?p2=2" , "http://host/path?p2=2" , [] string {}, false },
35+ {"extra params (blank)" , "http://host/login?url=http://host/path?p2=" , "http://host/path?p2=" , [] string {}, false },
3436 // This is not an RFC-compliant URL because it does not encode :// in the url param; we accept it anyway
3537 // Even though the p1 param is not a login param, we do not interpret is as part of the url param because it precedes it
36- {"prior params" , "http://host/login?p1=1&url=http://host/path" , "http://host/path" , true },
38+ {"prior params" , "http://host/login?p1=1&url=http://host/path" , "http://host/path" , [] string { "p1" }, false },
3739 // This is not an RFC-compliant URL because it does not encode :// in the url param; we accept it anyway
3840 // We assume vouch-* is a login param and do not fold it into url
39- {"vouch-* params after" , "http://host/login?url=http://host/path&vouch-xxx=2" , "http://host/path" , false },
41+ {"vouch-* params after" , "http://host/login?url=http://host/path&vouch-xxx=2" , "http://host/path" , [] string {}, false },
4042 // This is not an RFC-compliant URL because it does not encode :// in the url param; we accept it anyway
4143 // We assume vouch-* is a login param and do not fold it into url
42- {"vouch-* params before" , "http://host/login?vouch-xxx=1&url=http://host/path" , "http://host/path" , false },
44+ {"vouch-* params before" , "http://host/login?vouch-xxx=1&url=http://host/path" , "http://host/path" , [] string {}, false },
4345 // This is not an RFC-compliant URL because it does not encode :// in the url param; we accept it anyway
4446 // We assume x-vouch-* is a login param and do not fold it into url
45- {"x-vouch-* params after" , "http://host/login?url=http://host/path&vouch-xxx=2" , "http://host/path" , false },
47+ {"x-vouch-* params after" , "http://host/login?url=http://host/path&vouch-xxx=2" , "http://host/path" , [] string {}, false },
4648 // This is not an RFC-compliant URL because it does not encode :// in the url param; we accept it anyway
4749 // We assume x-vouch-* is a login param and do not fold it into url
48- {"x-vouch-* params before" , "http://host/login?x-vouch-xxx=1&url=http://host/path" , "http://host/path" , false },
50+ {"x-vouch-* params before" , "http://host/login?x-vouch-xxx=1&url=http://host/path" , "http://host/path" , [] string {}, false },
4951 // This is not an RFC-compliant URL because it does not encode :// in the url param; we accept it anyway
5052 // Even though p1 is not a login param, we do not interpret is as part of url because it follows a login param (vouch-*)
51- {"params after vouch-* params" , "http://host/login?url=http://host/path&vouch-xxx=2&p3=3" , "http://host/path" , true },
53+ {"params after vouch-* params" , "http://host/login?url=http://host/path&vouch-xxx=2&p3=3" , "http://host/path" , [] string { "p3" }, false },
5254 // This is not an RFC-compliant URL because it does not encode :// in the url param; we accept it anyway
5355 // Even though p1 is not a login param, we do not interpret is as part of url because it follows a login param (x-vouch-*)
54- {"params after x-vouch-* params" , "http://host/login?url=http://host/path&x-vouch-xxx=2&p3=3" , "http://host/path" , true },
56+ {"params after x-vouch-* params" , "http://host/login?url=http://host/path&x-vouch-xxx=2&p3=3" , "http://host/path" , [] string { "p3" }, false },
5557 // This is not an RFC-compliant URL; it combines all the aspects above
56- {"all params" , "http://host/login?p1=1&url=http://host/path?p2=2&p3=3&x-vouch-xxx=4&vouch=5&error=6&p7=7" , "http://host/path?p2=2&p3=3" , true },
58+ {"all params" , "http://host/login?p1=1&url=http://host/path?p2=2&p3=3&x-vouch-xxx=4&vouch=5&error=6&p7=7" , "http://host/path?p2=2&p3=3" , [] string { "p1" , "p7" }, false },
5759 // This is an RFC-compliant URL
58- {"all params (encoded)" , "http://host/login?p1=1&url=http%3a%2f%2fhost/path%3fp2=2%26p3=3&x-vouch-xxx=4&vouch=5&error=6&p7=7" , "http://host/path?p2=2&p3=3" , true },
60+ {"all params (encoded)" , "http://host/login?p1=1&url=http%3a%2f%2fhost/path%3fp2=2%26p3=3&x-vouch-xxx=4&vouch=5&error=6&p7=7" , "http://host/path?p2=2&p3=3" , [] string { "p1" , "p7" }, false },
5961 // This is not an RFC-compliant URL; it combines all the aspects above, and it uses semicolons as parameter separators
6062 // Note that when we fold a stray param into the url param, we always do so with &s
61- {"all params (semicolons)" , "http://host/login?p1=1;url=http://host/path?p2=2;p3=3;x-vouch-xxx=4;p5=5" , "http://host/path?p2=2&p3=3" , true },
63+ {"all params (semicolons)" , "http://host/login?p1=1;url=http://host/path?p2=2;p3=3;x-vouch-xxx=4;p5=5" , "http://host/path?p2=2&p3=3" , [] string { "p1" , "p5" }, false },
6264 // This is an RFC-compliant URL that uses semicolons as parameter separators
63- {"all params (encoded, semicolons)" , "http://host/login?p1=1;url=http%3a%2f%2fhost/path%3fp2=2%3bp3=3;x-vouch-xxx=4;p5=5" , "http://host/path?p2=2;p3=3" , true },
65+ {"all params (encoded, semicolons)" , "http://host/login?p1=1;url=http%3a%2f%2fhost/path%3fp2=2%3bp3=3;x-vouch-xxx=4;p5=5" , "http://host/path?p2=2;p3=3" , [] string { "p1" , "p5" }, false },
6466 // Real world tests
6567 // since v0.4.0 the vouch README has specified an Nginx config including a 302 redirect in the following format...
66- {"Vouch Proxy README (with error)" , "http://host/login?url=http://host/path?p2=2&vouch-failcount=3&X-Vouch-Token=TOKEN&error=anerror" , "http://host/path?p2=2" , false },
67- {"Vouch Proxy README (blank error)" , "http://host/login?url=http://host/path?p2=2&vouch-failcount=&X-Vouch-Token=&error=" , "http://host/path?p2=2" , false },
68- {"Vouch Proxy README (semicolons, blank error)" , "http://host/login?url=http://host/path?p2=2;p3=3&vouch-failcount=&X-Vouch-Token=&error=" , "http://host/path?p2=2&p3=3" , false },
68+ {"Vouch Proxy README (with error)" , "http://host/login?url=http://host/path?p2=2&vouch-failcount=3&X-Vouch-Token=TOKEN&error=anerror" , "http://host/path?p2=2" , [] string {}, false },
69+ {"Vouch Proxy README (blank error)" , "http://host/login?url=http://host/path?p2=2&vouch-failcount=&X-Vouch-Token=&error=" , "http://host/path?p2=2" , [] string {}, false },
70+ {"Vouch Proxy README (semicolons, blank error)" , "http://host/login?url=http://host/path?p2=2;p3=3&vouch-failcount=&X-Vouch-Token=&error=" , "http://host/path?p2=2&p3=3" , [] string {}, false },
6971 // Nginx Ingress controler for Kubernetes adds the parameter `rd` to these calls
7072 // https://github.com/vouch/vouch-proxy/issues/289
71- {"rd param appended by Nginx Ingress" , "http://host/login?url=http://host/path?p2=2&p3=3&vouch-failcount=&X-Vouch-Token=&error=&rd=http%3a%2f%2fhost/path%3fp2=2%3bp3=3" , "http://host/path?p2=2&p3=3" , false },
73+ {"rd param appended by Nginx Ingress" , "http://host/login?url=http://host/path?p2=2&p3=3&vouch-failcount=&X-Vouch-Token=&error=&rd=http%3a%2f%2fhost/path%3fp2=2%3bp3=3" , "http://host/path?p2=2&p3=3" , [] string {}, false },
7274 }
7375 for _ , tt := range tests {
7476 t .Run (tt .name , func (t * testing.T ) {
7577 u , _ := url .Parse (tt .url )
76- got , err := normalizeLoginURLParam (u )
78+ got , stray , err := normalizeLoginURLParam (u )
7779 if got .String () != tt .want {
7880 t .Errorf ("normalizeLoginURLParam() = %v, want %v" , got , tt .want )
7981 }
82+ if ! cmp .Equal (stray , tt .wantStray ) {
83+ t .Errorf ("normalizeLoginURLParam() stray params incorrectly parsed, got %+q, expected %+q" , stray , tt .wantStray )
84+ }
8085 if (err != nil ) != tt .wantErr {
8186 t .Errorf ("normalizeLoginURLParam() err = %v" , err )
8287 }
0 commit comments