Skip to content

Commit

Permalink
Add scope support
Browse files Browse the repository at this point in the history
  • Loading branch information
dstotijn committed Oct 29, 2020
1 parent 98dacbe commit 0d04996
Show file tree
Hide file tree
Showing 30 changed files with 2,837 additions and 149 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
**/rice-box.go
sqlite3_mod_regexp.dylib
dist
hetty
hetty.bolt
Expand Down
31 changes: 19 additions & 12 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
env:
- GO111MODULE=on
- CGO_ENABLED=1
- CGO_CFLAGS=-I/go/pkg/mod/github.com/mattn/go-sqlite3@v1.14.4
before:
hooks:
- make clean
Expand All @@ -15,6 +16,7 @@ builds:
env:
- CC=o64-clang
- CXX=o64-clang++
- CGO_LDFLAGS=-Wl,-undefined,dynamic_lookup
flags:
- -mod=readonly
ldflags:
Expand All @@ -24,22 +26,27 @@ builds:
- amd64
goos:
- linux
flags:
- -mod=readonly
ldflags:
- id: hetty-windows-amd64
main: ./cmd/hetty
goarch:
- amd64
goos:
- windows
env:
- CC=x86_64-w64-mingw32-gcc
- CXX=x86_64-w64-mingw32-g++
- CGO_CFLAGS=-I/go/pkg/mod/github.com/mattn/go-sqlite3@v1.14.4
- CGO_LDFLAGS=-Wl,--unresolved-symbols=ignore-in-object-files
flags:
- -mod=readonly
ldflags:
- -buildmode=exe
# - id: hetty-windows-amd64
# main: ./cmd/hetty
# goarch:
# - amd64
# goos:
# - windows
# env:
# - CC=x86_64-w64-mingw32-gcc
# - CXX=x86_64-w64-mingw32-g++
# - CGO_CFLAGS=-I/go/pkg/mod/github.com/mattn/go-sqlite3@v1.14.4
# - CGO_LDFLAGS=-Wl,--unresolved-symbols=ignore-in-object-files # Not working :(
# flags:
# - -mod=readonly
# ldflags:
# - -buildmode=exe
archives:
- replacements:
darwin: macOS
Expand Down
9 changes: 6 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ ARG GO_VERSION=1.15
ARG CGO_ENABLED=1
ARG NODE_VERSION=14.11

FROM golang:${GO_VERSION}-alpine AS go-builder
FROM golang:${GO_VERSION} AS go-builder
WORKDIR /app
RUN apk add --no-cache build-base
RUN apt-get update && \
apt-get install -y build-essential
COPY go.mod go.sum ./
RUN go mod download
COPY cmd ./cmd
COPY pkg ./pkg
ENV CGO_CFLAGS=-I/go/pkg/mod/github.com/mattn/go-sqlite3@v1.14.4
ENV CGO_LDFLAGS=-Wl,--unresolved-symbols=ignore-in-object-files
RUN go build -o hetty ./cmd/hetty

FROM node:${NODE_VERSION}-alpine AS node-builder
Expand All @@ -19,7 +22,7 @@ COPY admin/ .
ENV NEXT_TELEMETRY_DISABLED=1
RUN yarn run export

FROM alpine:3.12
FROM debian:buster-slim
WORKDIR /app
COPY --from=go-builder /app/hetty .
COPY --from=node-builder /app/dist admin
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ embed:
.PHONY: embed

build: embed
env CGO_ENABLED=1 go build ./cmd/hetty
env CGO_ENABLED=1 CGO_CFLAGS="-DUSE_LIBSQLITE3" CGO_LDFLAGS="-Wl,-undefined,dynamic_lookup" \
go build -tags libsqlite3 ./cmd/hetty
.PHONY: build

clean:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

- [x] HTTP man-in-the-middle (MITM) proxy and GraphQL server.
- [x] Web interface (Next.js) with proxy log viewer.
- [ ] Add scope support to the proxy.
- [x] Add scope support to the proxy.
- [ ] Full text search (with regex) in proxy log viewer.
- [x] Project management.
- [ ] Sender module for sending manual HTTP requests, either from scratch or based
Expand Down
2 changes: 1 addition & 1 deletion admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"export": "next build && next export -o dist"
"export": "rm -rf .next && next build && next export -o dist"
},
"dependencies": {
"@apollo/client": "^3.2.0",
Expand Down
18 changes: 18 additions & 0 deletions admin/src/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import HomeIcon from "@material-ui/icons/Home";
import SettingsEthernetIcon from "@material-ui/icons/SettingsEthernet";
import SendIcon from "@material-ui/icons/Send";
import FolderIcon from "@material-ui/icons/Folder";
import LocationSearchingIcon from "@material-ui/icons/LocationSearching";
import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import clsx from "clsx";
Expand All @@ -33,6 +34,7 @@ export enum Page {
ProxySetup,
ProxyLogs,
Sender,
Scope,
}

const drawerWidth = 240;
Expand Down Expand Up @@ -236,6 +238,22 @@ export function Layout({ title, page, children }: Props): JSX.Element {
<ListItemText primary="Sender" />
</ListItem>
</Link>
<Link href="/scope" passHref>
<ListItem
button
component="a"
key="scope"
selected={page === Page.Scope}
className={classes.listItem}
>
<Tooltip title="Scope">
<ListItemIcon className={classes.listItemIcon}>
<LocationSearchingIcon />
</ListItemIcon>
</Tooltip>
<ListItemText primary="Scope" />
</ListItem>
</Link>
<Link href="/projects" passHref>
<ListItem
button
Expand Down
6 changes: 6 additions & 0 deletions admin/src/components/projects/ProjectList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ function ProjectList(): JSX.Element {
});
return DELETE;
},
httpRequestLogFilter(_, { DELETE }) {
return DELETE;
},
},
});
},
Expand All @@ -136,6 +139,9 @@ function ProjectList(): JSX.Element {
projects(_, { DELETE }) {
return DELETE;
},
httpRequestLogFilter(_, { DELETE }) {
return DELETE;
},
},
});
},
Expand Down
201 changes: 201 additions & 0 deletions admin/src/components/reqlog/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
import {
Box,
Checkbox,
CircularProgress,
ClickAwayListener,
createStyles,
FormControlLabel,
InputBase,
makeStyles,
Paper,
Popper,
Theme,
Tooltip,
useTheme,
} from "@material-ui/core";
import IconButton from "@material-ui/core/IconButton";
import SearchIcon from "@material-ui/icons/Search";
import FilterListIcon from "@material-ui/icons/FilterList";
import React, { useRef, useState } from "react";
import { gql, useApolloClient, useMutation, useQuery } from "@apollo/client";
import { withoutTypename } from "../../lib/omitTypename";
import { Alert } from "@material-ui/lab";

const FILTER = gql`
query HttpRequestLogFilter {
httpRequestLogFilter {
onlyInScope
}
}
`;

const SET_FILTER = gql`
mutation SetHttpRequestLogFilter($filter: HttpRequestLogFilterInput) {
setHttpRequestLogFilter(filter: $filter) {
onlyInScope
}
}
`;

const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
padding: "2px 4px",
display: "flex",
alignItems: "center",
width: 400,
},
input: {
marginLeft: theme.spacing(1),
flex: 1,
},
iconButton: {
padding: 10,
},
filterPopper: {
width: 400,
marginTop: 6,
zIndex: 99,
},
filterOptions: {
padding: theme.spacing(2),
},
filterLoading: {
marginRight: 1,
color: theme.palette.text.primary,
},
})
);

export interface SearchFilter {
onlyInScope: boolean;
}

function Search(): JSX.Element {
const classes = useStyles();
const theme = useTheme();

const { loading: filterLoading, error: filterErr, data: filter } = useQuery(
FILTER
);

const client = useApolloClient();
const [
setFilterMutate,
{ error: setFilterErr, loading: setFilterLoading },
] = useMutation<{
setHttpRequestLogFilter: SearchFilter | null;
}>(SET_FILTER, {
update(_, { data: { setHttpRequestLogFilter } }) {
client.writeQuery({
query: FILTER,
data: {
httpRequestLogFilter: setHttpRequestLogFilter,
},
});
},
});

const filterRef = useRef<HTMLElement | null>();
const [filterOpen, setFilterOpen] = useState(false);

const handleSubmit = (e: React.SyntheticEvent) => {
e.preventDefault();
};

const handleClickAway = (event: React.MouseEvent<EventTarget>) => {
if (filterRef.current.contains(event.target as HTMLElement)) {
return;
}
setFilterOpen(false);
};

return (
<ClickAwayListener onClickAway={handleClickAway}>
<Box style={{ display: "inline-block" }}>
{filterErr && (
<Box mb={4}>
<Alert severity="error">
Error fetching filter: {filterErr.message}
</Alert>
</Box>
)}
{setFilterErr && (
<Box mb={4}>
<Alert severity="error">
Error setting filter: {setFilterErr.message}
</Alert>
</Box>
)}
<Paper
component="form"
onSubmit={handleSubmit}
ref={filterRef}
className={classes.root}
>
<Tooltip title="Toggle filter options">
<IconButton
className={classes.iconButton}
onClick={() => setFilterOpen(!filterOpen)}
style={{
color:
filter?.httpRequestLogFilter !== null
? theme.palette.secondary.main
: "inherit",
}}
>
{filterLoading || setFilterLoading ? (
<CircularProgress className={classes.filterLoading} size={23} />
) : (
<FilterListIcon />
)}
</IconButton>
</Tooltip>
<InputBase
className={classes.input}
placeholder="Search proxy logs…"
onFocus={() => setFilterOpen(true)}
/>
<Tooltip title="Search">
<IconButton type="submit" className={classes.iconButton}>
<SearchIcon />
</IconButton>
</Tooltip>
</Paper>

<Popper
className={classes.filterPopper}
open={filterOpen}
anchorEl={filterRef.current}
placement="bottom-start"
>
<Paper className={classes.filterOptions}>
<FormControlLabel
control={
<Checkbox
checked={
filter?.httpRequestLogFilter?.onlyInScope ? true : false
}
disabled={filterLoading || setFilterLoading}
onChange={(e) =>
setFilterMutate({
variables: {
filter: {
...withoutTypename(filter?.httpRequestLogFilter),
onlyInScope: e.target.checked,
},
},
})
}
/>
}
label="Only show in-scope requests"
/>
</Paper>
</Popper>
</Box>
</ClickAwayListener>
);
}

export default Search;
Loading

0 comments on commit 0d04996

Please sign in to comment.