diff --git a/portal-ui/src/common/SecureComponent/SecureComponent.tsx b/portal-ui/src/common/SecureComponent/SecureComponent.tsx
index bbd36e8c51..08a6e98d3f 100644
--- a/portal-ui/src/common/SecureComponent/SecureComponent.tsx
+++ b/portal-ui/src/common/SecureComponent/SecureComponent.tsx
@@ -15,95 +15,7 @@
// along with this program. If not, see .
import React, { cloneElement } from "react";
-import get from "lodash/get";
-import { store } from "../../store";
-import { hasAccessToResource } from "./permissions";
-
-export const hasPermission = (
- resource: string | string[] | undefined,
- scopes: string[],
- matchAll?: boolean,
- containsResource?: boolean
-) => {
- if (!resource) {
- return false;
- }
- const state = store.getState();
- const sessionGrants = state.console.session.permissions || {};
-
- const globalGrants = sessionGrants["arn:aws:s3:::*"] || [];
- let resources: string[] = [];
- let resourceGrants: string[] = [];
- let containsResourceGrants: string[] = [];
-
- if (resource) {
- if (Array.isArray(resource)) {
- resources = [...resources, ...resource];
- } else {
- resources.push(resource);
- }
-
- // Filter wildcard items
- const wildcards = Object.keys(sessionGrants).filter(
- (item) => item.includes("*") && item !== "arn:aws:s3:::*"
- );
-
- const getMatchingWildcards = (path: string) => {
- const items = wildcards.map((element) => {
- const wildcardItemSection = element.split(":").slice(-1)[0];
-
- const replaceWildcard = wildcardItemSection
- .replace("/", "\\/")
- .replace("\\/*", "($|(\\/.*?))");
-
- const inRegExp = new RegExp(`${replaceWildcard}$`, "gm");
-
- if(inRegExp.exec(path)) {
- return element;
- }
-
- return null;
- });
-
- return items.filter(itm => itm !== null);
- };
-
- resources.forEach((rsItem) => {
- // Validation against inner paths & wildcards
- let wildcardRules =getMatchingWildcards(rsItem);
-
- let wildcardGrants: string[] = [];
-
- wildcardRules.forEach((rule) => {
- if(rule) {
- const wcResources = get(sessionGrants, rule, []);
- wildcardGrants = [...wildcardGrants, ...wcResources];
- }
- });
-
- const simpleResources = get(sessionGrants, rsItem, []);
- const s3Resources = get(sessionGrants, `arn:aws:s3:::${rsItem}/*`, []);
-
- resourceGrants = [...simpleResources, ...s3Resources, ...wildcardGrants];
-
- if (containsResource) {
- const matchResource = `arn:aws:s3:::${rsItem}`;
-
- Object.entries(sessionGrants).forEach(([key, value]) => {
- if (key.includes(matchResource)) {
- containsResourceGrants = [...containsResourceGrants, ...value];
- }
- });
- }
- });
- }
-
- return hasAccessToResource(
- [...resourceGrants, ...globalGrants, ...containsResourceGrants],
- scopes,
- matchAll
- );
-};
+import hasPermission from "./accessControl";
interface ISecureComponentProps {
errorProps?: any;
diff --git a/portal-ui/src/common/SecureComponent/__tests__/accessControl.test.ts b/portal-ui/src/common/SecureComponent/__tests__/accessControl.test.ts
new file mode 100644
index 0000000000..93aef080d5
--- /dev/null
+++ b/portal-ui/src/common/SecureComponent/__tests__/accessControl.test.ts
@@ -0,0 +1,66 @@
+// This file is part of MinIO Console Server
+// Copyright (c) 2022 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+import hasPermission from "../accessControl";
+import { store } from "../../../store";
+import { SESSION_RESPONSE } from "../../../screens/Console/actions";
+
+const setPolicy1 = () => {
+ store.dispatch({
+ type: SESSION_RESPONSE,
+ message: {
+ distributedMode: true,
+ features: ["log-search"],
+ permissions: {
+ "arn:aws:s3:::testcafe": [
+ "admin:CreateUser",
+ "s3:GetBucketLocation",
+ "s3:ListBucket",
+ "admin:CreateServiceAccount",
+ ],
+ "arn:aws:s3:::testcafe/*": [
+ "admin:CreateServiceAccount",
+ "admin:CreateUser",
+ "s3:GetObject",
+ "s3:ListBucket",
+ ],
+ "arn:aws:s3:::testcafe/write/*": [
+ "admin:CreateServiceAccount",
+ "admin:CreateUser",
+ "s3:PutObject",
+ "s3:DeleteObject",
+ "s3:GetObject",
+ "s3:ListBucket",
+ ],
+ "console-ui": ["admin:CreateServiceAccount", "admin:CreateUser"],
+ },
+ operator: false,
+ status: "ok",
+ },
+ });
+};
+
+test("Upload button disabled", () => {
+ setPolicy1();
+ expect(hasPermission("testcafe", ["s3:PutObject"])).toBe(false);
+});
+
+test("Upload button enabled valid prefix", () => {
+ setPolicy1();
+ expect(hasPermission("testcafe/write", ["s3:PutObject"], false, true)).toBe(
+ true
+ );
+});
diff --git a/portal-ui/src/common/SecureComponent/accessControl.ts b/portal-ui/src/common/SecureComponent/accessControl.ts
new file mode 100644
index 0000000000..41edd811f5
--- /dev/null
+++ b/portal-ui/src/common/SecureComponent/accessControl.ts
@@ -0,0 +1,136 @@
+// This file is part of MinIO Console Server
+// Copyright (c) 2022 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+import { store } from "../../store";
+import get from "lodash/get";
+import { IAM_SCOPES } from "./permissions";
+
+const hasPermission = (
+ resource: string | string[] | undefined,
+ scopes: string[],
+ matchAll?: boolean,
+ containsResource?: boolean
+) => {
+ if (!resource) {
+ return false;
+ }
+ const state = store.getState();
+ const sessionGrants = state.console.session.permissions || {};
+
+ const globalGrants = sessionGrants["arn:aws:s3:::*"] || [];
+ let resources: string[] = [];
+ let resourceGrants: string[] = [];
+ let containsResourceGrants: string[] = [];
+
+ if (resource) {
+ if (Array.isArray(resource)) {
+ resources = [...resources, ...resource];
+ } else {
+ resources.push(resource);
+ }
+
+ // Filter wildcard items
+ const wildcards = Object.keys(sessionGrants).filter(
+ (item) => item.includes("*") && item !== "arn:aws:s3:::*"
+ );
+
+ const getMatchingWildcards = (path: string) => {
+ const items = wildcards.map((element) => {
+ const wildcardItemSection = element.split(":").slice(-1)[0];
+
+ const replaceWildcard = wildcardItemSection
+ .replace("/", "\\/")
+ .replace("\\/*", "($|(\\/.*?))");
+
+ const inRegExp = new RegExp(`${replaceWildcard}$`, "gm");
+
+ if (inRegExp.exec(path)) {
+ return element;
+ }
+
+ return null;
+ });
+
+ return items.filter((itm) => itm !== null);
+ };
+
+ resources.forEach((rsItem) => {
+ // Validation against inner paths & wildcards
+ let wildcardRules = getMatchingWildcards(rsItem);
+
+ let wildcardGrants: string[] = [];
+
+ wildcardRules.forEach((rule) => {
+ if (rule) {
+ const wcResources = get(sessionGrants, rule, []);
+ wildcardGrants = [...wildcardGrants, ...wcResources];
+ }
+ });
+
+ const simpleResources = get(sessionGrants, rsItem, []);
+ const s3Resources = get(sessionGrants, `arn:aws:s3:::${rsItem}/*`, []);
+
+ resourceGrants = [...simpleResources, ...s3Resources, ...wildcardGrants];
+
+ if (containsResource) {
+ const matchResource = `arn:aws:s3:::${rsItem}`;
+
+ Object.entries(sessionGrants).forEach(([key, value]) => {
+ if (key.includes(matchResource)) {
+ containsResourceGrants = [...containsResourceGrants, ...value];
+ }
+ });
+ }
+ });
+ }
+
+ return hasAccessToResource(
+ [...resourceGrants, ...globalGrants, ...containsResourceGrants],
+ scopes,
+ matchAll
+ );
+};
+
+// hasAccessToResource receives a list of user permissions to perform on a specific resource, then compares those permissions against
+// a list of required permissions and return true or false depending of the level of required access (match all permissions,
+// match some of the permissions)
+const hasAccessToResource = (
+ userPermissionsOnBucket: string[] | null | undefined,
+ requiredPermissions: string[] = [],
+ matchAll?: boolean
+) => {
+ if (!userPermissionsOnBucket) {
+ return false;
+ }
+
+ const s3All = userPermissionsOnBucket.includes(IAM_SCOPES.S3_ALL_ACTIONS);
+ const AdminAll = userPermissionsOnBucket.includes(
+ IAM_SCOPES.ADMIN_ALL_ACTIONS
+ );
+
+ const permissions = requiredPermissions.filter(function (n) {
+ return (
+ userPermissionsOnBucket.indexOf(n) !== -1 ||
+ (n.indexOf("s3:") !== -1 && s3All) ||
+ (n.indexOf("admin:") !== -1 && AdminAll)
+ );
+ });
+ return matchAll
+ ? permissions.length === requiredPermissions.length
+ : permissions.length > 0;
+};
+
+export default hasPermission;
diff --git a/portal-ui/src/common/SecureComponent/index.ts b/portal-ui/src/common/SecureComponent/index.ts
new file mode 100644
index 0000000000..9db2d90a9a
--- /dev/null
+++ b/portal-ui/src/common/SecureComponent/index.ts
@@ -0,0 +1,18 @@
+// This file is part of MinIO Console Server
+// Copyright (c) 2022 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+export { default as hasPermission } from "./accessControl";
+export { default as SecureComponent } from "./SecureComponent";
diff --git a/portal-ui/src/common/SecureComponent/permissions.ts b/portal-ui/src/common/SecureComponent/permissions.ts
index 09d72f2a8d..31cba791d8 100644
--- a/portal-ui/src/common/SecureComponent/permissions.ts
+++ b/portal-ui/src/common/SecureComponent/permissions.ts
@@ -14,35 +14,6 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-// hasAccessToResource receives a list of user permissions to perform on a specific resource, then compares those permissions against
-// a list of required permissions and return true or false depending of the level of required access (match all permissions,
-// match some of the permissions)
-export const hasAccessToResource = (
- userPermissionsOnBucket: string[] | null | undefined,
- requiredPermissions: string[] = [],
- matchAll?: boolean
-) => {
- if (!userPermissionsOnBucket) {
- return false;
- }
-
- const s3All = userPermissionsOnBucket.includes(IAM_SCOPES.S3_ALL_ACTIONS);
- const AdminAll = userPermissionsOnBucket.includes(
- IAM_SCOPES.ADMIN_ALL_ACTIONS
- );
-
- const permissions = requiredPermissions.filter(function (n) {
- return (
- userPermissionsOnBucket.indexOf(n) !== -1 ||
- (n.indexOf("s3:") !== -1 && s3All) ||
- (n.indexOf("admin:") !== -1 && AdminAll)
- );
- });
- return matchAll
- ? permissions.length === requiredPermissions.length
- : permissions.length > 0;
-};
-
export const IAM_ROLES = {
BUCKET_OWNER: "BUCKET_OWNER", // upload/delete objects from the bucket
BUCKET_VIEWER: "BUCKET_VIEWER", // only view objects on the bucket
diff --git a/portal-ui/src/screens/Console/Account/Account.tsx b/portal-ui/src/screens/Console/Account/Account.tsx
index 4c2a0849b7..4df9225848 100644
--- a/portal-ui/src/screens/Console/Account/Account.tsx
+++ b/portal-ui/src/screens/Console/Account/Account.tsx
@@ -49,7 +49,7 @@ import {
CONSOLE_UI_RESOURCE,
IAM_SCOPES,
} from "../../../common/SecureComponent/permissions";
-import SecureComponent from "../../../common/SecureComponent/SecureComponent";
+import { SecureComponent } from "../../../common/SecureComponent";
import RBIconButton from "../Buckets/BucketDetails/SummaryItems/RBIconButton";
import { selectSAs } from "../Configurations/utils";
import DeleteMultipleServiceAccounts from "../Users/DeleteMultipleServiceAccounts";
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessDetailsPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessDetailsPanel.tsx
index e910d86101..123003e46c 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessDetailsPanel.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessDetailsPanel.tsx
@@ -36,9 +36,10 @@ import {
IAM_SCOPES,
} from "../../../../common/SecureComponent/permissions";
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
-import SecureComponent, {
+import {
+ SecureComponent,
hasPermission,
-} from "../../../../common/SecureComponent/SecureComponent";
+} from "../../../../common/SecureComponent";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import { tableStyles } from "../../Common/FormComponents/common/styleLibrary";
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessRulePanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessRulePanel.tsx
index aba5f7f8cb..560c34a5b6 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessRulePanel.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/AccessRulePanel.tsx
@@ -39,9 +39,10 @@ import {
import { BucketInfo } from "../types";
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
-import SecureComponent, {
+import {
+ SecureComponent,
hasPermission,
-} from "../../../../common/SecureComponent/SecureComponent";
+} from "../../../../common/SecureComponent";
import withSuspense from "../../Common/Components/withSuspense";
import RBIconButton from "./SummaryItems/RBIconButton";
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BrowserHandler.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BrowserHandler.tsx
index c1e0e2cc44..9e337000ac 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BrowserHandler.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BrowserHandler.tsx
@@ -34,7 +34,7 @@ import PageHeader from "../../Common/PageHeader/PageHeader";
import SettingsIcon from "../../../../icons/SettingsIcon";
import { BucketInfo } from "../types";
import { setErrorSnackMessage } from "../../../../actions";
-import SecureComponent from "../../../../common/SecureComponent/SecureComponent";
+import { SecureComponent } from "../../../../common/SecureComponent";
import {
IAM_PERMISSIONS,
IAM_ROLES,
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketDetails.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketDetails.tsx
index ec48f5c25d..f6cb05f49f 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketDetails.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketDetails.tsx
@@ -44,9 +44,10 @@ import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
import PageLayout from "../../Common/Layout/PageLayout";
import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs";
import BackLink from "../../../../common/BackLink";
-import SecureComponent, {
+import {
+ SecureComponent,
hasPermission,
-} from "../../../../common/SecureComponent/SecureComponent";
+} from "../../../../common/SecureComponent";
import withSuspense from "../../Common/Components/withSuspense";
import RBIconButton from "./SummaryItems/RBIconButton";
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx
index 4648917140..4e960236cd 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx
@@ -36,9 +36,10 @@ import api from "../../../../common/api";
import HelpBox from "../../../../common/HelpBox";
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
-import SecureComponent, {
+import {
+ SecureComponent,
hasPermission,
-} from "../../../../common/SecureComponent/SecureComponent";
+} from "../../../../common/SecureComponent";
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
import withSuspense from "../../Common/Components/withSuspense";
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx
index 977d754b62..07d03d53ca 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx
@@ -37,9 +37,10 @@ import AddLifecycleModal from "./AddLifecycleModal";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import HelpBox from "../../../../common/HelpBox";
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
-import SecureComponent, {
+import {
+ SecureComponent,
hasPermission,
-} from "../../../../common/SecureComponent/SecureComponent";
+} from "../../../../common/SecureComponent";
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
import RBIconButton from "./SummaryItems/RBIconButton";
import DeleteBucketLifecycleRule from "./DeleteBucketLifecycleRule";
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx
index 45cb59e9fb..7ee2b60926 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx
@@ -40,9 +40,10 @@ import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import HelpBox from "../../../../common/HelpBox";
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
-import SecureComponent, {
+import {
+ SecureComponent,
hasPermission,
-} from "../../../../common/SecureComponent/SecureComponent";
+} from "../../../../common/SecureComponent";
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
import withSuspense from "../../Common/Components/withSuspense";
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketSummaryPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketSummaryPanel.tsx
index 4ce982bc95..27d1c120e4 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketSummaryPanel.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketSummaryPanel.tsx
@@ -44,9 +44,10 @@ import {
import api from "../../../../common/api";
import { setBucketDetailsLoad } from "../actions";
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
-import SecureComponent, {
+import {
+ SecureComponent,
hasPermission,
-} from "../../../../common/SecureComponent/SecureComponent";
+} from "../../../../common/SecureComponent";
import withSuspense from "../../Common/Components/withSuspense";
import LabelValuePair from "../../Common/UsageBarWrapper/LabelValuePair";
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/SummaryItems/BucketTags.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/SummaryItems/BucketTags.tsx
index 4c9e6afb07..4760779c9b 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/SummaryItems/BucketTags.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/SummaryItems/BucketTags.tsx
@@ -19,7 +19,7 @@ import { ErrorResponseHandler } from "../../../../../common/types";
import useApi from "../../../Common/Hooks/useApi";
import { Box, CircularProgress } from "@mui/material";
import { IAM_SCOPES } from "../../../../../common/SecureComponent/permissions";
-import SecureComponent from "../../../../../common/SecureComponent/SecureComponent";
+import { SecureComponent } from "../../../../../common/SecureComponent";
import get from "lodash/get";
import Chip from "@mui/material/Chip";
import CloseIcon from "@mui/icons-material/Close";
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/SummaryItems/EditablePropertyItem.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/SummaryItems/EditablePropertyItem.tsx
index e1caec1754..0918794a31 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/SummaryItems/EditablePropertyItem.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/SummaryItems/EditablePropertyItem.tsx
@@ -16,7 +16,7 @@
import React from "react";
import LabelValuePair from "../../../Common/UsageBarWrapper/LabelValuePair";
-import SecureComponent from "../../../../../common/SecureComponent/SecureComponent";
+import { SecureComponent } from "../../../../../common/SecureComponent";
import ActionLink from "./ActionLink";
import { Box } from "@mui/material";
import EditActionButton from "./EditActionButton";
diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/BucketListItem.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/BucketListItem.tsx
index e5f4cc5082..cef1208b8b 100644
--- a/portal-ui/src/screens/Console/Buckets/ListBuckets/BucketListItem.tsx
+++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/BucketListItem.tsx
@@ -33,7 +33,7 @@ import {
IAM_PERMISSIONS,
IAM_ROLES,
} from "../../../../common/SecureComponent/permissions";
-import SecureComponent from "../../../../common/SecureComponent/SecureComponent";
+import { SecureComponent } from "../../../../common/SecureComponent";
import RBIconButton from "../BucketDetails/SummaryItems/RBIconButton";
import clsx from "clsx";
diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx
index 18b95551f2..4f155eac3b 100644
--- a/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx
+++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx
@@ -22,7 +22,7 @@ import withStyles from "@mui/styles/withStyles";
import { LinearProgress } from "@mui/material";
import Grid from "@mui/material/Grid";
import { Bucket, BucketList } from "../types";
-import {AddIcon, BucketsIcon, LifecycleConfigIcon} from "../../../../icons";
+import { AddIcon, BucketsIcon, LifecycleConfigIcon } from "../../../../icons";
import { AppState } from "../../../../store";
import { setErrorSnackMessage } from "../../../../actions";
import {
@@ -41,7 +41,7 @@ import RefreshIcon from "../../../../icons/RefreshIcon";
import AButton from "../../Common/AButton/AButton";
import MultipleBucketsIcon from "../../../../icons/MultipleBucketsIcon";
import SelectMultipleIcon from "../../../../icons/SelectMultipleIcon";
-import SecureComponent from "../../../../common/SecureComponent/SecureComponent";
+import { SecureComponent } from "../../../../common/SecureComponent";
import {
CONSOLE_UI_RESOURCE,
IAM_SCOPES,
@@ -259,15 +259,15 @@ const ListBuckets = ({
/>
{
- setLifecycleModalOpen(true);
- }}
- text={""}
- icon={}
- disabled={selectedBuckets.length === 0}
- color={"primary"}
- variant={"outlined"}
+ tooltip={"Set Lifecycle"}
+ onClick={() => {
+ setLifecycleModalOpen(true);
+ }}
+ text={""}
+ icon={}
+ disabled={selectedBuckets.length === 0}
+ color={"primary"}
+ variant={"outlined"}
/>
-
- {
+ uploadFileFunction(handleCloseUpload);
+ }}
+ disabled={!uploadObjectAllowed || forceDisable}
>
-
-
-
+
+
+ Upload File
+
+
+
+
+
+ Upload Folder
+
);
diff --git a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx
index 2052cf2166..de7886872c 100644
--- a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx
+++ b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx
@@ -52,7 +52,7 @@ import {
IAM_PAGES,
IAM_SCOPES,
} from "../../../../common/SecureComponent/permissions";
-import SecureComponent from "../../../../common/SecureComponent/SecureComponent";
+import { SecureComponent } from "../../../../common/SecureComponent";
import { tierTypes } from "./utils";
import RBIconButton from "../../Buckets/BucketDetails/SummaryItems/RBIconButton";
diff --git a/portal-ui/src/screens/Console/Console.tsx b/portal-ui/src/screens/Console/Console.tsx
index bb4638a235..6d8bd557e5 100644
--- a/portal-ui/src/screens/Console/Console.tsx
+++ b/portal-ui/src/screens/Console/Console.tsx
@@ -47,7 +47,7 @@ import {
IAM_SCOPES,
S3_ALL_RESOURCES,
} from "../../common/SecureComponent/permissions";
-import { hasPermission } from "../../common/SecureComponent/SecureComponent";
+import { hasPermission } from "../../common/SecureComponent";
import { IRouteRule } from "./Menu/types";
import LoadingComponent from "../../common/LoadingComponent";
diff --git a/portal-ui/src/screens/Console/Groups/Groups.tsx b/portal-ui/src/screens/Console/Groups/Groups.tsx
index f49db04906..1f47802947 100644
--- a/portal-ui/src/screens/Console/Groups/Groups.tsx
+++ b/portal-ui/src/screens/Console/Groups/Groups.tsx
@@ -45,9 +45,10 @@ import {
IAM_PAGES,
IAM_SCOPES,
} from "../../../common/SecureComponent/permissions";
-import SecureComponent, {
+import {
+ SecureComponent,
hasPermission,
-} from "../../../common/SecureComponent/SecureComponent";
+} from "../../../common/SecureComponent";
import withSuspense from "../Common/Components/withSuspense";
import RBIconButton from "../Buckets/BucketDetails/SummaryItems/RBIconButton";
diff --git a/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx b/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx
index 2998fb71f3..da2254e2b3 100644
--- a/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx
+++ b/portal-ui/src/screens/Console/Groups/GroupsDetails.tsx
@@ -41,9 +41,10 @@ import {
IAM_PAGES,
IAM_SCOPES,
} from "../../../common/SecureComponent/permissions";
-import SecureComponent, {
+import {
+ SecureComponent,
hasPermission,
-} from "../../../common/SecureComponent/SecureComponent";
+} from "../../../common/SecureComponent";
import GroupDetailsHeader from "./GroupDetailsHeader";
import RBIconButton from "../Buckets/BucketDetails/SummaryItems/RBIconButton";
diff --git a/portal-ui/src/screens/Console/Heal/Heal.tsx b/portal-ui/src/screens/Console/Heal/Heal.tsx
index 353bc67b40..57e752d601 100644
--- a/portal-ui/src/screens/Console/Heal/Heal.tsx
+++ b/portal-ui/src/screens/Console/Heal/Heal.tsx
@@ -51,7 +51,7 @@ import CheckboxWrapper from "../Common/FormComponents/CheckboxWrapper/CheckboxWr
import PageHeader from "../Common/PageHeader/PageHeader";
import api from "../../../common/api";
import PageLayout from "../Common/Layout/PageLayout";
-import SecureComponent from "../../../common/SecureComponent/SecureComponent";
+import { SecureComponent } from "../../../common/SecureComponent";
import DistributedOnly from "../Common/DistributedOnly/DistributedOnly";
const styles = (theme: Theme) =>
diff --git a/portal-ui/src/screens/Console/License/License.tsx b/portal-ui/src/screens/Console/License/License.tsx
index d1fe1d4b9e..2436326b87 100644
--- a/portal-ui/src/screens/Console/License/License.tsx
+++ b/portal-ui/src/screens/Console/License/License.tsx
@@ -34,7 +34,7 @@ import PageHeader from "../Common/PageHeader/PageHeader";
import LicenseModal from "./LicenseModal";
import api from "../../../common/api";
import { LicenseIcon } from "../../../icons";
-import { hasPermission } from "../../../common/SecureComponent/SecureComponent";
+import { hasPermission } from "../../../common/SecureComponent";
import {
CONSOLE_UI_RESOURCE,
IAM_PAGES,
diff --git a/portal-ui/src/screens/Console/Logs/LogSearch/LogsSearchMain.tsx b/portal-ui/src/screens/Console/Logs/LogSearch/LogsSearchMain.tsx
index 66171ceb9b..ad97055378 100644
--- a/portal-ui/src/screens/Console/Logs/LogSearch/LogsSearchMain.tsx
+++ b/portal-ui/src/screens/Console/Logs/LogSearch/LogsSearchMain.tsx
@@ -45,7 +45,7 @@ import {
CONSOLE_UI_RESOURCE,
IAM_SCOPES,
} from "../../../../common/SecureComponent/permissions";
-import SecureComponent from "../../../../common/SecureComponent/SecureComponent";
+import { SecureComponent } from "../../../../common/SecureComponent";
import { SearchIcon } from "../../../../icons";
import MissingIntegration from "../../Common/MissingIntegration/MissingIntegration";
diff --git a/portal-ui/src/screens/Console/Menu/MenuItem.tsx b/portal-ui/src/screens/Console/Menu/MenuItem.tsx
index 040cc62b3c..57f94f7499 100644
--- a/portal-ui/src/screens/Console/Menu/MenuItem.tsx
+++ b/portal-ui/src/screens/Console/Menu/MenuItem.tsx
@@ -34,7 +34,7 @@ import {
MenuCollapsedIcon,
MenuExpandedIcon,
} from "../../../icons/SidebarMenus";
-import { hasPermission } from "../../../common/SecureComponent/SecureComponent";
+import { hasPermission } from "../../../common/SecureComponent";
import {
CONSOLE_UI_RESOURCE,
IAM_PAGES_PERMISSIONS,
diff --git a/portal-ui/src/screens/Console/Policies/ListPolicies.tsx b/portal-ui/src/screens/Console/Policies/ListPolicies.tsx
index 85ad11b762..a543c46b39 100644
--- a/portal-ui/src/screens/Console/Policies/ListPolicies.tsx
+++ b/portal-ui/src/screens/Console/Policies/ListPolicies.tsx
@@ -43,9 +43,10 @@ import {
IAM_PAGES,
IAM_SCOPES,
} from "../../../common/SecureComponent/permissions";
-import SecureComponent, {
+import {
+ SecureComponent,
hasPermission,
-} from "../../../common/SecureComponent/SecureComponent";
+} from "../../../common/SecureComponent";
import SearchBox from "../Common/SearchBox";
import withSuspense from "../Common/Components/withSuspense";
diff --git a/portal-ui/src/screens/Console/Policies/PolicyDetails.tsx b/portal-ui/src/screens/Console/Policies/PolicyDetails.tsx
index d6051031dd..7ac9417d19 100644
--- a/portal-ui/src/screens/Console/Policies/PolicyDetails.tsx
+++ b/portal-ui/src/screens/Console/Policies/PolicyDetails.tsx
@@ -51,9 +51,10 @@ import {
IAM_PAGES,
IAM_SCOPES,
} from "../../../common/SecureComponent/permissions";
-import SecureComponent, {
+import {
+ SecureComponent,
hasPermission,
-} from "../../../common/SecureComponent/SecureComponent";
+} from "../../../common/SecureComponent";
import withSuspense from "../Common/Components/withSuspense";
import { AppState } from "../../../store";
diff --git a/portal-ui/src/screens/Console/Speedtest/Speedtest.tsx b/portal-ui/src/screens/Console/Speedtest/Speedtest.tsx
index 6b8e724d84..ea503ecc6c 100644
--- a/portal-ui/src/screens/Console/Speedtest/Speedtest.tsx
+++ b/portal-ui/src/screens/Console/Speedtest/Speedtest.tsx
@@ -43,7 +43,7 @@ import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWr
import ProgressBarWrapper from "../Common/ProgressBarWrapper/ProgressBarWrapper";
import InputUnitMenu from "../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import PageLayout from "../Common/Layout/PageLayout";
-import SecureComponent from "../../../common/SecureComponent/SecureComponent";
+import { SecureComponent } from "../../../common/SecureComponent";
import DistributedOnly from "../Common/DistributedOnly/DistributedOnly";
import HelpBox from "../../../common/HelpBox";
import WarnIcon from "../../../icons/WarnIcon";
diff --git a/portal-ui/src/screens/Console/Support/Register.tsx b/portal-ui/src/screens/Console/Support/Register.tsx
index 1dd6c5703c..10157101e7 100644
--- a/portal-ui/src/screens/Console/Support/Register.tsx
+++ b/portal-ui/src/screens/Console/Support/Register.tsx
@@ -49,7 +49,7 @@ import {
import { ErrorResponseHandler } from "../../../common/types";
import LockOutlinedIcon from "@mui/icons-material/LockOutlined";
import SelectWrapper from "../Common/FormComponents/SelectWrapper/SelectWrapper";
-import { hasPermission } from "../../../common/SecureComponent/SecureComponent";
+import { hasPermission } from "../../../common/SecureComponent";
import {
CONSOLE_UI_RESOURCE,
IAM_PAGES,
diff --git a/portal-ui/src/screens/Console/Tools/ToolsPanel/ToolsList.tsx b/portal-ui/src/screens/Console/Tools/ToolsPanel/ToolsList.tsx
index 6eca0346c5..260c5e42f2 100644
--- a/portal-ui/src/screens/Console/Tools/ToolsPanel/ToolsList.tsx
+++ b/portal-ui/src/screens/Console/Tools/ToolsPanel/ToolsList.tsx
@@ -43,7 +43,7 @@ import {
IAM_PAGES,
IAM_PAGES_PERMISSIONS,
} from "../../../../common/SecureComponent/permissions";
-import { hasPermission } from "../../../../common/SecureComponent/SecureComponent";
+import { hasPermission } from "../../../../common/SecureComponent";
import { AppState } from "../../../../store";
import { connect } from "react-redux";
diff --git a/portal-ui/src/screens/Console/Users/ListUsers.tsx b/portal-ui/src/screens/Console/Users/ListUsers.tsx
index 850ed5e581..b50e9b667d 100644
--- a/portal-ui/src/screens/Console/Users/ListUsers.tsx
+++ b/portal-ui/src/screens/Console/Users/ListUsers.tsx
@@ -47,10 +47,12 @@ import {
IAM_SCOPES,
S3_ALL_RESOURCES,
} from "../../../common/SecureComponent/permissions";
-import SecureComponent, {
- hasPermission,
-} from "../../../common/SecureComponent/SecureComponent";
+
import RBIconButton from "../Buckets/BucketDetails/SummaryItems/RBIconButton";
+import {
+ hasPermission,
+ SecureComponent,
+} from "../../../common/SecureComponent";
const AddUser = withSuspense(React.lazy(() => import("./AddUser")));
const SetPolicy = withSuspense(
diff --git a/portal-ui/src/screens/Console/valid-routes.ts b/portal-ui/src/screens/Console/valid-routes.ts
index 77169143a2..c107088c15 100644
--- a/portal-ui/src/screens/Console/valid-routes.ts
+++ b/portal-ui/src/screens/Console/valid-routes.ts
@@ -40,7 +40,7 @@ import {
TraceMenuIcon,
UsersMenuIcon,
} from "../../icons/SidebarMenus";
-import { hasPermission } from "../../common/SecureComponent/SecureComponent";
+import { hasPermission } from "../../common/SecureComponent";
import WatchIcon from "../../icons/WatchIcon";
import RegisterMenuIcon from "../../icons/SidebarMenus/RegisterMenuIcon";
import {