From 64863e6f02c3d579aabe1362ae68f8087caa11ee Mon Sep 17 00:00:00 2001 From: Steven Tracey Date: Wed, 3 May 2023 08:56:24 -0400 Subject: [PATCH] Upload --- .gitignore | 1 + .gitmodules | 3 ++ .idea/.gitignore | 8 +++++ .idea/.name | 1 + .idea/SimpleFileSync.iml | 9 ++++++ .idea/modules.xml | 8 +++++ Main.go | 61 +++++++++++++++++++++++++++++++++++++ assets/icon.ico | Bin 0 -> 169607 bytes example-config.ini | 19 ++++++++++++ ezconf | 1 + filetransfer.go | 1 + filewatcher.go | 7 +++++ go.mod | 24 +++++++++++++++ go.sum | 32 ++++++++++++++++++++ go.work.sum | 2 ++ serverconnection.go | 64 +++++++++++++++++++++++++++++++++++++++ 16 files changed, 241 insertions(+) create mode 100644 .gitmodules create mode 100644 .idea/.gitignore create mode 100644 .idea/.name create mode 100644 .idea/SimpleFileSync.iml create mode 100644 .idea/modules.xml create mode 100644 Main.go create mode 100644 assets/icon.ico create mode 100644 example-config.ini create mode 160000 ezconf create mode 100644 filetransfer.go create mode 100644 filewatcher.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 go.work.sum create mode 100644 serverconnection.go diff --git a/.gitignore b/.gitignore index 8b04583..e2c1618 100644 --- a/.gitignore +++ b/.gitignore @@ -126,3 +126,4 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser +config.ini \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..8781b1e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ezconf"] + path = ezconf + url = https://git.nevets.tech/Steven/ezconf.git diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..2ec968e --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +SimpleFileSync \ No newline at end of file diff --git a/.idea/SimpleFileSync.iml b/.idea/SimpleFileSync.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/SimpleFileSync.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..6bbc0ea --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Main.go b/Main.go new file mode 100644 index 0000000..1f6a634 --- /dev/null +++ b/Main.go @@ -0,0 +1,61 @@ +package main + +import ( + "crypto/tls" + "fmt" + "git.nevets.tech/Steven/ezconf" + "github.com/getlantern/systray" + "os" + "time" +) + +var Config *ezconf.Configuration +var Connection *tls.Conn + +func main() { + Config = ezconf.NewConfiguration("./config.ini") + Connection = New(Config.GetAsString("General.server"), Config.GetAsInt("General.port")) + + systray.Run(onReady, onExit) +} + +func onReady() { + systray.SetIcon(getIcon("assets/icon.ico")) + systray.SetTooltip("SimpleFileSync") + itemOne := systray.AddMenuItem("Item-1", "Highlighted Item 1") + systray.AddSeparator() + sync := systray.AddMenuItem("Sync", "Trigger Sync Now") + systray.AddSeparator() + quit := systray.AddMenuItem("Quit", "Quit") + + go func() { + for { + select { + case <-itemOne.ClickedCh: + if itemOne.Checked() { + itemOne.Uncheck() + } else { + itemOne.Check() + } + case <-sync.ClickedCh: + sync.SetTitle("Syncing...") + time.Sleep(1000) + sync.SetTitle("Last sync at " + time.Now().Format(time.TimeOnly)) + case <-quit.ClickedCh: + systray.Quit() + } + } + }() +} + +func onExit() { + +} + +func getIcon(location string) []byte { + bytes, err := os.ReadFile(location) + if err != nil { + fmt.Print(err) + } + return bytes +} diff --git a/assets/icon.ico b/assets/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f8d94fb64dbbce5f1cd705ab31156c52bce9d0b1 GIT binary patch literal 169607 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

A2JUcXW?bzXWN?mnW{ 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 R4Zvatgb4wdI*=ZaUI1i1_Y434 literal 0 HcmV?d00001 diff --git a/example-config.ini b/example-config.ini new file mode 100644 index 0000000..e998b4a --- /dev/null +++ b/example-config.ini @@ -0,0 +1,19 @@ +[General] +server = sfs.example.com +port = 7392 +username = user +auth-token = token +; http:// or https:// is necessary +; port is optional +http-server = http://sfs.example.com:80 +public-key = + +[Share] +sync-interval = 60 + + +[Share.example] +; "anywhere", "non-metered", "local-only" +sync-location = anywhere +client-location = C:\Users\sfs\example\ + diff --git a/ezconf b/ezconf new file mode 160000 index 0000000..397365d --- /dev/null +++ b/ezconf @@ -0,0 +1 @@ +Subproject commit 397365ddd2fa6359058b7f6dd62eb516387e3994 diff --git a/filetransfer.go b/filetransfer.go new file mode 100644 index 0000000..06ab7d0 --- /dev/null +++ b/filetransfer.go @@ -0,0 +1 @@ +package main diff --git a/filewatcher.go b/filewatcher.go new file mode 100644 index 0000000..d65e1fb --- /dev/null +++ b/filewatcher.go @@ -0,0 +1,7 @@ +package main + +import "os" + +func checkDirectory(path os.File) { + +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..8e5087e --- /dev/null +++ b/go.mod @@ -0,0 +1,24 @@ +module main + +go 1.20 + +replace git.nevets.tech/Steven/ezconf v0.0.0-20230501190348-397365ddd2fa => ./ezconf + +require ( + git.nevets.tech/Steven/ezconf v0.0.0-20230501190348-397365ddd2fa + github.com/getlantern/systray v1.2.1 +) + +require ( + github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // indirect + github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 // indirect + github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 // indirect + github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 // indirect + github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 // indirect + github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f // indirect + github.com/go-stack/stack v1.8.0 // indirect + github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect + golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ee63953 --- /dev/null +++ b/go.sum @@ -0,0 +1,32 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4= +github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY= +github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 h1:6uJ+sZ/e03gkbqZ0kUG6mfKoqDb4XMAzMIwlajq19So= +github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A= +github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 h1:guBYzEaLz0Vfc/jv0czrr2z7qyzTOGC9hiQ0VC+hKjk= +github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7/go.mod h1:zx/1xUUeYPy3Pcmet8OSXLbF47l+3y6hIPpyLWoR9oc= +github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0= +github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o= +github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc= +github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA= +github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA= +github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= +github.com/getlantern/systray v1.2.1 h1:udsC2k98v2hN359VTFShuQW6GGprRprw6kD6539JikI= +github.com/getlantern/systray v1.2.1/go.mod h1:AecygODWIsBquJCJFop8MEQcJbWFfw/1yWbVabNgpCM= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= +github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9 h1:YTzHMGlqJu67/uEo1lBv0n3wBXhXNeUbB1XfN2vmTm0= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go.work.sum b/go.work.sum new file mode 100644 index 0000000..9adf377 --- /dev/null +++ b/go.work.sum @@ -0,0 +1,2 @@ +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/serverconnection.go b/serverconnection.go new file mode 100644 index 0000000..6e0a573 --- /dev/null +++ b/serverconnection.go @@ -0,0 +1,64 @@ +package main + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "io" + "net/http" + "os" +) + +type ClientConn struct { + tlsConn *tls.Conn + credentials Credentials + isAuthed bool +} + +type Credentials struct { + user string + pass string +} + +func New(host string, port int) *tls.Conn { + cert, err := os.ReadFile("./public.pem") + if err != nil { + fmt.Printf("Error reading cert from ./public.pem: %v", err) + os.Exit(1) + } + + certPool := x509.NewCertPool() + if ok := certPool.AppendCertsFromPEM(cert); !ok { + fmt.Printf("Error loading certificate %v into cert pool", cert) + os.Exit(1) + } + config := &tls.Config{RootCAs: certPool} + conn, err := tls.Dial("tcp", host+":"+string(rune(port)), config) + return conn +} + +func getPublicKey() { + out, err := os.Create("./public.pem") + if err != nil { + fmt.Printf("Error closing file writer: %v", err) + os.Exit(1) + } + defer out.Close() + + resp, err := http.Get(Config.GetAsString("General.http-server") + "/public.pem") + if err != nil { + fmt.Printf("Error fetching public key: %v", err) + os.Exit(1) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + fmt.Printf("Request was unseccessful with code %v", resp.StatusCode) + } + + _, err = io.Copy(out, resp.Body) + if err != nil { + fmt.Printf("Error writing public key to file: %v", err) + os.Exit(1) + } +}