mirror of
https://github.com/nicksherron/bashhub-server.git
synced 2025-09-13 15:54:49 +08:00
merge feature-bhdownload
This commit is contained in:
commit
9f5b50eb87
6 changed files with 372 additions and 12 deletions
|
@ -34,13 +34,10 @@ var cfgFile string
|
||||||
|
|
||||||
// rootCmd represents the base command when called without any subcommands
|
// rootCmd represents the base command when called without any subcommands
|
||||||
var (
|
var (
|
||||||
noWarning bool
|
rootCmd = &cobra.Command{
|
||||||
rootCmd = &cobra.Command{
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmd.Flags().Parse(args)
|
cmd.Flags().Parse(args)
|
||||||
if !noWarning {
|
checkBhEnv()
|
||||||
checkBhEnv()
|
|
||||||
}
|
|
||||||
startupMessage()
|
startupMessage()
|
||||||
internal.Run()
|
internal.Run()
|
||||||
},
|
},
|
||||||
|
@ -60,7 +57,6 @@ func init() {
|
||||||
rootCmd.PersistentFlags().StringVar(&internal.LogFile, "log", "", `Set filepath for HTTP log. "" logs to stderr`)
|
rootCmd.PersistentFlags().StringVar(&internal.LogFile, "log", "", `Set filepath for HTTP log. "" logs to stderr`)
|
||||||
rootCmd.PersistentFlags().StringVar(&internal.DbPath, "db", dbPath(), "DB location (sqlite or postgres)")
|
rootCmd.PersistentFlags().StringVar(&internal.DbPath, "db", dbPath(), "DB location (sqlite or postgres)")
|
||||||
rootCmd.PersistentFlags().StringVarP(&internal.Addr, "addr", "a", listenAddr(), "Ip and port to listen and serve on")
|
rootCmd.PersistentFlags().StringVarP(&internal.Addr, "addr", "a", listenAddr(), "Ip and port to listen and serve on")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&noWarning, "warning-disable", "w", false, `Disable BH_URL env variable startup warning`)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
328
cmd/transfer.go
Normal file
328
cmd/transfer.go
Normal file
|
@ -0,0 +1,328 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright © 2020 nicksherron <nsherron90@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/cheggaaa/pb/v3"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
type cList struct {
|
||||||
|
UUID string `json:"uuid"`
|
||||||
|
Command string `json:"command"`
|
||||||
|
Created int64 `json:"created"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type commandsList []cList
|
||||||
|
|
||||||
|
var (
|
||||||
|
barTemplate = `{{string . "message"}}{{counters . }} {{bar . }} {{percent . }} {{speed . "%s inserts/sec" }}`
|
||||||
|
bar *pb.ProgressBar
|
||||||
|
progress bool
|
||||||
|
srcUser string
|
||||||
|
dstUser string
|
||||||
|
srcURL string
|
||||||
|
dstURL string
|
||||||
|
srcPass string
|
||||||
|
dstPass string
|
||||||
|
srcToken string
|
||||||
|
dstToken string
|
||||||
|
sysRegistered bool
|
||||||
|
workers int
|
||||||
|
wg sync.WaitGroup
|
||||||
|
cmdList commandsList
|
||||||
|
transferCmd = &cobra.Command{
|
||||||
|
Use: "transfer",
|
||||||
|
Short: "transfer bashhub history ",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
cmd.Flags().Parse(args)
|
||||||
|
sysRegistered = false
|
||||||
|
srcToken = getToken(srcURL, srcUser, srcPass)
|
||||||
|
sysRegistered = false
|
||||||
|
dstToken = getToken(dstURL, dstUser, dstPass)
|
||||||
|
cmdList = getCommandList()
|
||||||
|
counter := 0
|
||||||
|
if !progress {
|
||||||
|
bar = pb.ProgressBarTemplate(barTemplate).Start(len(cmdList)).SetMaxWidth(70)
|
||||||
|
bar.Set("message", "inserting records \t")
|
||||||
|
}
|
||||||
|
for _, v := range cmdList {
|
||||||
|
wg.Add(1)
|
||||||
|
counter++
|
||||||
|
go func(c cList) {
|
||||||
|
defer wg.Done()
|
||||||
|
commandLookup(c.UUID)
|
||||||
|
}(v)
|
||||||
|
if counter > workers {
|
||||||
|
wg.Wait()
|
||||||
|
counter = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(transferCmd)
|
||||||
|
transferCmd.PersistentFlags().StringVar(&srcURL, "src-url", "https://bashhub.com", "source url")
|
||||||
|
transferCmd.PersistentFlags().StringVar(&srcUser, "src-user", "", "source username")
|
||||||
|
transferCmd.PersistentFlags().StringVar(&srcPass, "src-pass", "", "source password")
|
||||||
|
transferCmd.PersistentFlags().StringVar(&dstURL, "dst-url", "http://localhost:8080", "destination url")
|
||||||
|
transferCmd.PersistentFlags().StringVar(&dstUser, "dst-user", "", "destination username")
|
||||||
|
transferCmd.PersistentFlags().StringVar(&dstPass, "dst-pass", "", "destination password")
|
||||||
|
transferCmd.PersistentFlags().BoolVarP(&progress, "progress", "p", false, "show progress bar")
|
||||||
|
transferCmd.PersistentFlags().IntVarP(&workers, "workers", "w", 10, "max number of concurrent requests")
|
||||||
|
}
|
||||||
|
|
||||||
|
func sysRegister(mac string, site string, user string, pass string) string {
|
||||||
|
|
||||||
|
var token string
|
||||||
|
func() {
|
||||||
|
var null *string
|
||||||
|
auth := map[string]interface{}{
|
||||||
|
"username": user,
|
||||||
|
"password": pass,
|
||||||
|
"mac": null,
|
||||||
|
}
|
||||||
|
|
||||||
|
payloadBytes, err := json.Marshal(auth)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
body := bytes.NewReader(payloadBytes)
|
||||||
|
|
||||||
|
u := fmt.Sprintf("%v/api/v1/login", site)
|
||||||
|
req, err := http.NewRequest("POST", u, body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
buf, err := ioutil.ReadAll(resp.Body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
j := make(map[string]interface{})
|
||||||
|
|
||||||
|
json.Unmarshal(buf, &j)
|
||||||
|
|
||||||
|
if len(j) == 0 {
|
||||||
|
log.Fatal("login failed for ", site)
|
||||||
|
|
||||||
|
}
|
||||||
|
token = fmt.Sprintf("Bearer %v", j["accessToken"])
|
||||||
|
|
||||||
|
}()
|
||||||
|
|
||||||
|
host, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
sys := map[string]interface{}{
|
||||||
|
"clientVersion": "1.2.0",
|
||||||
|
"name": "migration",
|
||||||
|
"hostname": host,
|
||||||
|
"mac": mac,
|
||||||
|
}
|
||||||
|
payloadBytes, err := json.Marshal(sys)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
body := bytes.NewReader(payloadBytes)
|
||||||
|
|
||||||
|
u := fmt.Sprintf("%v/api/v1/system", srcURL)
|
||||||
|
req, err := http.NewRequest("POST", u, body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Add("Authorization", token)
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
log.Println(resp.StatusCode)
|
||||||
|
b, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
log.Println(string(b))
|
||||||
|
|
||||||
|
sysRegistered = true
|
||||||
|
return getToken(site, user, pass)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getToken(site string, user string, pass string) string {
|
||||||
|
// function used by bashhub to identify system
|
||||||
|
cmd := exec.Command("python", "-c", "import uuid; print(str(uuid.getnode()))")
|
||||||
|
m, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
mac := strings.ReplaceAll(string(m), "\n", ``)
|
||||||
|
auth := map[string]interface{}{
|
||||||
|
"username": user,
|
||||||
|
"password": pass,
|
||||||
|
"mac": mac,
|
||||||
|
}
|
||||||
|
|
||||||
|
payloadBytes, err := json.Marshal(auth)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
body := bytes.NewReader(payloadBytes)
|
||||||
|
|
||||||
|
u := fmt.Sprintf("%v/api/v1/login", site)
|
||||||
|
req, err := http.NewRequest("POST", u, body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == 409 && !sysRegistered {
|
||||||
|
// register system
|
||||||
|
return sysRegister(mac, site, user, pass)
|
||||||
|
}
|
||||||
|
buf, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
j := make(map[string]interface{})
|
||||||
|
|
||||||
|
json.Unmarshal(buf, &j)
|
||||||
|
|
||||||
|
if len(j) == 0 {
|
||||||
|
log.Fatal("login failed for ", site)
|
||||||
|
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Bearer %v", j["accessToken"])
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCommandList() commandsList {
|
||||||
|
u := strings.TrimSpace(srcURL) + "/api/v1/command/search?unique=true&limit=1000000"
|
||||||
|
req, err := http.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Add("Authorization", srcToken)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error on response.\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
log.Fatalf("failed to get command list from %v, go status code %v", srcURL, resp.StatusCode)
|
||||||
|
}
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
var result commandsList
|
||||||
|
json.Unmarshal(body, &result)
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func commandLookup(uuid string) {
|
||||||
|
u := strings.TrimSpace(srcURL) + "/api/v1/command/" + strings.TrimSpace(uuid)
|
||||||
|
req, err := http.NewRequest("GET", u, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Add("Authorization", srcToken)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error on response.\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
log.Fatalf("failed command lookup from %v, go status code %v", srcURL, resp.StatusCode)
|
||||||
|
}
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
srcSend(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
func srcSend(data []byte) {
|
||||||
|
defer func() {
|
||||||
|
if !progress {
|
||||||
|
bar.Add(1)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
body := bytes.NewReader(data)
|
||||||
|
|
||||||
|
u := dstURL + "/api/v1/import"
|
||||||
|
req, err := http.NewRequest("POST", u, body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
req.Header.Add("Authorization", dstToken)
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error on response.\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
1
go.mod
1
go.mod
|
@ -2,6 +2,7 @@ module github.com/nicksherron/bashhub-server
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/appleboy/gin-jwt/v2 v2.6.3
|
github.com/appleboy/gin-jwt/v2 v2.6.3
|
||||||
|
github.com/cheggaaa/pb/v3 v3.0.4
|
||||||
github.com/fatih/color v1.9.0
|
github.com/fatih/color v1.9.0
|
||||||
github.com/gin-gonic/gin v1.5.0
|
github.com/gin-gonic/gin v1.5.0
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
|
|
12
go.sum
12
go.sum
|
@ -1,7 +1,11 @@
|
||||||
|
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||||
|
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||||
github.com/appleboy/gin-jwt/v2 v2.6.3 h1:aK4E3DjihWEBUTjEeRnGkA5nUkmwJPL1CPonMa2usRs=
|
github.com/appleboy/gin-jwt/v2 v2.6.3 h1:aK4E3DjihWEBUTjEeRnGkA5nUkmwJPL1CPonMa2usRs=
|
||||||
github.com/appleboy/gin-jwt/v2 v2.6.3/go.mod h1:MfPYA4ogzvOcVkRwAxT7quHOtQmVKDpTwxyUrC2DNw0=
|
github.com/appleboy/gin-jwt/v2 v2.6.3/go.mod h1:MfPYA4ogzvOcVkRwAxT7quHOtQmVKDpTwxyUrC2DNw0=
|
||||||
github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4=
|
github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4=
|
||||||
github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw=
|
github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw=
|
||||||
|
github.com/cheggaaa/pb/v3 v3.0.4 h1:QZEPYOj2ix6d5oEg63fbHmpolrnNiwjUsk+h74Yt4bM=
|
||||||
|
github.com/cheggaaa/pb/v3 v3.0.4/go.mod h1:7rgWxLrAUcFMkvJuv09+DYi7mMUYi8nO9iOWcvGJPfw=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
@ -11,6 +15,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumC
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||||
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||||
|
@ -48,14 +53,18 @@ github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdA
|
||||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
|
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
|
||||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
|
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
|
||||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||||
|
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||||
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
|
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
|
||||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||||
|
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||||
|
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
|
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
|
||||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
@ -99,8 +108,11 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU=
|
||||||
|
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
|
|
@ -97,11 +97,13 @@ func dbInit() {
|
||||||
gormdb.AutoMigrate(&Config{})
|
gormdb.AutoMigrate(&Config{})
|
||||||
|
|
||||||
//TODO: ensure these are the most efficient indexes
|
//TODO: ensure these are the most efficient indexes
|
||||||
gormdb.Model(&User{}).AddIndex("idx_user", "username")
|
gormdb.Model(&User{}).AddUniqueIndex("idx_user", "username")
|
||||||
gormdb.Model(&System{}).AddIndex("idx_mac", "mac")
|
gormdb.Model(&System{}).AddIndex("idx_mac", "mac")
|
||||||
gormdb.Model(&Command{}).AddIndex("idx_user_command_created", "user_id, created, command")
|
gormdb.Model(&Command{}).AddIndex("idx_user_command_created", "user_id, created, command")
|
||||||
gormdb.Model(&Command{}).AddIndex("idx_user_uuid", "user_id, uuid")
|
gormdb.Model(&Command{}).AddIndex("idx_user_uuid", "user_id, uuid")
|
||||||
gormdb.Model(&Config{}).AddUniqueIndex("idx_config_id", "id")
|
gormdb.Model(&Config{}).AddUniqueIndex("idx_config_id", "id")
|
||||||
|
gormdb.Model(&Command{}).AddUniqueIndex("idx_uuid", "uuid")
|
||||||
|
|
||||||
|
|
||||||
// Just need gorm for migration and index creation.
|
// Just need gorm for migration and index creation.
|
||||||
gormdb.Close()
|
gormdb.Close()
|
||||||
|
@ -545,5 +547,16 @@ func (status Status) statusGet() (Status, error) {
|
||||||
return Status{}, err
|
return Status{}, err
|
||||||
}
|
}
|
||||||
return status, err
|
return status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func importCommands(q Query) {
|
||||||
|
_, err := db.Exec(`INSERT INTO commands
|
||||||
|
("command", "path", "created", "uuid", "exit_status",
|
||||||
|
"system_name", "session_id", "user_id" )
|
||||||
|
VALUES ($1,$2,$3,$4,$5,$6,$7,(select "id" from users where "username" = $8)) ON CONFLICT do nothing`,
|
||||||
|
q.Command, q.Path, q.Created, q.Uuid, q.ExitStatus,
|
||||||
|
q.SystemName, q.SessionID, q.Username)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,15 +42,14 @@ type User struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Query struct {
|
type Query struct {
|
||||||
Uuid string `json:"uuid"`
|
|
||||||
Command string `json:"command"`
|
Command string `json:"command"`
|
||||||
Created int64 `json:"created"`
|
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
|
Created int64 `json:"created"`
|
||||||
|
Uuid string `json:"uuid"`
|
||||||
ExitStatus int `json:"exitStatus"`
|
ExitStatus int `json:"exitStatus"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
SystemName string `gorm:"-" json:"systemName"`
|
SystemName string `gorm:"-" json:"systemName"`
|
||||||
//TODO: implement sessions
|
SessionID string `json:"sessionId"`
|
||||||
SessionID string `json:"session_id"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Command struct {
|
type Command struct {
|
||||||
|
@ -67,6 +66,7 @@ type Command struct {
|
||||||
Limit int `gorm:"-"`
|
Limit int `gorm:"-"`
|
||||||
Unique bool `gorm:"-"`
|
Unique bool `gorm:"-"`
|
||||||
Query string `gorm:"-"`
|
Query string `gorm:"-"`
|
||||||
|
SessionID string `json:"sessionId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type System struct {
|
type System struct {
|
||||||
|
@ -371,7 +371,17 @@ func Run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
c.IndentedJSON(http.StatusOK, result)
|
c.IndentedJSON(http.StatusOK, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
r.POST("/api/v1/import", func(c *gin.Context) {
|
||||||
|
var query Query
|
||||||
|
if err := c.ShouldBindJSON(&query); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
claims := jwt.ExtractClaims(c)
|
||||||
|
query.Username = claims["username"].(string)
|
||||||
|
importCommands(query)
|
||||||
})
|
})
|
||||||
|
|
||||||
Addr = strings.ReplaceAll(Addr, "http://", "")
|
Addr = strings.ReplaceAll(Addr, "http://", "")
|
||||||
|
|
Loading…
Add table
Reference in a new issue