Skip to content

Commit 6866732

Browse files
authored
chore: support signed token query param for web terminal (coder#7197)
* chore: add endpoint to get token for web terminal * chore: support signed token query param for web terminal
1 parent ac3c530 commit 6866732

25 files changed

+886
-164
lines changed

coderd/apidoc/docs.go

Lines changed: 67 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 58 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbauthz/querier.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,10 +1701,6 @@ func (q *querier) GetWorkspaceProxyByName(ctx context.Context, name string) (dat
17011701
return fetch(q.log, q.auth, q.db.GetWorkspaceProxyByName)(ctx, name)
17021702
}
17031703

1704-
func (q *querier) GetWorkspaceProxyByHostname(ctx context.Context, hostname string) (database.WorkspaceProxy, error) {
1705-
return fetch(q.log, q.auth, q.db.GetWorkspaceProxyByHostname)(ctx, hostname)
1706-
}
1707-
17081704
func (q *querier) InsertWorkspaceProxy(ctx context.Context, arg database.InsertWorkspaceProxyParams) (database.WorkspaceProxy, error) {
17091705
return insert(q.log, q.auth, rbac.ResourceWorkspaceProxy, q.db.InsertWorkspaceProxy)(ctx, arg)
17101706
}

coderd/database/dbauthz/system.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,3 +438,10 @@ func (q *querier) InsertParameterSchema(ctx context.Context, arg database.Insert
438438
}
439439
return q.db.InsertParameterSchema(ctx, arg)
440440
}
441+
442+
func (q *querier) GetWorkspaceProxyByHostname(ctx context.Context, params database.GetWorkspaceProxyByHostnameParams) (database.WorkspaceProxy, error) {
443+
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
444+
return database.WorkspaceProxy{}, err
445+
}
446+
return q.db.GetWorkspaceProxyByHostname(ctx, params)
447+
}

coderd/database/dbfake/databasefake.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
"github.com/coder/coder/coderd/util/slice"
2525
)
2626

27-
var validProxyByHostnameRegex = regexp.MustCompile(`^[a-zA-Z0-9.-]+$`)
27+
var validProxyByHostnameRegex = regexp.MustCompile(`^[a-zA-Z0-9._-]+$`)
2828

2929
// FakeDatabase is helpful for knowing if the underlying db is an in memory fake
3030
// database. This is only in the databasefake package, so will only be used
@@ -5142,34 +5142,36 @@ func (q *fakeQuerier) GetWorkspaceProxyByName(_ context.Context, name string) (d
51425142
return database.WorkspaceProxy{}, sql.ErrNoRows
51435143
}
51445144

5145-
func (q *fakeQuerier) GetWorkspaceProxyByHostname(_ context.Context, hostname string) (database.WorkspaceProxy, error) {
5145+
func (q *fakeQuerier) GetWorkspaceProxyByHostname(_ context.Context, params database.GetWorkspaceProxyByHostnameParams) (database.WorkspaceProxy, error) {
51465146
q.mutex.RLock()
51475147
defer q.mutex.RUnlock()
51485148

51495149
// Return zero rows if this is called with a non-sanitized hostname. The SQL
51505150
// version of this query does the same thing.
5151-
if !validProxyByHostnameRegex.MatchString(hostname) {
5151+
if !validProxyByHostnameRegex.MatchString(params.Hostname) {
51525152
return database.WorkspaceProxy{}, sql.ErrNoRows
51535153
}
51545154

51555155
// This regex matches the SQL version.
5156-
accessURLRegex := regexp.MustCompile(`[^:]*://` + regexp.QuoteMeta(hostname) + `([:/]?.)*`)
5156+
accessURLRegex := regexp.MustCompile(`[^:]*://` + regexp.QuoteMeta(params.Hostname) + `([:/]?.)*`)
51575157

51585158
for _, proxy := range q.workspaceProxies {
51595159
if proxy.Deleted {
51605160
continue
51615161
}
5162-
if accessURLRegex.MatchString(proxy.Url) {
5162+
if params.AllowAccessUrl && accessURLRegex.MatchString(proxy.Url) {
51635163
return proxy, nil
51645164
}
51655165

51665166
// Compile the app hostname regex. This is slow sadly.
5167-
wildcardRegexp, err := httpapi.CompileHostnamePattern(proxy.WildcardHostname)
5168-
if err != nil {
5169-
return database.WorkspaceProxy{}, xerrors.Errorf("compile hostname pattern %q for proxy %q (%s): %w", proxy.WildcardHostname, proxy.Name, proxy.ID.String(), err)
5170-
}
5171-
if _, ok := httpapi.ExecuteHostnamePattern(wildcardRegexp, hostname); ok {
5172-
return proxy, nil
5167+
if params.AllowWildcardHostname {
5168+
wildcardRegexp, err := httpapi.CompileHostnamePattern(proxy.WildcardHostname)
5169+
if err != nil {
5170+
return database.WorkspaceProxy{}, xerrors.Errorf("compile hostname pattern %q for proxy %q (%s): %w", proxy.WildcardHostname, proxy.Name, proxy.ID.String(), err)
5171+
}
5172+
if _, ok := httpapi.ExecuteHostnamePattern(wildcardRegexp, params.Hostname); ok {
5173+
return proxy, nil
5174+
}
51735175
}
51745176
}
51755177

coderd/database/dbfake/databasefake_test.go

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -160,44 +160,74 @@ func TestProxyByHostname(t *testing.T) {
160160
}
161161

162162
cases := []struct {
163-
name string
164-
testHostname string
165-
matchProxyName string
163+
name string
164+
testHostname string
165+
allowAccessURL bool
166+
allowWildcardHost bool
167+
matchProxyName string
166168
}{
167169
{
168-
name: "NoMatch",
169-
testHostname: "test.com",
170-
matchProxyName: "",
170+
name: "NoMatch",
171+
testHostname: "test.com",
172+
allowAccessURL: true,
173+
allowWildcardHost: true,
174+
matchProxyName: "",
171175
},
172176
{
173-
name: "MatchAccessURL",
174-
testHostname: "one.coder.com",
175-
matchProxyName: "one",
177+
name: "MatchAccessURL",
178+
testHostname: "one.coder.com",
179+
allowAccessURL: true,
180+
allowWildcardHost: true,
181+
matchProxyName: "one",
176182
},
177183
{
178-
name: "MatchWildcard",
179-
testHostname: "something.wildcard.one.coder.com",
180-
matchProxyName: "one",
184+
name: "MatchWildcard",
185+
testHostname: "something.wildcard.one.coder.com",
186+
allowAccessURL: true,
187+
allowWildcardHost: true,
188+
matchProxyName: "one",
181189
},
182190
{
183-
name: "MatchSuffix",
184-
testHostname: "something--suffix.two.coder.com",
185-
matchProxyName: "two",
191+
name: "MatchSuffix",
192+
testHostname: "something--suffix.two.coder.com",
193+
allowAccessURL: true,
194+
allowWildcardHost: true,
195+
matchProxyName: "two",
186196
},
187197
{
188-
name: "ValidateHostname/1",
189-
testHostname: ".*ne.coder.com",
190-
matchProxyName: "",
198+
name: "ValidateHostname/1",
199+
testHostname: ".*ne.coder.com",
200+
allowAccessURL: true,
201+
allowWildcardHost: true,
202+
matchProxyName: "",
191203
},
192204
{
193-
name: "ValidateHostname/2",
194-
testHostname: "https://one.coder.com",
195-
matchProxyName: "",
205+
name: "ValidateHostname/2",
206+
testHostname: "https://one.coder.com",
207+
allowAccessURL: true,
208+
allowWildcardHost: true,
209+
matchProxyName: "",
196210
},
197211
{
198-
name: "ValidateHostname/3",
199-
testHostname: "one.coder.com:8080/hello",
200-
matchProxyName: "",
212+
name: "ValidateHostname/3",
213+
testHostname: "one.coder.com:8080/hello",
214+
allowAccessURL: true,
215+
allowWildcardHost: true,
216+
matchProxyName: "",
217+
},
218+
{
219+
name: "IgnoreAccessURLMatch",
220+
testHostname: "one.coder.com",
221+
allowAccessURL: false,
222+
allowWildcardHost: true,
223+
matchProxyName: "",
224+
},
225+
{
226+
name: "IgnoreWildcardMatch",
227+
testHostname: "hi.wildcard.one.coder.com",
228+
allowAccessURL: true,
229+
allowWildcardHost: false,
230+
matchProxyName: "",
201231
},
202232
}
203233

@@ -206,7 +236,11 @@ func TestProxyByHostname(t *testing.T) {
206236
t.Run(c.name, func(t *testing.T) {
207237
t.Parallel()
208238

209-
proxy, err := db.GetWorkspaceProxyByHostname(context.Background(), c.testHostname)
239+
proxy, err := db.GetWorkspaceProxyByHostname(context.Background(), database.GetWorkspaceProxyByHostnameParams{
240+
Hostname: c.testHostname,
241+
AllowAccessUrl: c.allowAccessURL,
242+
AllowWildcardHostname: c.allowWildcardHost,
243+
})
210244
if c.matchProxyName == "" {
211245
require.ErrorIs(t, err, sql.ErrNoRows)
212246
require.Empty(t, proxy)

coderd/database/querier.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)