Skip to content

Commit fdbd31e

Browse files
committed
tests for ExtractWorkspaceProxy
1 parent d4d9bf9 commit fdbd31e

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed

coderd/httpmw/workspaceproxy_test.go

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package httpmw_test
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
"net/http/httptest"
8+
"testing"
9+
10+
"github.com/google/uuid"
11+
"github.com/stretchr/testify/require"
12+
13+
"github.com/coder/coder/coderd/database"
14+
"github.com/coder/coder/coderd/database/dbfake"
15+
"github.com/coder/coder/coderd/database/dbgen"
16+
"github.com/coder/coder/coderd/httpapi"
17+
"github.com/coder/coder/coderd/httpmw"
18+
"github.com/coder/coder/codersdk"
19+
"github.com/coder/coder/cryptorand"
20+
)
21+
22+
func TestExtractWorkspaceProxy(t *testing.T) {
23+
t.Parallel()
24+
25+
successHandler := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
26+
// Only called if the API key passes through the handler.
27+
httpapi.Write(context.Background(), rw, http.StatusOK, codersdk.Response{
28+
Message: "It worked!",
29+
})
30+
})
31+
32+
t.Run("NoHeader", func(t *testing.T) {
33+
t.Parallel()
34+
var (
35+
db = dbfake.New()
36+
r = httptest.NewRequest("GET", "/", nil)
37+
rw = httptest.NewRecorder()
38+
)
39+
httpmw.ExtractWorkspaceProxy(httpmw.ExtractWorkspaceProxyConfig{
40+
DB: db,
41+
})(successHandler).ServeHTTP(rw, r)
42+
res := rw.Result()
43+
defer res.Body.Close()
44+
require.Equal(t, http.StatusUnauthorized, res.StatusCode)
45+
})
46+
47+
t.Run("InvalidFormat", func(t *testing.T) {
48+
t.Parallel()
49+
var (
50+
db = dbfake.New()
51+
r = httptest.NewRequest("GET", "/", nil)
52+
rw = httptest.NewRecorder()
53+
)
54+
r.Header.Set(httpmw.WorkspaceProxyAuthTokenHeader, "test:wow-hello")
55+
56+
httpmw.ExtractWorkspaceProxy(httpmw.ExtractWorkspaceProxyConfig{
57+
DB: db,
58+
})(successHandler).ServeHTTP(rw, r)
59+
res := rw.Result()
60+
defer res.Body.Close()
61+
require.Equal(t, http.StatusUnauthorized, res.StatusCode)
62+
})
63+
64+
t.Run("InvalidID", func(t *testing.T) {
65+
t.Parallel()
66+
var (
67+
db = dbfake.New()
68+
r = httptest.NewRequest("GET", "/", nil)
69+
rw = httptest.NewRecorder()
70+
)
71+
r.Header.Set(httpmw.WorkspaceProxyAuthTokenHeader, "test:wow")
72+
73+
httpmw.ExtractWorkspaceProxy(httpmw.ExtractWorkspaceProxyConfig{
74+
DB: db,
75+
})(successHandler).ServeHTTP(rw, r)
76+
res := rw.Result()
77+
defer res.Body.Close()
78+
require.Equal(t, http.StatusUnauthorized, res.StatusCode)
79+
})
80+
81+
t.Run("InvalidSecretLength", func(t *testing.T) {
82+
t.Parallel()
83+
var (
84+
db = dbfake.New()
85+
r = httptest.NewRequest("GET", "/", nil)
86+
rw = httptest.NewRecorder()
87+
)
88+
r.Header.Set(httpmw.WorkspaceProxyAuthTokenHeader, fmt.Sprintf("%s:%s", uuid.NewString(), "wow"))
89+
90+
httpmw.ExtractWorkspaceProxy(httpmw.ExtractWorkspaceProxyConfig{
91+
DB: db,
92+
})(successHandler).ServeHTTP(rw, r)
93+
res := rw.Result()
94+
defer res.Body.Close()
95+
require.Equal(t, http.StatusUnauthorized, res.StatusCode)
96+
})
97+
98+
t.Run("NotFound", func(t *testing.T) {
99+
t.Parallel()
100+
var (
101+
db = dbfake.New()
102+
r = httptest.NewRequest("GET", "/", nil)
103+
rw = httptest.NewRecorder()
104+
)
105+
106+
secret, err := cryptorand.HexString(64)
107+
require.NoError(t, err)
108+
r.Header.Set(httpmw.WorkspaceProxyAuthTokenHeader, fmt.Sprintf("%s:%s", uuid.NewString(), secret))
109+
110+
httpmw.ExtractWorkspaceProxy(httpmw.ExtractWorkspaceProxyConfig{
111+
DB: db,
112+
})(successHandler).ServeHTTP(rw, r)
113+
res := rw.Result()
114+
defer res.Body.Close()
115+
require.Equal(t, http.StatusUnauthorized, res.StatusCode)
116+
})
117+
118+
t.Run("InvalidSecret", func(t *testing.T) {
119+
t.Parallel()
120+
var (
121+
db = dbfake.New()
122+
r = httptest.NewRequest("GET", "/", nil)
123+
rw = httptest.NewRecorder()
124+
125+
proxy, _ = dbgen.WorkspaceProxy(t, db, database.WorkspaceProxy{})
126+
)
127+
128+
// Use a different secret so they don't match!
129+
secret, err := cryptorand.HexString(64)
130+
require.NoError(t, err)
131+
r.Header.Set(httpmw.WorkspaceProxyAuthTokenHeader, fmt.Sprintf("%s:%s", proxy.ID.String(), secret))
132+
133+
httpmw.ExtractWorkspaceProxy(httpmw.ExtractWorkspaceProxyConfig{
134+
DB: db,
135+
})(successHandler).ServeHTTP(rw, r)
136+
res := rw.Result()
137+
defer res.Body.Close()
138+
require.Equal(t, http.StatusUnauthorized, res.StatusCode)
139+
})
140+
141+
t.Run("Valid", func(t *testing.T) {
142+
t.Parallel()
143+
var (
144+
db = dbfake.New()
145+
r = httptest.NewRequest("GET", "/", nil)
146+
rw = httptest.NewRecorder()
147+
148+
proxy, secret = dbgen.WorkspaceProxy(t, db, database.WorkspaceProxy{})
149+
)
150+
r.Header.Set(httpmw.WorkspaceProxyAuthTokenHeader, fmt.Sprintf("%s:%s", proxy.ID.String(), secret))
151+
152+
httpmw.ExtractWorkspaceProxy(httpmw.ExtractWorkspaceProxyConfig{
153+
DB: db,
154+
})(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
155+
// Checks that it exists on the context!
156+
_ = httpmw.WorkspaceProxy(r)
157+
successHandler.ServeHTTP(rw, r)
158+
})).ServeHTTP(rw, r)
159+
res := rw.Result()
160+
defer res.Body.Close()
161+
require.Equal(t, http.StatusOK, res.StatusCode)
162+
})
163+
}

0 commit comments

Comments
 (0)