Skip to content

Commit ccfe1bd

Browse files
authored
fix: fix permissions for workspace creation (#17241)
This fixes the permissions check when creating a workspace by setting the owner_id to the current user's id. This was originally setting owner_id to * ``` createWorkspace: { object: { resource_type: "workspace", organization_id: organizationId, owner_id: userId, }, action: "create", }, ```
1 parent b61f0ab commit ccfe1bd

File tree

12 files changed

+54
-36
lines changed

12 files changed

+54
-36
lines changed

site/src/api/queries/organizations.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ export const organizationsPermissions = (
306306

307307
export const workspacePermissionsByOrganization = (
308308
organizationIds: string[] | undefined,
309+
userId: string,
309310
) => {
310311
if (!organizationIds) {
311312
return { enabled: false };
@@ -315,10 +316,9 @@ export const workspacePermissionsByOrganization = (
315316
queryKey: ["workspaces", organizationIds.sort(), "permissions"],
316317
queryFn: async () => {
317318
const prefixedChecks = organizationIds.flatMap((orgId) =>
318-
Object.entries(workspacePermissionChecks(orgId)).map(([key, val]) => [
319-
`${orgId}.${key}`,
320-
val,
321-
]),
319+
Object.entries(workspacePermissionChecks(orgId, userId)).map(
320+
([key, val]) => [`${orgId}.${key}`, val],
321+
),
322322
);
323323

324324
const response = await API.checkAuthorization({

site/src/modules/permissions/workspaces.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
export const workspacePermissionChecks = (organizationId: string) =>
1+
export const workspacePermissionChecks = (
2+
organizationId: string,
3+
userId: string,
4+
) =>
25
({
3-
createWorkspaceForUser: {
6+
createWorkspace: {
47
object: {
58
resource_type: "workspace",
69
organization_id: organizationId,
7-
owner_id: "*",
10+
owner_id: userId,
811
},
912
action: "create",
1013
},

site/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ import { Loader } from "components/Loader/Loader";
1717
import { useAuthenticated } from "contexts/auth/RequireAuth";
1818
import { useEffectEvent } from "hooks/hookPolyfills";
1919
import { useDashboard } from "modules/dashboard/useDashboard";
20-
import {
21-
type WorkspacePermissions,
22-
workspacePermissionChecks,
23-
} from "modules/permissions/workspaces";
2420
import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName";
2521
import { type FC, useCallback, useEffect, useRef, useState } from "react";
2622
import { Helmet } from "react-helmet-async";
@@ -30,6 +26,7 @@ import { pageTitle } from "utils/page";
3026
import type { AutofillBuildParameter } from "utils/richParameters";
3127
import { paramsUsedToCreateWorkspace } from "utils/workspace";
3228
import { CreateWorkspacePageView } from "./CreateWorkspacePageView";
29+
import { type CreateWSPermissions, createWorkspaceChecks } from "./permissions";
3330

3431
export const createWorkspaceModes = ["form", "auto", "duplicate"] as const;
3532
export type CreateWorkspaceMode = (typeof createWorkspaceModes)[number];
@@ -67,7 +64,7 @@ const CreateWorkspacePage: FC = () => {
6764
const permissionsQuery = useQuery(
6865
templateQuery.data
6966
? checkAuthorization({
70-
checks: workspacePermissionChecks(templateQuery.data.organization_id),
67+
checks: createWorkspaceChecks(templateQuery.data.organization_id),
7168
})
7269
: { enabled: false },
7370
);
@@ -209,7 +206,7 @@ const CreateWorkspacePage: FC = () => {
209206
externalAuthPollingState={externalAuthPollingState}
210207
startPollingExternalAuth={startPollingExternalAuth}
211208
hasAllRequiredExternalAuth={hasAllRequiredExternalAuth}
212-
permissions={permissionsQuery.data as WorkspacePermissions}
209+
permissions={permissionsQuery.data as CreateWSPermissions}
213210
parameters={realizedParameters as TemplateVersionParameter[]}
214211
presets={templateVersionPresetsQuery.data ?? []}
215212
creatingWorkspace={createWorkspaceMutation.isLoading}

site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import { Stack } from "components/Stack/Stack";
2828
import { Switch } from "components/Switch/Switch";
2929
import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete";
3030
import { type FormikContextType, useFormik } from "formik";
31-
import type { WorkspacePermissions } from "modules/permissions/workspaces";
3231
import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName";
3332
import { type FC, useCallback, useEffect, useMemo, useState } from "react";
3433
import {
@@ -47,7 +46,7 @@ import type {
4746
ExternalAuthPollingState,
4847
} from "./CreateWorkspacePage";
4948
import { ExternalAuthButton } from "./ExternalAuthButton";
50-
49+
import type { CreateWSPermissions } from "./permissions";
5150
export const Language = {
5251
duplicationWarning:
5352
"Duplicating a workspace only copies its parameters. No state from the old workspace is copied over.",
@@ -69,7 +68,7 @@ export interface CreateWorkspacePageViewProps {
6968
parameters: TypesGen.TemplateVersionParameter[];
7069
autofillParameters: AutofillBuildParameter[];
7170
presets: TypesGen.Preset[];
72-
permissions: WorkspacePermissions;
71+
permissions: CreateWSPermissions;
7372
creatingWorkspace: boolean;
7473
onCancel: () => void;
7574
onSubmit: (
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export const createWorkspaceChecks = (organizationId: string) =>
2+
({
3+
createWorkspaceForUser: {
4+
object: {
5+
resource_type: "workspace",
6+
organization_id: organizationId,
7+
owner_id: "*",
8+
},
9+
action: "create",
10+
},
11+
}) as const;
12+
13+
export type CreateWSPermissions = Record<
14+
keyof ReturnType<typeof createWorkspaceChecks>,
15+
boolean
16+
>;

site/src/pages/TemplatePage/TemplateLayout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ErrorAlert } from "components/Alert/ErrorAlert";
55
import { Loader } from "components/Loader/Loader";
66
import { Margins } from "components/Margins/Margins";
77
import { TabLink, Tabs, TabsList } from "components/Tabs/Tabs";
8+
import { useAuthenticated } from "contexts/auth/RequireAuth";
89
import { workspacePermissionChecks } from "modules/permissions/workspaces";
910
import {
1011
type FC,
@@ -73,6 +74,7 @@ export const TemplateLayout: FC<PropsWithChildren> = ({
7374
children = <Outlet />,
7475
}) => {
7576
const navigate = useNavigate();
77+
const { user: me } = useAuthenticated();
7678
const { organization: organizationName = "default", template: templateName } =
7779
useParams() as { organization?: string; template: string };
7880
const { data, error, isLoading } = useQuery({
@@ -81,7 +83,7 @@ export const TemplateLayout: FC<PropsWithChildren> = ({
8183
});
8284
const workspacePermissionsQuery = useQuery(
8385
checkAuthorization({
84-
checks: workspacePermissionChecks(organizationName),
86+
checks: workspacePermissionChecks(organizationName, me.id),
8587
}),
8688
);
8789

site/src/pages/TemplatePage/TemplatePageHeader.stories.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const meta: Meta<typeof TemplatePageHeader> = {
1414
canUpdateTemplate: true,
1515
},
1616
workspacePermissions: {
17-
createWorkspaceForUser: true,
17+
createWorkspace: true,
1818
},
1919
},
2020
};
@@ -35,7 +35,7 @@ export const CanNotUpdate: Story = {
3535
export const CannotCreateWorkspace: Story = {
3636
args: {
3737
workspacePermissions: {
38-
createWorkspaceForUser: false,
38+
createWorkspace: false,
3939
},
4040
},
4141
};

site/src/pages/TemplatePage/TemplatePageHeader.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -179,17 +179,16 @@ export const TemplatePageHeader: FC<TemplatePageHeaderProps> = ({
179179
<PageHeader
180180
actions={
181181
<>
182-
{!template.deprecated &&
183-
workspacePermissions.createWorkspaceForUser && (
184-
<Button
185-
variant="contained"
186-
startIcon={<AddIcon />}
187-
component={RouterLink}
188-
to={`${templateLink}/workspace`}
189-
>
190-
Create Workspace
191-
</Button>
192-
)}
182+
{!template.deprecated && workspacePermissions.createWorkspace && (
183+
<Button
184+
variant="contained"
185+
startIcon={<AddIcon />}
186+
component={RouterLink}
187+
to={`${templateLink}/workspace`}
188+
>
189+
Create Workspace
190+
</Button>
191+
)}
193192

194193
{permissions.canUpdateTemplate && (
195194
<TemplateMenu

site/src/pages/TemplatesPage/TemplatesPage.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { pageTitle } from "utils/page";
1111
import { TemplatesPageView } from "./TemplatesPageView";
1212

1313
export const TemplatesPage: FC = () => {
14-
const { permissions } = useAuthenticated();
14+
const { permissions, user: me } = useAuthenticated();
1515
const { showOrganizations } = useDashboard();
1616

1717
const searchParamsResult = useSearchParams();
@@ -30,6 +30,7 @@ export const TemplatesPage: FC = () => {
3030
const workspacePermissionsQuery = useQuery(
3131
workspacePermissionsByOrganization(
3232
templatesQuery.data?.map((template) => template.organization_id),
33+
me.id,
3334
),
3435
);
3536

site/src/pages/TemplatesPage/TemplatesPageView.stories.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export const WithTemplates: Story = {
7676
examples: [],
7777
workspacePermissions: {
7878
[MockTemplate.organization_id]: {
79-
createWorkspaceForUser: true,
79+
createWorkspace: true,
8080
},
8181
},
8282
},
@@ -94,7 +94,7 @@ export const CannotCreateWorkspaces: Story = {
9494
...WithTemplates.args,
9595
workspacePermissions: {
9696
[MockTemplate.organization_id]: {
97-
createWorkspaceForUser: false,
97+
createWorkspace: false,
9898
},
9999
},
100100
},

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