github.com/minio/console@v1.4.1/web-app/src/screens/Console/Buckets/BucketDetails/SetAccessPolicy.tsx (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2021 MinIO, Inc.
     3  //
     4  // This program is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Affero General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // This program is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  // GNU Affero General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Affero General Public License
    15  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16  
    17  import React, { useEffect, useState, Fragment } from "react";
    18  import { api } from "api";
    19  import { BucketAccess } from "api/consoleApi";
    20  import { errorToHandler } from "api/errors";
    21  import {
    22    Box,
    23    Button,
    24    ChangeAccessPolicyIcon,
    25    FormLayout,
    26    Grid,
    27    Select,
    28  } from "mds";
    29  import { modalStyleUtils } from "../../Common/FormComponents/common/styleLibrary";
    30  import { setModalErrorSnackMessage } from "../../../../systemSlice";
    31  import { useAppDispatch } from "../../../../store";
    32  import { emptyPolicy } from "../../Policies/utils";
    33  import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
    34  import CodeMirrorWrapper from "../../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper";
    35  
    36  interface ISetAccessPolicyProps {
    37    open: boolean;
    38    bucketName: string;
    39    actualPolicy: BucketAccess | string;
    40    actualDefinition: string;
    41    closeModalAndRefresh: () => void;
    42  }
    43  
    44  const SetAccessPolicy = ({
    45    open,
    46    bucketName,
    47    actualPolicy,
    48    actualDefinition,
    49    closeModalAndRefresh,
    50  }: ISetAccessPolicyProps) => {
    51    const dispatch = useAppDispatch();
    52    const [addLoading, setAddLoading] = useState<boolean>(false);
    53    const [accessPolicy, setAccessPolicy] = useState<BucketAccess | string>("");
    54    const [policyDefinition, setPolicyDefinition] = useState<string>(emptyPolicy);
    55    const addRecord = (event: React.FormEvent) => {
    56      event.preventDefault();
    57      if (addLoading || !accessPolicy) {
    58        return;
    59      }
    60      setAddLoading(true);
    61      api.buckets
    62        .bucketSetPolicy(bucketName, {
    63          access: accessPolicy as BucketAccess,
    64          definition: policyDefinition,
    65        })
    66        .then(() => {
    67          setAddLoading(false);
    68          closeModalAndRefresh();
    69        })
    70        .catch((err) => {
    71          setAddLoading(false);
    72          dispatch(setModalErrorSnackMessage(errorToHandler(err.error)));
    73        });
    74    };
    75  
    76    useEffect(() => {
    77      setAccessPolicy(actualPolicy);
    78      setPolicyDefinition(
    79        actualDefinition
    80          ? JSON.stringify(JSON.parse(actualDefinition), null, 4)
    81          : emptyPolicy,
    82      );
    83    }, [setAccessPolicy, actualPolicy, setPolicyDefinition, actualDefinition]);
    84  
    85    return (
    86      <ModalWrapper
    87        title="Change Access Policy"
    88        modalOpen={open}
    89        onClose={() => {
    90          closeModalAndRefresh();
    91        }}
    92        titleIcon={<ChangeAccessPolicyIcon />}
    93      >
    94        <form
    95          noValidate
    96          autoComplete="off"
    97          onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
    98            addRecord(e);
    99          }}
   100        >
   101          <FormLayout withBorders={false} containerPadding={false}>
   102            <Select
   103              value={accessPolicy}
   104              label="Access Policy"
   105              id="select-access-policy"
   106              name="select-access-policy"
   107              onChange={(value) => {
   108                setAccessPolicy(value as BucketAccess);
   109              }}
   110              options={[
   111                { value: BucketAccess.PRIVATE, label: "Private" },
   112                { value: BucketAccess.PUBLIC, label: "Public" },
   113                { value: BucketAccess.CUSTOM, label: "Custom" },
   114              ]}
   115            />
   116            {accessPolicy === "PUBLIC" && (
   117              <Box
   118                className={"muted"}
   119                style={{
   120                  marginTop: "25px",
   121                  fontSize: "14px",
   122                  fontStyle: "italic",
   123                }}
   124              >
   125                * Warning: With Public access anyone will be able to upload,
   126                download and delete files from this Bucket *
   127              </Box>
   128            )}
   129            {accessPolicy === "CUSTOM" && (
   130              <Grid item xs={12}>
   131                <CodeMirrorWrapper
   132                  label={`Write Policy`}
   133                  value={policyDefinition}
   134                  onChange={(value) => {
   135                    setPolicyDefinition(value);
   136                  }}
   137                  editorHeight={"300px"}
   138                  helptip={
   139                    <Fragment>
   140                      <a
   141                        target="blank"
   142                        href="https://min.io/docs/minio/kubernetes/upstream/administration/identity-access-management/policy-based-access-control.html#policy-document-structure"
   143                      >
   144                        Guide to access policy structure
   145                      </a>
   146                    </Fragment>
   147                  }
   148                />
   149              </Grid>
   150            )}
   151          </FormLayout>
   152          <Box sx={modalStyleUtils.modalButtonBar}>
   153            <Button
   154              id={"cancel"}
   155              type="button"
   156              variant="regular"
   157              onClick={() => {
   158                closeModalAndRefresh();
   159              }}
   160              disabled={addLoading}
   161              label={"Cancel"}
   162            />
   163            <Button
   164              id={"set"}
   165              type="submit"
   166              variant="callAction"
   167              disabled={
   168                addLoading || (accessPolicy === "CUSTOM" && !policyDefinition)
   169              }
   170              label={"Set"}
   171            />
   172          </Box>
   173        </form>
   174      </ModalWrapper>
   175    );
   176  };
   177  
   178  export default SetAccessPolicy;