Skip to content

Commit 4724f79

Browse files
committed
claude be doing something certainly
1 parent 232c72f commit 4724f79

File tree

14 files changed

+409
-17
lines changed

14 files changed

+409
-17
lines changed

coderd/apidoc/docs.go

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

coderd/database/dump.sql

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
-- Remove 'organization' from the app_sharing_level enum
2+
3+
-- Drop the view that depends on the templates table
4+
DROP VIEW template_with_names;
5+
6+
CREATE TYPE new_app_sharing_level AS ENUM (
7+
'owner',
8+
'authenticated',
9+
'public'
10+
);
11+
12+
-- Update workspace_agent_port_share table to use old enum
13+
-- Convert any 'organization' values to 'authenticated' during downgrade
14+
ALTER TABLE workspace_agent_port_share
15+
ALTER COLUMN share_level TYPE new_app_sharing_level USING (
16+
CASE
17+
WHEN share_level = 'organization' THEN 'authenticated'::new_app_sharing_level
18+
ELSE share_level::text::new_app_sharing_level
19+
END
20+
);
21+
22+
-- Update workspace_apps table to use old enum
23+
-- Convert any 'organization' values to 'authenticated' during downgrade
24+
ALTER TABLE workspace_apps
25+
ALTER COLUMN sharing_level DROP DEFAULT,
26+
ALTER COLUMN sharing_level TYPE new_app_sharing_level USING (
27+
CASE
28+
WHEN sharing_level = 'organization' THEN 'authenticated'::new_app_sharing_level
29+
ELSE sharing_level::text::new_app_sharing_level
30+
END
31+
),
32+
ALTER COLUMN sharing_level SET DEFAULT 'owner'::new_app_sharing_level;
33+
34+
-- Update templates table to use old enum
35+
-- Convert any 'organization' values to 'authenticated' during downgrade
36+
ALTER TABLE templates
37+
ALTER COLUMN max_port_sharing_level DROP DEFAULT,
38+
ALTER COLUMN max_port_sharing_level TYPE new_app_sharing_level USING (
39+
CASE
40+
WHEN max_port_sharing_level = 'organization' THEN 'authenticated'::new_app_sharing_level
41+
ELSE max_port_sharing_level::text::new_app_sharing_level
42+
END
43+
),
44+
ALTER COLUMN max_port_sharing_level SET DEFAULT 'owner'::new_app_sharing_level;
45+
46+
-- Drop old enum and rename new one
47+
DROP TYPE app_sharing_level;
48+
ALTER TYPE new_app_sharing_level RENAME TO app_sharing_level;
49+
50+
-- Recreate the template_with_names view
51+
CREATE VIEW template_with_names AS
52+
SELECT
53+
templates.id,
54+
templates.created_at,
55+
templates.updated_at,
56+
templates.organization_id,
57+
templates.deleted,
58+
templates.name,
59+
templates.provisioner,
60+
templates.active_version_id,
61+
templates.description,
62+
templates.default_ttl,
63+
templates.created_by,
64+
templates.icon,
65+
templates.user_acl,
66+
templates.group_acl,
67+
templates.display_name,
68+
templates.allow_user_cancel_workspace_jobs,
69+
templates.allow_user_autostart,
70+
templates.allow_user_autostop,
71+
templates.failure_ttl,
72+
templates.time_til_dormant,
73+
templates.time_til_dormant_autodelete,
74+
templates.autostop_requirement_days_of_week,
75+
templates.autostop_requirement_weeks,
76+
templates.autostart_block_days_of_week,
77+
templates.require_active_version,
78+
templates.deprecated,
79+
templates.activity_bump,
80+
templates.max_port_sharing_level,
81+
templates.use_classic_parameter_flow,
82+
COALESCE(
83+
visible_users.avatar_url,
84+
''::text
85+
) AS created_by_avatar_url,
86+
COALESCE(
87+
visible_users.username,
88+
''::text
89+
) AS created_by_username,
90+
COALESCE(visible_users.name, ''::text) AS created_by_name,
91+
COALESCE(organizations.name, ''::text) AS organization_name,
92+
COALESCE(
93+
organizations.display_name,
94+
''::text
95+
) AS organization_display_name,
96+
COALESCE(organizations.icon, ''::text) AS organization_icon
97+
FROM (
98+
(
99+
templates
100+
LEFT JOIN visible_users ON (
101+
(
102+
templates.created_by = visible_users.id
103+
)
104+
)
105+
)
106+
LEFT JOIN organizations ON (
107+
(
108+
templates.organization_id = organizations.id
109+
)
110+
)
111+
);
112+
113+
COMMENT ON VIEW template_with_names IS 'Joins in the display name information such as username, avatar, and organization name.';
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
-- Add 'organization' to the app_sharing_level enum
2+
3+
-- Drop the view that depends on the templates table
4+
DROP VIEW template_with_names;
5+
6+
CREATE TYPE new_app_sharing_level AS ENUM (
7+
'owner',
8+
'authenticated',
9+
'organization',
10+
'public'
11+
);
12+
13+
-- Update workspace_agent_port_share table to use new enum
14+
ALTER TABLE workspace_agent_port_share
15+
ALTER COLUMN share_level TYPE new_app_sharing_level USING (share_level::text::new_app_sharing_level);
16+
17+
-- Update workspace_apps table to use new enum
18+
ALTER TABLE workspace_apps
19+
ALTER COLUMN sharing_level DROP DEFAULT,
20+
ALTER COLUMN sharing_level TYPE new_app_sharing_level USING (sharing_level::text::new_app_sharing_level),
21+
ALTER COLUMN sharing_level SET DEFAULT 'owner'::new_app_sharing_level;
22+
23+
-- Update templates table to use new enum
24+
ALTER TABLE templates
25+
ALTER COLUMN max_port_sharing_level DROP DEFAULT,
26+
ALTER COLUMN max_port_sharing_level TYPE new_app_sharing_level USING (max_port_sharing_level::text::new_app_sharing_level),
27+
ALTER COLUMN max_port_sharing_level SET DEFAULT 'owner'::new_app_sharing_level;
28+
29+
-- Drop old enum and rename new one
30+
DROP TYPE app_sharing_level;
31+
ALTER TYPE new_app_sharing_level RENAME TO app_sharing_level;
32+
33+
-- Recreate the template_with_names view
34+
CREATE VIEW template_with_names AS
35+
SELECT
36+
templates.id,
37+
templates.created_at,
38+
templates.updated_at,
39+
templates.organization_id,
40+
templates.deleted,
41+
templates.name,
42+
templates.provisioner,
43+
templates.active_version_id,
44+
templates.description,
45+
templates.default_ttl,
46+
templates.created_by,
47+
templates.icon,
48+
templates.user_acl,
49+
templates.group_acl,
50+
templates.display_name,
51+
templates.allow_user_cancel_workspace_jobs,
52+
templates.allow_user_autostart,
53+
templates.allow_user_autostop,
54+
templates.failure_ttl,
55+
templates.time_til_dormant,
56+
templates.time_til_dormant_autodelete,
57+
templates.autostop_requirement_days_of_week,
58+
templates.autostop_requirement_weeks,
59+
templates.autostart_block_days_of_week,
60+
templates.require_active_version,
61+
templates.deprecated,
62+
templates.activity_bump,
63+
templates.max_port_sharing_level,
64+
templates.use_classic_parameter_flow,
65+
COALESCE(
66+
visible_users.avatar_url,
67+
''::text
68+
) AS created_by_avatar_url,
69+
COALESCE(
70+
visible_users.username,
71+
''::text
72+
) AS created_by_username,
73+
COALESCE(visible_users.name, ''::text) AS created_by_name,
74+
COALESCE(organizations.name, ''::text) AS organization_name,
75+
COALESCE(
76+
organizations.display_name,
77+
''::text
78+
) AS organization_display_name,
79+
COALESCE(organizations.icon, ''::text) AS organization_icon
80+
FROM (
81+
(
82+
templates
83+
LEFT JOIN visible_users ON (
84+
(
85+
templates.created_by = visible_users.id
86+
)
87+
)
88+
)
89+
LEFT JOIN organizations ON (
90+
(
91+
templates.organization_id = organizations.id
92+
)
93+
)
94+
);
95+
96+
COMMENT ON VIEW template_with_names IS 'Joins in the display name information such as username, avatar, and organization name.';

coderd/database/models.go

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

coderd/workspaceapps/db.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,32 @@ func (p *DBTokenProvider) authorizeRequest(ctx context.Context, roles *rbac.Subj
316316
return false, warnings, nil
317317
}
318318

319+
// For organization level path-based apps, block access if path app sharing is disabled
320+
// and the user is not in the same organization
321+
if isPathApp &&
322+
sharingLevel == database.AppSharingLevelOrganization &&
323+
!p.DeploymentValues.Dangerous.AllowPathAppSharing.Value() {
324+
// Check if user is in the same organization as the workspace
325+
workspaceOrgID := dbReq.Workspace.OrganizationID
326+
inSameOrg := false
327+
expandedRoles, err := roles.Roles.Expand()
328+
if err != nil {
329+
return false, warnings, xerrors.Errorf("expand roles: %w", err)
330+
}
331+
for _, role := range expandedRoles {
332+
if _, ok := role.Org[workspaceOrgID.String()]; ok {
333+
inSameOrg = true
334+
break
335+
}
336+
}
337+
if !inSameOrg {
338+
if roles != nil && slices.Contains(roles.Roles.Names(), rbac.RoleOwner()) {
339+
warnings = append(warnings, "path-based apps with \"organization\" share level are only accessible by organization members (see --dangerous-allow-path-app-sharing)")
340+
}
341+
return false, warnings, nil
342+
}
343+
}
344+
319345
// Figure out which RBAC resource to check. For terminals we use execution
320346
// instead of application connect.
321347
var (
@@ -354,6 +380,27 @@ func (p *DBTokenProvider) authorizeRequest(ctx context.Context, roles *rbac.Subj
354380
if err == nil {
355381
return true, []string{}, nil
356382
}
383+
case database.AppSharingLevelOrganization:
384+
// Check if the user is a member of the same organization as the workspace
385+
// First check if they have permission to connect to their own workspace (enforces scopes)
386+
err := p.Authorizer.Authorize(ctx, *roles, rbacAction, rbacResourceOwned)
387+
if err != nil {
388+
return false, warnings, nil
389+
}
390+
391+
// Check if the user is a member of the workspace's organization
392+
workspaceOrgID := dbReq.Workspace.OrganizationID
393+
expandedRoles, err := roles.Roles.Expand()
394+
if err != nil {
395+
return false, warnings, xerrors.Errorf("expand roles: %w", err)
396+
}
397+
for _, role := range expandedRoles {
398+
if _, ok := role.Org[workspaceOrgID.String()]; ok {
399+
return true, []string{}, nil
400+
}
401+
}
402+
// User is not a member of the workspace's organization
403+
return false, warnings, nil
357404
case database.AppSharingLevelPublic:
358405
// We don't really care about scopes and stuff if it's public anyways.
359406
// Someone with a restricted-scope API key could just not submit the API

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy