@scality/data-browser-library 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/__tests__/BucketOverview.test.js +94 -9
- package/dist/components/buckets/BucketList.js +2 -1
- package/dist/components/buckets/BucketOverview.js +98 -13
- package/dist/components/buckets/EmptyBucketButton.js +5 -2
- package/dist/components/buckets/PublicAccessBlock.d.ts +18 -0
- package/dist/components/buckets/PublicAccessBlock.js +113 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +2 -1
- package/dist/hooks/bucketConfiguration.d.ts +3 -1
- package/dist/hooks/bucketConfiguration.js +9 -2
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +2 -2
- package/dist/test/msw/handlers/getPublicAccessBlock.d.ts +2 -0
- package/dist/test/msw/handlers/getPublicAccessBlock.js +50 -0
- package/dist/test/msw/handlers.js +4 -1
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { fireEvent, render, screen } from "@testing-library/react";
|
|
2
|
+
import { fireEvent, render, screen, within } from "@testing-library/react";
|
|
3
3
|
import { MemoryRouter } from "react-router";
|
|
4
|
-
import { useGetBucketAcl, useGetBucketCors, useGetBucketLocation, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketTagging, useGetBucketVersioning, useISVBucketStatus } from "../../hooks/index.js";
|
|
4
|
+
import { useGetBucketAcl, useGetBucketCors, useGetBucketLocation, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketTagging, useGetBucketVersioning, useGetPublicAccessBlock, useISVBucketStatus, usePutPublicAccessBlock, useSetBucketAcl } from "../../hooks/index.js";
|
|
5
5
|
import { useFeatures } from "../../hooks/useFeatures.js";
|
|
6
|
-
import { applyBucketMocks, createTestWrapper } from "../../test/testUtils.js";
|
|
6
|
+
import { applyBucketMocks, createMockMutationResult, createTestWrapper } from "../../test/testUtils.js";
|
|
7
7
|
import { EnhancedS3Error, ErrorCategory } from "../../utils/errorHandling.js";
|
|
8
8
|
import { BucketOverview, useBucketOverviewContext } from "../buckets/BucketOverview.js";
|
|
9
9
|
import * as __rspack_external__contexts_DataBrowserUICustomizationContext_js_f267b01c from "../../contexts/DataBrowserUICustomizationContext.js";
|
|
@@ -16,6 +16,9 @@ const mockUseGetBucketCors = jest.mocked(useGetBucketCors);
|
|
|
16
16
|
const mockUseGetBucketObjectLockConfiguration = jest.mocked(useGetBucketObjectLockConfiguration);
|
|
17
17
|
const mockUseGetBucketPolicy = jest.mocked(useGetBucketPolicy);
|
|
18
18
|
const mockUseGetBucketTagging = jest.mocked(useGetBucketTagging);
|
|
19
|
+
const mockUseGetPublicAccessBlock = jest.mocked(useGetPublicAccessBlock);
|
|
20
|
+
const mockUsePutPublicAccessBlock = jest.mocked(usePutPublicAccessBlock);
|
|
21
|
+
const mockUseSetBucketAcl = jest.mocked(useSetBucketAcl);
|
|
19
22
|
const mockUseISVBucketStatus = jest.mocked(useISVBucketStatus);
|
|
20
23
|
const mockUseFeatures = jest.mocked(useFeatures);
|
|
21
24
|
const mockUseDataBrowserUICustomization = (config = {})=>{
|
|
@@ -69,6 +72,20 @@ describe('BucketOverview', ()=>{
|
|
|
69
72
|
jest.clearAllMocks();
|
|
70
73
|
mockHookDefaults();
|
|
71
74
|
mockUseDataBrowserUICustomization({});
|
|
75
|
+
mockUseGetPublicAccessBlock.mockReturnValue({
|
|
76
|
+
data: {
|
|
77
|
+
PublicAccessBlockConfiguration: {
|
|
78
|
+
BlockPublicAcls: false,
|
|
79
|
+
IgnorePublicAcls: false,
|
|
80
|
+
BlockPublicPolicy: false,
|
|
81
|
+
RestrictPublicBuckets: false
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
status: 'success',
|
|
85
|
+
error: null
|
|
86
|
+
});
|
|
87
|
+
mockUsePutPublicAccessBlock.mockReturnValue(createMockMutationResult(jest.fn()));
|
|
88
|
+
mockUseSetBucketAcl.mockReturnValue(createMockMutationResult(jest.fn()));
|
|
72
89
|
});
|
|
73
90
|
it('renders bucket overview with all sections', ()=>{
|
|
74
91
|
renderBucketOverview();
|
|
@@ -100,7 +117,9 @@ describe('BucketOverview', ()=>{
|
|
|
100
117
|
status: 'success'
|
|
101
118
|
});
|
|
102
119
|
renderBucketOverview();
|
|
103
|
-
|
|
120
|
+
const versioningLabel = screen.getByText('Versioning');
|
|
121
|
+
const row = versioningLabel.closest('[class]').parentElement;
|
|
122
|
+
expect(within(row).getByText('Inactive')).toBeInTheDocument();
|
|
104
123
|
});
|
|
105
124
|
it('displays bucket location', ()=>{
|
|
106
125
|
mockUseGetBucketLocation.mockReturnValue({
|
|
@@ -156,7 +175,9 @@ describe('BucketOverview', ()=>{
|
|
|
156
175
|
status: 'success'
|
|
157
176
|
});
|
|
158
177
|
renderBucketOverview();
|
|
159
|
-
|
|
178
|
+
const retentionLabel = screen.getByText('Default Retention');
|
|
179
|
+
const row = retentionLabel.closest('[class]').parentElement;
|
|
180
|
+
expect(within(row).getByText('Inactive')).toBeInTheDocument();
|
|
160
181
|
});
|
|
161
182
|
it('shows default retention with days in Governance mode', ()=>{
|
|
162
183
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
@@ -378,7 +399,9 @@ describe('BucketOverview', ()=>{
|
|
|
378
399
|
status: 'success'
|
|
379
400
|
});
|
|
380
401
|
renderBucketOverview();
|
|
381
|
-
|
|
402
|
+
const publicToggle = document.getElementById('publicToggle');
|
|
403
|
+
expect(publicToggle).toBeInTheDocument();
|
|
404
|
+
expect(publicToggle).toBeChecked();
|
|
382
405
|
});
|
|
383
406
|
it('shows non-public bucket when no public grants', ()=>{
|
|
384
407
|
mockUseGetBucketAcl.mockReturnValue({
|
|
@@ -398,8 +421,68 @@ describe('BucketOverview', ()=>{
|
|
|
398
421
|
status: 'success'
|
|
399
422
|
});
|
|
400
423
|
renderBucketOverview();
|
|
401
|
-
const
|
|
402
|
-
expect(
|
|
424
|
+
const publicToggle = document.getElementById('publicToggle');
|
|
425
|
+
expect(publicToggle).toBeInTheDocument();
|
|
426
|
+
expect(publicToggle).not.toBeChecked();
|
|
427
|
+
});
|
|
428
|
+
it('shows disabled toggle and warning when IgnorePublicAcls blocks public access', ()=>{
|
|
429
|
+
mockUseGetBucketAcl.mockReturnValue({
|
|
430
|
+
data: {
|
|
431
|
+
Owner: {
|
|
432
|
+
DisplayName: 'owner'
|
|
433
|
+
},
|
|
434
|
+
Grants: [
|
|
435
|
+
{
|
|
436
|
+
Grantee: {
|
|
437
|
+
URI: 'http://acs.amazonaws.com/groups/global/AllUsers'
|
|
438
|
+
},
|
|
439
|
+
Permission: 'READ'
|
|
440
|
+
}
|
|
441
|
+
]
|
|
442
|
+
},
|
|
443
|
+
status: 'success'
|
|
444
|
+
});
|
|
445
|
+
mockUseGetPublicAccessBlock.mockReturnValue({
|
|
446
|
+
data: {
|
|
447
|
+
PublicAccessBlockConfiguration: {
|
|
448
|
+
BlockPublicAcls: true,
|
|
449
|
+
IgnorePublicAcls: true,
|
|
450
|
+
BlockPublicPolicy: false,
|
|
451
|
+
RestrictPublicBuckets: false
|
|
452
|
+
}
|
|
453
|
+
},
|
|
454
|
+
status: 'success',
|
|
455
|
+
error: null
|
|
456
|
+
});
|
|
457
|
+
renderBucketOverview();
|
|
458
|
+
const publicToggle = document.getElementById('publicToggle');
|
|
459
|
+
expect(publicToggle).toBeInTheDocument();
|
|
460
|
+
expect(publicToggle).not.toBeChecked();
|
|
461
|
+
expect(publicToggle).toBeDisabled();
|
|
462
|
+
expect(screen.getByText('Public access blocked by advanced settings below.')).toBeInTheDocument();
|
|
463
|
+
});
|
|
464
|
+
it('shows PAB collapsible section when PAB is supported', ()=>{
|
|
465
|
+
renderBucketOverview();
|
|
466
|
+
expect(screen.getByText('Public Access Block (PAB)')).toBeInTheDocument();
|
|
467
|
+
});
|
|
468
|
+
it('hides PAB section when API returns 501', ()=>{
|
|
469
|
+
mockUseGetPublicAccessBlock.mockReturnValue({
|
|
470
|
+
data: void 0,
|
|
471
|
+
status: 'error',
|
|
472
|
+
error: {
|
|
473
|
+
statusCode: 501
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
renderBucketOverview();
|
|
477
|
+
expect(screen.queryByText('Public Access Block (PAB)')).not.toBeInTheDocument();
|
|
478
|
+
});
|
|
479
|
+
it('expands PAB section and shows 4 toggles', ()=>{
|
|
480
|
+
renderBucketOverview();
|
|
481
|
+
fireEvent.click(screen.getByText('Public Access Block (PAB)'));
|
|
482
|
+
expect(screen.getByText('BlockPublicAcls')).toBeInTheDocument();
|
|
483
|
+
expect(screen.getByText('IgnorePublicAcls')).toBeInTheDocument();
|
|
484
|
+
expect(screen.getByText('BlockPublicPolicy')).toBeInTheDocument();
|
|
485
|
+
expect(screen.getByText('RestrictPublicBuckets')).toBeInTheDocument();
|
|
403
486
|
});
|
|
404
487
|
it('shows loading states while data is being fetched', ()=>{
|
|
405
488
|
mockUseGetBucketVersioning.mockReturnValue({
|
|
@@ -516,7 +599,9 @@ describe('BucketOverview', ()=>{
|
|
|
516
599
|
status: 'success'
|
|
517
600
|
});
|
|
518
601
|
renderBucketOverview();
|
|
519
|
-
|
|
602
|
+
const versioningLabel = screen.getByText('Versioning');
|
|
603
|
+
const row = versioningLabel.closest('[class]').parentElement;
|
|
604
|
+
expect(within(row).getByText('Inactive')).toBeInTheDocument();
|
|
520
605
|
});
|
|
521
606
|
it('handles CORS error state', ()=>{
|
|
522
607
|
mockUseGetBucketCors.mockReturnValue({
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { ConstrainedText, Icon, Loader, Stack, spacing } from "@scality/core-ui";
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ConstrainedText, Icon, Loader, Stack, Text, Toggle, Tooltip, spacing, useToast } from "@scality/core-ui";
|
|
3
3
|
import { Box, Button } from "@scality/core-ui/dist/next";
|
|
4
|
-
import { createContext, memo, useContext, useMemo } from "react";
|
|
4
|
+
import { Fragment as external_react_Fragment, createContext, memo, useCallback, useContext, useMemo } from "react";
|
|
5
5
|
import { useDataBrowserUICustomization } from "../../contexts/DataBrowserUICustomizationContext.js";
|
|
6
|
-
import { useGetBucketAcl, useGetBucketCors, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketVersioning, useISVBucketStatus } from "../../hooks/index.js";
|
|
6
|
+
import { useGetBucketAcl, useGetBucketCors, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketVersioning, useISVBucketStatus, useSetBucketAcl } from "../../hooks/index.js";
|
|
7
7
|
import { isNotFoundError } from "../../utils/errorHandling.js";
|
|
8
8
|
import { EditRetentionButton } from "../objects/ObjectLock/EditRetentionButton.js";
|
|
9
9
|
import { useDataBrowserConfig } from "../providers/DataBrowserProvider.js";
|
|
10
10
|
import { Body, Group, GroupContent, GroupName, GroupValues, Key, Row, Table, TableContainer, Value } from "../ui/Table.elements.js";
|
|
11
11
|
import { BucketConfigEditButton } from "./BucketConfigEditButton.js";
|
|
12
12
|
import { BucketLocation } from "./BucketLocation.js";
|
|
13
|
+
import { PublicAccessBlock, usePublicAccessBlockStatus } from "./PublicAccessBlock.js";
|
|
13
14
|
const DEFAULT_PUBLIC_ACL_URI = 'http://acs.amazonaws.com/groups/global/AllUsers';
|
|
14
15
|
const STATUS_PENDING = 'pending';
|
|
15
16
|
const STATUS_ERROR = 'error';
|
|
@@ -189,8 +190,26 @@ const createCorsField = (bucketName, corsData, corsStatus, corsError, onEditCors
|
|
|
189
190
|
})
|
|
190
191
|
};
|
|
191
192
|
};
|
|
192
|
-
const createPublicField = (bucketName, aclStatus, isPublic, publicField, renderPublic)=>{
|
|
193
|
-
|
|
193
|
+
const createPublicField = ({ bucketName, aclStatus, isPublic, pabStatus, onPublicToggle, publicField, renderPublic })=>{
|
|
194
|
+
let defaultValue;
|
|
195
|
+
if (aclStatus === STATUS_PENDING || pabStatus.isPending) defaultValue = /*#__PURE__*/ jsx(Loader, {});
|
|
196
|
+
else {
|
|
197
|
+
const isDisabled = !pabStatus.isNotImplemented && (pabStatus.isPublicIgnored || pabStatus.isSettingPublicBlocked && !isPublic);
|
|
198
|
+
const toggleElement = /*#__PURE__*/ jsx(Toggle, {
|
|
199
|
+
id: "publicToggle",
|
|
200
|
+
disabled: isDisabled,
|
|
201
|
+
toggle: isPublic,
|
|
202
|
+
label: isPublic ? 'Yes' : 'No',
|
|
203
|
+
onChange: ()=>onPublicToggle?.()
|
|
204
|
+
});
|
|
205
|
+
defaultValue = isDisabled ? /*#__PURE__*/ jsx(Tooltip, {
|
|
206
|
+
overlay: "Public access is blocked by Public Access Block settings",
|
|
207
|
+
children: /*#__PURE__*/ jsx(Box, {
|
|
208
|
+
display: "inline-block",
|
|
209
|
+
children: toggleElement
|
|
210
|
+
})
|
|
211
|
+
}) : toggleElement;
|
|
212
|
+
}
|
|
194
213
|
return {
|
|
195
214
|
id: 'public',
|
|
196
215
|
label: 'Public',
|
|
@@ -434,16 +453,54 @@ const PermissionsSection = /*#__PURE__*/ memo(({ onEditPolicy, onEditCors, owner
|
|
|
434
453
|
const { data: policyData, error: policyError, status: policyStatus } = useGetBucketPolicy({
|
|
435
454
|
Bucket: bucketName
|
|
436
455
|
});
|
|
437
|
-
const
|
|
456
|
+
const pabStatus = usePublicAccessBlockStatus(bucketName);
|
|
457
|
+
const { mutate: setBucketAcl } = useSetBucketAcl();
|
|
458
|
+
const { showToast } = useToast();
|
|
459
|
+
const hasPublicAcl = useMemo(()=>aclData?.Grants?.some((grant)=>grant.Grantee?.URI === (config.publicAclIndicator || DEFAULT_PUBLIC_ACL_URI)) ?? false, [
|
|
438
460
|
aclData?.Grants,
|
|
439
461
|
config.publicAclIndicator
|
|
440
462
|
]);
|
|
463
|
+
const isPublic = hasPublicAcl && !pabStatus.isPublicIgnored;
|
|
464
|
+
const handlePublicToggle = useCallback(()=>{
|
|
465
|
+
setBucketAcl({
|
|
466
|
+
Bucket: bucketName,
|
|
467
|
+
ACL: isPublic ? 'private' : 'public-read'
|
|
468
|
+
}, {
|
|
469
|
+
onSuccess: ()=>{
|
|
470
|
+
showToast({
|
|
471
|
+
open: true,
|
|
472
|
+
message: `Bucket is now ${isPublic ? 'private' : 'public'}`,
|
|
473
|
+
status: 'success'
|
|
474
|
+
});
|
|
475
|
+
},
|
|
476
|
+
onError: (error)=>{
|
|
477
|
+
showToast({
|
|
478
|
+
open: true,
|
|
479
|
+
message: error instanceof Error ? error.message : 'Failed to update bucket visibility',
|
|
480
|
+
status: 'error'
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
}, [
|
|
485
|
+
bucketName,
|
|
486
|
+
isPublic,
|
|
487
|
+
setBucketAcl,
|
|
488
|
+
showToast
|
|
489
|
+
]);
|
|
441
490
|
const fields = useMemo(()=>{
|
|
442
491
|
const defaultFields = {
|
|
443
492
|
owner: createOwnerField(bucketName, aclData, aclStatus, ownerField, renderOwner),
|
|
444
493
|
acl: createAclField(bucketName, aclData, aclStatus, aclField, renderAcl),
|
|
445
494
|
cors: createCorsField(bucketName, corsData, corsStatus, corsError, onEditCors, corsField, renderCors, isISVManaged, isvApplication),
|
|
446
|
-
public: createPublicField(
|
|
495
|
+
public: createPublicField({
|
|
496
|
+
bucketName,
|
|
497
|
+
aclStatus,
|
|
498
|
+
isPublic,
|
|
499
|
+
pabStatus,
|
|
500
|
+
onPublicToggle: handlePublicToggle,
|
|
501
|
+
publicField,
|
|
502
|
+
renderPublic
|
|
503
|
+
}),
|
|
447
504
|
bucketPolicy: createBucketPolicyField(bucketName, policyData, policyStatus, policyError, onEditPolicy, bucketPolicyField, renderBucketPolicy, isISVManaged, isvApplication)
|
|
448
505
|
};
|
|
449
506
|
return mergeFieldsWithExtras(defaultFields, extraBucketOverviewPermissions, bucketName, [
|
|
@@ -478,14 +535,42 @@ const PermissionsSection = /*#__PURE__*/ memo(({ onEditPolicy, onEditCors, owner
|
|
|
478
535
|
policyStatus,
|
|
479
536
|
isPublic,
|
|
480
537
|
isISVManaged,
|
|
481
|
-
isvApplication
|
|
538
|
+
isvApplication,
|
|
539
|
+
pabStatus,
|
|
540
|
+
handlePublicToggle
|
|
482
541
|
]);
|
|
542
|
+
const showPab = !pabStatus.isNotImplemented && !pabStatus.isPending;
|
|
483
543
|
return /*#__PURE__*/ jsx(Section, {
|
|
484
544
|
title: "Permissions",
|
|
485
|
-
children: fields.map((field)=>/*#__PURE__*/
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
545
|
+
children: fields.map((field)=>/*#__PURE__*/ jsxs(external_react_Fragment, {
|
|
546
|
+
children: [
|
|
547
|
+
/*#__PURE__*/ jsx(Field, {
|
|
548
|
+
label: field.label,
|
|
549
|
+
actions: field.actions,
|
|
550
|
+
children: field.value
|
|
551
|
+
}),
|
|
552
|
+
'public' === field.id && showPab && /*#__PURE__*/ jsxs(Fragment, {
|
|
553
|
+
children: [
|
|
554
|
+
(pabStatus.isPublicIgnored || pabStatus.isSettingPublicBlocked && !isPublic) && /*#__PURE__*/ jsxs(Row, {
|
|
555
|
+
children: [
|
|
556
|
+
/*#__PURE__*/ jsx(Key, {}),
|
|
557
|
+
/*#__PURE__*/ jsx(Value, {
|
|
558
|
+
children: /*#__PURE__*/ jsx(Text, {
|
|
559
|
+
color: "statusWarning",
|
|
560
|
+
variant: "Small",
|
|
561
|
+
children: "Public access blocked by advanced settings below."
|
|
562
|
+
})
|
|
563
|
+
})
|
|
564
|
+
]
|
|
565
|
+
}),
|
|
566
|
+
/*#__PURE__*/ jsx(PublicAccessBlock, {
|
|
567
|
+
bucketName: bucketName,
|
|
568
|
+
data: pabStatus.data,
|
|
569
|
+
status: pabStatus.status
|
|
570
|
+
})
|
|
571
|
+
]
|
|
572
|
+
})
|
|
573
|
+
]
|
|
489
574
|
}, field.id))
|
|
490
575
|
});
|
|
491
576
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Banner, Icon, Loader, Modal, Stack, Text, Tooltip, Wrap } from "@scality/core-ui";
|
|
2
|
+
import { Banner, ConstrainedText, Icon, Loader, Modal, Stack, Text, Tooltip, Wrap } from "@scality/core-ui";
|
|
3
3
|
import { Input } from "@scality/core-ui/dist/components/inputv2/inputv2";
|
|
4
4
|
import { Box, Button } from "@scality/core-ui/dist/next";
|
|
5
5
|
import { useMemo, useState } from "react";
|
|
@@ -91,7 +91,10 @@ const EmptyBucketButton = ({ bucketName })=>{
|
|
|
91
91
|
}),
|
|
92
92
|
/*#__PURE__*/ jsx(Modal, {
|
|
93
93
|
isOpen: isEmptyModalOpen,
|
|
94
|
-
title:
|
|
94
|
+
title: /*#__PURE__*/ jsx(ConstrainedText, {
|
|
95
|
+
text: `Empty Bucket '${bucketName}'?`,
|
|
96
|
+
lineClamp: 1
|
|
97
|
+
}),
|
|
95
98
|
close: ()=>{
|
|
96
99
|
if (!isEmptying) {
|
|
97
100
|
setIsEmptyModalOpen(false);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { GetPublicAccessBlockOutput } from '@aws-sdk/client-s3';
|
|
2
|
+
interface PublicAccessBlockProps {
|
|
3
|
+
bucketName: string;
|
|
4
|
+
data: GetPublicAccessBlockOutput | undefined;
|
|
5
|
+
status: 'pending' | 'success' | 'error';
|
|
6
|
+
}
|
|
7
|
+
export declare const PublicAccessBlock: import("react").MemoExoticComponent<({ bucketName, data, status }: PublicAccessBlockProps) => import("react/jsx-runtime").JSX.Element | null>;
|
|
8
|
+
export declare function usePublicAccessBlockStatus(bucketName: string): {
|
|
9
|
+
data: import("@aws-sdk/client-s3").GetPublicAccessBlockCommandOutput | undefined;
|
|
10
|
+
status: "error" | "success" | "pending";
|
|
11
|
+
isNotImplemented: boolean;
|
|
12
|
+
isPending: boolean;
|
|
13
|
+
isError: boolean;
|
|
14
|
+
isAnyBlockActive: boolean;
|
|
15
|
+
isPublicIgnored: boolean;
|
|
16
|
+
isSettingPublicBlocked: boolean;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Icon, Text, Toggle, Tooltip, spacing } from "@scality/core-ui";
|
|
3
|
+
import { Accordion } from "@scality/core-ui/dist/components/accordion/Accordion.component";
|
|
4
|
+
import { Box } from "@scality/core-ui/dist/next";
|
|
5
|
+
import { memo, useCallback, useMemo } from "react";
|
|
6
|
+
import { useGetPublicAccessBlock, usePutPublicAccessBlock } from "../../hooks/index.js";
|
|
7
|
+
import { Key, Row, Value } from "../ui/Table.elements.js";
|
|
8
|
+
const PAB_SETTINGS = [
|
|
9
|
+
{
|
|
10
|
+
key: 'BlockPublicAcls',
|
|
11
|
+
label: 'BlockPublicAcls',
|
|
12
|
+
tooltip: 'Rejects PUT requests that include public ACL grants. Existing public ACLs are not affected.'
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
key: 'IgnorePublicAcls',
|
|
16
|
+
label: 'IgnorePublicAcls',
|
|
17
|
+
tooltip: 'Ignores all public ACLs on this bucket and its objects. The ACLs still exist but have no effect on access.'
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
key: 'BlockPublicPolicy',
|
|
21
|
+
label: 'BlockPublicPolicy',
|
|
22
|
+
tooltip: 'Rejects bucket policy changes that would grant public access. Existing public policies are not affected.'
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
key: 'RestrictPublicBuckets',
|
|
26
|
+
label: 'RestrictPublicBuckets',
|
|
27
|
+
tooltip: 'Restricts access to buckets with public policies to only AWS service principals and authorized users within the bucket owner\'s account. The policy still exists but public and cross-account access is denied.'
|
|
28
|
+
}
|
|
29
|
+
];
|
|
30
|
+
const PublicAccessBlock = /*#__PURE__*/ memo(({ bucketName, data, status })=>{
|
|
31
|
+
const { mutate: putPublicAccessBlock, isPending } = usePutPublicAccessBlock();
|
|
32
|
+
const config = data?.PublicAccessBlockConfiguration;
|
|
33
|
+
const handleToggle = useCallback((key)=>{
|
|
34
|
+
const currentConfig = config ?? {};
|
|
35
|
+
putPublicAccessBlock({
|
|
36
|
+
Bucket: bucketName,
|
|
37
|
+
PublicAccessBlockConfiguration: {
|
|
38
|
+
...currentConfig,
|
|
39
|
+
[key]: !currentConfig[key]
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}, [
|
|
43
|
+
bucketName,
|
|
44
|
+
config,
|
|
45
|
+
putPublicAccessBlock
|
|
46
|
+
]);
|
|
47
|
+
if ('pending' === status) return null;
|
|
48
|
+
return /*#__PURE__*/ jsx(Box, {
|
|
49
|
+
marginTop: spacing.r8,
|
|
50
|
+
marginBottom: spacing.r16,
|
|
51
|
+
children: /*#__PURE__*/ jsx(Accordion, {
|
|
52
|
+
id: "pab",
|
|
53
|
+
title: "Public Access Block (PAB)",
|
|
54
|
+
children: 'error' === status ? /*#__PURE__*/ jsx(Text, {
|
|
55
|
+
color: "statusWarning",
|
|
56
|
+
children: "Failed to load Public Access Block settings"
|
|
57
|
+
}) : PAB_SETTINGS.map(({ key, label, tooltip })=>/*#__PURE__*/ jsxs(Row, {
|
|
58
|
+
children: [
|
|
59
|
+
/*#__PURE__*/ jsx(Key, {
|
|
60
|
+
children: /*#__PURE__*/ jsxs(Box, {
|
|
61
|
+
display: "flex",
|
|
62
|
+
alignItems: "center",
|
|
63
|
+
gap: spacing.r4,
|
|
64
|
+
children: [
|
|
65
|
+
label,
|
|
66
|
+
/*#__PURE__*/ jsx(Tooltip, {
|
|
67
|
+
overlay: tooltip,
|
|
68
|
+
children: /*#__PURE__*/ jsx(Icon, {
|
|
69
|
+
name: "Info",
|
|
70
|
+
size: "xs"
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
]
|
|
74
|
+
})
|
|
75
|
+
}),
|
|
76
|
+
/*#__PURE__*/ jsx(Value, {
|
|
77
|
+
children: /*#__PURE__*/ jsx(Toggle, {
|
|
78
|
+
id: `pab-${key}`,
|
|
79
|
+
disabled: isPending,
|
|
80
|
+
toggle: config?.[key] ?? false,
|
|
81
|
+
label: config?.[key] ? 'Active' : 'Inactive',
|
|
82
|
+
onChange: ()=>handleToggle(key)
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
]
|
|
86
|
+
}, key))
|
|
87
|
+
})
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
PublicAccessBlock.displayName = 'PublicAccessBlock';
|
|
91
|
+
function usePublicAccessBlockStatus(bucketName) {
|
|
92
|
+
const { data, status, error } = useGetPublicAccessBlock({
|
|
93
|
+
Bucket: bucketName
|
|
94
|
+
});
|
|
95
|
+
const isNotImplemented = error?.statusCode === 501;
|
|
96
|
+
const config = data?.PublicAccessBlockConfiguration;
|
|
97
|
+
const isAnyBlockActive = useMemo(()=>!!(config?.BlockPublicAcls || config?.IgnorePublicAcls || config?.BlockPublicPolicy || config?.RestrictPublicBuckets), [
|
|
98
|
+
config
|
|
99
|
+
]);
|
|
100
|
+
const isPublicIgnored = !!config?.IgnorePublicAcls;
|
|
101
|
+
const isSettingPublicBlocked = !!config?.BlockPublicAcls;
|
|
102
|
+
return {
|
|
103
|
+
data,
|
|
104
|
+
status,
|
|
105
|
+
isNotImplemented,
|
|
106
|
+
isPending: 'pending' === status,
|
|
107
|
+
isError: 'error' === status && !isNotImplemented,
|
|
108
|
+
isAnyBlockActive,
|
|
109
|
+
isPublicIgnored,
|
|
110
|
+
isSettingPublicBlocked
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
export { PublicAccessBlock, usePublicAccessBlockStatus };
|
|
@@ -13,6 +13,7 @@ export { BucketVersioning } from './buckets/BucketVersioning';
|
|
|
13
13
|
export { DeleteBucketButton } from './buckets/DeleteBucketButton';
|
|
14
14
|
export { EmptyBucketButton } from './buckets/EmptyBucketButton';
|
|
15
15
|
export { BucketNotificationFormPage } from './buckets/notifications/BucketNotificationFormPage';
|
|
16
|
+
export { PublicAccessBlock, usePublicAccessBlockStatus } from './buckets/PublicAccessBlock';
|
|
16
17
|
export { DataBrowserUI } from './DataBrowserUI';
|
|
17
18
|
export { CreateFolderButton } from './objects/CreateFolderButton';
|
|
18
19
|
export { ObjectDetails } from './objects/ObjectDetails';
|
package/dist/components/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import { BucketVersioning } from "./buckets/BucketVersioning.js";
|
|
|
13
13
|
import { DeleteBucketButton } from "./buckets/DeleteBucketButton.js";
|
|
14
14
|
import { EmptyBucketButton } from "./buckets/EmptyBucketButton.js";
|
|
15
15
|
import { BucketNotificationFormPage } from "./buckets/notifications/BucketNotificationFormPage.js";
|
|
16
|
+
import { PublicAccessBlock, usePublicAccessBlockStatus } from "./buckets/PublicAccessBlock.js";
|
|
16
17
|
import { DataBrowserUI } from "./DataBrowserUI.js";
|
|
17
18
|
import { CreateFolderButton } from "./objects/CreateFolderButton.js";
|
|
18
19
|
import { ObjectDetails } from "./objects/ObjectDetails/index.js";
|
|
@@ -25,4 +26,4 @@ import { DataBrowserProvider, useDataBrowserConfig, useDataBrowserContext, useIn
|
|
|
25
26
|
import { QueryProvider } from "./providers/QueryProvider.js";
|
|
26
27
|
import { MetadataSearch } from "./search/MetadataSearch.js";
|
|
27
28
|
import { ArrayFieldActions } from "./ui/ArrayFieldActions.js";
|
|
28
|
-
export { ArrayFieldActions, Breadcrumb, BucketAccessor, BucketCorsPage, BucketCreate, BucketLifecycleFormPage, BucketList, BucketNotificationFormPage, BucketOverview, BucketOverviewField, BucketOverviewSection, BucketPage, BucketPolicyPage, BucketReplicationFormPage, BucketVersioning, CreateFolderButton, DataBrowserBreadcrumb, DataBrowserProvider, DataBrowserUI, DefaultReplicationDestinationFields, DeleteBucketButton, EditRetentionButton, EmptyBucketButton, MetadataSearch, ObjectDetails, ObjectList, ObjectLockSettings, ObjectPage, QueryProvider, UploadButton, baseBucketCreateSchema, bucketErrorMessage, bucketNameValidationSchema, useBreadcrumbPaths, useBucketOverviewContext, useDataBrowserConfig, useDataBrowserContext, useDataBrowserNavigate, useInvalidateQueries };
|
|
29
|
+
export { ArrayFieldActions, Breadcrumb, BucketAccessor, BucketCorsPage, BucketCreate, BucketLifecycleFormPage, BucketList, BucketNotificationFormPage, BucketOverview, BucketOverviewField, BucketOverviewSection, BucketPage, BucketPolicyPage, BucketReplicationFormPage, BucketVersioning, CreateFolderButton, DataBrowserBreadcrumb, DataBrowserProvider, DataBrowserUI, DefaultReplicationDestinationFields, DeleteBucketButton, EditRetentionButton, EmptyBucketButton, MetadataSearch, ObjectDetails, ObjectList, ObjectLockSettings, ObjectPage, PublicAccessBlock, QueryProvider, UploadButton, baseBucketCreateSchema, bucketErrorMessage, bucketNameValidationSchema, useBreadcrumbPaths, useBucketOverviewContext, useDataBrowserConfig, useDataBrowserContext, useDataBrowserNavigate, useInvalidateQueries, usePublicAccessBlockStatus };
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This file contains hooks for managing bucket configuration settings
|
|
5
5
|
* like ACL, policies, versioning, CORS, lifecycle, etc.
|
|
6
6
|
*/
|
|
7
|
-
import { type DeleteBucketCorsCommandInput, type DeleteBucketCorsCommandOutput, type DeleteBucketLifecycleCommandInput, type DeleteBucketLifecycleCommandOutput, type DeleteBucketPolicyCommandInput, type DeleteBucketPolicyCommandOutput, type DeleteBucketReplicationCommandInput, type DeleteBucketReplicationCommandOutput, type DeleteBucketTaggingCommandInput, type DeleteBucketTaggingCommandOutput, type GetBucketAclCommandInput, type GetBucketAclCommandOutput, type GetBucketCorsCommandInput, type GetBucketCorsCommandOutput, type GetBucketEncryptionCommandInput, type GetBucketEncryptionCommandOutput, type GetBucketLifecycleConfigurationCommandInput, type GetBucketLifecycleConfigurationCommandOutput, type GetBucketNotificationConfigurationCommandInput, type GetBucketNotificationConfigurationCommandOutput, type GetBucketPolicyCommandInput, type GetBucketPolicyCommandOutput, type GetBucketReplicationCommandInput, type GetBucketReplicationCommandOutput, type GetBucketTaggingCommandInput, type GetBucketTaggingCommandOutput, type GetBucketVersioningCommandInput, type GetBucketVersioningCommandOutput, type GetObjectLockConfigurationCommandInput, type GetObjectLockConfigurationCommandOutput, type GetPublicAccessBlockCommandInput, type GetPublicAccessBlockCommandOutput, type PutBucketAclCommandInput, type PutBucketAclCommandOutput, type PutBucketCorsCommandInput, type PutBucketCorsCommandOutput, type PutBucketEncryptionCommandInput, type PutBucketEncryptionCommandOutput, type PutBucketLifecycleConfigurationCommandInput, type PutBucketLifecycleConfigurationCommandOutput, type PutBucketNotificationConfigurationCommandInput, type PutBucketNotificationConfigurationCommandOutput, type PutBucketPolicyCommandInput, type PutBucketPolicyCommandOutput, type PutBucketReplicationCommandInput, type PutBucketReplicationCommandOutput, type PutBucketTaggingCommandInput, type PutBucketTaggingCommandOutput, type PutBucketVersioningCommandInput, type PutBucketVersioningCommandOutput, type PutObjectLockConfigurationCommandInput, type PutObjectLockConfigurationCommandOutput } from '@aws-sdk/client-s3';
|
|
7
|
+
import { type DeleteBucketCorsCommandInput, type DeleteBucketCorsCommandOutput, type DeleteBucketLifecycleCommandInput, type DeleteBucketLifecycleCommandOutput, type DeleteBucketPolicyCommandInput, type DeleteBucketPolicyCommandOutput, type DeleteBucketReplicationCommandInput, type DeleteBucketReplicationCommandOutput, type DeleteBucketTaggingCommandInput, type DeleteBucketTaggingCommandOutput, type DeletePublicAccessBlockCommandInput, type DeletePublicAccessBlockCommandOutput, type GetBucketAclCommandInput, type GetBucketAclCommandOutput, type GetBucketCorsCommandInput, type GetBucketCorsCommandOutput, type GetBucketEncryptionCommandInput, type GetBucketEncryptionCommandOutput, type GetBucketLifecycleConfigurationCommandInput, type GetBucketLifecycleConfigurationCommandOutput, type GetBucketNotificationConfigurationCommandInput, type GetBucketNotificationConfigurationCommandOutput, type GetBucketPolicyCommandInput, type GetBucketPolicyCommandOutput, type GetBucketReplicationCommandInput, type GetBucketReplicationCommandOutput, type GetBucketTaggingCommandInput, type GetBucketTaggingCommandOutput, type GetBucketVersioningCommandInput, type GetBucketVersioningCommandOutput, type GetObjectLockConfigurationCommandInput, type GetObjectLockConfigurationCommandOutput, type GetPublicAccessBlockCommandInput, type GetPublicAccessBlockCommandOutput, type PutBucketAclCommandInput, type PutBucketAclCommandOutput, type PutBucketCorsCommandInput, type PutBucketCorsCommandOutput, type PutBucketEncryptionCommandInput, type PutBucketEncryptionCommandOutput, type PutBucketLifecycleConfigurationCommandInput, type PutBucketLifecycleConfigurationCommandOutput, type PutBucketNotificationConfigurationCommandInput, type PutBucketNotificationConfigurationCommandOutput, type PutBucketPolicyCommandInput, type PutBucketPolicyCommandOutput, type PutBucketReplicationCommandInput, type PutBucketReplicationCommandOutput, type PutBucketTaggingCommandInput, type PutBucketTaggingCommandOutput, type PutBucketVersioningCommandInput, type PutBucketVersioningCommandOutput, type PutObjectLockConfigurationCommandInput, type PutObjectLockConfigurationCommandOutput, type PutPublicAccessBlockCommandInput, type PutPublicAccessBlockCommandOutput } from '@aws-sdk/client-s3';
|
|
8
8
|
/**
|
|
9
9
|
* Hook for retrieving S3 bucket access control list (ACL) settings
|
|
10
10
|
*
|
|
@@ -173,3 +173,5 @@ export declare const useDeleteBucketReplication: (options?: Omit<import("@tansta
|
|
|
173
173
|
* This configuration determines whether public access is blocked at the bucket level.
|
|
174
174
|
*/
|
|
175
175
|
export declare const useGetPublicAccessBlock: (params?: GetPublicAccessBlockCommandInput | undefined, options?: Omit<import("@tanstack/react-query").UseQueryOptions<GetPublicAccessBlockCommandOutput, import("..").EnhancedS3Error, GetPublicAccessBlockCommandOutput, readonly unknown[]>, "queryKey" | "queryFn"> | undefined) => import("@tanstack/react-query").UseQueryResult<GetPublicAccessBlockCommandOutput, import("..").EnhancedS3Error>;
|
|
176
|
+
export declare const usePutPublicAccessBlock: (options?: Omit<import("@tanstack/react-query").UseMutationOptions<PutPublicAccessBlockCommandOutput, import("..").EnhancedS3Error, PutPublicAccessBlockCommandInput, unknown>, "mutationFn"> | undefined) => import("@tanstack/react-query").UseMutationResult<PutPublicAccessBlockCommandOutput, import("..").EnhancedS3Error, PutPublicAccessBlockCommandInput>;
|
|
177
|
+
export declare const useDeletePublicAccessBlock: (options?: Omit<import("@tanstack/react-query").UseMutationOptions<DeletePublicAccessBlockCommandOutput, import("..").EnhancedS3Error, DeletePublicAccessBlockCommandInput, unknown>, "mutationFn"> | undefined) => import("@tanstack/react-query").UseMutationResult<DeletePublicAccessBlockCommandOutput, import("..").EnhancedS3Error, DeletePublicAccessBlockCommandInput>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DeleteBucketCorsCommand, DeleteBucketLifecycleCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, GetBucketAclCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, PutBucketAclCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketLifecycleConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutObjectLockConfigurationCommand } from "@aws-sdk/client-s3";
|
|
1
|
+
import { DeleteBucketCorsCommand, DeleteBucketLifecycleCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeletePublicAccessBlockCommand, GetBucketAclCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, PutBucketAclCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketLifecycleConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand } from "@aws-sdk/client-s3";
|
|
2
2
|
import { useCreateS3MutationHook } from "./factories/useCreateS3MutationHook.js";
|
|
3
3
|
import { useCreateS3QueryHook } from "./factories/useCreateS3QueryHook.js";
|
|
4
4
|
const useGetBucketAcl = useCreateS3QueryHook(GetBucketAclCommand, 'GetBucketAcl');
|
|
@@ -65,4 +65,11 @@ const useDeleteBucketReplication = useCreateS3MutationHook(DeleteBucketReplicati
|
|
|
65
65
|
'GetBucketReplication'
|
|
66
66
|
]);
|
|
67
67
|
const useGetPublicAccessBlock = useCreateS3QueryHook(GetPublicAccessBlockCommand, 'GetPublicAccessBlock');
|
|
68
|
-
|
|
68
|
+
const usePutPublicAccessBlock = useCreateS3MutationHook(PutPublicAccessBlockCommand, 'PutPublicAccessBlock', [
|
|
69
|
+
'GetPublicAccessBlock',
|
|
70
|
+
'ListBuckets'
|
|
71
|
+
]);
|
|
72
|
+
const useDeletePublicAccessBlock = useCreateS3MutationHook(DeletePublicAccessBlockCommand, 'DeletePublicAccessBlock', [
|
|
73
|
+
'GetPublicAccessBlock'
|
|
74
|
+
]);
|
|
75
|
+
export { useDeleteBucketCors, useDeleteBucketLifecycle, useDeleteBucketPolicy, useDeleteBucketReplication, useDeleteBucketTagging, useDeletePublicAccessBlock, useGetBucketAcl, useGetBucketCors, useGetBucketEncryption, useGetBucketLifecycle, useGetBucketNotification, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketReplication, useGetBucketTagging, useGetBucketVersioning, useGetPublicAccessBlock, usePutPublicAccessBlock, useSetBucketAcl, useSetBucketCors, useSetBucketEncryption, useSetBucketLifecycle, useSetBucketNotification, useSetBucketObjectLockConfiguration, useSetBucketPolicy, useSetBucketReplication, useSetBucketTagging, useSetBucketVersioning };
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { useDeleteBucketCors, useDeleteBucketLifecycle, useDeleteBucketPolicy, useDeleteBucketReplication, useDeleteBucketTagging, useGetBucketAcl, useGetBucketCors, useGetBucketEncryption, useGetBucketLifecycle, useGetBucketNotification, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketReplication, useGetBucketTagging, useGetBucketVersioning, useGetPublicAccessBlock, useSetBucketAcl, useSetBucketCors, useSetBucketEncryption, useSetBucketLifecycle, useSetBucketNotification, useSetBucketObjectLockConfiguration, useSetBucketPolicy, useSetBucketReplication, useSetBucketTagging, useSetBucketVersioning, } from './bucketConfiguration';
|
|
1
|
+
export { useDeleteBucketCors, useDeleteBucketLifecycle, useDeleteBucketPolicy, useDeleteBucketReplication, useDeleteBucketTagging, useDeletePublicAccessBlock, useGetBucketAcl, useGetBucketCors, useGetBucketEncryption, useGetBucketLifecycle, useGetBucketNotification, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketReplication, useGetBucketTagging, useGetBucketVersioning, useGetPublicAccessBlock, usePutPublicAccessBlock, useSetBucketAcl, useSetBucketCors, useSetBucketEncryption, useSetBucketLifecycle, useSetBucketNotification, useSetBucketObjectLockConfiguration, useSetBucketPolicy, useSetBucketReplication, useSetBucketTagging, useSetBucketVersioning, } from './bucketConfiguration';
|
|
2
2
|
export { useBuckets, useCreateBucket, useDeleteBucket, useGetBucketLocation, useValidateBucketAccess, } from './bucketOperations';
|
|
3
3
|
export type { LoginConfig, LoginMutationResult } from './loginOperations';
|
|
4
4
|
export { useLoginMutation } from './loginOperations';
|
package/dist/hooks/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useDeleteBucketCors, useDeleteBucketLifecycle, useDeleteBucketPolicy, useDeleteBucketReplication, useDeleteBucketTagging, useGetBucketAcl, useGetBucketCors, useGetBucketEncryption, useGetBucketLifecycle, useGetBucketNotification, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketReplication, useGetBucketTagging, useGetBucketVersioning, useGetPublicAccessBlock, useSetBucketAcl, useSetBucketCors, useSetBucketEncryption, useSetBucketLifecycle, useSetBucketNotification, useSetBucketObjectLockConfiguration, useSetBucketPolicy, useSetBucketReplication, useSetBucketTagging, useSetBucketVersioning } from "./bucketConfiguration.js";
|
|
1
|
+
import { useDeleteBucketCors, useDeleteBucketLifecycle, useDeleteBucketPolicy, useDeleteBucketReplication, useDeleteBucketTagging, useDeletePublicAccessBlock, useGetBucketAcl, useGetBucketCors, useGetBucketEncryption, useGetBucketLifecycle, useGetBucketNotification, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketReplication, useGetBucketTagging, useGetBucketVersioning, useGetPublicAccessBlock, usePutPublicAccessBlock, useSetBucketAcl, useSetBucketCors, useSetBucketEncryption, useSetBucketLifecycle, useSetBucketNotification, useSetBucketObjectLockConfiguration, useSetBucketPolicy, useSetBucketReplication, useSetBucketTagging, useSetBucketVersioning } from "./bucketConfiguration.js";
|
|
2
2
|
import { useBuckets, useCreateBucket, useDeleteBucket, useGetBucketLocation, useValidateBucketAccess } from "./bucketOperations.js";
|
|
3
3
|
import { useLoginMutation } from "./loginOperations.js";
|
|
4
4
|
import { useCopyObject, useCreateFolder, useDeleteObject, useDeleteObjectTagging, useDeleteObjects, useGetObject, useGetObjectAttributes, useGetObjectTorrent, useListMultipartUploads, useListObjectVersions, useListObjects, useObjectAcl, useObjectLegalHold, useObjectMetadata, useObjectRetention, useObjectTagging, usePutObject, useRestoreObject, useSearchObjects, useSearchObjectsVersions, useSelectObjectContent, useSetObjectAcl, useSetObjectLegalHold, useSetObjectRetention, useSetObjectTagging, useUploadObjects } from "./objectOperations.js";
|
|
@@ -17,4 +17,4 @@ import { useS3Client } from "./useS3Client.js";
|
|
|
17
17
|
import { useS3ConfigSwitch } from "./useS3ConfigSwitch.js";
|
|
18
18
|
import { useSupportedNotificationEvents } from "./useSupportedNotificationEvents.js";
|
|
19
19
|
import { useTableRowSelection } from "./useTableRowSelection.js";
|
|
20
|
-
export { getAccessibleBucketsStorageKey, getLimitedAccessFlagKey, setLimitedAccessFlag, useAccessibleBuckets, useBatchObjectLegalHold, useBucketConfigEditor, useBucketLocations, useBuckets, useCopyObject, useCreateBucket, useCreateFolder, useDeleteBucket, useDeleteBucketConfigRule, useDeleteBucketCors, useDeleteBucketLifecycle, useDeleteBucketPolicy, useDeleteBucketReplication, useDeleteBucketTagging, useDeleteObject, useDeleteObjectTagging, useDeleteObjects, useEmptyBucket, useFeatures, useGetBucketAcl, useGetBucketCors, useGetBucketEncryption, useGetBucketLifecycle, useGetBucketLocation, useGetBucketNotification, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketReplication, useGetBucketTagging, useGetBucketVersioning, useGetObject, useGetObjectAttributes, useGetObjectTorrent, useGetPresignedDownload, useGetPresignedPost, useGetPresignedUpload, useGetPublicAccessBlock, useISVBucketStatus, useIsBucketEmpty, useLimitedAccessFlow, useListMultipartUploads, useListObjectVersions, useListObjects, useLoginMutation, useObjectAcl, useObjectLegalHold, useObjectMetadata, useObjectRetention, useObjectTagging, usePutObject, useRestoreObject, useS3Client, useS3ConfigSwitch, useSearchObjects, useSearchObjectsVersions, useSelectObjectContent, useSetBucketAcl, useSetBucketCors, useSetBucketEncryption, useSetBucketLifecycle, useSetBucketNotification, useSetBucketObjectLockConfiguration, useSetBucketPolicy, useSetBucketReplication, useSetBucketTagging, useSetBucketVersioning, useSetObjectAcl, useSetObjectLegalHold, useSetObjectRetention, useSetObjectTagging, useSupportedNotificationEvents, useTableRowSelection, useUploadObjects, useValidateBucketAccess };
|
|
20
|
+
export { getAccessibleBucketsStorageKey, getLimitedAccessFlagKey, setLimitedAccessFlag, useAccessibleBuckets, useBatchObjectLegalHold, useBucketConfigEditor, useBucketLocations, useBuckets, useCopyObject, useCreateBucket, useCreateFolder, useDeleteBucket, useDeleteBucketConfigRule, useDeleteBucketCors, useDeleteBucketLifecycle, useDeleteBucketPolicy, useDeleteBucketReplication, useDeleteBucketTagging, useDeleteObject, useDeleteObjectTagging, useDeleteObjects, useDeletePublicAccessBlock, useEmptyBucket, useFeatures, useGetBucketAcl, useGetBucketCors, useGetBucketEncryption, useGetBucketLifecycle, useGetBucketLocation, useGetBucketNotification, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketReplication, useGetBucketTagging, useGetBucketVersioning, useGetObject, useGetObjectAttributes, useGetObjectTorrent, useGetPresignedDownload, useGetPresignedPost, useGetPresignedUpload, useGetPublicAccessBlock, useISVBucketStatus, useIsBucketEmpty, useLimitedAccessFlow, useListMultipartUploads, useListObjectVersions, useListObjects, useLoginMutation, useObjectAcl, useObjectLegalHold, useObjectMetadata, useObjectRetention, useObjectTagging, usePutObject, usePutPublicAccessBlock, useRestoreObject, useS3Client, useS3ConfigSwitch, useSearchObjects, useSearchObjectsVersions, useSelectObjectContent, useSetBucketAcl, useSetBucketCors, useSetBucketEncryption, useSetBucketLifecycle, useSetBucketNotification, useSetBucketObjectLockConfiguration, useSetBucketPolicy, useSetBucketReplication, useSetBucketTagging, useSetBucketVersioning, useSetObjectAcl, useSetObjectLegalHold, useSetObjectRetention, useSetObjectTagging, useSupportedNotificationEvents, useTableRowSelection, useUploadObjects, useValidateBucketAccess };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { HttpResponse, http } from "msw";
|
|
2
|
+
import { createS3ErrorXml, getS3BaseUrl } from "../utils.js";
|
|
3
|
+
const getPublicAccessBlockHandler = http.get(`${getS3BaseUrl()}/:bucketName`, async ({ request, params })=>{
|
|
4
|
+
const { bucketName } = params;
|
|
5
|
+
const url = new URL(request.url);
|
|
6
|
+
if (!url.searchParams.has('publicAccessBlock')) return;
|
|
7
|
+
if ('string' == typeof bucketName) {
|
|
8
|
+
if (bucketName.includes('pab-not-implemented')) return HttpResponse.xml(createS3ErrorXml('NotImplemented', 'A header you provided implies functionality that is not implemented'), {
|
|
9
|
+
status: 501
|
|
10
|
+
});
|
|
11
|
+
if (bucketName.includes('pab-not-found')) return HttpResponse.xml(createS3ErrorXml('NoSuchPublicAccessBlockConfiguration', 'The public access block configuration was not found', bucketName), {
|
|
12
|
+
status: 404
|
|
13
|
+
});
|
|
14
|
+
if (bucketName.includes('pab-all-blocked')) return HttpResponse.xml(`<?xml version="1.0" encoding="UTF-8"?>
|
|
15
|
+
<PublicAccessBlockConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
|
|
16
|
+
<BlockPublicAcls>TRUE</BlockPublicAcls>
|
|
17
|
+
<IgnorePublicAcls>TRUE</IgnorePublicAcls>
|
|
18
|
+
<BlockPublicPolicy>TRUE</BlockPublicPolicy>
|
|
19
|
+
<RestrictPublicBuckets>TRUE</RestrictPublicBuckets>
|
|
20
|
+
</PublicAccessBlockConfiguration>`, {
|
|
21
|
+
status: 200
|
|
22
|
+
});
|
|
23
|
+
if (bucketName.includes('pab-acl-blocked')) return HttpResponse.xml(`<?xml version="1.0" encoding="UTF-8"?>
|
|
24
|
+
<PublicAccessBlockConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
|
|
25
|
+
<BlockPublicAcls>TRUE</BlockPublicAcls>
|
|
26
|
+
<IgnorePublicAcls>TRUE</IgnorePublicAcls>
|
|
27
|
+
<BlockPublicPolicy>FALSE</BlockPublicPolicy>
|
|
28
|
+
<RestrictPublicBuckets>FALSE</RestrictPublicBuckets>
|
|
29
|
+
</PublicAccessBlockConfiguration>`, {
|
|
30
|
+
status: 200
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return HttpResponse.xml(`<?xml version="1.0" encoding="UTF-8"?>
|
|
34
|
+
<PublicAccessBlockConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
|
|
35
|
+
<BlockPublicAcls>FALSE</BlockPublicAcls>
|
|
36
|
+
<IgnorePublicAcls>FALSE</IgnorePublicAcls>
|
|
37
|
+
<BlockPublicPolicy>FALSE</BlockPublicPolicy>
|
|
38
|
+
<RestrictPublicBuckets>FALSE</RestrictPublicBuckets>
|
|
39
|
+
</PublicAccessBlockConfiguration>`, {
|
|
40
|
+
status: 200
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
const putPublicAccessBlockHandler = http.put(`${getS3BaseUrl()}/:bucketName`, async ({ request })=>{
|
|
44
|
+
const url = new URL(request.url);
|
|
45
|
+
if (!url.searchParams.has('publicAccessBlock')) return;
|
|
46
|
+
return new HttpResponse(null, {
|
|
47
|
+
status: 200
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
export { getPublicAccessBlockHandler, putPublicAccessBlockHandler };
|
|
@@ -3,6 +3,7 @@ import { deleteBucketHandler } from "./handlers/deleteBucket.js";
|
|
|
3
3
|
import { getBucketAclHandler } from "./handlers/getBucketAcl.js";
|
|
4
4
|
import { getBucketLocationHandler } from "./handlers/getBucketLocation.js";
|
|
5
5
|
import { getBucketPolicyHandler } from "./handlers/getBucketPolicy.js";
|
|
6
|
+
import { getPublicAccessBlockHandler, putPublicAccessBlockHandler } from "./handlers/getPublicAccessBlock.js";
|
|
6
7
|
import { headObjectHandler } from "./handlers/headObject.js";
|
|
7
8
|
import { listBucketsHandler } from "./handlers/listBuckets.js";
|
|
8
9
|
import { listObjectsHandler } from "./handlers/listObjects.js";
|
|
@@ -126,7 +127,9 @@ const s3Handlers = [
|
|
|
126
127
|
getObjectLegalHoldHandler,
|
|
127
128
|
putObjectHandler,
|
|
128
129
|
headObjectHandler,
|
|
129
|
-
putBucketAclHandler
|
|
130
|
+
putBucketAclHandler,
|
|
131
|
+
getPublicAccessBlockHandler,
|
|
132
|
+
putPublicAccessBlockHandler
|
|
130
133
|
];
|
|
131
134
|
const handlers = s3Handlers;
|
|
132
135
|
export { createBucketHandler, handlers as default, getBucketVersioningHandler, s3Handlers };
|