diff --git a/misc/visualization_tool_images/details.webp b/misc/visualization_tool_images/details.webp index fabea5c6..7ffc5b95 100644 Binary files a/misc/visualization_tool_images/details.webp and b/misc/visualization_tool_images/details.webp differ diff --git a/misc/visualization_tool_images/expand_role.webp b/misc/visualization_tool_images/expand_role.webp index fd729bea..cb41ac4b 100644 Binary files a/misc/visualization_tool_images/expand_role.webp and b/misc/visualization_tool_images/expand_role.webp differ diff --git a/misc/visualization_tool_images/filter.webp b/misc/visualization_tool_images/filter.webp index 5b70ff9e..ce89401a 100644 Binary files a/misc/visualization_tool_images/filter.webp and b/misc/visualization_tool_images/filter.webp differ diff --git a/misc/visualization_tool_images/iam_policies.webp b/misc/visualization_tool_images/iam_policies.webp index 3124c279..f2a52c57 100644 Binary files a/misc/visualization_tool_images/iam_policies.webp and b/misc/visualization_tool_images/iam_policies.webp differ diff --git a/misc/visualization_tool_images/search_resources.webp b/misc/visualization_tool_images/search_resources.webp index 5702712a..58a86f15 100644 Binary files a/misc/visualization_tool_images/search_resources.webp and b/misc/visualization_tool_images/search_resources.webp differ diff --git a/misc/visualization_tool_images/search_role.webp b/misc/visualization_tool_images/search_role.webp index 5c4a4a56..7c74e941 100644 Binary files a/misc/visualization_tool_images/search_role.webp and b/misc/visualization_tool_images/search_role.webp differ diff --git a/misc/visualization_tool_images/sort.webp b/misc/visualization_tool_images/sort.webp index 75800f00..2a46112c 100644 Binary files a/misc/visualization_tool_images/sort.webp and b/misc/visualization_tool_images/sort.webp differ diff --git a/misc/visualization_tool_images/start_page.webp b/misc/visualization_tool_images/start_page.webp index 5c6eb27e..e994304b 100644 Binary files a/misc/visualization_tool_images/start_page.webp and b/misc/visualization_tool_images/start_page.webp differ diff --git a/misc/visualization_tool_images/upload.webp b/misc/visualization_tool_images/upload.webp index 6e4f5931..c7d32d72 100644 Binary files a/misc/visualization_tool_images/upload.webp and b/misc/visualization_tool_images/upload.webp differ diff --git a/visualization_tool/docs/USAGE.md b/visualization_tool/docs/USAGE.md index 5d15284e..4058220b 100644 --- a/visualization_tool/docs/USAGE.md +++ b/visualization_tool/docs/USAGE.md @@ -8,13 +8,13 @@ To run the tool, you can use the following command `gcp-scanner-visualizer`. The Then you can open your browser and navigate to `http://localhost:8080` to use the tool. -![GCP Scanner Visualizer](../misc/visualization_tool_images/start_page.webp) +![GCP Scanner Visualizer](../../misc/visualization_tool_images/start_page.webp) ## Uploading the results -To upload the results, head to the `Upload` Section and click on the `Choose File` button. Then select the JSON file that you want to upload and click on the `Plus` icon. +To upload the results, head to the `Upload` Section and click on the `Choose File` button. Then choose the JSON file that you want to upload. Note that you can upload multiple files at once. -![GCP Scanner Visualizer](../misc/visualization_tool_images/upload.webp) +![GCP Scanner Visualizer](../../misc/visualization_tool_images/upload.webp) After uploading the result file, the tool will scan the file and append the results to UI. @@ -28,39 +28,39 @@ There are two main pages in the tool: This is the main page and it shows the list of resources that were found in the result file. You can click on the `Details` button to see more details about the resource. -![GCP Scanner Visualizer](../misc/visualization_tool_images/details.webp) +![GCP Scanner Visualizer](../../misc/visualization_tool_images/details.webp) #### Sorting and filtering resources You can sort the shown resources by their name or creation time. By default, the resources are sorted by their creation date in descending order and you can change the sorting type from the `Sort` Section on the left menu. -![GCP Scanner Visualizer](../misc/visualization_tool_images/sort.webp) +![GCP Scanner Visualizer](../../misc/visualization_tool_images/sort.webp) The tool provides several options to filter the resources. You can filter the resources by: - Project - Resource Type -![GCP Scanner Visualizer](../misc/visualization_tool_images/filter.webp) +![GCP Scanner Visualizer](../../misc/visualization_tool_images/filter.webp) #### Searching for resources You can search for resources by their name in the search bar. The tool will show the resources that contain the search term in their name. -![GCP Scanner Visualizer](../misc/visualization_tool_images/search_resources.webp) +![GCP Scanner Visualizer](../../misc/visualization_tool_images/search_resources.webp) ### IAM Policy Page -This page shows the list of IAM policies that were found in the result file. The policies are visualized in a table view with each row represents a single role and the roles names prefixed with the project name. +This page shows the list of IAM policies that were found in the result file. The policies are visualized in a table view with each row represents a single role. The roles are grouped by the project that they belong to. -![GCP Scanner Visualizer](../misc/visualization_tool_images/iam_policies.webp) +![GCP Scanner Visualizer](../../misc/visualization_tool_images/iam_policies.webp) To see the members of a role, you can click on the icon next to the role name to expand the role. -![GCP Scanner Visualizer](../misc/visualization_tool_images/expand_role.webp) +![GCP Scanner Visualizer](../../misc/visualization_tool_images/expand_role.webp) #### Searching for IAM policies You can search for a member in the IAM policies by using the search bar. The tool will show the policies that contain the email address of the member in the search bar. -![GCP Scanner Visualizer](../misc/visualization_tool_images/search_role.webp) +![GCP Scanner Visualizer](../../misc/visualization_tool_images/search_role.webp) diff --git a/visualization_tool/src/components/ResourcesList/ResourcesList.css b/visualization_tool/src/components/ResourcesList/ResourcesList.css index c76e1ce1..90965f7d 100644 --- a/visualization_tool/src/components/ResourcesList/ResourcesList.css +++ b/visualization_tool/src/components/ResourcesList/ResourcesList.css @@ -16,20 +16,15 @@ .resources-list__table { display: flex; flex-wrap: wrap; - gap: 20px; + gap: 15px; } .resources-list__table__card { width: 210px; - padding: 10px 12px 30px 12px; + padding: 20px 15px 25px 15px; box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.25); } -.resources-list__table__card img { - width: 55px; - margin-bottom: 10px; -} - .resource-name { color: #000; font-family: Inter; @@ -42,12 +37,22 @@ overflow: hidden; } +.resources-image { + width: 40px; +} + .resource-type { color: #a3a3a3; font-family: Inter; font-size: 16px; font-weight: 400; - margin-bottom: 20px; +} + +.resource-type_container { + display: flex; + align-items: center; + gap: 5px; + margin-block: 10px; } .resource-status { diff --git a/visualization_tool/src/components/ResourcesList/ResourcesList.tsx b/visualization_tool/src/components/ResourcesList/ResourcesList.tsx index fb300361..b8af4ef8 100644 --- a/visualization_tool/src/components/ResourcesList/ResourcesList.tsx +++ b/visualization_tool/src/components/ResourcesList/ResourcesList.tsx @@ -44,9 +44,11 @@ const ResourcesList = ({ {filteredResources.map(resource => { return (
-

{resource.name}

-

{resource.type}

+
+ +

{resource.type}

+

{ const filteredRoles = useFilter(roles, emailQuery, allowedProjects); - // console.log(filteredRoles); + const projects = [...new Set(roles.map(role => role.projectId))]; return (

{roles.length > 0 ? 'Found Roles' : 'No Roles Found'}

{filteredRoles.length > 0 && ( - +
{ Role @@ -47,9 +47,46 @@ const RolesList = ({roles, emailQuery, allowedProjects}: RolesListProps) => { - {filteredRoles.map(role => ( - - ))} + { + // create a outer cell for each project + projects.map(project => { + // filter roles by project + const projectRoles = filteredRoles.filter( + role => role.projectId === project + ); + return ( + <> + + + + {project} + + + { + // create a row for each role + projectRoles.map(role => ( + + )) + } + + ); + }) + }
diff --git a/visualization_tool/src/components/RolesList/partials/Row.tsx b/visualization_tool/src/components/RolesList/partials/Row.tsx index 69009325..3d77e305 100644 --- a/visualization_tool/src/components/RolesList/partials/Row.tsx +++ b/visualization_tool/src/components/RolesList/partials/Row.tsx @@ -33,14 +33,7 @@ const Row = ({row}: RowProps) => { {open ? : } - + {row.role} diff --git a/visualization_tool/src/parser/parser.ts b/visualization_tool/src/parser/parser.ts index 17e4ae8c..2d82ecd5 100644 --- a/visualization_tool/src/parser/parser.ts +++ b/visualization_tool/src/parser/parser.ts @@ -73,7 +73,7 @@ const parseIAMRoles = (data: OutputFile, fileName: string) => { roles.push({ file: fileName, projectId, - role: `${projectId}__${role.role.split('/')[1]}`, + role: `${role.role.split('/')[1]}`, members: role.members.map(member => { return { memberType: member.split(':')[0],