Skip to content

Commit e18cc8b

Browse files
fix: [M3-10458] - IAM incorrect tags permission on Linode details page (linode#12674)
* fix tags permission * Added changeset: Incorrect tags permission check on Linode details page * update unit test * clean up comment --------- Co-authored-by: Banks Nussman <[email protected]>
1 parent 63f22d9 commit e18cc8b

File tree

3 files changed

+43
-24
lines changed

3 files changed

+43
-24
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Fixed
3+
---
4+
5+
Incorrect tags permission check on Linode details page ([#12674](https://github.com/linode/manager/pull/12674))
Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
import * as React from 'react';
1+
import { profileFactory } from '@linode/utilities';
2+
import { waitFor } from '@testing-library/react';
3+
import React from 'react';
24

5+
import { http, HttpResponse, server } from 'src/mocks/testServer';
36
import { renderWithTheme } from 'src/utilities/testHelpers';
47

58
import { LinodeEntityDetailFooter } from './LinodeEntityDetailFooter';
@@ -13,40 +16,48 @@ const props = {
1316
linodeTags: ['test', 'linode'],
1417
};
1518

16-
const queryMocks = vi.hoisted(() => ({
17-
userPermissions: vi.fn(() => ({
18-
data: { update_account: false },
19-
})),
20-
}));
19+
describe('LinodeEntityDetailFooter', () => {
20+
it('should disable the "Add a tag" button by default', async () => {
21+
const { getByRole } = renderWithTheme(
22+
<LinodeEntityDetailFooter {...props} />
23+
);
2124

22-
vi.mock('src/features/IAM/hooks/usePermissions', () => ({
23-
usePermissions: queryMocks.userPermissions,
24-
}));
25+
expect(getByRole('button', { name: 'Add a tag' })).toBeDisabled();
26+
});
27+
28+
it('should enable the "Add a tag" button if the user is unrestricted (legacy grants)', async () => {
29+
server.use(
30+
http.get('*/v4*/profile', () =>
31+
HttpResponse.json(profileFactory.build({ restricted: false }))
32+
)
33+
);
2534

26-
describe('LinodeEntityDetailFooter', () => {
27-
it('should disable "Add a tag" button if the user does not have update_account permission', async () => {
2835
const { getByRole } = renderWithTheme(
2936
<LinodeEntityDetailFooter {...props} />
3037
);
3138

32-
const addTagBtn = getByRole('button', {
33-
name: 'Add a tag',
39+
await waitFor(() => {
40+
expect(getByRole('button', { name: 'Add a tag' })).toBeEnabled();
3441
});
35-
expect(addTagBtn).toHaveAttribute('aria-disabled', 'true');
3642
});
3743

38-
it('should enable "Add a tag" button if the user has update_account permission', async () => {
39-
queryMocks.userPermissions.mockReturnValue({
40-
data: { update_account: true },
41-
});
44+
it('should enable the "Add a tag" button if the user is an account admin (IAM)', async () => {
45+
server.use(
46+
http.get('*/v4*/profile', () =>
47+
HttpResponse.json(profileFactory.build({ restricted: true }))
48+
),
49+
http.get('*/v4*/iam/users/:username/permissions/account', () =>
50+
HttpResponse.json(['is_account_admin'])
51+
)
52+
);
4253

4354
const { getByRole } = renderWithTheme(
44-
<LinodeEntityDetailFooter {...props} />
55+
<LinodeEntityDetailFooter {...props} />,
56+
{ flags: { iam: { enabled: true, beta: true } } }
4557
);
4658

47-
const addTagBtn = getByRole('button', {
48-
name: 'Add a tag',
59+
await waitFor(() => {
60+
expect(getByRole('button', { name: 'Add a tag' })).toBeEnabled();
4961
});
50-
expect(addTagBtn).not.toHaveAttribute('aria-disabled', 'true');
5162
});
5263
});

packages/manager/src/features/Linodes/LinodeEntityDetailFooter.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const LinodeEntityDetailFooter = React.memo((props: FooterProps) => {
4040
linodeTags,
4141
} = props;
4242

43-
const { data: permissions } = usePermissions('account', ['update_account']);
43+
const { data: permissions } = usePermissions('account', ['is_account_admin']);
4444

4545
const { mutateAsync: updateLinode } = useLinodeUpdateMutation(linodeId);
4646

@@ -143,7 +143,10 @@ export const LinodeEntityDetailFooter = React.memo((props: FooterProps) => {
143143
}}
144144
>
145145
<TagCell
146-
disabled={!permissions.update_account}
146+
// A restricted user can technically add tags to a Linode if they have read-write permission on the Linode,
147+
// but for the sake of the user experience, we choose to disable the "Add a tag" button in the UI because
148+
// restricted users can't see account tags using GET /v4/tags
149+
disabled={!permissions.is_account_admin}
147150
entityLabel={linodeLabel}
148151
sx={{
149152
width: '100%',

0 commit comments

Comments
 (0)