Skip to content

Commit 08c4fd4

Browse files
committed
feat: restrict access links to workspace owner
1 parent 3878e64 commit 08c4fd4

File tree

4 files changed

+44
-26
lines changed

4 files changed

+44
-26
lines changed

site/src/components/Resources/Resources.tsx

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import TableHead from "@material-ui/core/TableHead"
66
import TableRow from "@material-ui/core/TableRow"
77
import useTheme from "@material-ui/styles/useTheme"
88
import { FC } from "react"
9-
import { Workspace, WorkspaceResource } from "../../api/typesGenerated"
9+
import { User, Workspace, WorkspaceResource } from "../../api/typesGenerated"
1010
import { getDisplayAgentStatus } from "../../util/workspace"
1111
import { AppLink } from "../AppLink/AppLink"
1212
import { Stack } from "../Stack/Stack"
@@ -27,9 +27,10 @@ interface ResourcesProps {
2727
resources?: WorkspaceResource[]
2828
getResourcesError?: Error
2929
workspace: Workspace
30+
user?: User
3031
}
3132

32-
export const Resources: FC<ResourcesProps> = ({ resources, getResourcesError, workspace }) => {
33+
export const Resources: FC<ResourcesProps> = ({ resources, getResourcesError, workspace, user }) => {
3334
const styles = useStyles()
3435
const theme: Theme = useTheme()
3536

@@ -43,7 +44,7 @@ export const Resources: FC<ResourcesProps> = ({ resources, getResourcesError, wo
4344
<TableHeaderRow>
4445
<TableCell>{Language.resourceLabel}</TableCell>
4546
<TableCell className={styles.agentColumn}>{Language.agentLabel}</TableCell>
46-
<TableCell>{Language.accessLabel}</TableCell>
47+
{user?.username === workspace.owner_name && <TableCell>{Language.accessLabel}</TableCell>}
4748
<TableCell>{Language.statusLabel}</TableCell>
4849
</TableHeaderRow>
4950
</TableHead>
@@ -84,28 +85,30 @@ export const Resources: FC<ResourcesProps> = ({ resources, getResourcesError, wo
8485
{agent.name}
8586
<span className={styles.operatingSystem}>{agent.operating_system}</span>
8687
</TableCell>
87-
<TableCell>
88-
<Stack>
89-
{agent.status === "connected" && (
90-
<TerminalLink
91-
className={styles.accessLink}
92-
workspaceName={workspace.name}
93-
agentName={agent.name}
94-
userName={workspace.owner_name}
95-
/>
96-
)}
97-
{agent.status === "connected" &&
98-
agent.apps.map((app) => (
99-
<AppLink
100-
key={app.name}
101-
appIcon={app.icon}
102-
appName={app.name}
103-
userName={workspace.owner_name}
88+
{user?.username === workspace.owner_name && (
89+
<TableCell>
90+
<Stack>
91+
{agent.status === "connected" && (
92+
<TerminalLink
93+
className={styles.accessLink}
10494
workspaceName={workspace.name}
95+
agentName={agent.name}
96+
userName={workspace.owner_name}
10597
/>
106-
))}
107-
</Stack>
108-
</TableCell>
98+
)}
99+
{agent.status === "connected" &&
100+
agent.apps.map((app) => (
101+
<AppLink
102+
key={app.name}
103+
appIcon={app.icon}
104+
appName={app.name}
105+
userName={workspace.owner_name}
106+
workspaceName={workspace.name}
107+
/>
108+
))}
109+
</Stack>
110+
</TableCell>
111+
)}
109112
<TableCell>
110113
<span style={{ color: getDisplayAgentStatus(theme, agent).color }}>
111114
{getDisplayAgentStatus(theme, agent).status}

site/src/components/Workspace/Workspace.stories.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ Started.args = {
2222
handleStop: action("stop"),
2323
resources: [Mocks.MockWorkspaceResource, Mocks.MockWorkspaceResource2],
2424
builds: [Mocks.MockWorkspaceBuild],
25+
user: Mocks.MockUser,
26+
}
27+
28+
export const OtherUser = Template.bind({})
29+
OtherUser.args = {
30+
...Started.args,
31+
user: Mocks.MockUser2,
2532
}
2633

2734
export const Starting = Template.bind({})

site/src/components/Workspace/Workspace.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export interface WorkspaceProps {
2626
resources?: TypesGen.WorkspaceResource[]
2727
getResourcesError?: Error
2828
builds?: TypesGen.WorkspaceBuild[]
29+
user?: TypesGen.User
2930
}
3031

3132
/**
@@ -42,6 +43,7 @@ export const Workspace: FC<WorkspaceProps> = ({
4243
resources,
4344
getResourcesError,
4445
builds,
46+
user,
4547
}) => {
4648
const styles = useStyles()
4749

@@ -84,7 +86,7 @@ export const Workspace: FC<WorkspaceProps> = ({
8486

8587
<WorkspaceStats workspace={workspace} />
8688

87-
<Resources resources={resources} getResourcesError={getResourcesError} workspace={workspace} />
89+
<Resources resources={resources} getResourcesError={getResourcesError} workspace={workspace} user={user} />
8890

8991
<WorkspaceSection title="Timeline" contentsProps={{ className: styles.timelineContents }}>
9092
<BuildsTable builds={builds} className={styles.timelineTable} />

site/src/pages/WorkspacePage/WorkspacePage.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { useMachine } from "@xstate/react"
2-
import React, { useEffect } from "react"
1+
import { useActor, useMachine } from "@xstate/react"
2+
import React, { useContext, useEffect } from "react"
33
import { Helmet } from "react-helmet"
44
import { useNavigate, useParams } from "react-router-dom"
55
import { DeleteWorkspaceDialog } from "../../components/DeleteWorkspaceDialog/DeleteWorkspaceDialog"
@@ -10,6 +10,7 @@ import { Stack } from "../../components/Stack/Stack"
1010
import { Workspace } from "../../components/Workspace/Workspace"
1111
import { firstOrItem } from "../../util/array"
1212
import { pageTitle } from "../../util/page"
13+
import { XServiceContext } from "../../xServices/StateContext"
1314
import { workspaceMachine } from "../../xServices/workspace/workspaceXService"
1415
import { workspaceScheduleBannerMachine } from "../../xServices/workspaceSchedule/workspaceScheduleBannerXService"
1516

@@ -24,6 +25,10 @@ export const WorkspacePage: React.FC = () => {
2425

2526
const [bannerState, bannerSend] = useMachine(workspaceScheduleBannerMachine)
2627

28+
const xServices = useContext(XServiceContext)
29+
const [authState, _] = useActor(xServices.authXService)
30+
const { me } = authState.context
31+
2732
/**
2833
* Get workspace, template, and organization on mount and whenever workspaceId changes.
2934
* workspaceSend should not change.
@@ -60,6 +65,7 @@ export const WorkspacePage: React.FC = () => {
6065
resources={resources}
6166
getResourcesError={getResourcesError instanceof Error ? getResourcesError : undefined}
6267
builds={builds}
68+
user={me}
6369
/>
6470
<DeleteWorkspaceDialog
6571
isOpen={workspaceState.matches({ ready: { build: "askingDelete" } })}

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