mirror of
https://github.com/pldubouilh/gossa.git
synced 2026-09-03 23:57:45 -04:00
hash state
This commit is contained in:
@@ -7,11 +7,11 @@ build:
|
|||||||
|
|
||||||
run:
|
run:
|
||||||
make build
|
make build
|
||||||
./gossa test-fixture
|
./gossa -verb=true test-fixture
|
||||||
|
|
||||||
run-extra:
|
run-extra:
|
||||||
make build
|
make build
|
||||||
./gossa -prefix="/fancy-path/" -symlinks=true test-fixture
|
./gossa -verb=true -prefix="/fancy-path/" -symlinks=true test-fixture
|
||||||
|
|
||||||
ci:
|
ci:
|
||||||
-@cd test-fixture && ln -s ../support .
|
-@cd test-fixture && ln -s ../support .
|
||||||
|
|||||||
+21
-15
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
@@ -23,7 +24,7 @@ var port = flag.String("p", "8001", "port to listen to")
|
|||||||
var history = flag.Bool("history", true, "keep history for paths visited. default location is path/.gossa_history")
|
var history = flag.Bool("history", true, "keep history for paths visited. default location is path/.gossa_history")
|
||||||
var extraPath = flag.String("prefix", "/", "url prefix at which gossa can be reached, e.g. /gossa/ (slashes of importance)")
|
var extraPath = flag.String("prefix", "/", "url prefix at which gossa can be reached, e.g. /gossa/ (slashes of importance)")
|
||||||
var symlinks = flag.Bool("symlinks", false, "follow symlinks \033[4mWARNING\033[0m: symlinks will by nature allow to escape the defined path (default: false)")
|
var symlinks = flag.Bool("symlinks", false, "follow symlinks \033[4mWARNING\033[0m: symlinks will by nature allow to escape the defined path (default: false)")
|
||||||
var verb = flag.Bool("verb", true, "verbosity")
|
var verb = flag.Bool("verb", false, "verbosity")
|
||||||
var skipHidden = flag.Bool("k", true, "skip hidden files")
|
var skipHidden = flag.Bool("k", true, "skip hidden files")
|
||||||
var initPath = "."
|
var initPath = "."
|
||||||
var historyPath = ""
|
var historyPath = ""
|
||||||
@@ -32,15 +33,15 @@ var fs http.Handler
|
|||||||
var page, _ = template.New("pageTemplate").Parse(`template_will_be_here`)
|
var page, _ = template.New("pageTemplate").Parse(`template_will_be_here`)
|
||||||
|
|
||||||
type rowTemplate struct {
|
type rowTemplate struct {
|
||||||
Name string
|
Name string
|
||||||
Href template.HTML
|
Href template.HTML
|
||||||
Size string
|
Size string
|
||||||
Ext string
|
Ext string
|
||||||
|
Selected bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type pageTemplate struct {
|
type pageTemplate struct {
|
||||||
Title template.HTML
|
Title template.HTML
|
||||||
State template.HTML
|
|
||||||
ExtraPath template.HTML
|
ExtraPath template.HTML
|
||||||
RowsFiles []rowTemplate
|
RowsFiles []rowTemplate
|
||||||
RowsFolders []rowTemplate
|
RowsFolders []rowTemplate
|
||||||
@@ -57,6 +58,10 @@ func check(e error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hash(s string) string {
|
||||||
|
return fmt.Sprintf("%x", sha256.Sum256([]byte(s)))
|
||||||
|
}
|
||||||
|
|
||||||
func exitPath(w http.ResponseWriter, s ...interface{}) {
|
func exitPath(w http.ResponseWriter, s ...interface{}) {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
log.Println("error", s, r)
|
log.Println("error", s, r)
|
||||||
@@ -81,7 +86,6 @@ func humanize(bytes int64) string {
|
|||||||
func replyList(w http.ResponseWriter, r *http.Request, fullPath string, path string) {
|
func replyList(w http.ResponseWriter, r *http.Request, fullPath string, path string) {
|
||||||
_files, err := ioutil.ReadDir(fullPath)
|
_files, err := ioutil.ReadDir(fullPath)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
if !strings.HasSuffix(path, "/") {
|
if !strings.HasSuffix(path, "/") {
|
||||||
path += "/"
|
path += "/"
|
||||||
}
|
}
|
||||||
@@ -89,11 +93,11 @@ func replyList(w http.ResponseWriter, r *http.Request, fullPath string, path str
|
|||||||
title := "/" + strings.TrimPrefix(path, *extraPath)
|
title := "/" + strings.TrimPrefix(path, *extraPath)
|
||||||
p := pageTemplate{}
|
p := pageTemplate{}
|
||||||
if path != *extraPath {
|
if path != *extraPath {
|
||||||
p.RowsFolders = append(p.RowsFolders, rowTemplate{"../", "../", "", "folder"})
|
p.RowsFolders = append(p.RowsFolders, rowTemplate{"../", "../", "", "folder", false})
|
||||||
}
|
}
|
||||||
p.ExtraPath = template.HTML(html.EscapeString(*extraPath))
|
p.ExtraPath = template.HTML(html.EscapeString(*extraPath))
|
||||||
p.Title = template.HTML(html.EscapeString(title))
|
p.Title = template.HTML(html.EscapeString(title))
|
||||||
p.State = template.HTML(html.EscapeString(state[r.Header.Get("Authorization")+path]))
|
loc := state[hash(r.Header.Get("Authorization")+path)]
|
||||||
|
|
||||||
for _, el := range _files {
|
for _, el := range _files {
|
||||||
if *skipHidden && strings.HasPrefix(el.Name(), ".") {
|
if *skipHidden && strings.HasPrefix(el.Name(), ".") {
|
||||||
@@ -105,11 +109,10 @@ func replyList(w http.ResponseWriter, r *http.Request, fullPath string, path str
|
|||||||
href = strings.Replace(href, "/", "", 1)
|
href = strings.Replace(href, "/", "", 1)
|
||||||
}
|
}
|
||||||
if el.IsDir() {
|
if el.IsDir() {
|
||||||
p.RowsFolders = append(p.RowsFolders, rowTemplate{el.Name() + "/", template.HTML(href), "", "folder"})
|
p.RowsFolders = append(p.RowsFolders, rowTemplate{el.Name() + "/", template.HTML(href), "", "folder", loc == hash(el.Name()+"/")})
|
||||||
} else {
|
} else {
|
||||||
sl := strings.Split(el.Name(), ".")
|
sl := strings.Split(el.Name(), ".")
|
||||||
ext := strings.ToLower(sl[len(sl)-1])
|
p.RowsFiles = append(p.RowsFiles, rowTemplate{el.Name(), template.HTML(href), humanize(el.Size()), strings.ToLower(sl[len(sl)-1]), loc == hash(el.Name())})
|
||||||
p.RowsFiles = append(p.RowsFiles, rowTemplate{el.Name(), template.HTML(href), humanize(el.Size()), ext})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +154,7 @@ func rpc(w http.ResponseWriter, r *http.Request) {
|
|||||||
bodyBytes, _ := ioutil.ReadAll(r.Body)
|
bodyBytes, _ := ioutil.ReadAll(r.Body)
|
||||||
json.Unmarshal(bodyBytes, &rpc)
|
json.Unmarshal(bodyBytes, &rpc)
|
||||||
defer exitPath(w, "rpc", rpc)
|
defer exitPath(w, "rpc", rpc)
|
||||||
|
ret := "ok"
|
||||||
|
|
||||||
if rpc.Call == "mkdirp" {
|
if rpc.Call == "mkdirp" {
|
||||||
err = os.MkdirAll(checkPath(rpc.Args[0]), os.ModePerm)
|
err = os.MkdirAll(checkPath(rpc.Args[0]), os.ModePerm)
|
||||||
@@ -158,14 +162,16 @@ func rpc(w http.ResponseWriter, r *http.Request) {
|
|||||||
err = os.Rename(checkPath(rpc.Args[0]), checkPath(rpc.Args[1]))
|
err = os.Rename(checkPath(rpc.Args[0]), checkPath(rpc.Args[1]))
|
||||||
} else if rpc.Call == "rm" {
|
} else if rpc.Call == "rm" {
|
||||||
err = os.RemoveAll(checkPath(rpc.Args[0]))
|
err = os.RemoveAll(checkPath(rpc.Args[0]))
|
||||||
} else if rpc.Call == "history" && *history {
|
} else if rpc.Call == "historySet" && *history {
|
||||||
state[r.Header.Get("Authorization")+rpc.Args[0]] = rpc.Args[1]
|
state[hash(r.Header.Get("Authorization")+rpc.Args[0])] = rpc.Args[1] // first arg is always hashed (url), second is hashed on the browser depending on payload
|
||||||
f, _ := json.MarshalIndent(state, "", " ")
|
f, _ := json.MarshalIndent(state, "", " ")
|
||||||
ioutil.WriteFile(historyPath, f, 0644)
|
ioutil.WriteFile(historyPath, f, 0644)
|
||||||
|
} else if rpc.Call == "historyGet" && *history {
|
||||||
|
ret = state[hash(r.Header.Get("Authorization")+rpc.Args[0])]
|
||||||
}
|
}
|
||||||
|
|
||||||
check(err)
|
check(err)
|
||||||
w.Write([]byte("ok"))
|
w.Write([]byte(ret))
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkPath(p string) string {
|
func checkPath(p string) string {
|
||||||
|
|||||||
+38
-14
@@ -116,7 +116,7 @@ func doTest(t *testing.T, url string, symlinkEnabled bool) {
|
|||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
fmt.Println("\r\n~~~~~~~~~~ test mkdir rpc")
|
fmt.Println("\r\n~~~~~~~~~~ test mkdir rpc")
|
||||||
bodyStr = postJSON(t, url+"rpc", `{"call":"mkdirp","args":["/AAA"]}`)
|
bodyStr = postJSON(t, url+"rpc", `{"call":"mkdirp","args":["/AAA"]}`)
|
||||||
if !strings.Contains(bodyStr, `ok`) {
|
if bodyStr != `ok` {
|
||||||
t.Fatal("mkdir rpc errored")
|
t.Fatal("mkdir rpc errored")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ func doTest(t *testing.T, url string, symlinkEnabled bool) {
|
|||||||
path = "%2F%E1%84%92%E1%85%A1%20%E1%84%92%E1%85%A1" // "하 하" encoded
|
path = "%2F%E1%84%92%E1%85%A1%20%E1%84%92%E1%85%A1" // "하 하" encoded
|
||||||
payload = "123 하"
|
payload = "123 하"
|
||||||
bodyStr = postDummyFile(t, url, path, payload)
|
bodyStr = postDummyFile(t, url, path, payload)
|
||||||
if !strings.Contains(bodyStr, `ok`) {
|
if bodyStr != `ok` {
|
||||||
t.Fatal("post file errored")
|
t.Fatal("post file errored")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ func doTest(t *testing.T, url string, symlinkEnabled bool) {
|
|||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
fmt.Println("\r\n~~~~~~~~~~ test mv rpc")
|
fmt.Println("\r\n~~~~~~~~~~ test mv rpc")
|
||||||
bodyStr = postJSON(t, url+"rpc", `{"call":"mv","args":["/AAA", "/hols/AAA"]}`)
|
bodyStr = postJSON(t, url+"rpc", `{"call":"mv","args":["/AAA", "/hols/AAA"]}`)
|
||||||
if !strings.Contains(bodyStr, `ok`) {
|
if bodyStr != `ok` {
|
||||||
t.Fatal("mv rpc errored")
|
t.Fatal("mv rpc errored")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +175,19 @@ func doTest(t *testing.T, url string, symlinkEnabled bool) {
|
|||||||
t.Fatal("mv rpc folder not moved")
|
t.Fatal("mv rpc folder not moved")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
// Test where auth header unset, otherwise it'd be apended to the first arg
|
||||||
|
fmt.Println("\r\n~~~~~~~~~~ test history rpc")
|
||||||
|
bodyStr = postJSON(t, url+"rpc", `{"call":"historySet","args":["a", "123"]}`)
|
||||||
|
if bodyStr != `ok` {
|
||||||
|
t.Fatal("mv rpc errored")
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyStr = postJSON(t, url+"rpc", `{"call":"historyGet","args":["a"]}`)
|
||||||
|
if bodyStr != `123` {
|
||||||
|
t.Fatal("error historyGet")
|
||||||
|
}
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
fmt.Println("\r\n~~~~~~~~~~ test upload in new folder")
|
fmt.Println("\r\n~~~~~~~~~~ test upload in new folder")
|
||||||
payload = "abcdef1234"
|
payload = "abcdef1234"
|
||||||
@@ -199,17 +212,35 @@ func doTest(t *testing.T, url string, symlinkEnabled bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if symlinkEnabled {
|
if symlinkEnabled {
|
||||||
fmt.Println("\r\n~~~~~~~~~~ test symlink mkdir")
|
fmt.Println("\r\n~~~~~~~~~~ test symlink mkdir & cleanup")
|
||||||
bodyStr = postJSON(t, url+"rpc", `{"call":"mkdirp","args":["/support/testfolder"]}`)
|
bodyStr = postJSON(t, url+"rpc", `{"call":"mkdirp","args":["/support/testfolder"]}`)
|
||||||
if !strings.Contains(bodyStr, `ok`) {
|
if bodyStr != `ok` {
|
||||||
t.Fatal("error symlink mkdir")
|
t.Fatal("error symlink mkdir")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bodyStr = postJSON(t, url+"rpc", `{"call":"rm","args":["/support/testfolder"]}`)
|
||||||
|
if bodyStr != `ok` {
|
||||||
|
t.Fatal("error symlink rm")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fmt.Println("\r\n~~~~~~~~~~ test upload in new folder")
|
||||||
|
payload = "abcdef1234"
|
||||||
|
bodyStr = postDummyFile(t, url, "%2Fhols%2FAAA%2Fabcdef", payload)
|
||||||
|
if strings.Contains(bodyStr, `err`) {
|
||||||
|
t.Fatal("upload in new folder errored")
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyStr = get(t, url+"hols/AAA/abcdef")
|
||||||
|
if !strings.Contains(bodyStr, payload) {
|
||||||
|
t.Fatal("upload in new folder error reaching new file")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
fmt.Println("\r\n~~~~~~~~~~ test rm rpc & cleanup")
|
fmt.Println("\r\n~~~~~~~~~~ test rm rpc & cleanup")
|
||||||
bodyStr = postJSON(t, url+"rpc", `{"call":"rm","args":["/hols/AAA"]}`)
|
bodyStr = postJSON(t, url+"rpc", `{"call":"rm","args":["/hols/AAA"]}`)
|
||||||
if !strings.Contains(bodyStr, `ok`) {
|
if bodyStr != `ok` {
|
||||||
t.Fatal("cleanup errored #0")
|
t.Fatal("cleanup errored #0")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,16 +250,9 @@ func doTest(t *testing.T, url string, symlinkEnabled bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bodyStr = postJSON(t, url+"rpc", `{"call":"rm","args":["/하 하"]}`)
|
bodyStr = postJSON(t, url+"rpc", `{"call":"rm","args":["/하 하"]}`)
|
||||||
if !strings.Contains(bodyStr, `ok`) {
|
if bodyStr != `ok` {
|
||||||
t.Fatal("cleanup errored #2")
|
t.Fatal("cleanup errored #2")
|
||||||
}
|
}
|
||||||
|
|
||||||
if symlinkEnabled {
|
|
||||||
bodyStr = postJSON(t, url+"rpc", `{"call":"rm","args":["/support/testfolder"]}`)
|
|
||||||
if !strings.Contains(bodyStr, `ok`) {
|
|
||||||
t.Fatal("error symlink rm")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetFolder(t *testing.T) {
|
func TestGetFolder(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user