Added anonymous access modal in folder selection (#2736)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
"local-storage-fallback": "^4.1.1",
|
||||
"lodash": "^4.17.21",
|
||||
"luxon": "^3.3.0",
|
||||
"mds": "https://github.com/minio/mds.git#v0.3.1",
|
||||
"mds": "https://github.com/minio/mds.git#v0.3.2",
|
||||
"minio": "^7.0.32",
|
||||
"react": "^18.1.0",
|
||||
"react-component-export-image": "^1.0.6",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// 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 React, { useState } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
||||
import { Grid } from "@mui/material";
|
||||
import { AddAccessRuleIcon, Button } from "mds";
|
||||
@@ -30,7 +30,10 @@ import {
|
||||
import api from "../../../../common/api";
|
||||
import { ErrorResponseHandler } from "../../../../common/types";
|
||||
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
|
||||
import { setErrorSnackMessage } from "../../../../systemSlice";
|
||||
import {
|
||||
setErrorSnackMessage,
|
||||
setSnackBarMessage,
|
||||
} from "../../../../systemSlice";
|
||||
import { useAppDispatch } from "../../../../store";
|
||||
|
||||
interface IAddAccessRule {
|
||||
@@ -38,6 +41,7 @@ interface IAddAccessRule {
|
||||
modalOpen: boolean;
|
||||
onClose: () => any;
|
||||
bucket: string;
|
||||
prefilledRoute?: string;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
@@ -51,12 +55,19 @@ const AddAccessRule = ({
|
||||
onClose,
|
||||
classes,
|
||||
bucket,
|
||||
prefilledRoute,
|
||||
}: IAddAccessRule) => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [prefix, setPrefix] = useState("");
|
||||
const [selectedAccess, setSelectedAccess] = useState<any>("readonly");
|
||||
|
||||
useEffect(() => {
|
||||
if (prefilledRoute) {
|
||||
setPrefix(prefilledRoute);
|
||||
}
|
||||
}, [prefilledRoute]);
|
||||
|
||||
const accessOptions = [
|
||||
{ label: "readonly", value: "readonly" },
|
||||
{ label: "writeonly", value: "writeonly" },
|
||||
@@ -75,6 +86,7 @@ const AddAccessRule = ({
|
||||
access: selectedAccess,
|
||||
})
|
||||
.then((res: any) => {
|
||||
dispatch(setSnackBarMessage("Access Rule added successfully"));
|
||||
onClose();
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
@@ -86,7 +98,7 @@ const AddAccessRule = ({
|
||||
return (
|
||||
<ModalWrapper
|
||||
modalOpen={modalOpen}
|
||||
title="Add Access Rule"
|
||||
title="Add Anonymous Access Rule"
|
||||
onClose={onClose}
|
||||
titleIcon={<AddAccessRuleIcon />}
|
||||
>
|
||||
|
||||
@@ -61,7 +61,7 @@ const DeleteAccessRule = ({
|
||||
|
||||
return (
|
||||
<ConfirmDialog
|
||||
title={`Delete Access Rule`}
|
||||
title={`Delete Anonymous Access Rule`}
|
||||
confirmText={"Delete"}
|
||||
isOpen={modalOpen}
|
||||
isLoading={deleteLoading}
|
||||
|
||||
@@ -87,7 +87,7 @@ const EditAccessRule = ({
|
||||
<React.Fragment>
|
||||
<ModalWrapper
|
||||
modalOpen={modalOpen}
|
||||
title={`Edit Access Rule for ${`${bucket}/${toEdit || ""}`}`}
|
||||
title={`Edit Anonymous Access Rule for ${`${bucket}/${toEdit || ""}`}`}
|
||||
onClose={onClose}
|
||||
titleIcon={<AddAccessRuleIcon />}
|
||||
>
|
||||
|
||||
@@ -28,6 +28,7 @@ import { useDropzone } from "react-dropzone";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import { CSSObject } from "styled-components";
|
||||
import {
|
||||
AccessRuleIcon,
|
||||
BucketsIcon,
|
||||
Button,
|
||||
DeleteIcon,
|
||||
@@ -103,6 +104,7 @@ import {
|
||||
openList,
|
||||
resetMessages,
|
||||
resetRewind,
|
||||
setAnonymousAccessOpen,
|
||||
setDownloadRenameModal,
|
||||
setLoadingObjects,
|
||||
setLoadingRecords,
|
||||
@@ -133,11 +135,13 @@ import TooltipWrapper from "../../../../Common/TooltipWrapper/TooltipWrapper";
|
||||
import ListObjectsTable from "./ListObjectsTable";
|
||||
import {
|
||||
downloadSelected,
|
||||
openAnonymousAccess,
|
||||
openPreview,
|
||||
openShare,
|
||||
} from "../../../../ObjectBrowser/objectBrowserThunks";
|
||||
|
||||
import FilterObjectsSB from "../../../../ObjectBrowser/FilterObjectsSB";
|
||||
import AddAccessRule from "../../../BucketDetails/AddAccessRule";
|
||||
|
||||
const DeleteMultipleObjects = withSuspense(
|
||||
React.lazy(() => import("./DeleteMultipleObjects"))
|
||||
@@ -280,6 +284,9 @@ const ListObjects = () => {
|
||||
const colorVariants = useSelector(
|
||||
(state: AppState) => state.system.overrideStyles
|
||||
);
|
||||
const anonymousAccessOpen = useSelector(
|
||||
(state: AppState) => state.objectBrowser.anonymousAccessOpen
|
||||
);
|
||||
|
||||
const loadingBucket = useSelector(selBucketDetailsLoading);
|
||||
const bucketInfo = useSelector(selBucketDetailsInfo);
|
||||
@@ -323,6 +330,13 @@ const ListObjects = () => {
|
||||
const displayDeleteObject = hasPermission(bucketName, [
|
||||
IAM_SCOPES.S3_DELETE_OBJECT,
|
||||
]);
|
||||
const canSetAnonymousAccess = hasPermission(bucketName, [
|
||||
IAM_SCOPES.S3_GET_BUCKET_POLICY,
|
||||
IAM_SCOPES.S3_PUT_BUCKET_POLICY,
|
||||
IAM_SCOPES.S3_GET_ACTIONS,
|
||||
IAM_SCOPES.S3_PUT_ACTIONS,
|
||||
]);
|
||||
|
||||
const selectedObjects = useSelector(
|
||||
(state: AppState) => state.objectBrowser.selectedObjects
|
||||
);
|
||||
@@ -782,6 +796,10 @@ const ListObjects = () => {
|
||||
dispatch(setDownloadRenameModal(null));
|
||||
};
|
||||
|
||||
const closeAddAccessRule = () => {
|
||||
dispatch(setAnonymousAccessOpen(false));
|
||||
};
|
||||
|
||||
let createdTime = DateTime.now();
|
||||
|
||||
if (bucketInfo?.creation_date) {
|
||||
@@ -855,6 +873,21 @@ const ListObjects = () => {
|
||||
icon: <PreviewIcon />,
|
||||
tooltip: canPreviewFile ? "Preview Selected File" : "Preview unavailable",
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
dispatch(openAnonymousAccess());
|
||||
},
|
||||
label: "Anonymous Access",
|
||||
disabled:
|
||||
selectedObjects.length !== 1 ||
|
||||
!selectedObjects[0].endsWith("/") ||
|
||||
!canSetAnonymousAccess,
|
||||
icon: <AccessRuleIcon />,
|
||||
tooltip:
|
||||
selectedObjects.length === 1 && selectedObjects[0].endsWith("/")
|
||||
? "Set Anonymous Access to this Folder"
|
||||
: "Anonymous Access unavailable",
|
||||
},
|
||||
{
|
||||
action: () => {
|
||||
setDeleteMultipleOpen(true);
|
||||
@@ -925,6 +958,14 @@ const ListObjects = () => {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{anonymousAccessOpen && (
|
||||
<AddAccessRule
|
||||
onClose={closeAddAccessRule}
|
||||
bucket={bucketName}
|
||||
modalOpen={anonymousAccessOpen}
|
||||
prefilledRoute={`${selectedObjects[0]}*`}
|
||||
/>
|
||||
)}
|
||||
|
||||
<PageLayout variant={"full"}>
|
||||
{anonymousMode && (
|
||||
|
||||
@@ -67,6 +67,7 @@ const initialState: ObjectBrowserState = {
|
||||
previewOpen: false,
|
||||
shareFileModalOpen: false,
|
||||
isOpeningObjectDetail: false,
|
||||
anonymousAccessOpen: false,
|
||||
retentionConfig: {
|
||||
mode: "",
|
||||
unit: "",
|
||||
@@ -361,6 +362,9 @@ export const objectBrowserSlice = createSlice({
|
||||
setLongFileOpen: (state, action: PayloadAction<boolean>) => {
|
||||
state.longFileOpen = action.payload;
|
||||
},
|
||||
setAnonymousAccessOpen: (state, action: PayloadAction<boolean>) => {
|
||||
state.anonymousAccessOpen = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
export const {
|
||||
@@ -407,6 +411,7 @@ export const {
|
||||
setRetentionConfig,
|
||||
setSelectedBucket,
|
||||
setLongFileOpen,
|
||||
setAnonymousAccessOpen,
|
||||
} = objectBrowserSlice.actions;
|
||||
|
||||
export default objectBrowserSlice.reducer;
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
cancelObjectInList,
|
||||
completeObject,
|
||||
failObject,
|
||||
setAnonymousAccessOpen,
|
||||
setDownloadRenameModal,
|
||||
setNewObject,
|
||||
setPreviewOpen,
|
||||
@@ -155,3 +156,17 @@ export const openShare = createAsyncThunk(
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export const openAnonymousAccess = createAsyncThunk(
|
||||
"objectBrowser/openAnonymousAccess",
|
||||
async (_, { getState, dispatch }) => {
|
||||
const state = getState() as AppState;
|
||||
|
||||
if (
|
||||
state.objectBrowser.selectedObjects.length === 1 &&
|
||||
state.objectBrowser.selectedObjects[0].endsWith("/")
|
||||
) {
|
||||
dispatch(setAnonymousAccessOpen(true));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -95,6 +95,7 @@ export interface ObjectBrowserState {
|
||||
isOpeningObjectDetail: boolean;
|
||||
retentionConfig: IRetentionConfig | null;
|
||||
longFileOpen: boolean;
|
||||
anonymousAccessOpen: boolean;
|
||||
}
|
||||
|
||||
export interface ObjectManager {
|
||||
|
||||
@@ -4877,10 +4877,10 @@ destroy@1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
|
||||
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
|
||||
|
||||
detect-gpu@^5.0.15:
|
||||
version "5.0.15"
|
||||
resolved "https://registry.yarnpkg.com/detect-gpu/-/detect-gpu-5.0.15.tgz#d375f89b246f21167859efbbd89eff60ccbcfd4d"
|
||||
integrity sha512-ImImgPRhTvo/bmtotR1KG534ZE+L6yIV9sMe4y3zOUzeInnYk/9KOBqxz9M5hKkHXhGKKjY04pMrLMb+rp3FWw==
|
||||
detect-gpu@^5.0.16:
|
||||
version "5.0.16"
|
||||
resolved "https://registry.yarnpkg.com/detect-gpu/-/detect-gpu-5.0.16.tgz#a42054724f4a75d667add68ad1073c80d29ef733"
|
||||
integrity sha512-6+o6Sy+FzgQJG7Ray0fN7B4kRGGPuyaM5FHXJ4N3sLcQhsUO9+NEw9emM7vxN7DroZGG16ZydCX6kpgDmNXyKQ==
|
||||
dependencies:
|
||||
webgl-constants "^1.1.1"
|
||||
|
||||
@@ -8316,14 +8316,14 @@ mdn-data@2.0.4:
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b"
|
||||
integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==
|
||||
|
||||
"mds@https://github.com/minio/mds.git#v0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://github.com/minio/mds.git#8beec5b36aef3ba4c389b170a0108f301a5f29e3"
|
||||
"mds@https://github.com/minio/mds.git#v0.3.2":
|
||||
version "0.3.2"
|
||||
resolved "https://github.com/minio/mds.git#85654388adaec4d2624b61bee439c7d9cd5801f7"
|
||||
dependencies:
|
||||
"@types/styled-components" "^5.1.25"
|
||||
detect-gpu "^5.0.15"
|
||||
detect-gpu "^5.0.16"
|
||||
react-virtualized "^9.22.3"
|
||||
styled-components "^5.3.8"
|
||||
styled-components "^5.3.9"
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
@@ -11212,7 +11212,7 @@ style-loader@^3.3.1:
|
||||
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.2.tgz#eaebca714d9e462c19aa1e3599057bc363924899"
|
||||
integrity sha512-RHs/vcrKdQK8wZliteNK4NKzxvLBzpuHMqYmUVWeKa6MkaIQ97ZTOS0b+zapZhy6GcrgWnvWYCMHRirC3FsUmw==
|
||||
|
||||
styled-components@^5.3.8, styled-components@^5.3.9:
|
||||
styled-components@^5.3.9:
|
||||
version "5.3.9"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.9.tgz#641af2a8bb89904de708c71b439caa9633e8f0ba"
|
||||
integrity sha512-Aj3kb13B75DQBo2oRwRa/APdB5rSmwUfN5exyarpX+x/tlM/rwZA2vVk2vQgVSP6WKaZJHWwiFrzgHt+CLtB4A==
|
||||
|
||||
Reference in New Issue
Block a user