8000 feat: bypass built-in CORS handling for workspace apps by dannykopping · Pull Request #15669 · coder/coder · GitHub
[go: up one dir, main page]

Skip to content
Closed
Next Next commit
Working implementation
Signed-off-by: Danny Kopping <danny@coder.com>
  • Loading branch information
dannykopping committed Nov 28, 2024
commit 0dc7ca368f34d22dcfbf1f75501da6561e25c084
1 change: 1 addition & 0 deletions coderd/database/dbmem/dbmem.go
Original file line number Diff line number Diff line change
Expand Up @@ -8174,6 +8174,7 @@ func (q *FakeQuerier) InsertWorkspaceApp(_ context.Context, arg database.InsertW
Health: arg.Health,
Hidden: arg.Hidden,
DisplayOrder: arg.DisplayOrder,
CorsBehavior: arg.CorsBehavior,
}
q.workspaceApps = append(q.workspaceApps, workspaceApp)
return workspaceApp, nil
Expand Down
8 changes: 7 additions & 1 deletion coderd/database/dump.sql

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ALTER TABLE workspace_apps
DROP COLUMN IF EXISTS cors_behavior;

DROP TYPE IF EXISTS app_cors_behavior;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CREATE TYPE app_cors_behavior AS ENUM (
'simple',
'passthru'
);

-- https://www.postgresql.org/docs/16/sql-altertable.html
-- When a column is added with ADD COLUMN and a non-volatile DEFAULT is specified, the default is evaluated at the time
-- of the statement and the result stored in the table's metadata. That value will be used for the column for all existing rows.
ALTER TABLE workspace_apps
ADD COLUMN cors_behavior app_cors_behavior NOT NULL DEFAULT 'simple'::app_cors_behavior;
61 changes: 60 additions & 1 deletion coderd/database/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 13 additions & 5 deletions coderd/database/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion coderd/database/queries/workspaceapps.sql
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ INSERT INTO
external,
subdomain,
sharing_level,
cors_behavior,
healthcheck_url,
healthcheck_interval,
healthcheck_threshold,
Expand All @@ -32,7 +33,7 @@ INSERT INTO
hidden
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17) RETURNING *;
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18) RETURNING *;

-- name: UpdateWorkspaceAppHealthByID :exec
UPDATE
Expand Down
1 change: 1 addition & 0 deletions coderd/database/sqlc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ sql:
login_type_oauth2_provider_app: LoginTypeOAuth2ProviderApp
crypto_key_feature_workspace_apps_api_key: CryptoKeyFeatureWorkspaceAppsAPIKey
crypto_key_feature_oidc_convert: CryptoKeyFeatureOIDCConvert
app_cors_behavior: AppCORSBehavior
rules:
- name: do-not-use-public-schema-in-queries
message: "do not use public schema in queries"
Expand Down
6 changes: 6 additions & 0 deletions coderd/httpmw/cors.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/go-chi/cors"

"github.com/coder/coder/v2/coderd/workspaceapps/appurl"
ws_cors "github.com/coder/coder/v2/coderd/workspaceapps/cors"
)

const (
Expand Down Expand Up @@ -47,6 +48,11 @@ func Cors(allowAll bool, origins ...string) func(next http.Handler) http.Handler
func WorkspaceAppCors(regex *regexp.Regexp, app appurl.ApplicationURL) func(next http.Handler) http.Handler {
return cors.Handler(cors.Options{
AllowOriginFunc: func(r *http.Request, rawOrigin string) bool {
// If passthru behavior is set, disable our simplified CORS handling.
if ws_cors.HasBehavior(r.Context(), ws_cors.AppCORSBehaviorPassthru) {
return true
}

origin, err := url.Parse(rawOrigin)
if rawOrigin == "" || origin.Host == "" || err != nil {
return false
Expand Down
3 changes: 2 additions & 1 deletion coderd/httpmw/cors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ func TestWorkspaceAppCors(t *testing.T) {
r.Header.Set("Access-Control-Request-Method", method)
}

handler := httpmw.WorkspaceAppCors(regex, test.app)(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
// TODO: signed token provider
handler := httpmw.WorkspaceAppCors(nil, regex, test.app)(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.WriteHeader(http.StatusNoContent)
}))

Expand Down
10 changes: 10 additions & 0 deletions coderd/provisionerdserver/provisionerdserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -1988,6 +1988,15 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
sharingLevel = database.AppSharingLevelPublic
}

// TODO: consider backwards-compat where proto might not contain this field
var corsBehavior database.AppCORSBehavior
switch app.CorsBehavior {
case sdkproto.AppCORSBehavior_PASSTHRU:
corsBehavior = database.AppCorsBehaviorPassthru
default:
corsBehavior = database.AppCorsBehaviorSimple
}

dbApp, err := db.InsertWorkspaceApp(ctx, database.InsertWorkspaceAppParams{
ID: uuid.New(),
CreatedAt: dbtime.Now(),
Expand All @@ -2006,6 +2015,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
External: app.External,
Subdomain: app.Subdomain,
SharingLevel: sharingLevel,
CorsBehavior: corsBehavior,
HealthcheckUrl: app.Healthcheck.Url,
HealthcheckInterval: app.Healthcheck.Interval,
HealthcheckThreshold: app.Healthcheck.Threshold,
Expand Down
Loading
0