mirror of
https://github.com/coder/coder.git
synced 2025-07-06 15:41:45 +00:00
59 lines
1.7 KiB
Go
59 lines
1.7 KiB
Go
package wsproxy
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"cdr.dev/slog"
|
|
|
|
"github.com/coder/coder/coderd/workspaceapps"
|
|
"github.com/coder/coder/enterprise/wsproxy/wsproxysdk"
|
|
)
|
|
|
|
var _ workspaceapps.SignedTokenProvider = (*TokenProvider)(nil)
|
|
|
|
type TokenProvider struct {
|
|
DashboardURL *url.URL
|
|
AccessURL *url.URL
|
|
AppHostname string
|
|
|
|
Client *wsproxysdk.Client
|
|
SecurityKey workspaceapps.SecurityKey
|
|
Logger slog.Logger
|
|
}
|
|
|
|
func (p *TokenProvider) FromRequest(r *http.Request) (*workspaceapps.SignedToken, bool) {
|
|
return workspaceapps.FromRequest(r, p.SecurityKey)
|
|
}
|
|
|
|
func (p *TokenProvider) Issue(ctx context.Context, rw http.ResponseWriter, r *http.Request, issueReq workspaceapps.IssueTokenRequest) (*workspaceapps.SignedToken, string, bool) {
|
|
appReq := issueReq.AppRequest.Normalize()
|
|
err := appReq.Validate()
|
|
if err != nil {
|
|
workspaceapps.WriteWorkspaceApp500(p.Logger, p.DashboardURL, rw, r, &appReq, err, "invalid app request")
|
|
return nil, "", false
|
|
}
|
|
issueReq.AppRequest = appReq
|
|
|
|
resp, ok := p.Client.IssueSignedAppTokenHTML(ctx, rw, issueReq)
|
|
if !ok {
|
|
return nil, "", false
|
|
}
|
|
|
|
// Check that it verifies properly and matches the string.
|
|
token, err := p.SecurityKey.VerifySignedToken(resp.SignedTokenStr)
|
|
if err != nil {
|
|
workspaceapps.WriteWorkspaceApp500(p.Logger, p.DashboardURL, rw, r, &appReq, err, "failed to verify newly generated signed token")
|
|
return nil, "", false
|
|
}
|
|
|
|
// Check that it matches the request.
|
|
if !token.MatchesRequest(appReq) {
|
|
workspaceapps.WriteWorkspaceApp500(p.Logger, p.DashboardURL, rw, r, &appReq, err, "newly generated signed token does not match request")
|
|
return nil, "", false
|
|
}
|
|
|
|
return &token, resp.SignedTokenStr, true
|
|
}
|