Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit70309ce

Browse files
committed
Renamed from PR review
1 parent7e0ea10 commit70309ce

File tree

7 files changed

+80
-69
lines changed

7 files changed

+80
-69
lines changed

‎coderd/coderd.go‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ type Options struct {
8686
// It will use the same scheme and port number as the access URL.
8787
// E.g. "*.apps.coder.com" or "*-apps.coder.com".
8888
AppHostnamestring
89-
// AppHostnameRegex contains the regex version of options.AppHostname as
89+
// AppHostnameRegex contains the regex version of options.Hostname as
9090
// generated by httpapi.CompileHostnamePattern(). It MUST be set if
91-
// options.AppHostname is set.
91+
// options.Hostname is set.
9292
AppHostnameRegex*regexp.Regexp
9393
Logger slog.Logger
9494
Database database.Store
@@ -125,7 +125,7 @@ type Options struct {
125125
TemplateScheduleStore schedule.TemplateScheduleStore
126126
// AppSigningKey denotes the symmetric key to use for signing temporary app
127127
// tokens.
128-
AppSigningKey workspaceapps.AppSigningKey
128+
AppSigningKey workspaceapps.SigningKey
129129
HealthcheckFuncfunc(ctx context.Context) (*healthcheck.Report,error)
130130
HealthcheckTimeout time.Duration
131131
HealthcheckRefresh time.Duration
@@ -183,7 +183,7 @@ func New(options *Options) *API {
183183
options.Logger,options.DeploymentValues.Experiments.Value(),
184184
)
185185
ifoptions.AppHostname!=""&&options.AppHostnameRegex==nil||options.AppHostname==""&&options.AppHostnameRegex!=nil {
186-
panic("coderd: bothAppHostname andAppHostnameRegex must be set or unset")
186+
panic("coderd: bothHostname andHostnameRegex must be set or unset")
187187
}
188188
ifoptions.AgentConnectionUpdateFrequency==0 {
189189
options.AgentConnectionUpdateFrequency=3*time.Second
@@ -328,19 +328,19 @@ func New(options *Options) *API {
328328
api.workspaceAgentCache=wsconncache.New(api.dialWorkspaceAgentTailnet,0)
329329
api.TailnetCoordinator.Store(&options.TailnetCoordinator)
330330

331-
workspaceAppServer:= workspaceapps.WorkspaceAppServer{
331+
workspaceAppServer:= workspaceapps.Server{
332332
Logger:options.Logger.Named("workspaceapps"),
333333

334-
PrimaryAccessURL:api.AccessURL,
334+
DashboardURL:api.AccessURL,
335335
AccessURL:api.AccessURL,
336-
AppHostname:api.AppHostname,
337-
AppHostnameRegex:api.AppHostnameRegex,
336+
Hostname:api.AppHostname,
337+
HostnameRegex:api.AppHostnameRegex,
338338
DeploymentValues:options.DeploymentValues,
339339
RealIPConfig:options.RealIPConfig,
340340

341-
TokenProvider:api.WorkspaceAppsProvider,
342-
WorkspaceConnCache:api.workspaceAgentCache,
343-
AppSigningKey:options.AppSigningKey,
341+
SignedTokenProvider:api.WorkspaceAppsProvider,
342+
WorkspaceConnCache:api.workspaceAgentCache,
343+
AppSigningKey:options.AppSigningKey,
344344
}
345345

346346
apiKeyMiddleware:=httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{

‎coderd/workspaceapps.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func (api *API) workspaceApplicationAuth(rw http.ResponseWriter, r *http.Request
8181
// security purposes.
8282
u.Scheme=api.AccessURL.Scheme
8383

84-
// Ensure that the redirect URI is a subdomain of api.AppHostname and is a
84+
// Ensure that the redirect URI is a subdomain of api.Hostname and is a
8585
// valid app subdomain.
8686
subdomain,ok:=httpapi.ExecuteHostnamePattern(api.AppHostnameRegex,u.Host)
8787
if!ok {

‎coderd/workspaceapps/db.go‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ type DBTokenProvider struct {
3232
DeploymentValues*codersdk.DeploymentValues
3333
OAuth2Configs*httpmw.OAuth2Configs
3434
WorkspaceAgentInactiveTimeout time.Duration
35-
TokenSigningKeyAppSigningKey
35+
TokenSigningKeySigningKey
3636
}
3737

3838
var_SignedTokenProvider=&DBTokenProvider{}
3939

40-
funcNewDBTokenProvider(log slog.Logger,accessURL*url.URL,authz rbac.Authorizer,db database.Store,cfg*codersdk.DeploymentValues,oauth2Cfgs*httpmw.OAuth2Configs,workspaceAgentInactiveTimeout time.Duration,tokenSigningKeyAppSigningKey)SignedTokenProvider {
40+
funcNewDBTokenProvider(log slog.Logger,accessURL*url.URL,authz rbac.Authorizer,db database.Store,cfg*codersdk.DeploymentValues,oauth2Cfgs*httpmw.OAuth2Configs,workspaceAgentInactiveTimeout time.Duration,tokenSigningKeySigningKey)SignedTokenProvider {
4141
iflen(tokenSigningKey)!=64 {
4242
panic("token signing key must be 64 bytes")
4343
}

‎coderd/workspaceapps/provider.go‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ const (
1919
RedirectURIQueryParam="redirect_uri"
2020
)
2121

22-
// ResolveRequest callsTokenProvider to use an existing signed app token in the
22+
// ResolveRequest callsSignedTokenProvider to use an existing signed app token in the
2323
// request or issue a new one. If it returns a newly minted token, it sets the
2424
// cookie for you.
25-
funcResolveRequest(log slog.Logger,accessURL*url.URL,pSignedTokenProvider,rw http.ResponseWriter,r*http.Request,appReqRequest) (*SignedToken,bool) {
25+
funcResolveRequest(log slog.Logger,dashboardURL*url.URL,pSignedTokenProvider,rw http.ResponseWriter,r*http.Request,appReqRequest) (*SignedToken,bool) {
2626
appReq=appReq.Normalize()
2727
err:=appReq.Validate()
2828
iferr!=nil {
29-
WriteWorkspaceApp500(log,accessURL,rw,r,&appReq,err,"invalid app request")
29+
WriteWorkspaceApp500(log,dashboardURL,rw,r,&appReq,err,"invalid app request")
3030
returnnil,false
3131
}
3232

‎coderd/workspaceapps/proxy.go‎

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -59,28 +59,34 @@ var nonCanonicalHeaders = map[string]string{
5959
"Sec-Websocket-Version":"Sec-WebSocket-Version",
6060
}
6161

62-
//WorkspaceAppServer serves workspace apps endpoints, including:
62+
//Server serves workspace apps endpoints, including:
6363
// - Path-based apps
6464
// - Subdomain app middleware
6565
// - Workspace reconnecting-pty (aka. web terminal)
66-
typeWorkspaceAppServerstruct {
66+
typeServerstruct {
6767
Logger slog.Logger
6868

69-
// PrimaryAccessURL should be a url to the coderd dashboard. This can be the
70-
// same as the AccessURL if the WorkspaceAppServer is embedded.
71-
PrimaryAccessURL*url.URL
72-
AccessURL*url.URL
73-
AppHostnamestring
74-
AppHostnameRegex*regexp.Regexp
69+
// DashboardURL should be a url to the coderd dashboard. This can be the
70+
// same as the AccessURL if the Server is embedded.
71+
DashboardURL*url.URL
72+
AccessURL*url.URL
73+
// Hostname should be the wildcard hostname to use for workspace
74+
// applications INCLUDING the asterisk, (optional) suffix and leading dot.
75+
// It will use the same scheme and port number as the access URL.
76+
// E.g. "*.apps.coder.com" or "*-apps.coder.com".
77+
Hostnamestring
78+
// HostnameRegex contains the regex version of Hostname as generated by
79+
// httpapi.CompileHostnamePattern(). It MUST be set if Hostname is set.
80+
HostnameRegex*regexp.Regexp
7581
DeploymentValues*codersdk.DeploymentValues
7682
RealIPConfig*httpmw.RealIPConfig
7783

78-
TokenProviderSignedTokenProvider
79-
WorkspaceConnCache*wsconncache.Cache
80-
AppSigningKeyAppSigningKey
84+
SignedTokenProviderSignedTokenProvider
85+
WorkspaceConnCache*wsconncache.Cache
86+
AppSigningKeySigningKey
8187
}
8288

83-
func (s*WorkspaceAppServer)Attach(r chi.Router,pathAppRateLimiterfunc(http.Handler) http.Handler) {
89+
func (s*Server)Attach(r chi.Router,pathAppRateLimiterfunc(http.Handler) http.Handler) {
8490
servePathApps:=func(r chi.Router) {
8591
r.Use(pathAppRateLimiter)
8692
r.HandleFunc("/*",s.workspaceAppsProxyPath)
@@ -97,14 +103,14 @@ func (s *WorkspaceAppServer) Attach(r chi.Router, pathAppRateLimiter func(http.H
97103

98104
// workspaceAppsProxyPath proxies requests to a workspace application
99105
// through a relative URL path.
100-
func (s*WorkspaceAppServer)workspaceAppsProxyPath(rw http.ResponseWriter,r*http.Request) {
106+
func (s*Server)workspaceAppsProxyPath(rw http.ResponseWriter,r*http.Request) {
101107
ifs.DeploymentValues.DisablePathApps.Value() {
102108
site.RenderStaticErrorPage(rw,r, site.ErrorPageData{
103109
Status:http.StatusUnauthorized,
104110
Title:"Unauthorized",
105111
Description:"Path-based applications are disabled on this Coder deployment by the administrator.",
106112
RetryEnabled:false,
107-
DashboardURL:s.PrimaryAccessURL.String(),
113+
DashboardURL:s.DashboardURL.String(),
108114
})
109115
return
110116
}
@@ -117,7 +123,7 @@ func (s *WorkspaceAppServer) workspaceAppsProxyPath(rw http.ResponseWriter, r *h
117123
Title:"Application Not Found",
118124
Description:"Applications must be accessed with the full username, not @me.",
119125
RetryEnabled:false,
120-
DashboardURL:s.PrimaryAccessURL.String(),
126+
DashboardURL:s.DashboardURL.String(),
121127
})
122128
return
123129
}
@@ -132,7 +138,7 @@ func (s *WorkspaceAppServer) workspaceAppsProxyPath(rw http.ResponseWriter, r *h
132138

133139
// ResolveRequest will only return a new signed token if the actor has the RBAC
134140
// permissions to connect to a workspace.
135-
token,ok:=ResolveRequest(s.Logger,s.AccessURL,s.TokenProvider,rw,r,Request{
141+
token,ok:=ResolveRequest(s.Logger,s.DashboardURL,s.SignedTokenProvider,rw,r,Request{
136142
AccessMethod:AccessMethodPath,
137143
BasePath:basePath,
138144
UsernameOrID:chi.URLParam(r,"user"),
@@ -152,20 +158,20 @@ func (s *WorkspaceAppServer) workspaceAppsProxyPath(rw http.ResponseWriter, r *h
152158
// DevURLs in Coder V1).
153159
//
154160
// There are a lot of paths here:
155-
// 1. If api.AppHostname is not set then we pass on.
161+
// 1. If api.Hostname is not set then we pass on.
156162
// 2. If we can't read the request hostname then we return a 400.
157163
// 3. If the request hostname matches api.AccessURL then we pass on.
158164
// 5. We split the subdomain into the subdomain and the "rest". If there are no
159165
// periods in the hostname then we pass on.
160166
// 5. We parse the subdomain into a httpapi.ApplicationURL struct. If we
161167
// encounter an error:
162-
// a. If the "rest" does not match api.AppHostname then we pass on;
168+
// a. If the "rest" does not match api.Hostname then we pass on;
163169
// b. Otherwise, we return a 400.
164-
// 6. Finally, we verify that the "rest" matches api.AppHostname, else we
170+
// 6. Finally, we verify that the "rest" matches api.Hostname, else we
165171
// return a 404.
166172
//
167173
// Rationales for each of the above steps:
168-
// 1. We pass on if api.AppHostname is not set to avoid returning any errors if
174+
// 1. We pass on if api.Hostname is not set to avoid returning any errors if
169175
// `--app-hostname` is not configured.
170176
// 2. Every request should have a valid Host header anyways.
171177
// 3. We pass on if the request hostname matches api.AccessURL so we can
@@ -175,22 +181,22 @@ func (s *WorkspaceAppServer) workspaceAppsProxyPath(rw http.ResponseWriter, r *h
175181
// must be a subdomain of a hostname, which implies there must be at least
176182
// one period.
177183
// 5. a. If the request subdomain is not a valid application URL, and the
178-
// "rest" does not match api.AppHostname, then it is very unlikely that
184+
// "rest" does not match api.Hostname, then it is very unlikely that
179185
// the request was intended for this handler. We pass on.
180186
// b. If the request subdomain is not a valid application URL, but the
181-
// "rest" matches api.AppHostname, then we return a 400 because the
187+
// "rest" matches api.Hostname, then we return a 400 because the
182188
// request is probably a typo or something.
183-
// 6. We finally verify that the "rest" matches api.AppHostname for security
189+
// 6. We finally verify that the "rest" matches api.Hostname for security
184190
// purposes regarding re-authentication and application proxy session
185191
// tokens.
186-
func (s*WorkspaceAppServer)SubdomainAppMW(middlewares...func(http.Handler) http.Handler)func(http.Handler) http.Handler {
192+
func (s*Server)SubdomainAppMW(middlewares...func(http.Handler) http.Handler)func(http.Handler) http.Handler {
187193
returnfunc(next http.Handler) http.Handler {
188194
returnhttp.HandlerFunc(func(rw http.ResponseWriter,r*http.Request) {
189195
ctx:=r.Context()
190196

191197
// Step 1: Pass on if subdomain-based application proxying is not
192198
// configured.
193-
ifs.AppHostname==""||s.AppHostnameRegex==nil {
199+
ifs.Hostname==""||s.HostnameRegex==nil {
194200
next.ServeHTTP(rw,r)
195201
return
196202
}
@@ -214,7 +220,7 @@ func (s *WorkspaceAppServer) SubdomainAppMW(middlewares ...func(http.Handler) ht
214220
}
215221

216222
// Steps 3-6: Parse application from subdomain.
217-
app,ok:=s.parseWorkspaceApplicationHostname(rw,r,next,host)
223+
app,ok:=s.parseHostname(rw,r,next,host)
218224
if!ok {
219225
return
220226
}
@@ -233,7 +239,7 @@ func (s *WorkspaceAppServer) SubdomainAppMW(middlewares ...func(http.Handler) ht
233239
// Retry is disabled because the user needs to remove
234240
// the query parameter before they try again.
235241
RetryEnabled:false,
236-
DashboardURL:s.AccessURL.String(),
242+
DashboardURL:s.DashboardURL.String(),
237243
})
238244
return
239245
}
@@ -256,7 +262,7 @@ func (s *WorkspaceAppServer) SubdomainAppMW(middlewares ...func(http.Handler) ht
256262
return
257263
}
258264

259-
token,ok:=ResolveRequest(s.Logger,s.AccessURL,s.TokenProvider,rw,r,Request{
265+
token,ok:=ResolveRequest(s.Logger,s.DashboardURL,s.SignedTokenProvider,rw,r,Request{
260266
AccessMethod:AccessMethodSubdomain,
261267
BasePath:"/",
262268
UsernameOrID:app.Username,
@@ -278,11 +284,16 @@ func (s *WorkspaceAppServer) SubdomainAppMW(middlewares ...func(http.Handler) ht
278284
}
279285
}
280286

281-
func (s*WorkspaceAppServer)parseWorkspaceApplicationHostname(rw http.ResponseWriter,r*http.Request,next http.Handler,hoststring) (httpapi.ApplicationURL,bool) {
287+
// parseHostname will return if a given request is attempting to access a
288+
// workspace app via a subdomain. If it is, the hostname of the request is parsed
289+
// into an httpapi.ApplicationURL and true is returned. If the request is not
290+
// accessing a workspace app, then the next handler is called and false is
291+
// returned.
292+
func (s*Server)parseHostname(rw http.ResponseWriter,r*http.Request,next http.Handler,hoststring) (httpapi.ApplicationURL,bool) {
282293
// Check if the hostname matches either of the access URLs. If it does, the
283294
// user was definitely trying to connect to the dashboard/API or a
284295
// path-based app.
285-
ifhttpapi.HostnamesMatch(s.PrimaryAccessURL.Hostname(),host)||httpapi.HostnamesMatch(s.AccessURL.Hostname(),host) {
296+
ifhttpapi.HostnamesMatch(s.DashboardURL.Hostname(),host)||httpapi.HostnamesMatch(s.AccessURL.Hostname(),host) {
286297
next.ServeHTTP(rw,r)
287298
return httpapi.ApplicationURL{},false
288299
}
@@ -296,7 +307,7 @@ func (s *WorkspaceAppServer) parseWorkspaceApplicationHostname(rw http.ResponseW
296307

297308
// Split the subdomain so we can parse the application details and verify it
298309
// matches the configured app hostname later.
299-
subdomain,ok:=httpapi.ExecuteHostnamePattern(s.AppHostnameRegex,host)
310+
subdomain,ok:=httpapi.ExecuteHostnamePattern(s.HostnameRegex,host)
300311
if!ok {
301312
// Doesn't match the regex, so it's not a valid application URL.
302313
next.ServeHTTP(rw,r)
@@ -318,7 +329,7 @@ func (s *WorkspaceAppServer) parseWorkspaceApplicationHostname(rw http.ResponseW
318329
Title:"Invalid Application URL",
319330
Description:fmt.Sprintf("Could not parse subdomain application URL %q: %s",subdomain,err.Error()),
320331
RetryEnabled:false,
321-
DashboardURL:s.AccessURL.String(),
332+
DashboardURL:s.DashboardURL.String(),
322333
})
323334
return httpapi.ApplicationURL{},false
324335
}
@@ -329,23 +340,23 @@ func (s *WorkspaceAppServer) parseWorkspaceApplicationHostname(rw http.ResponseW
329340
// setWorkspaceAppCookie sets a cookie on the workspace app domain. If the app
330341
// hostname cannot be parsed properly, a static error page is rendered and false
331342
// is returned.
332-
func (s*WorkspaceAppServer)setWorkspaceAppCookie(rw http.ResponseWriter,r*http.Request,tokenstring)bool {
333-
hostSplit:=strings.SplitN(s.AppHostname,".",2)
343+
func (s*Server)setWorkspaceAppCookie(rw http.ResponseWriter,r*http.Request,tokenstring)bool {
344+
hostSplit:=strings.SplitN(s.Hostname,".",2)
334345
iflen(hostSplit)!=2 {
335346
// This should be impossible as we verify the app hostname on
336347
// startup, but we'll check anyways.
337-
s.Logger.Error(r.Context(),"could not split invalid app hostname",slog.F("hostname",s.AppHostname))
348+
s.Logger.Error(r.Context(),"could not split invalid app hostname",slog.F("hostname",s.Hostname))
338349
site.RenderStaticErrorPage(rw,r, site.ErrorPageData{
339350
Status:http.StatusInternalServerError,
340351
Title:"Internal Server Error",
341352
Description:"The app is configured with an invalid app wildcard hostname. Please contact an administrator.",
342353
RetryEnabled:false,
343-
DashboardURL:s.AccessURL.String(),
354+
DashboardURL:s.DashboardURL.String(),
344355
})
345356
returnfalse
346357
}
347358

348-
// Set the app cookie for all subdomains of s.AppHostname. We don't set an
359+
// Set the app cookie for all subdomains of s.Hostname. We don't set an
349360
// expiration because the key in the database already has an expiration, and
350361
// expired tokens don't affect the user experience (they get auto-redirected
351362
// to re-smuggle the API key).
@@ -364,7 +375,7 @@ func (s *WorkspaceAppServer) setWorkspaceAppCookie(rw http.ResponseWriter, r *ht
364375
returntrue
365376
}
366377

367-
func (s*WorkspaceAppServer)proxyWorkspaceApp(rw http.ResponseWriter,r*http.Request,appTokenSignedToken,pathstring) {
378+
func (s*Server)proxyWorkspaceApp(rw http.ResponseWriter,r*http.Request,appTokenSignedToken,pathstring) {
368379
ctx:=r.Context()
369380

370381
// Filter IP headers from untrusted origins.
@@ -384,7 +395,7 @@ func (s *WorkspaceAppServer) proxyWorkspaceApp(rw http.ResponseWriter, r *http.R
384395
Title:"Bad Request",
385396
Description:fmt.Sprintf("Application has an invalid URL %q: %s",appToken.AppURL,err.Error()),
386397
RetryEnabled:true,
387-
DashboardURL:s.PrimaryAccessURL.String(),
398+
DashboardURL:s.DashboardURL.String(),
388399
})
389400
return
390401
}
@@ -439,7 +450,7 @@ func (s *WorkspaceAppServer) proxyWorkspaceApp(rw http.ResponseWriter, r *http.R
439450
Title:"Bad Gateway",
440451
Description:"Failed to proxy request to application: "+err.Error(),
441452
RetryEnabled:true,
442-
DashboardURL:s.PrimaryAccessURL.String(),
453+
DashboardURL:s.DashboardURL.String(),
443454
})
444455
}
445456

@@ -450,7 +461,7 @@ func (s *WorkspaceAppServer) proxyWorkspaceApp(rw http.ResponseWriter, r *http.R
450461
Title:"Bad Gateway",
451462
Description:"Could not connect to workspace agent: "+err.Error(),
452463
RetryEnabled:true,
453-
DashboardURL:s.PrimaryAccessURL.String(),
464+
DashboardURL:s.DashboardURL.String(),
454465
})
455466
return
456467
}
@@ -490,7 +501,7 @@ func (s *WorkspaceAppServer) proxyWorkspaceApp(rw http.ResponseWriter, r *http.R
490501
// @Param workspaceagent path string true "Workspace agent ID" format(uuid)
491502
// @Success 101
492503
// @Router /workspaceagents/{workspaceagent}/pty [get]
493-
func (s*WorkspaceAppServer)workspaceAgentPTY(rw http.ResponseWriter,r*http.Request) {
504+
func (s*Server)workspaceAgentPTY(rw http.ResponseWriter,r*http.Request) {
494505
ctx:=r.Context()
495506

496507
// TODO: Fix this later
@@ -499,7 +510,7 @@ func (s *WorkspaceAppServer) workspaceAgentPTY(rw http.ResponseWriter, r *http.R
499510
// s.WebsocketWaitMutex.Unlock()
500511
// defer s.WebsocketWaitGroup.Done()
501512

502-
appToken,ok:=ResolveRequest(s.Logger,s.AccessURL,s.TokenProvider,rw,r,Request{
513+
appToken,ok:=ResolveRequest(s.Logger,s.AccessURL,s.SignedTokenProvider,rw,r,Request{
503514
AccessMethod:AccessMethodTerminal,
504515
BasePath:r.URL.Path,
505516
AgentNameOrID:chi.URLParam(r,"workspaceagent"),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp