Enable/Disable upload file and folder button for bucket (#1486)

This commit is contained in:
Lenin Alevski
2022-01-28 16:16:38 -06:00
committed by GitHub
parent 2e9a42320c
commit d8b387434b
3 changed files with 117 additions and 65 deletions

View File

@@ -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) ? (

View File

@@ -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>
}
/>

View File

@@ -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>
);