@@ -0,0 +1,138 @@
1+package providers
2+
3+import (
4+ "net/http"
5+ "net/http/httptest"
6+ "net/url"
7+ "testing"
8+
9+ "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
10+ "github.com/stretchr/testify/assert"
11+)
12+
13+const formatJSON = "format=json"
14+const userPath = "/ocs/v2.php/cloud/user"
15+
16+func testNextcloudProvider(hostname string) *NextcloudProvider {
17+ p := NewNextcloudProvider(
18+ &ProviderData{
19+ ProviderName: "",
20+ LoginURL: &url.URL{},
21+ RedeemURL: &url.URL{},
22+ ProfileURL: &url.URL{},
23+ ValidateURL: &url.URL{},
24+ Scope: ""})
25+ if hostname != "" {
26+ updateURL(p.Data().LoginURL, hostname)
27+ updateURL(p.Data().RedeemURL, hostname)
28+ updateURL(p.Data().ProfileURL, hostname)
29+ updateURL(p.Data().ValidateURL, hostname)
30+ }
31+ return p
32+}
33+
34+func testNextcloudBackend(payload string) *httptest.Server {
35+ path := userPath
36+ query := formatJSON
37+
38+ return httptest.NewServer(http.HandlerFunc(
39+ func(w http.ResponseWriter, r *http.Request) {
40+ if r.URL.Path != path || r.URL.RawQuery != query {
41+ w.WriteHeader(404)
42+ } else if r.Header.Get("Authorization") != "Bearer imaginary_access_token_nextcloud" {
43+ w.WriteHeader(403)
44+ } else {
45+ w.WriteHeader(200)
46+ w.Write([]byte(payload))
47+ }
48+ }))
49+}
50+
51+func TestNextcloudProviderDefaults(t *testing.T) {
52+ p := testNextcloudProvider("")
53+ assert.NotEqual(t, nil, p)
54+ assert.Equal(t, "Nextcloud", p.Data().ProviderName)
55+ assert.Equal(t, "",
56+ p.Data().LoginURL.String())
57+ assert.Equal(t, "",
58+ p.Data().RedeemURL.String())
59+ assert.Equal(t, "",
60+ p.Data().ValidateURL.String())
61+}
62+
63+func TestNextcloudProviderOverrides(t *testing.T) {
64+ p := NewNextcloudProvider(
65+ &ProviderData{
66+ LoginURL: &url.URL{
67+ Scheme: "https",
68+ Host: "example.com",
69+ Path: "/index.php/apps/oauth2/authorize"},
70+ RedeemURL: &url.URL{
71+ Scheme: "https",
72+ Host: "example.com",
73+ Path: "/index.php/apps/oauth2/api/v1/token"},
74+ ValidateURL: &url.URL{
75+ Scheme: "https",
76+ Host: "example.com",
77+ Path: "/test/ocs/v2.php/cloud/user",
78+ RawQuery: formatJSON},
79+ Scope: "profile"})
80+ assert.NotEqual(t, nil, p)
81+ assert.Equal(t, "Nextcloud", p.Data().ProviderName)
82+ assert.Equal(t, "https://example.com/index.php/apps/oauth2/authorize",
83+ p.Data().LoginURL.String())
84+ assert.Equal(t, "https://example.com/index.php/apps/oauth2/api/v1/token",
85+ p.Data().RedeemURL.String())
86+ assert.Equal(t, "https://example.com/test/ocs/v2.php/cloud/user?"+formatJSON,
87+ p.Data().ValidateURL.String())
88+}
89+
90+func TestNextcloudProviderGetEmailAddress(t *testing.T) {
91+ b := testNextcloudBackend("{\"ocs\": {\"data\": { \"email\": \"michael.bland@gsa.gov\"}}}")
92+ defer b.Close()
93+
94+ bURL, _ := url.Parse(b.URL)
95+ p := testNextcloudProvider(bURL.Host)
96+ p.ValidateURL.Path = userPath
97+ p.ValidateURL.RawQuery = formatJSON
98+
99+ session := &sessions.SessionState{AccessToken: "imaginary_access_token_nextcloud"}
100+ email, err := p.GetEmailAddress(session)
101+ assert.Equal(t, nil, err)
102+ assert.Equal(t, "michael.bland@gsa.gov", email)
103+}
104+
105+// Note that trying to trigger the "failed building request" case is not
106+// practical, since the only way it can fail is if the URL fails to parse.
107+func TestNextcloudProviderGetEmailAddressFailedRequest(t *testing.T) {
108+ b := testNextcloudBackend("unused payload")
109+ defer b.Close()
110+
111+ bURL, _ := url.Parse(b.URL)
112+ p := testNextcloudProvider(bURL.Host)
113+ p.ValidateURL.Path = userPath
114+ p.ValidateURL.RawQuery = formatJSON
115+
116+ // We'll trigger a request failure by using an unexpected access
117+ // token. Alternatively, we could allow the parsing of the payload as
118+ // JSON to fail.
119+ session := &sessions.SessionState{AccessToken: "unexpected_access_token"}
120+ email, err := p.GetEmailAddress(session)
121+ assert.NotEqual(t, nil, err)
122+ assert.Equal(t, "", email)
123+}
124+
125+func TestNextcloudProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) {
126+ b := testNextcloudBackend("{\"foo\": \"bar\"}")
127+ defer b.Close()
128+
129+ bURL, _ := url.Parse(b.URL)
130+ p := testNextcloudProvider(bURL.Host)
131+ p.ValidateURL.Path = userPath
132+ p.ValidateURL.RawQuery = formatJSON
133+
134+ session := &sessions.SessionState{AccessToken: "imaginary_access_token_nextcloud"}
135+ email, err := p.GetEmailAddress(session)
136+ assert.NotEqual(t, nil, err)
137+ assert.Equal(t, "", email)
138+}