Skip to content

Commit ffbfaf2

Browse files
authored
feat: allow bypassing current CORS magic based on template config (#18706)
Solves #15096 This is a slight rework/refactor of the earlier PRs from @dannykopping and @Emyrk: - #15669 - #15684 - #17596 Rather than having a per-app CORS behaviour setting and additionally a template level setting for ports, this PR adds a single template level CORS behaviour setting that is then used by all apps/ports for workspaces created from that template. The main changes are in `proxy.go` and `request.go` to: a) get the CORS behaviour setting from the template b) have `HandleSubdomain` bypass the CORS middleware handler if the selected behaviour is `passthru` c) in `proxyWorkspaceApp`, do not modify the response if the selected behaviour is `passthru` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for configuring CORS behavior ("simple" or "passthru") at the template level for all shared ports. * Introduced a new "CORS Behavior" setting in the template creation and settings forms. * API endpoints and responses now include the optional `cors_behavior` property for templates. * Workspace apps and proxy now honor the specified CORS behavior, enabling conditional CORS middleware application. * Enhanced workspace app tests with comprehensive scenarios covering CORS behaviors and authentication states. * **Bug Fixes** * None. * **Documentation** * Updated API and admin documentation to describe the new `cors_behavior` property and its usage. * Added examples and schema references for CORS behavior in relevant API docs. * **Tests** * Extended automated tests to cover different CORS behavior scenarios for templates and workspace apps. * **Chores** * Updated audit logging to track changes to the `cors_behavior` field on templates. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Callum Styan <callumstyan@gmail.com>
1 parent 96e32d6 commit ffbfaf2

File tree

36 files changed

+1149
-108
lines changed

36 files changed

+1149
-108
lines changed

coderd/apidoc/docs.go

Lines changed: 22 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: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,7 @@ func (s *MethodTestSuite) TestTemplate() {
14621462
Provisioner: "echo",
14631463
OrganizationID: orgID,
14641464
MaxPortSharingLevel: database.AppSharingLevelOwner,
1465+
CorsBehavior: database.CorsBehaviorSimple,
14651466
}).Asserts(rbac.ResourceTemplate.InOrg(orgID), policy.ActionCreate)
14661467
}))
14671468
s.Run("InsertTemplateVersion", s.Subtest(func(db database.Store, check *expects) {
@@ -1582,6 +1583,7 @@ func (s *MethodTestSuite) TestTemplate() {
15821583
check.Args(database.UpdateTemplateMetaByIDParams{
15831584
ID: t1.ID,
15841585
MaxPortSharingLevel: "owner",
1586+
CorsBehavior: database.CorsBehaviorSimple,
15851587
}).Asserts(t1, policy.ActionUpdate)
15861588
}))
15871589
s.Run("UpdateTemplateVersionByID", s.Subtest(func(db database.Store, check *expects) {

coderd/database/dbgen/dbgen.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ func Template(t testing.TB, db database.Store, seed database.Template) database.
148148
AllowUserCancelWorkspaceJobs: seed.AllowUserCancelWorkspaceJobs,
149149
MaxPortSharingLevel: takeFirst(seed.MaxPortSharingLevel, database.AppSharingLevelOwner),
150150
UseClassicParameterFlow: takeFirst(seed.UseClassicParameterFlow, false),
151+
CorsBehavior: takeFirst(seed.CorsBehavior, database.CorsBehaviorSimple),
151152
})
152153
require.NoError(t, err, "insert template")
153154

coderd/database/dump.sql

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
DROP VIEW IF EXISTS template_with_names;
2+
CREATE VIEW template_with_names AS
3+
SELECT templates.id,
4+
templates.created_at,
5+
templates.updated_at,
6+
templates.organization_id,
7+
templates.deleted,
8+
templates.name,
9+
templates.provisioner,
10+
templates.active_version_id,
11+
templates.description,
12+
templates.default_ttl,
13+
templates.created_by,
14+
templates.icon,
15+
templates.user_acl,
16+
templates.group_acl,
17+
templates.display_name,
18+
templates.allow_user_cancel_workspace_jobs,
19+
templates.allow_user_autostart,
20+
templates.allow_user_autostop,
21+
templates.failure_ttl,
22+
templates.time_til_dormant,
23+
templates.time_til_dormant_autodelete,
24+
templates.autostop_requirement_days_of_week,
25+
templates.autostop_requirement_weeks,
26+
templates.autostart_block_days_of_week,
27+
templates.require_active_version,
28+
templates.deprecated,
29+
templates.activity_bump,
30+
templates.max_port_sharing_level,
31+
templates.use_classic_parameter_flow,
32+
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
33+
COALESCE(visible_users.username, ''::text) AS created_by_username,
34+
COALESCE(visible_users.name, ''::text) AS created_by_name,
35+
COALESCE(organizations.name, ''::text) AS organization_name,
36+
COALESCE(organizations.display_name, ''::text) AS organization_display_name,
37+
COALESCE(organizations.icon, ''::text) AS organization_icon
38+
FROM ((templates
39+
LEFT JOIN visible_users ON ((templates.created_by = visible_users.id)))
40+
LEFT JOIN organizations ON ((templates.organization_id = organizations.id)));
41+
42+
COMMENT ON VIEW template_with_names IS 'Joins in the display name information such as username, avatar, and organization name.';
43+
44+
ALTER TABLE templates DROP COLUMN cors_behavior;
45+
46+
DROP TYPE IF EXISTS cors_behavior;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
CREATE TYPE cors_behavior AS ENUM (
2+
'simple',
3+
'passthru'
4+
);
5+
6+
ALTER TABLE templates
7+
ADD COLUMN cors_behavior cors_behavior NOT NULL DEFAULT 'simple'::cors_behavior;
8+
9+
-- Update the template_with_users view by recreating it.
10+
DROP VIEW IF EXISTS template_with_names;
11+
CREATE VIEW template_with_names AS
12+
SELECT templates.id,
13+
templates.created_at,
14+
templates.updated_at,
15+
templates.organization_id,
16+
templates.deleted,
17+
templates.name,
18+
templates.provisioner,
19+
templates.active_version_id,
20+
templates.description,
21+
templates.default_ttl,
22+
templates.created_by,
23+
templates.icon,
24+
templates.user_acl,
25+
templates.group_acl,
26+
templates.display_name,
27+
templates.allow_user_cancel_workspace_jobs,
28+
templates.allow_user_autostart,
29+
templates.allow_user_autostop,
30+
templates.failure_ttl,
31+
templates.time_til_dormant,
32+
templates.time_til_dormant_autodelete,
33+
templates.autostop_requirement_days_of_week,
34+
templates.autostop_requirement_weeks,
35+
templates.autostart_block_days_of_week,
36+
templates.require_active_version,
37+
templates.deprecated,
38+
templates.activity_bump,
39+
templates.max_port_sharing_level,
40+
templates.use_classic_parameter_flow,
41+
templates.cors_behavior, -- <--- adding this column
42+
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
43+
COALESCE(visible_users.username, ''::text) AS created_by_username,
44+
COALESCE(visible_users.name, ''::text) AS created_by_name,
45+
COALESCE(organizations.name, ''::text) AS organization_name,
46+
COALESCE(organizations.display_name, ''::text) AS organization_display_name,
47+
COALESCE(organizations.icon, ''::text) AS organization_icon
48+
FROM ((templates
49+
LEFT JOIN visible_users ON ((templates.created_by = visible_users.id)))
50+
LEFT JOIN organizations ON ((templates.organization_id = organizations.id)));
51+
52+
COMMENT ON VIEW template_with_names IS 'Joins in the display name information such as username, avatar, and organization name.';

coderd/database/modelqueries.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ func (q *sqlQuerier) GetAuthorizedTemplates(ctx context.Context, arg GetTemplate
120120
&i.ActivityBump,
121121
&i.MaxPortSharingLevel,
122122
&i.UseClassicParameterFlow,
123+
&i.CorsBehavior,
123124
&i.CreatedByAvatarURL,
124125
&i.CreatedByUsername,
125126
&i.CreatedByName,

coderd/database/models.go

Lines changed: 61 additions & 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)