add webinterface WIP

This commit is contained in:
Martin/Geno 2019-03-01 10:54:19 +01:00
parent d20e749038
commit 42c43478dc
No known key found for this signature in database
GPG Key ID: 9D7D3C6BFF600C6A
20 changed files with 14730 additions and 12 deletions

View File

@ -24,7 +24,7 @@ test-my-project:
stage: test
script:
- go get github.com/client9/misspell/cmd/misspell
- misspell -error .
- find . -type f | grep -v webroot/assets | xargs misspell -error
- ./.ci/check-gofmt
- ./.ci/check-testfiles
- go test $(go list ./... | grep -v /vendor/) -v -coverprofile .testCoverage.txt
@ -47,4 +47,5 @@ deploy:
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- scp -6 -o StrictHostKeyChecking=no -P $SSH_PORT "/go/bin/$CI_PROJECT_NAME" "$CI_PROJECT_NAME@$SSH_HOST":/opt/$CI_PROJECT_NAME/bin
- scp -6 -o StrictHostKeyChecking=no -P $SSH_PORT -r "/builds/$CI_PROJECT_PATH/webroot" "$CI_PROJECT_NAME@$SSH_HOST":/opt/$CI_PROJECT_NAME/webroot
- ssh -6 -o StrictHostKeyChecking=no -p $SSH_PORT "$CI_PROJECT_NAME@$SSH_HOST" sudo /usr/bin/systemctl restart $CI_PROJECT_NAME

View File

@ -13,6 +13,7 @@ import (
"dev.sum7.eu/genofire/wifictld-analyzer/config"
"dev.sum7.eu/genofire/wifictld-analyzer/controller"
"dev.sum7.eu/genofire/wifictld-analyzer/database"
"dev.sum7.eu/genofire/wifictld-analyzer/web"
)
// queryCmd represents the query command
@ -37,6 +38,13 @@ var controllerCmd = &cobra.Command{
ctr.Send = coll.Send
ctr.SendTo = coll.SendTo
if configObj.Webserver.Enable {
log.Infof("starting webserver on %s", configObj.Webserver.Bind)
srv := web.New(configObj.Webserver)
go web.Start(srv)
defer srv.Close()
}
// Wait for INT/TERM
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
@ -47,5 +55,5 @@ var controllerCmd = &cobra.Command{
}
func init() {
RootCmd.AddCommand(controllerCmd)
RootCMD.AddCommand(controllerCmd)
}

View File

@ -58,7 +58,7 @@ var dumpCmd = &cobra.Command{
}
func init() {
RootCmd.AddCommand(dumpCmd)
RootCMD.AddCommand(dumpCmd)
dumpCmd.Flags().IntVar(&port, "port", capture.Port, "define a port to listen (if not set or set to 0 the kernel will use a random free port at its own)")
dumpCmd.Flags().StringVar(&ipAddress, "listen", capture.MulticastAddressDefault, "")
}

View File

@ -6,19 +6,22 @@ import (
"github.com/spf13/cobra"
)
var debug bool
var (
debug bool
timestamps bool
)
// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
// RootCMD represents the base command when called without any subcommands
var RootCMD = &cobra.Command{
Use: "analyzer",
Short: "wifictld analyzer",
Long: `capture wifictld traffic and display thus`,
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
// This is called by main.main(). It only needs to happen once to the RootCMD.
func Execute() {
if err := RootCmd.Execute(); err != nil {
if err := RootCMD.Execute(); err != nil {
log.Error(err)
}
}
@ -27,7 +30,11 @@ func init() {
if debug {
log.SetLevel(log.DebugLevel)
}
log.SetFormatter(&log.TextFormatter{
DisableTimestamp: timestamps,
})
log.Debug("show debug")
})
RootCmd.PersistentFlags().BoolVar(&debug, "v", false, "show debug log")
RootCMD.PersistentFlags().BoolVar(&debug, "v", false, "show debug log")
RootCMD.PersistentFlags().BoolVar(&timestamps, "timestamps", false, "Enables timestamps for log output")
}

View File

@ -2,9 +2,11 @@ package config
import (
"dev.sum7.eu/genofire/wifictld-analyzer/capture"
"dev.sum7.eu/genofire/wifictld-analyzer/web"
)
type Config struct {
StatePath string `toml:"state_path"`
Webserver *web.Config `toml:"webserver"`
Interfaces []*capture.IFaceConfig `toml:"interfaces"`
}

View File

@ -1,6 +1,11 @@
state_path = "/tmp/wifictld.json"
[webserver]
enable = true
bind = ":8080"
webroot = "./webroot/"
[[interfaces]]
ifname = "wlp4s0"
#port = 1000
#ip_address = "ff02::31f1"
ifname = "wlp4s0"
#port = 1000
#ip_address = "ff02::31f1"

7
web/config.go Normal file
View File

@ -0,0 +1,7 @@
package web
type Config struct {
Enable bool `toml:"enable"`
Bind string `toml:"bind"`
Webroot string `toml:"webroot"`
}

23
web/webserver.go Normal file
View File

@ -0,0 +1,23 @@
package web
import (
"net/http"
"github.com/NYTimes/gziphandler"
"github.com/bdlm/log"
)
// New creates a new webserver and starts it
func New(config *Config) *http.Server {
return &http.Server{
Addr: config.Bind,
Handler: gziphandler.GzipHandler(http.FileServer(http.Dir(config.Webroot))),
}
}
func Start(srv *http.Server) {
// service connections
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
log.Panicf("webserver crashed: %s", err)
}
}

28
web/webserver_test.go Normal file
View File

@ -0,0 +1,28 @@
package web
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestWebserver(t *testing.T) {
assert := assert.New(t)
srv := New(&Config{
Bind: ":12345",
Webroot: "/tmp",
})
assert.NotNil(srv)
go Start(srv)
time.Sleep(time.Millisecond * 200)
assert.Panics(func() {
Start(srv)
}, "not allowed to listen twice")
srv.Close()
}

6
webroot/assets/get_assets.sh Executable file
View File

@ -0,0 +1,6 @@
wget -O vanilla-framework.css https://assets.ubuntu.com/v1/vanilla-framework-version-1.8.1.min.css
wget -O vue.js https://cdn.jsdelivr.net/npm/vue@2.6.7/dist/vue.js
wget -O vue-route.js https://unpkg.com/vue-router/dist/vue-router.js
wget -O vuex.js https://unpkg.com/vuex@2.0.0/dist/vuex.min.js
wget -O vue-websocket.js https://raw.githubusercontent.com/nathantsoi/vue-native-websocket/master/dist/build.js
wget -O vue-websocket.js.map https://raw.githubusercontent.com/nathantsoi/vue-native-websocket/master/dist/build.js.map

File diff suppressed because one or more lines are too long

2626
webroot/assets/vue-route.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

11907
webroot/assets/vue.js Normal file

File diff suppressed because it is too large Load Diff

6
webroot/assets/vuex.js Normal file

File diff suppressed because one or more lines are too long

4
webroot/css/main.css Normal file
View File

@ -0,0 +1,4 @@
.p-navigation__logo {
font-size: 1.5rem;
line-height: 3rem;
}

42
webroot/index.html Normal file
View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Wifictld</title>
<link rel="stylesheet" href="assets/vanilla-framework.css" />
<link rel="stylesheet" href="css/main.css" />
<script src="assets/vue.js"></script>
<script src="assets/vue-route.js"></script>
<script src="assets/vuex.js"></script>
<script src="assets/vue-websocket.js"></script>
</head>
<body role="document">
<div id="app">
<header id="navigation" class="p-navigation">
<div class="p-navigation__banner">
<div class="p-navigation__logo">
<a class="p-navigation__link" href="/">Wifictld</a>
</div>
<a href="#navigation" class="p-navigation__toggle--open" title="menu">Menu</a>
<a href="#navigation-closed" class="p-navigation__toggle--close" title="close menu">Close menu</a>
</div>
<nav class="p-navigation__nav" role="menubar">
<span class="u-off-screen">
<a href="#main-content">Jump to main content</a>
</span>
<ul class="p-navigation__links" role="menu">
<li class="p-navigation__link is-selected">
<router-link to="/">Access Points</router-link>
</li>
</ul>
</nav>
</header>
<div class="content">
<router-view></router-view>
</div>
</div>
<script src="js/view/accesspoint.js"></script>
<script src="js/main.js"></script>
</body>
</html>

16
webroot/js/main.js Normal file
View File

@ -0,0 +1,16 @@
const router = new VueRouter({
routes: [
{ path: '/', component: ViewAccessPoints }
]
})
Vue.use(VueNativeSock, 'ws://localhost:9090',{
reconnection: true,
reconnectionDelay: 5000,
})
const app = new Vue({
router
}).$mount('#app')
Vue.$connect()

View File

@ -0,0 +1,25 @@
const ViewAccessPoints = {
template: `<div class="row">
<h1>AccessPoints</h1>
<table class="p-table--mobile-card" role="grid">
<thead>
<tr role="row">
<th scope="col" role="columnheader" id="t-name" aria-sort="none">Name</th>
<th scope="col" role="columnheader" id="t-users" aria-sort="none" class="u-align--right">Users</th>
<th scope="col" role="columnheader" id="t-units" aria-sort="none" class="u-align--right">Units</th>
</tr>
</thead>
<tbody>
<accesspoint-table-item/>
</tbody>
</table>
</div>`
}
Vue.component('accesspoint-table-item', {
template: `<tr role="row">
<td role="rowheader" aria-label="Name">Grape</td>
<td role="gridcell" aria-label="Users" class="u-align--right">8</td>
<td role="gridcell" aria-label="Units" class="u-align--right">19</td>
</tr>`
})