github.com/minio/console@v1.4.1/web-app/src/screens/Console/Policies/PolicyView.tsx (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2022 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, { Fragment, useState } from "react"; 18 import { DisabledIcon, EnabledIcon, Box, Grid, HelpTip } from "mds"; 19 import SearchBox from "../Common/SearchBox"; 20 import { STATUS_COLORS } from "../Dashboard/BasicDashboard/Utils"; 21 import { IAMStatement } from "./types"; 22 23 const rowGridStyle = { 24 display: "grid", 25 gridTemplateColumns: "70px 1fr", 26 gap: 15, 27 }; 28 29 const escapeRegExp = (str = "") => 30 str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); 31 32 const Highlight = ({ search = "", children = "" }): any => { 33 const txtParts = new RegExp(`(${escapeRegExp(search)})`, "i"); 34 const parts = String(children).split(txtParts); 35 36 if (search) { 37 return parts.map((part, index) => 38 txtParts.test(part) ? <mark key={index}>{part}</mark> : part, 39 ); 40 } else { 41 return children; 42 } 43 }; 44 45 const PolicyView = ({ 46 policyStatements, 47 }: { 48 policyStatements: IAMStatement[]; 49 }) => { 50 const [filter, setFilter] = useState<string>(""); 51 52 return ( 53 <Grid container> 54 <Grid item xs={12}> 55 <Grid container sx={{ display: "flex", alignItems: "center" }}> 56 <HelpTip 57 content={ 58 <Fragment> 59 Define which actions are permitted on a specified resource. 60 Learn more about{" "} 61 <a 62 target="blank" 63 href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html" 64 > 65 IAM conditional statements 66 </a> 67 . 68 </Fragment> 69 } 70 placement="right" 71 > 72 <Grid item xs={12} sm={6} sx={{ fontWeight: "bold" }}> 73 Statements 74 </Grid> 75 </HelpTip> 76 <Grid 77 item 78 xs={12} 79 sm={6} 80 sx={{ display: "flex", justifyContent: "flex-end" }} 81 > 82 <SearchBox 83 placeholder={"Search"} 84 onChange={setFilter} 85 value={filter} 86 sx={{ 87 maxWidth: 380, 88 }} 89 /> 90 </Grid> 91 </Grid> 92 </Grid> 93 {!policyStatements && <Fragment>Policy has no statements</Fragment>} 94 {policyStatements && ( 95 <Grid 96 item 97 xs={12} 98 sx={{ 99 "& .policy-row": { 100 borderBottom: "1px solid #eaeaea", 101 }, 102 "& .policy-row:first-child": { 103 borderTop: "1px solid #eaeaea", 104 }, 105 "& .policy-row:last-child": { 106 borderBottom: "0px", 107 }, 108 paddingTop: "15px", 109 "& mark": { 110 color: "#000000", 111 fontWeight: 500, 112 }, 113 }} 114 > 115 {policyStatements.map((stmt, i) => { 116 const effect = stmt.Effect; 117 const isAllow = effect === "Allow"; 118 return ( 119 <Box 120 className="policy-row" 121 key={`${i}`} 122 sx={{ 123 display: "grid", 124 gridTemplateColumns: "1fr", 125 gap: "15px", 126 fontSize: "14px", 127 padding: "10px 0 10px 0", 128 "& .label": { 129 fontWeight: 600, 130 }, 131 }} 132 > 133 <Box sx={rowGridStyle}> 134 <Box className="label">Effect:</Box> 135 <Box 136 sx={{ 137 display: "flex", 138 139 alignItems: "center", 140 "& .min-icon": { 141 marginRight: "5px", 142 fill: isAllow ? STATUS_COLORS.GREEN : STATUS_COLORS.RED, 143 height: "14px", 144 width: "14px", 145 }, 146 }} 147 > 148 {isAllow ? <EnabledIcon /> : <DisabledIcon />} 149 {effect} 150 </Box> 151 </Box> 152 <Grid container sx={{ gap: 15 }}> 153 <Grid item xs={12} sm={6} sx={rowGridStyle}> 154 <Box className="label">Actions:</Box> 155 <Box> 156 {stmt.Action && 157 stmt.Action.map((act, actIndex) => ( 158 <div key={`${i}-r-${actIndex}`}> 159 <Highlight search={filter}>{act}</Highlight> 160 </div> 161 ))} 162 </Box> 163 </Grid> 164 <Grid item xs={12} sm={6} sx={rowGridStyle}> 165 <Box className="label">Resources:</Box> 166 <Box> 167 {stmt.Resource && 168 stmt.Resource.map((res, resIndex) => ( 169 <div key={`${i}-r-${resIndex}`}> 170 {" "} 171 <Highlight search={filter}>{res}</Highlight> 172 </div> 173 ))} 174 </Box> 175 </Grid> 176 </Grid> 177 </Box> 178 ); 179 })} 180 </Grid> 181 )} 182 </Grid> 183 ); 184 }; 185 186 export default PolicyView;