Enable/Disable upload file and folder button for bucket (#1486)
This commit is contained in:
@@ -21,7 +21,8 @@ import { hasAccessToResource } from "./permissions";
|
||||
export const hasPermission = (
|
||||
resource: string | undefined,
|
||||
scopes: string[],
|
||||
matchAll?: boolean
|
||||
matchAll?: boolean,
|
||||
containsResource?: boolean
|
||||
) => {
|
||||
if (!resource) {
|
||||
return false;
|
||||
@@ -33,8 +34,17 @@ export const hasPermission = (
|
||||
sessionGrants[`arn:aws:s3:::${resource}/*`] ||
|
||||
[];
|
||||
const globalGrants = sessionGrants["arn:aws:s3:::*"] || [];
|
||||
let containsResourceGrants: string[] = [];
|
||||
if (containsResource) {
|
||||
const matchResource = `arn:aws:s3:::${resource}`;
|
||||
for (const [key, value] of Object.entries(sessionGrants)) {
|
||||
if (key.includes(matchResource)) {
|
||||
containsResourceGrants = containsResourceGrants.concat(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return hasAccessToResource(
|
||||
[...resourceGrants, ...globalGrants],
|
||||
[...resourceGrants, ...globalGrants, ...containsResourceGrants],
|
||||
scopes,
|
||||
matchAll
|
||||
);
|
||||
@@ -47,6 +57,7 @@ interface ISecureComponentProps {
|
||||
children: any;
|
||||
scopes: string[];
|
||||
resource: string;
|
||||
containsResource?: boolean;
|
||||
}
|
||||
|
||||
const SecureComponent = ({
|
||||
@@ -56,8 +67,14 @@ const SecureComponent = ({
|
||||
matchAll = false,
|
||||
scopes = [],
|
||||
resource,
|
||||
containsResource = false,
|
||||
}: ISecureComponentProps) => {
|
||||
const permissionGranted = hasPermission(resource, scopes, matchAll);
|
||||
const permissionGranted = hasPermission(
|
||||
resource,
|
||||
scopes,
|
||||
matchAll,
|
||||
containsResource
|
||||
);
|
||||
if (!permissionGranted && !errorProps) return <RenderError />;
|
||||
if (!permissionGranted && errorProps) {
|
||||
return Array.isArray(children) ? (
|
||||
|
||||
@@ -142,7 +142,7 @@ const styles = (theme: Theme) =>
|
||||
right: 1,
|
||||
width: 5,
|
||||
height: 5,
|
||||
minWidth: 5
|
||||
minWidth: 5,
|
||||
},
|
||||
},
|
||||
screenTitle: {
|
||||
@@ -764,7 +764,12 @@ const ListObjects = ({
|
||||
xhr.status === 400 ||
|
||||
xhr.status === 500
|
||||
) {
|
||||
setSnackBarMessage(errorMessage);
|
||||
if (xhr.response) {
|
||||
const err = JSON.parse(xhr.response);
|
||||
setSnackBarMessage(err.detailedMessage);
|
||||
} else {
|
||||
setSnackBarMessage(errorMessage);
|
||||
}
|
||||
}
|
||||
if (xhr.status === 413) {
|
||||
setSnackBarMessage("Error - File size too large");
|
||||
@@ -1061,7 +1066,10 @@ const ListObjects = ({
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let uploadPath = [bucketName];
|
||||
if (currentPath.length > 0) {
|
||||
uploadPath = uploadPath.concat(currentPath);
|
||||
}
|
||||
return (
|
||||
<React.Fragment>
|
||||
{shareFileModalOpen && selectedPreview && (
|
||||
@@ -1131,42 +1139,36 @@ const ListObjects = ({
|
||||
}
|
||||
actions={
|
||||
<Fragment>
|
||||
<SecureComponent
|
||||
resource={bucketName}
|
||||
scopes={[IAM_SCOPES.S3_PUT_OBJECT]}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<Fragment>
|
||||
<UploadFilesButton
|
||||
uploadFileFunction={(closeMenu) => {
|
||||
if (fileUpload && fileUpload.current) {
|
||||
fileUpload.current.click();
|
||||
}
|
||||
closeMenu();
|
||||
}}
|
||||
uploadFolderFunction={(closeMenu) => {
|
||||
if (folderUpload && folderUpload.current) {
|
||||
folderUpload.current.click();
|
||||
}
|
||||
closeMenu();
|
||||
}}
|
||||
/>
|
||||
<input
|
||||
type="file"
|
||||
multiple
|
||||
onChange={handleUploadButton}
|
||||
style={{ display: "none" }}
|
||||
ref={fileUpload}
|
||||
/>
|
||||
<input
|
||||
type="file"
|
||||
multiple
|
||||
onChange={handleUploadButton}
|
||||
style={{ display: "none" }}
|
||||
ref={folderUpload}
|
||||
/>
|
||||
</Fragment>
|
||||
</SecureComponent>
|
||||
<input
|
||||
type="file"
|
||||
multiple
|
||||
onChange={handleUploadButton}
|
||||
style={{ display: "none" }}
|
||||
ref={fileUpload}
|
||||
/>
|
||||
<input
|
||||
type="file"
|
||||
multiple
|
||||
onChange={handleUploadButton}
|
||||
style={{ display: "none" }}
|
||||
ref={folderUpload}
|
||||
/>
|
||||
<UploadFilesButton
|
||||
bucketName={bucketName}
|
||||
uploadPath={uploadPath.join("/")}
|
||||
uploadFileFunction={(closeMenu) => {
|
||||
if (fileUpload && fileUpload.current) {
|
||||
fileUpload.current.click();
|
||||
}
|
||||
closeMenu();
|
||||
}}
|
||||
uploadFolderFunction={(closeMenu) => {
|
||||
if (folderUpload && folderUpload.current) {
|
||||
folderUpload.current.click();
|
||||
}
|
||||
closeMenu();
|
||||
}}
|
||||
/>
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -23,9 +23,15 @@ import ListItemText from "@mui/material/ListItemText";
|
||||
import ListItemIcon from "@mui/material/ListItemIcon";
|
||||
import { UploadFolderIcon, UploadIcon } from "../../../../icons";
|
||||
import RBIconButton from "../BucketDetails/SummaryItems/RBIconButton";
|
||||
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
|
||||
import SecureComponent, {
|
||||
hasPermission,
|
||||
} from "../../../../common/SecureComponent/SecureComponent";
|
||||
|
||||
interface IUploadFilesButton {
|
||||
buttonDisabled?: boolean;
|
||||
uploadPath: string;
|
||||
bucketName: string;
|
||||
forceDisable?: boolean;
|
||||
uploadFileFunction: (closeFunction: () => void) => void;
|
||||
uploadFolderFunction: (closeFunction: () => void) => void;
|
||||
classes: any;
|
||||
@@ -43,7 +49,9 @@ const styles = (theme: Theme) =>
|
||||
});
|
||||
|
||||
const UploadFilesButton = ({
|
||||
buttonDisabled = false,
|
||||
uploadPath,
|
||||
bucketName,
|
||||
forceDisable = false,
|
||||
uploadFileFunction,
|
||||
uploadFolderFunction,
|
||||
classes,
|
||||
@@ -57,6 +65,18 @@ const UploadFilesButton = ({
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const uploadObjectAllowed = hasPermission(uploadPath, [
|
||||
IAM_SCOPES.S3_PUT_OBJECT,
|
||||
]);
|
||||
const uploadFolderAllowed = hasPermission(
|
||||
bucketName,
|
||||
[IAM_SCOPES.S3_PUT_OBJECT],
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
const uploadEnabled: boolean = uploadObjectAllowed || uploadFolderAllowed;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<RBIconButton
|
||||
@@ -70,7 +90,7 @@ const UploadFilesButton = ({
|
||||
icon={<UploadIcon />}
|
||||
color="primary"
|
||||
variant={"contained"}
|
||||
disabled={buttonDisabled}
|
||||
disabled={forceDisable || !uploadEnabled}
|
||||
/>
|
||||
<Menu
|
||||
id={`upload-main-menu`}
|
||||
@@ -89,28 +109,41 @@ const UploadFilesButton = ({
|
||||
horizontal: "center",
|
||||
}}
|
||||
>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
uploadFileFunction(handleCloseUpload);
|
||||
}}
|
||||
disabled={buttonDisabled}
|
||||
<SecureComponent
|
||||
resource={uploadPath}
|
||||
scopes={[IAM_SCOPES.S3_PUT_OBJECT]}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<ListItemIcon className={classes.listUploadIcons}>
|
||||
<UploadIcon />
|
||||
</ListItemIcon>{" "}
|
||||
<ListItemText>Upload File</ListItemText>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
uploadFolderFunction(handleCloseUpload);
|
||||
}}
|
||||
disabled={buttonDisabled}
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
uploadFileFunction(handleCloseUpload);
|
||||
}}
|
||||
disabled={forceDisable}
|
||||
>
|
||||
<ListItemIcon className={classes.listUploadIcons}>
|
||||
<UploadIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText>Upload File</ListItemText>
|
||||
</MenuItem>
|
||||
</SecureComponent>
|
||||
<SecureComponent
|
||||
resource={bucketName}
|
||||
containsResource
|
||||
scopes={[IAM_SCOPES.S3_PUT_OBJECT]}
|
||||
errorProps={{ disabled: true }}
|
||||
>
|
||||
<ListItemIcon className={classes.listUploadIcons}>
|
||||
<UploadFolderIcon />
|
||||
</ListItemIcon>{" "}
|
||||
<ListItemText>Upload Folder</ListItemText>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
uploadFolderFunction(handleCloseUpload);
|
||||
}}
|
||||
disabled={forceDisable}
|
||||
>
|
||||
<ListItemIcon className={classes.listUploadIcons}>
|
||||
<UploadFolderIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText>Upload Folder</ListItemText>
|
||||
</MenuItem>
|
||||
</SecureComponent>
|
||||
</Menu>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user