@@ -0,0 +1,151 @@
9+ "github.com/bmizerany/assert"
10+ "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
13+const imaginaryAccessToken = "imaginary_access_token"
14+const bearerAccessToken = "Bearer " + imaginaryAccessToken
16+func testKeycloakProvider(hostname, group string) *KeycloakProvider {
17+ p := NewKeycloakProvider(
20+ LoginURL: &url.URL{},
21+ RedeemURL: &url.URL{},
22+ ProfileURL: &url.URL{},
23+ ValidateURL: &url.URL{},
31+ updateURL(p.Data().LoginURL, hostname)
32+ updateURL(p.Data().RedeemURL, hostname)
33+ updateURL(p.Data().ProfileURL, hostname)
34+ updateURL(p.Data().ValidateURL, hostname)
39+func testKeycloakBackend(payload string) *httptest.Server {
40+ path := "/api/v3/user"
42+ return httptest.NewServer(http.HandlerFunc(
43+ func(w http.ResponseWriter, r *http.Request) {
45+ if url.Path != path {
47+ } else if r.Header.Get("Authorization") != bearerAccessToken {
51+ w.Write([]byte(payload))
56+func TestKeycloakProviderDefaults(t *testing.T) {
57+ p := testKeycloakProvider("", "")
58+ assert.NotEqual(t, nil, p)
59+ assert.Equal(t, "Keycloak", p.Data().ProviderName)
60+ assert.Equal(t, "https://keycloak.org/oauth/authorize",
61+ p.Data().LoginURL.String())
62+ assert.Equal(t, "https://keycloak.org/oauth/token",
63+ p.Data().RedeemURL.String())
64+ assert.Equal(t, "https://keycloak.org/api/v3/user",
65+ p.Data().ValidateURL.String())
66+ assert.Equal(t, "api", p.Data().Scope)
69+func TestKeycloakProviderOverrides(t *testing.T) {
70+ p := NewKeycloakProvider(
75+ Path: "/oauth/auth"},
79+ Path: "/oauth/token"},
80+ ValidateURL: &url.URL{
83+ Path: "/api/v3/user"},
85+ assert.NotEqual(t, nil, p)
86+ assert.Equal(t, "Keycloak", p.Data().ProviderName)
87+ assert.Equal(t, "https://example.com/oauth/auth",
88+ p.Data().LoginURL.String())
89+ assert.Equal(t, "https://example.com/oauth/token",
90+ p.Data().RedeemURL.String())
91+ assert.Equal(t, "https://example.com/api/v3/user",
92+ p.Data().ValidateURL.String())
93+ assert.Equal(t, "profile", p.Data().Scope)
96+func TestKeycloakProviderGetEmailAddress(t *testing.T) {
97+ b := testKeycloakBackend("{\"email\": \"michael.bland@gsa.gov\"}")
100+ bURL, _ := url.Parse(b.URL)
101+ p := testKeycloakProvider(bURL.Host, "")
103+ session := &sessions.SessionState{AccessToken: imaginaryAccessToken}
104+ email, err := p.GetEmailAddress(session)
105+ assert.Equal(t, nil, err)
106+ assert.Equal(t, "michael.bland@gsa.gov", email)
109+func TestKeycloakProviderGetEmailAddressAndGroup(t *testing.T) {
110+ b := testKeycloakBackend("{\"email\": \"michael.bland@gsa.gov\", \"groups\": [\"test-grp1\", \"test-grp2\"]}")
113+ bURL, _ := url.Parse(b.URL)
114+ p := testKeycloakProvider(bURL.Host, "test-grp1")
116+ session := &sessions.SessionState{AccessToken: imaginaryAccessToken}
117+ email, err := p.GetEmailAddress(session)
118+ assert.Equal(t, nil, err)
119+ assert.Equal(t, "michael.bland@gsa.gov", email)
122+// Note that trying to trigger the "failed building request" case is not
123+// practical, since the only way it can fail is if the URL fails to parse.
124+func TestKeycloakProviderGetEmailAddressFailedRequest(t *testing.T) {
125+ b := testKeycloakBackend("unused payload")
128+ bURL, _ := url.Parse(b.URL)
129+ p := testKeycloakProvider(bURL.Host, "")
131+ // We'll trigger a request failure by using an unexpected access
132+ // token. Alternatively, we could allow the parsing of the payload as
134+ session := &sessions.SessionState{AccessToken: "unexpected_access_token"}
135+ email, err := p.GetEmailAddress(session)
136+ assert.NotEqual(t, nil, err)
137+ assert.Equal(t, "", email)
140+func TestKeycloakProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) {
141+ b := testKeycloakBackend("{\"foo\": \"bar\"}")
144+ bURL, _ := url.Parse(b.URL)
145+ p := testKeycloakProvider(bURL.Host, "")
147+ session := &sessions.SessionState{AccessToken: imaginaryAccessToken}
148+ email, err := p.GetEmailAddress(session)
149+ assert.NotEqual(t, nil, err)
150+ assert.Equal(t, "", email)