Fix Upload Button Logic (#1580)

* Fix Upload Button Logic

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Re-org function hasAccessToResource

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Fix Warnings

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2022-02-15 13:29:09 -08:00
committed by GitHub
parent 0ac6ceca3f
commit 25ff4982a0
38 changed files with 312 additions and 212 deletions

View File

@@ -15,95 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@@ -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 <http://www.gnu.org/licenses/>.
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
);
});

View File

@@ -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 <http://www.gnu.org/licenses/>.
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;

View File

@@ -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 <http://www.gnu.org/licenses/>.
export { default as hasPermission } from "./accessControl";
export { default as SecureComponent } from "./SecureComponent";

View File

@@ -14,35 +14,6 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// 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

View File

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

View File

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

View File

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

View File

@@ -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,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 = ({
/>
<RBIconButton
tooltip={"Set Lifecycle"}
onClick={() => {
setLifecycleModalOpen(true);
}}
text={""}
icon={<LifecycleConfigIcon />}
disabled={selectedBuckets.length === 0}
color={"primary"}
variant={"outlined"}
tooltip={"Set Lifecycle"}
onClick={() => {
setLifecycleModalOpen(true);
}}
text={""}
icon={<LifecycleConfigIcon />}
disabled={selectedBuckets.length === 0}
color={"primary"}
variant={"outlined"}
/>
<RBIconButton

View File

@@ -84,9 +84,10 @@ import { AppState } from "../../../../../../store";
import PageLayout from "../../../../Common/Layout/PageLayout";
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 { displayName } from "./utils";

View File

@@ -62,7 +62,7 @@ import AddTagModal from "../ObjectDetails/AddTagModal";
import DeleteTagModal from "../ObjectDetails/DeleteTagModal";
import SetLegalHoldModal from "../ObjectDetails/SetLegalHoldModal";
import RestoreFileVersion from "../ObjectDetails/RestoreFileVersion";
import SecureComponent from "../../../../../../common/SecureComponent/SecureComponent";
import { SecureComponent } from "../../../../../../common/SecureComponent";
import ObjectTags from "../ObjectDetails/ObjectTags";
import LabelWithIcon from "../../../BucketDetails/SummaryItems/LabelWithIcon";
import PreviewFileModal from "../Preview/PreviewFileModal";

View File

@@ -59,7 +59,7 @@ import PreviewFileContent from "../Preview/PreviewFileContent";
import RestoreFileVersion from "./RestoreFileVersion";
import PageLayout from "../../../../Common/Layout/PageLayout";
import VerticalTabs from "../../../../Common/VerticalTabs/VerticalTabs";
import SecureComponent from "../../../../../../common/SecureComponent/SecureComponent";
import { SecureComponent } from "../../../../../../common/SecureComponent";
import {
completeObject,
setNewObject,

View File

@@ -2,7 +2,7 @@ import React from "react";
import { IAM_SCOPES } from "../../../../../../common/SecureComponent/permissions";
import { Box } from "@mui/material";
import get from "lodash/get";
import SecureComponent from "../../../../../../common/SecureComponent/SecureComponent";
import { SecureComponent } from "../../../../../../common/SecureComponent";
import Chip from "@mui/material/Chip";
import CloseIcon from "@mui/icons-material/Close";
import AddIcon from "@mui/icons-material/Add";

View File

@@ -24,9 +24,7 @@ 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";
import { hasPermission } from "../../../../common/SecureComponent";
interface IUploadFilesButton {
uploadPath: string;
@@ -109,43 +107,28 @@ const UploadFilesButton = ({
horizontal: "center",
}}
>
<SecureComponent
resource={uploadPath}
containsResource
scopes={[IAM_SCOPES.S3_PUT_OBJECT]}
errorProps={{ disabled: true }}
<MenuItem
onClick={() => {
uploadFileFunction(handleCloseUpload);
}}
disabled={!uploadObjectAllowed || forceDisable}
>
<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}>
<UploadIcon />
</ListItemIcon>
<ListItemText>Upload File</ListItemText>
</MenuItem>
<MenuItem
onClick={() => {
uploadFolderFunction(handleCloseUpload);
}}
disabled={!uploadFolderAllowed || forceDisable}
>
<MenuItem
onClick={() => {
uploadFolderFunction(handleCloseUpload);
}}
disabled={forceDisable}
>
<ListItemIcon className={classes.listUploadIcons}>
<UploadFolderIcon />
</ListItemIcon>
<ListItemText>Upload Folder</ListItemText>
</MenuItem>
</SecureComponent>
<ListItemIcon className={classes.listUploadIcons}>
<UploadFolderIcon />
</ListItemIcon>
<ListItemText>Upload Folder</ListItemText>
</MenuItem>
</Menu>
</Fragment>
);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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,

View File

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

View File

@@ -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,

View File

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

View File

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

View File

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

View File

@@ -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,

View File

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

View File

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

View File

@@ -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 {