diff --git a/agent/main.go b/agent/main.go index 06387c0e9..bff6e8c46 100644 --- a/agent/main.go +++ b/agent/main.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "log" "mizuserver/pkg/api" + "mizuserver/pkg/controllers" "mizuserver/pkg/models" "mizuserver/pkg/routes" "mizuserver/pkg/utils" @@ -144,6 +145,7 @@ func loadExtensions() { allOutboundPorts = mergeUnique(allOutboundPorts, extension.Protocol.OutboundPorts) allInboundPorts = mergeUnique(allInboundPorts, extension.Protocol.InboundPorts) } + controllers.InitExtensionsMap(extensionsMap) log.Printf("allOutboundPorts: %v\n", allOutboundPorts) log.Printf("allInboundPorts: %v\n", allInboundPorts) } diff --git a/agent/pkg/controllers/entries_controller.go b/agent/pkg/controllers/entries_controller.go index 894a0d83d..d5d637a2e 100644 --- a/agent/pkg/controllers/entries_controller.go +++ b/agent/pkg/controllers/entries_controller.go @@ -21,6 +21,12 @@ import ( tapApi "github.com/up9inc/mizu/tap/api" ) +var extensionsMap map[string]*tapApi.Extension // global + +func InitExtensionsMap(ref map[string]*tapApi.Extension) { + extensionsMap = ref +} + func GetEntries(c *gin.Context) { entriesFilter := &models.EntriesFilter{} @@ -230,7 +236,10 @@ func GetEntry(c *gin.Context) { // "msg": "Can't get entry details", // }) // } - c.JSON(http.StatusOK, entryData) + c.JSON(http.StatusOK, tapApi.MizuEntryWrapper{ + Protocol: extensionsMap[entryData.ProtocolName].Protocol, + Data: entryData, + }) } func DeleteAllEntries(c *gin.Context) { diff --git a/tap/api/api.go b/tap/api/api.go index 59349f628..0f8936785 100644 --- a/tap/api/api.go +++ b/tap/api/api.go @@ -88,6 +88,7 @@ type MizuEntry struct { ID uint `gorm:"primarykey"` CreatedAt time.Time UpdatedAt time.Time + ProtocolName string `json:"protocol_key" gorm:"column:protocolKey"` Entry string `json:"entry,omitempty" gorm:"column:entry"` EntryId string `json:"entryId" gorm:"column:entryId"` Url string `json:"url" gorm:"column:url"` @@ -107,6 +108,11 @@ type MizuEntry struct { EstimatedSizeBytes int `json:"-" gorm:"column:estimatedSizeBytes"` } +type MizuEntryWrapper struct { + Protocol Protocol `json:"protocol"` + Data MizuEntry `json:"data"` +} + type BaseEntryDetails struct { Id string `json:"id,omitempty"` Protocol Protocol `json:"protocol,omitempty"` diff --git a/tap/extensions/http/main.go b/tap/extensions/http/main.go index b5d36c8c7..f6b10c272 100644 --- a/tap/extensions/http/main.go +++ b/tap/extensions/http/main.go @@ -116,6 +116,7 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, entryId string, resolve entryBytes, _ := json.Marshal(item.Pair) service := fmt.Sprintf("http://%s", host) return &api.MizuEntry{ + ProtocolName: protocol.Name, EntryId: entryId, Entry: string(entryBytes), Url: fmt.Sprintf("%s%s", service, request["url"].(string)), diff --git a/ui/src/components/HarEntry.tsx b/ui/src/components/HarEntry.tsx index a95acc100..aa854ab27 100644 --- a/ui/src/components/HarEntry.tsx +++ b/ui/src/components/HarEntry.tsx @@ -76,7 +76,7 @@ export const HarEntry: React.FC = ({entry, setFocusedEntryId, isS onClick={() => setFocusedEntryId(entry.id)} style={{border: isSelected ? `1px ${entry.protocol.background_color} solid` : "1px transparent solid"}} > - + {entry.status_code &&
} diff --git a/ui/src/components/HarEntryDetailed.tsx b/ui/src/components/HarEntryDetailed.tsx index c0c04c0cb..3eb878215 100644 --- a/ui/src/components/HarEntryDetailed.tsx +++ b/ui/src/components/HarEntryDetailed.tsx @@ -3,16 +3,26 @@ import {singleEntryToHAR} from "./utils"; import styles from './style/HarEntryDetailed.module.sass'; import HAREntryViewer from "./HarEntryViewer/HAREntryViewer"; import {makeStyles} from "@material-ui/core"; +import Protocol, {ProtocolInterface} from "./Protocol" import StatusCode from "./StatusCode"; import {EndpointPath} from "./EndpointPath"; const useStyles = makeStyles(() => ({ entryTitle: { display: 'flex', - minHeight: 46, + minHeight: 20, maxHeight: 46, alignItems: 'center', - marginBottom: 8, + marginBottom: 4, + padding: 2, + paddingBottom: 0 + }, + entrySummary: { + display: 'flex', + minHeight: 36, + maxHeight: 46, + alignItems: 'center', + marginBottom: 4, padding: 5, paddingBottom: 0 } @@ -25,33 +35,47 @@ interface HarEntryDetailedProps { export const formatSize = (n: number) => n > 1000 ? `${Math.round(n / 1000)}KB` : `${n} B`; -const HarEntryTitle: React.FC = ({har}) => { +const HarEntryTitle: React.FC = ({protocol, har}) => { + const classes = useStyles(); + + const {log: {entries}} = har; + const {response} = JSON.parse(entries[0].entry); + const {bodySize} = response.payload; + + + return
+ +
+
{formatSize(bodySize)}
+
{'rulesMatched' in entries[0] ? entries[0].rulesMatched?.length : '0'} Rules Applied
+
+
; +}; + +const HarEntrySummary: React.FC = ({har}) => { const classes = useStyles(); const {log: {entries}} = har; const {response, request} = JSON.parse(entries[0].entry); - const {status, statusText, bodySize} = response; + const {status} = response.payload; - return
+ return
{status &&
}
- +
-
{formatSize(bodySize)}
-
{status} {statusText}
- {/*
{Math.round(receive)}ms
*/} -
{'rulesMatched' in entries[0] ? entries[0].rulesMatched?.length : '0'} Rules Applied
; }; export const HAREntryDetailed: React.FC = ({classes, harEntry}) => { - const har = singleEntryToHAR(harEntry); + const har = singleEntryToHAR(harEntry.data); return <> - {har && } + + {har && } <> {har && = ({har, entry, isCollapsed: initialIsCollapsed, isResponseMocked}) => { const {request, response} = JSON.parse(entry); - console.log('request:', request) - console.log('response:', response) const rulesMatched = har.log.entries[0].rulesMatched const TABS = [ {tab: 'request'}, diff --git a/ui/src/components/Protocol.tsx b/ui/src/components/Protocol.tsx index c2572d89c..a04ca4fec 100644 --- a/ui/src/components/Protocol.tsx +++ b/ui/src/components/Protocol.tsx @@ -1,37 +1,53 @@ import React from "react"; -import internal from "stream"; import styles from './style/Protocol.module.sass'; export interface ProtocolInterface { - name: string, - long_name: string, - abbreviation: string, - background_color: string, - foreground_color: string, - font_size: number, - reference_link: string, - outbound_ports: string[], - inbound_ports: string, + name: string + long_name: string + abbreviation: string + background_color: string + foreground_color: string + font_size: number + reference_link: string + outbound_ports: string[] + inbound_ports: string } interface ProtocolProps { protocol: ProtocolInterface + horizontal: boolean } -const Protocol: React.FC = ({protocol}) => { - return - - {protocol.abbreviation} - - +const Protocol: React.FC = ({protocol, horizontal}) => { + if (horizontal) { + return + + {protocol.long_name} + + + } else { + return + + {protocol.abbreviation} + + + } }; export default Protocol; diff --git a/ui/src/components/style/HarEntryDetailed.module.sass b/ui/src/components/style/HarEntryDetailed.module.sass index 0bd23ce9a..fca266d6b 100644 --- a/ui/src/components/style/HarEntryDetailed.module.sass +++ b/ui/src/components/style/HarEntryDetailed.module.sass @@ -1,5 +1,5 @@ .loader - margin: 30px auto 0 + margin: 30px auto 0 .har display: flex diff --git a/ui/src/components/style/Protocol.module.sass b/ui/src/components/style/Protocol.module.sass index 60c393711..0790c0f67 100644 --- a/ui/src/components/style/Protocol.module.sass +++ b/ui/src/components/style/Protocol.module.sass @@ -1,20 +1,27 @@ @import 'variables.module' .base - // border-radius: 4px - border-radius: 4px 0 0 4px - width: 22px - height: 48px - font-size: 10px display: inline-block text-align: center - line-height: 22px + font-size: 10px font-weight: 600 - writing-mode: vertical-lr; - // transform: rotate(-180deg); - text-orientation: upright; // letter-spacing: 2px; background-color: #000 color: #fff margin-left: -8px; margin-bottom: -4px; + +.vertical + line-height: 22px + width: 22px + height: 48px + border-radius: 4px 0 0 4px + writing-mode: vertical-lr; + // transform: rotate(-180deg); + text-orientation: upright; + +.horizontal + border-radius: 4px + font-size: 22px + padding: 5px 10px + font-weight: 600