github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/webui/src/pages/auth/policies/index.jsx (about)

     1  import React, {useEffect, useState} from "react";
     2  import { useOutletContext } from "react-router-dom";
     3  import Button from "react-bootstrap/Button";
     4  
     5  import {auth} from "../../../lib/api";
     6  import {useAPIWithPagination} from "../../../lib/hooks/api";
     7  import {ConfirmationButton} from "../../../lib/components/modals";
     8  import {Paginator} from "../../../lib/components/pagination";
     9  import {PolicyEditor} from "../../../lib/components/policy";
    10  import {
    11      ActionGroup,
    12      ActionsBar,
    13      Checkbox,
    14      DataTable,
    15      AlertError,
    16      FormattedDate,
    17      Loading,
    18      RefreshButton,
    19      Warning,
    20  } from "../../../lib/components/controls";
    21  import {useRouter} from "../../../lib/hooks/router";
    22  import {useLoginConfigContext} from "../../../lib/hooks/conf";
    23  import {Link} from "../../../lib/components/nav";
    24  import { disallowPercentSign, INVALID_POLICY_ID_ERROR_MESSAGE } from "../validation";
    25  
    26  
    27  const PoliciesContainer = () => {
    28      const [selected, setSelected] = useState([]);
    29      const [deleteError, setDeleteError] = useState(null);
    30      const [showCreate, setShowCreate] = useState(false);
    31      const [refresh, setRefresh] = useState(false);
    32      const [createModalError, setCreateModalError] = useState(null);
    33  
    34      const router = useRouter();
    35      const after = (router.query.after) ? router.query.after : "";
    36      const { results, loading, error, nextPage } =  useAPIWithPagination(() => {
    37          return auth.listPolicies("", after);
    38      }, [after, refresh]);
    39  
    40      useEffect(() => { setSelected([]); }, [after, refresh]);
    41  
    42      const {RBAC: rbac} = useLoginConfigContext();
    43  
    44      if (error) return <AlertError error={error}/>;
    45      if (loading) return <Loading/>;
    46  
    47      return (
    48          <>
    49              <ActionsBar>
    50                  <ActionGroup orientation="left">
    51                      <Button
    52                          variant="success"
    53                          onClick={() => setShowCreate(true)}>
    54                          Create Policy
    55                      </Button>
    56  
    57                      <ConfirmationButton
    58                          onConfirm={() => {
    59                              auth.deletePolicies(selected.map(p => p.id))
    60                                  .catch(err => setDeleteError(err))
    61                                  .then(() => {
    62                                      setSelected([]);
    63                                      setRefresh(!refresh);
    64                                  });
    65                          }}
    66                          disabled={(selected.length === 0)}
    67                          variant="danger"
    68                          msg={`Are you sure you'd like to delete ${selected.length} policies?`}>
    69                          Delete Selected
    70                      </ConfirmationButton>
    71                  </ActionGroup>
    72                  <ActionGroup orientation="right">
    73                      <RefreshButton onClick={() => setRefresh(!refresh)}/>
    74                  </ActionGroup>
    75              </ActionsBar>
    76              {rbac === 'simplified' && <Warning>
    77                                  <b>Deprecation Notice:</b> RBAC (Role-Based Access Control) is being deprecated
    78                                  and will be replaced by ACL (Access Control Lists) in future releases.
    79                                  For more information on the transition from RBAC to ACL, please visit
    80                                  our <a href="https://docs.lakefs.io/posts/security_update.html">documentation page</a>.
    81                              </Warning>}
    82              <div className="auth-learn-more">
    83                  A policy defines the permissions of a user or a group. <a href="https://docs.lakefs.io/reference/authorization.html#authorization" target="_blank" rel="noopener noreferrer">Learn more.</a>
    84              </div>
    85  
    86              {(!!deleteError) && <AlertError error={deleteError}/>}
    87  
    88              <PolicyEditor
    89                  onSubmit={(policyId, policyBody) => {
    90                      return auth.createPolicy(policyId, policyBody).then(() => {
    91                          setSelected([]);
    92                          setCreateModalError(null);
    93                          setShowCreate(false);
    94                          setRefresh(!refresh);
    95                      }).catch((err) => {
    96                          setCreateModalError(err.message);
    97                      })
    98                  }}
    99                  onHide={() => {
   100                      setCreateModalError(null);
   101                      setShowCreate(false)
   102                  }}
   103                  show={showCreate}
   104                  validationFunction={disallowPercentSign(INVALID_POLICY_ID_ERROR_MESSAGE)}
   105                  externalError={createModalError}
   106              />
   107  
   108              <DataTable
   109                  results={results}
   110                  headers={['', 'Policy ID', 'Created At']}
   111                  keyFn={policy => policy.id}
   112                  rowFn={policy => [
   113                      <Checkbox
   114                          name={policy.id}
   115                          onAdd={() => setSelected([...selected, policy])}
   116                          onRemove={() => setSelected(selected.filter(p => p !== policy))}
   117                      />,
   118                      <Link href={{pathname: '/auth/policies/:policyId', params: {policyId: policy.id}}}>
   119                          {policy.id}
   120                      </Link>,
   121                      <FormattedDate dateValue={policy.creation_date}/>
   122                  ]}/>
   123  
   124              <Paginator
   125                  nextPage={nextPage}
   126                  after={after}
   127                  onPaginate={after => router.push({pathname: '/auth/policies', query: {after}})}
   128              />
   129          </>
   130      );
   131  };
   132  
   133  
   134  const PoliciesPage = () => {
   135      const [setActiveTab] = useOutletContext();
   136      useEffect(() => setActiveTab("policies"), [setActiveTab]);
   137      return <PoliciesContainer/>;
   138  };
   139  
   140  export default PoliciesPage;