diff --git a/portal-ui/src/common/SecureComponent/SecureComponent.tsx b/portal-ui/src/common/SecureComponent/SecureComponent.tsx
index f2544c446..575475aa6 100644
--- a/portal-ui/src/common/SecureComponent/SecureComponent.tsx
+++ b/portal-ui/src/common/SecureComponent/SecureComponent.tsx
@@ -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 ;
if (!permissionGranted && errorProps) {
return Array.isArray(children) ? (
diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx
index c39defe8f..f7a9f3a75 100644
--- a/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx
+++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx
@@ -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 (
{shareFileModalOpen && selectedPreview && (
@@ -1131,42 +1139,36 @@ const ListObjects = ({
}
actions={
-
-
- {
- if (fileUpload && fileUpload.current) {
- fileUpload.current.click();
- }
- closeMenu();
- }}
- uploadFolderFunction={(closeMenu) => {
- if (folderUpload && folderUpload.current) {
- folderUpload.current.click();
- }
- closeMenu();
- }}
- />
-
-
-
-
+
+
+ {
+ if (fileUpload && fileUpload.current) {
+ fileUpload.current.click();
+ }
+ closeMenu();
+ }}
+ uploadFolderFunction={(closeMenu) => {
+ if (folderUpload && folderUpload.current) {
+ folderUpload.current.click();
+ }
+ closeMenu();
+ }}
+ />
}
/>
diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/UploadFilesButton.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/UploadFilesButton.tsx
index 67016ce04..8266cc85a 100644
--- a/portal-ui/src/screens/Console/Buckets/ListBuckets/UploadFilesButton.tsx
+++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/UploadFilesButton.tsx
@@ -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 (
}
color="primary"
variant={"contained"}
- disabled={buttonDisabled}
+ disabled={forceDisable || !uploadEnabled}
/>
);