diff --git a/src/components/SearchContainer/TabContainer.jsx b/src/components/SearchContainer/TabContainer.jsx
index 3fa5b51d3..c746db5a9 100644
--- a/src/components/SearchContainer/TabContainer.jsx
+++ b/src/components/SearchContainer/TabContainer.jsx
@@ -34,6 +34,8 @@ import BaseNodeData from "./Tabs/BaseNodeData";
import ContainerNodeData from "./Tabs/ContainerNodeData";
import AZManagementGroupNodeData from "./Tabs/AZManagementGroupNodeData";
import AZRoleNodeData from "./Tabs/AZRoleNodeData";
+import AZStorageAccountNodeData from './Tabs/AZStorageAccountNodeData';
+import AZStorageContainerNodeData from './Tabs/AZStorageContainerNodeData';
class TabContainer extends Component {
@@ -64,6 +66,11 @@ class TabContainer extends Component {
azTenantVisible: false,
azVMVisible: false,
azServicePrincipalVisible: false,
+ azStorageAccountVisible: false,
+ azStorageContainerVisible: false,
+ azAutomationAccountVisible: false,
+ azLogicAppVisible: false,
+ azWebAppVisible: false,
azAppVisible: false,
azManagementGroupVisible: false,
azRoleVisible: false,
@@ -136,7 +143,18 @@ class TabContainer extends Component {
this._azManagementGroupNodeClicked()
} else if (type === 'AZRole') {
this._azRoleNodeClicked()
+ } else if (type === 'AZStorageAccount') {
+ this._azStorageAccountNodeClicked();
+ } else if (type === 'AZStorageContainer') {
+ this._azStorageContainerNodeClicked();
+ } else if (type === 'AZAutomationAccount') {
+ this._azAutomationAccountNodeClicked();
+ } else if (type === 'AZLogicApp') {
+ this._azLogicAppNodeClicked();
+ } else if (type === 'AZWebApp') {
+ this._azWebAppNodeClicked();
}
+
}
componentDidMount() {
@@ -369,6 +387,46 @@ class TabContainer extends Component {
});
}
+ _azStorageAccountNodeClicked() {
+ this.clearVisible()
+ this.setState({
+ azStorageAccountVisible: true,
+ selected: 2
+ });
+ }
+
+ _azStorageContainerNodeClicked() {
+ this.clearVisible()
+ this.setState({
+ azStorageContainerVisible: true,
+ selected: 2
+ });
+ }
+
+ _azAutomationAccountNodeClicked() {
+ this.clearVisible()
+ this.setState({
+ azAutomationAccountVisible: true,
+ selected: 2
+ });
+ }
+
+ _azLogicAppNodeClicked() {
+ this.clearVisible()
+ this.setState({
+ azLogicAppVisible: true,
+ selected: 2
+ });
+ }
+
+ _azWebAppNodeClicked() {
+ this.clearVisible()
+ this.setState({
+ azWebAppVisible: true,
+ selected: 2
+ });
+ }
+
_azAppNodeClicked() {
this.clearVisible()
this.setState({
@@ -421,6 +479,11 @@ class TabContainer extends Component {
!this.state.azTenantVisible &&
!this.state.azVMVisible &&
!this.state.azServicePrincipalVisible &&
+ !this.state.azStorageAccountVisble &&
+ !this.state.azStorageContainerVisble &&
+ !this.state.azAutomationAccountVisible &&
+ !this.state.azLogicAppVisible &&
+ !this.state.azWebAppVisible &&
!this.state.azAppVisible &&
!this.state.baseVisible &&
!this.state.azManagementGroupVisible &&
@@ -465,6 +528,11 @@ class TabContainer extends Component {
+
+
+
+
+
diff --git a/src/components/SearchContainer/Tabs/AZAutomationAccountNodeData.jsx b/src/components/SearchContainer/Tabs/AZAutomationAccountNodeData.jsx
index c13f82028..2ae7fd8f7 100644
--- a/src/components/SearchContainer/Tabs/AZAutomationAccountNodeData.jsx
+++ b/src/components/SearchContainer/Tabs/AZAutomationAccountNodeData.jsx
@@ -75,18 +75,28 @@ const AZAutomationAccountNodeData = () => {
property='See Automation Account within Tenant'
query='MATCH p = (d:AZTenant)-[r:AZContains*1..]->(u:AZAutomationAccount {objectid: $objectid}) RETURN p'
/>
- (n)'
+
+ (n) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p=(:AZAutomationAccount {objectid:$objectid})-[:AZManagedIdentity]->(n) RETURN p'
}
+ start={label}
property={'Managed Identities'}
target={objectid}
+ distinct
/>
-
+
{
properties={nodeProps}
label={label}
/>
-
+
{
properties={nodeProps}
label={label}
/>
-
+
+
+
+
+ (u:AZAutomationAccount {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:Owner*1..]->(u:AZAutomationAccount {objectid: $objectid}) RETURN p'
+ }
+ property={'Automation Account Owners'}
+ target={objectid}
+ />
+ (u:AZAutomationAccount {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:Contributor*1..]->(u:AZAutomationAccount {objectid: $objectid}) RETURN p'
+ }
+ property={'Automation Account Contributors'}
+ target={objectid}
+ />
+ (u:AZAutomationAccount {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:UserAccessAdministrator*1..]->(u:AZAutomationAccount {objectid: $objectid}) RETURN p'
+ }
+ property={'User Access Administrators'}
+ target={objectid}
+ />
+ (u:AZAutomationAccount {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r]->(u:AZAutomationAccount {objectid: $objectid}) RETURN p'
+ }
+ property={'All Relations'}
+ target={objectid}
+ />
+
@@ -141,7 +195,6 @@ const AZAutomationAccountNodeData = () => {
-
);
diff --git a/src/components/SearchContainer/Tabs/AZLogicAppNodeData.jsx b/src/components/SearchContainer/Tabs/AZLogicAppNodeData.jsx
index 037f4d00b..e61bee72b 100644
--- a/src/components/SearchContainer/Tabs/AZLogicAppNodeData.jsx
+++ b/src/components/SearchContainer/Tabs/AZLogicAppNodeData.jsx
@@ -75,18 +75,27 @@ const AZLogicAppNodeData = () => {
property='See Logic App within Tenant'
query='MATCH p = (d:AZTenant)-[r:AZContains*1..]->(u:AZLogicApp {objectid: $objectid}) RETURN p'
/>
- (n)'
+
+ (n) RETURN COUNT(p)'
}
+ graphQuery={
+ 'MATCH p=(:AZLogicApp {objectid:$objectid})-[:AZManagedIdentity]->(n) RETURN p'
+ }
+ start={label}
property={'Managed Identities'}
target={objectid}
+ distinct
/>
-
{
properties={nodeProps}
label={label}
/>
-
{
properties={nodeProps}
label={label}
/>
-
+
-
+
+ (u:AZLogicApp {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:Owner*1..]->(u:AZLogicApp {objectid: $objectid}) RETURN p'
+ }
+ property={'Logic App Owners'}
+ target={objectid}
+ />
+ (u:AZLogicApp {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:Contributor*1..]->(u:AZLogicApp {objectid: $objectid}) RETURN p'
+ }
+ property={'Logic App Contributors'}
+ target={objectid}
+ />
+ (u:AZLogicApp {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:UserAccessAdministrator*1..]->(u:AZLogicApp {objectid: $objectid}) RETURN p'
+ }
+ property={'User Access Administrators'}
+ target={objectid}
+ />
+ (u:AZLogicApp {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r]->(u:AZLogicApp {objectid: $objectid}) RETURN p'
+ }
+ property={'All Relations'}
+ target={objectid}
+ />
+
+
+
+
+
+
{
end={label}
distinct
/>
-
-
-
-
+
);
diff --git a/src/components/SearchContainer/Tabs/AZStorageAccountNodeData.jsx b/src/components/SearchContainer/Tabs/AZStorageAccountNodeData.jsx
new file mode 100644
index 000000000..bb7b116c7
--- /dev/null
+++ b/src/components/SearchContainer/Tabs/AZStorageAccountNodeData.jsx
@@ -0,0 +1,204 @@
+import React, { useContext, useEffect, useState } from 'react';
+import clsx from 'clsx';
+import CollapsibleSection from './Components/CollapsibleSection';
+import NodeCypherLinkComplex from './Components/NodeCypherLinkComplex';
+import NodeCypherLink from './Components/NodeCypherLink';
+import NodeCypherNoNumberLink from './Components/NodeCypherNoNumberLink';
+import MappedNodeProps from './Components/MappedNodeProps';
+import ExtraNodeProps from './Components/ExtraNodeProps';
+import NodePlayCypherLink from './Components/NodePlayCypherLink';
+import { Table } from 'react-bootstrap';
+import styles from './NodeData.module.css';
+import { AppContext } from '../../../AppContext';
+
+const AZStorageAccountNodeData = () => {
+ const [visible, setVisible] = useState(false);
+ const [objectid, setObjectid] = useState(null);
+ const [label, setLabel] = useState(null);
+ const [domain, setDomain] = useState(null);
+ const [nodeProps, setNodeProps] = useState({});
+ const context = useContext(AppContext);
+
+ useEffect(() => {
+ emitter.on('nodeClicked', nodeClickEvent);
+
+ return () => {
+ emitter.removeListener('nodeClicked', nodeClickEvent);
+ };
+ }, []);
+
+ const nodeClickEvent = (type, id, blocksinheritance, domain) => {
+ if (type === 'AZStorageAccount') {
+ setVisible(true);
+ setObjectid(id);
+ setDomain(domain);
+ let session = driver.session();
+ session
+ .run(`MATCH (n:AZStorageAccount {objectid: $objectid}) RETURN n AS node`, {
+ objectid: id,
+ })
+ .then((r) => {
+ let props = r.records[0].get('node').properties;
+ setNodeProps(props);
+ setLabel(props.name || props.azname || objectid);
+ session.close();
+ });
+ } else {
+ setObjectid(null);
+ setVisible(false);
+ }
+ };
+
+ const displayMap = {
+ objectid: 'Object ID',
+ };
+
+ return objectid === null ? (
+
+ ) : (
+
+
+
{label || objectid}
+
+
+
+
+
+
+
+
+ (n) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p=(:AZStorageAccount {objectid:$objectid})-[:AZManagedIdentity]->(n) RETURN p'
+ }
+ start={label}
+ property={'Managed Identities'}
+ target={objectid}
+ distinct
+ />
+ (d) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (u:AZStorageAccount {objectid: $objectid})-[r:AZContains*1..]->(d) RETURN p'
+ }
+ property={'Storage Containers'}
+ target={objectid}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (u:AZStorageAccount {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:Owner*1..]->(u:AZStorageAccount {objectid: $objectid}) RETURN p'
+ }
+ property={'Storage Account Owners'}
+ target={objectid}
+ />
+ (u:AZStorageAccount {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:Contributor*1..]->(u:AZStorageAccount {objectid: $objectid}) RETURN p'
+ }
+ property={'Storage Account Contributors'}
+ target={objectid}
+ />
+ (u:AZStorageAccount {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:ReaderAndDataAccess*1..]->(u:AZStorageAccount {objectid: $objectid}) RETURN p'
+ }
+ property={'Storage Account Data Readers'}
+ target={objectid}
+ />
+ (u:AZStorageAccount {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:StorageAccountKeyOperator*1..]->(u:AZStorageAccount {objectid: $objectid}) RETURN p'
+ }
+ property={'Storage Account Key Operator'}
+ target={objectid}
+ />
+ (u:AZStorageAccount {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:UserAccessAdministrator*1..]->(u:AZStorageAccount {objectid: $objectid}) RETURN p'
+ }
+ property={'User Access Administrators'}
+ target={objectid}
+ />
+ (u:AZStorageAccount {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r]->(u:AZStorageAccount {objectid: $objectid}) RETURN p'
+ }
+ property={'All Relations'}
+ target={objectid}
+ />
+
+
+
+
+
+
+
+ );
+};
+
+AZStorageAccountNodeData.propTypes = {};
+export default AZStorageAccountNodeData;
\ No newline at end of file
diff --git a/src/components/SearchContainer/Tabs/AZStorageContainerNodeData.jsx b/src/components/SearchContainer/Tabs/AZStorageContainerNodeData.jsx
new file mode 100644
index 000000000..78037e9c4
--- /dev/null
+++ b/src/components/SearchContainer/Tabs/AZStorageContainerNodeData.jsx
@@ -0,0 +1,177 @@
+import React, { useContext, useEffect, useState } from 'react';
+import clsx from 'clsx';
+import CollapsibleSection from './Components/CollapsibleSection';
+import NodeCypherLinkComplex from './Components/NodeCypherLinkComplex';
+import NodeCypherLink from './Components/NodeCypherLink';
+import NodeCypherNoNumberLink from './Components/NodeCypherNoNumberLink';
+import MappedNodeProps from './Components/MappedNodeProps';
+import ExtraNodeProps from './Components/ExtraNodeProps';
+import NodePlayCypherLink from './Components/NodePlayCypherLink';
+import { Table } from 'react-bootstrap';
+import styles from './NodeData.module.css';
+import { AppContext } from '../../../AppContext';
+
+const AZStorageContainerNodeData = () => {
+ const [visible, setVisible] = useState(false);
+ const [objectid, setObjectid] = useState(null);
+ const [label, setLabel] = useState(null);
+ const [domain, setDomain] = useState(null);
+ const [nodeProps, setNodeProps] = useState({});
+ const context = useContext(AppContext);
+
+ useEffect(() => {
+ emitter.on('nodeClicked', nodeClickEvent);
+
+ return () => {
+ emitter.removeListener('nodeClicked', nodeClickEvent);
+ };
+ }, []);
+
+ const nodeClickEvent = (type, id, blocksinheritance, domain) => {
+ if (type === 'AZStorageContainer') {
+ setVisible(true);
+ setObjectid(id);
+ setDomain(domain);
+ let session = driver.session();
+ session
+ .run(`MATCH (n:AZStorageContainer {objectid: $objectid}) RETURN n AS node`, {
+ objectid: id,
+ })
+ .then((r) => {
+ let props = r.records[0].get('node').properties;
+ setNodeProps(props);
+ setLabel(props.name || props.azname || objectid);
+ session.close();
+ });
+ } else {
+ setObjectid(null);
+ setVisible(false);
+ }
+ };
+
+ const displayMap = {
+ objectid: 'Object ID',
+ };
+
+ return objectid === null ? (
+
+ ) : (
+
+
+
{label || objectid}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (u:AZStorageContainer {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:Owner*1..]->(u:AZStorageContainer {objectid: $objectid}) RETURN p'
+ }
+ property={'Storage Container Owners'}
+ target={objectid}
+ />
+ (u:AZStorageContainer {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:Contributor*1..]->(u:AZStorageContainer {objectid: $objectid}) RETURN p'
+ }
+ property={'Storage Container Contributors'}
+ target={objectid}
+ />
+ (u:AZStorageContainer {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:ReaderAndDataAccess*1..]->(u:AZStorageContainer {objectid: $objectid}) RETURN p'
+ }
+ property={'Storage Container Data Readers'}
+ target={objectid}
+ />
+ (u:AZStorageContainer {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:UserAccessAdministrator*1..]->(u:AZStorageContainer {objectid: $objectid}) RETURN p'
+ }
+ property={'User Access Administrators'}
+ target={objectid}
+ />
+ (u:AZStorageContainer {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r]->(u:AZStorageContainer {objectid: $objectid}) RETURN p'
+ }
+ property={'All Relations'}
+ target={objectid}
+ />
+
+
+
+
+
+
+
+ );
+};
+
+AZStorageContainerNodeData.propTypes = {};
+export default AZStorageContainerNodeData;
diff --git a/src/components/SearchContainer/Tabs/AZWebAppNodeData.jsx b/src/components/SearchContainer/Tabs/AZWebAppNodeData.jsx
index d9e6dbe3b..fe1ba7e1f 100644
--- a/src/components/SearchContainer/Tabs/AZWebAppNodeData.jsx
+++ b/src/components/SearchContainer/Tabs/AZWebAppNodeData.jsx
@@ -75,18 +75,27 @@ const AZWebAppNodeData = () => {
property='See Web App within Tenant'
query='MATCH p = (d:AZTenant)-[r:AZContains*1..]->(u:AZWebApp {objectid: $objectid}) RETURN p'
/>
- (n)'
+
+ (n) RETURN COUNT(p)'
}
+ graphQuery={
+ 'MATCH p=(:AZWebApp {objectid:$objectid})-[:AZManagedIdentity]->(n) RETURN p'
+ }
+ start={label}
property={'Managed Identities'}
target={objectid}
+ distinct
/>
-
{
properties={nodeProps}
label={label}
/>
-
{
properties={nodeProps}
label={label}
/>
-
+
-
+
+ (u:AZWebApp {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:Owner*1..]->(u:AZWebApp {objectid: $objectid}) RETURN p'
+ }
+ property={'Web App Owners'}
+ target={objectid}
+ />
+ (u:AZWebApp {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:Contributor*1..]->(u:AZWebApp {objectid: $objectid}) RETURN p'
+ }
+ property={'Web App Contributors'}
+ target={objectid}
+ />
+ (u:AZWebApp {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r:UserAccessAdministrator*1..]->(u:AZWebApp {objectid: $objectid}) RETURN p'
+ }
+ property={'User Access Administrators'}
+ target={objectid}
+ />
+ (u:AZWebApp {objectid: $objectid}) RETURN COUNT(p)'
+ }
+ graphQuery={
+ 'MATCH p = (d)-[r]->(u:AZWebApp {objectid: $objectid}) RETURN p'
+ }
+ property={'All Relations'}
+ target={objectid}
+ />
+
+
+
+
+
+
+
{
end={label}
distinct
/>
-
-
-
+
-
);
diff --git a/src/components/SearchContainer/Tabs/DatabaseDataDisplay.jsx b/src/components/SearchContainer/Tabs/DatabaseDataDisplay.jsx
index a411c2829..c215e8d6d 100644
--- a/src/components/SearchContainer/Tabs/DatabaseDataDisplay.jsx
+++ b/src/components/SearchContainer/Tabs/DatabaseDataDisplay.jsx
@@ -236,9 +236,24 @@ const DatabaseDataDisplay = () => {
label={'AZVM'}
/>
+
+
+