Tooltips for Bucket Lifecycle, Delete bucket, Manage bucket (#2334)

This commit is contained in:
jinapurapu
2022-09-23 10:30:37 -07:00
committed by GitHub
parent 43c5f9094a
commit c4c6d48abf
4 changed files with 103 additions and 11 deletions

View File

@@ -18,6 +18,7 @@ export const IAM_ROLES = {
BUCKET_OWNER: "BUCKET_OWNER", // upload/delete objects from the bucket
BUCKET_VIEWER: "BUCKET_VIEWER", // only view objects on the bucket
BUCKET_ADMIN: "BUCKET_ADMIN", // administrate the bucket
BUCKET_LIFECYCLE: "BUCKET_LIFECYCLE", // can manage bucket lifecycle
};
export const IAM_SCOPES = {
@@ -281,6 +282,12 @@ export const IAM_PERMISSIONS = {
IAM_SCOPES.ADMIN_LIST_USERS,
IAM_SCOPES.ADMIN_HEAL,
],
[IAM_ROLES.BUCKET_LIFECYCLE]: [
IAM_SCOPES.S3_GET_LIFECYCLE_CONFIGURATION,
IAM_SCOPES.S3_PUT_LIFECYCLE_CONFIGURATION,
IAM_SCOPES.ADMIN_LIST_TIERS,
IAM_SCOPES.ADMIN_SET_TIER,
],
};
// application pages/routes and required scopes/roles
@@ -434,6 +441,10 @@ export const permissionTooltipHelper = (scopes: string[], name: string) => {
name +
". Please ask your MinIO administrator to grant you " +
scopes +
" permission in order to enable Versioning."
" permission" +
(scopes.length > 1 ? "s" : "") +
" in order to enable " +
name +
"."
);
};

View File

@@ -45,7 +45,12 @@ import ScreenTitle from "../../Common/ScreenTitle/ScreenTitle";
import { Box } from "@mui/material";
import RefreshIcon from "../../../../icons/RefreshIcon";
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
import {
IAM_SCOPES,
IAM_PERMISSIONS,
IAM_ROLES,
permissionTooltipHelper,
} from "../../../../common/SecureComponent/permissions";
import PageLayout from "../../Common/Layout/PageLayout";
import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs";
import BackLink from "../../../../common/BackLink";
@@ -136,6 +141,14 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
selTab = selTab ? selTab : "summary";
const [activeTab, setActiveTab] = useState(selTab);
const canDelete = hasPermission(bucketName, [
IAM_SCOPES.S3_DELETE_BUCKET,
IAM_SCOPES.S3_FORCE_DELETE_BUCKET,
]);
const canBrowse = hasPermission(
bucketName,
IAM_PERMISSIONS[IAM_ROLES.BUCKET_VIEWER]
);
useEffect(() => {
setActiveTab(selTab);
@@ -209,7 +222,16 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
<PageHeader
label={<BackLink to={"/buckets"} label={"Buckets"} />}
actions={
<TooltipWrapper tooltip={"Browse Bucket"}>
<TooltipWrapper
tooltip={
canBrowse
? "Browse Bucket"
: permissionTooltipHelper(
IAM_PERMISSIONS[IAM_ROLES.BUCKET_VIEWER],
"browsing this bucket"
)
}
>
<Button
id={"switch-browse-view"}
aria-label="Browse Bucket"
@@ -220,6 +242,7 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
style={{
padding: "0 10px",
}}
disabled={!canBrowse}
/>
</TooltipWrapper>
}
@@ -260,7 +283,19 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
resource={bucketName}
errorProps={{ disabled: true }}
>
<TooltipWrapper tooltip={"Delete Bucket"}>
<TooltipWrapper
tooltip={
canDelete
? ""
: permissionTooltipHelper(
[
IAM_SCOPES.S3_DELETE_BUCKET,
IAM_SCOPES.S3_FORCE_DELETE_BUCKET,
],
"deleting this bucket"
)
}
>
<Button
id={"delete-bucket-button"}
onClick={() => {
@@ -269,6 +304,7 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
label={"Delete Bucket"}
icon={<TrashIcon />}
variant={"secondary"}
disabled={!canDelete}
/>
</TooltipWrapper>
</SecureComponent>

View File

@@ -38,10 +38,12 @@ import { Link, useNavigate } from "react-router-dom";
import {
IAM_PERMISSIONS,
IAM_ROLES,
permissionTooltipHelper,
} from "../../../../common/SecureComponent/permissions";
import { SecureComponent } from "../../../../common/SecureComponent";
import clsx from "clsx";
import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
import { hasPermission } from "../../../../common/SecureComponent";
const styles = (theme: Theme) =>
createStyles({
@@ -187,6 +189,11 @@ const BucketListItem = ({
const quota = get(bucket, "details.quota.quota", "0");
const quotaForString = calculateBytes(quota, true, false);
const manageAllowed = hasPermission(
bucket.name,
IAM_PERMISSIONS[IAM_ROLES.BUCKET_ADMIN]
);
const accessToStr = (bucket: Bucket): string => {
if (bucket.rw_access?.read && !bucket.rw_access?.write) {
return "R";
@@ -249,7 +256,16 @@ const BucketListItem = ({
scopes={IAM_PERMISSIONS[IAM_ROLES.BUCKET_ADMIN]}
resource={bucket.name}
>
<TooltipWrapper tooltip={"Manage"}>
<TooltipWrapper
tooltip={
manageAllowed
? "Manage Bucket"
: permissionTooltipHelper(
IAM_PERMISSIONS[IAM_ROLES.BUCKET_ADMIN],
"managing this bucket"
)
}
>
<Button
onClick={() => navigate(`/buckets/${bucket.name}/admin`)}
label={"Manage"}
@@ -257,6 +273,7 @@ const BucketListItem = ({
color={"primary"}
variant={"regular"}
id={`manage-${bucket.name}`}
disabled={!manageAllowed}
/>
</TooltipWrapper>
</SecureComponent>

View File

@@ -47,7 +47,10 @@ import { SecureComponent } from "../../../../common/SecureComponent";
import {
CONSOLE_UI_RESOURCE,
IAM_PAGES,
IAM_PERMISSIONS,
IAM_ROLES,
IAM_SCOPES,
permissionTooltipHelper,
} from "../../../../common/SecureComponent/permissions";
import PageLayout from "../../Common/Layout/PageLayout";
import SearchBox from "../../Common/SearchBox";
@@ -105,6 +108,7 @@ const ListBuckets = ({ classes }: IListBucketsProps) => {
const [replicationModalOpen, setReplicationModalOpen] =
useState<boolean>(false);
const [lifecycleModalOpen, setLifecycleModalOpen] = useState<boolean>(false);
const [canPutLifecycle, setCanPutLifecycle] = useState<boolean>(false);
const [bulkSelect, setBulkSelect] = useState<boolean>(false);
const features = useSelector(selFeatures);
@@ -172,6 +176,16 @@ const ListBuckets = ({ classes }: IListBucketsProps) => {
}
};
useEffect(() => {
var failLifecycle = false;
selectedBuckets.forEach((bucket: string) => {
hasPermission(bucket, IAM_PERMISSIONS[IAM_ROLES.BUCKET_LIFECYCLE], true)
? setCanPutLifecycle(true)
: (failLifecycle = true);
});
failLifecycle ? setCanPutLifecycle(false) : setCanPutLifecycle(true);
}, [selectedBuckets]);
const renderItemLine = (index: number) => {
const bucket = filteredRecords[index] || null;
if (bucket) {
@@ -282,7 +296,20 @@ const ListBuckets = ({ classes }: IListBucketsProps) => {
</TooltipWrapper>
)}
<TooltipWrapper tooltip={"Set Lifecycle"}>
<TooltipWrapper
tooltip={
selectedBuckets.length === 0
? bulkSelect
? "Please select at least one bucket on which to configure Lifecycle"
: "Use the Select Multiple Buckets button to choose buckets on which to configure Lifecycle"
: canPutLifecycle
? "Set Lifecycle"
: permissionTooltipHelper(
IAM_PERMISSIONS[IAM_ROLES.BUCKET_LIFECYCLE],
"configuring lifecycle for the selected buckets"
)
}
>
<Button
id={"set-lifecycle"}
onClick={() => {
@@ -290,7 +317,7 @@ const ListBuckets = ({ classes }: IListBucketsProps) => {
}}
icon={<LifecycleConfigIcon />}
variant={"regular"}
disabled={selectedBuckets.length === 0}
disabled={selectedBuckets.length === 0 || !canPutLifecycle}
/>
</TooltipWrapper>
@@ -323,10 +350,11 @@ const ListBuckets = ({ classes }: IListBucketsProps) => {
<TooltipWrapper
tooltip={
canCreateBucket
? "Create Bucket"
: "You require additional permissions in order to create a new Bucket. Please ask your MinIO administrator to grant you " +
IAM_SCOPES.S3_CREATE_BUCKET +
" permission in order to create a Bucket."
? ""
: permissionTooltipHelper(
[IAM_SCOPES.S3_CREATE_BUCKET],
"creating a bucket"
)
}
>
<Button