mirror of
https://github.com/pldubouilh/gossa
synced 2025-12-06 08:22:32 +01:00
read only mode
This commit is contained in:
parent
be39e6aca8
commit
49cfc28d34
7 changed files with 124 additions and 33 deletions
2
.github/workflows/go.yml
vendored
2
.github/workflows/go.yml
vendored
|
|
@ -19,4 +19,4 @@ jobs:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
- name: Run
|
- name: Run
|
||||||
run: make ci
|
run: make test
|
||||||
|
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -4,6 +4,7 @@ gossa-linux-arm
|
||||||
gossa-linux-arm64
|
gossa-linux-arm64
|
||||||
gossa-mac
|
gossa-mac
|
||||||
gossa-windows.exe
|
gossa-windows.exe
|
||||||
|
gossa_test.go
|
||||||
|
|
||||||
.vscode
|
.vscode
|
||||||
test-fixture/*
|
test-fixture/*
|
||||||
|
|
|
||||||
32
Makefile
32
Makefile
|
|
@ -3,33 +3,26 @@ build:
|
||||||
make -C gossa-ui/
|
make -C gossa-ui/
|
||||||
go vet && go fmt
|
go vet && go fmt
|
||||||
CGO_ENABLED=0 go build gossa.go
|
CGO_ENABLED=0 go build gossa.go
|
||||||
sleep 1 && rm gossa.go
|
rm gossa.go
|
||||||
|
|
||||||
run:
|
run:
|
||||||
make build
|
make build
|
||||||
./gossa -verb=true test-fixture
|
./gossa -verb=true test-fixture
|
||||||
|
|
||||||
|
run-ro:
|
||||||
|
make build
|
||||||
|
./gossa -verb=true -ro=true test-fixture
|
||||||
|
|
||||||
run-extra:
|
run-extra:
|
||||||
make build
|
make build
|
||||||
./gossa -verb=true -prefix="/fancy-path/" -k=false -symlinks=true test-fixture
|
./gossa -verb=true -prefix="/fancy-path/" -k=false -symlinks=true test-fixture
|
||||||
|
|
||||||
test:
|
test:
|
||||||
timeout 60 make run &
|
make build
|
||||||
sleep 15 && cp src/gossa_test.go . && go test -run TestNormal
|
-rm gossa_test.go
|
||||||
rm gossa_test.go
|
|
||||||
-killall gossa
|
|
||||||
|
|
||||||
test-extra:
|
|
||||||
timeout 60 make run-extra &
|
|
||||||
sleep 15 && cp src/gossa_test.go . && go test -run TestExtra
|
|
||||||
rm gossa_test.go
|
|
||||||
-killall gossa
|
|
||||||
|
|
||||||
ci:
|
|
||||||
-@cd test-fixture && ln -s ../support .
|
-@cd test-fixture && ln -s ../support .
|
||||||
make test
|
cp src/gossa_test.go .
|
||||||
make test-extra
|
go test
|
||||||
|
|
||||||
|
|
||||||
watch:
|
watch:
|
||||||
ls src/* gossa-ui/* | entr -rc make run
|
ls src/* gossa-ui/* | entr -rc make run
|
||||||
|
|
@ -37,8 +30,11 @@ watch:
|
||||||
watch-extra:
|
watch-extra:
|
||||||
ls src/* gossa-ui/* | entr -rc make run-extra
|
ls src/* gossa-ui/* | entr -rc make run-extra
|
||||||
|
|
||||||
watch-ci:
|
watch-ro:
|
||||||
ls src/* gossa-ui/* | entr -rc make ci
|
ls src/* gossa-ui/* | entr -rc make run-ro
|
||||||
|
|
||||||
|
watch-test:
|
||||||
|
ls src/* gossa-ui/* | entr -rc make test
|
||||||
|
|
||||||
build-all:
|
build-all:
|
||||||
cp src/gossa.go gossa.go
|
cp src/gossa.go gossa.go
|
||||||
|
|
|
||||||
2
gossa-ui
2
gossa-ui
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6a14c317ef43828b171f8478feff13bae224b3ac
|
Subproject commit 597b49973f8f855f74a3c12b2be769031098def8
|
||||||
|
|
@ -14,13 +14,14 @@ a [simple UI](https://github.com/pldubouilh/gossa-ui) comes as default, featurin
|
||||||
|
|
||||||
* 🔍 files/directories browser
|
* 🔍 files/directories browser
|
||||||
* 📩 drag-and-drop file/directory uploader
|
* 📩 drag-and-drop file/directory uploader
|
||||||
|
* 🚀 lightweight, default ui weights 110kB and prints in ms
|
||||||
* 🗺️ files handling - move/rename/delete
|
* 🗺️ files handling - move/rename/delete
|
||||||
* 📸 picture browser
|
* 📸 picture browser
|
||||||
* 📽️ video streaming
|
* 📽️ video streaming
|
||||||
* ✍️ simple text editor
|
* ✍️ simple text editor
|
||||||
* ⌨️ keyboard shortcuts
|
* ⌨️ keyboard shortcuts
|
||||||
* 🥂 speed - will easily fill available bandwidth
|
* 🥂 fast golang static server, easily fills available bandwidth
|
||||||
* 🔒 safe - easy/secure multi account setup
|
* 🔒 easy/secure multi account setup
|
||||||
|
|
||||||
### build
|
### build
|
||||||
built blobs are available on the [release page](https://github.com/pldubouilh/gossa/releases) - or simply `make build` this repo.
|
built blobs are available on the [release page](https://github.com/pldubouilh/gossa/releases) - or simply `make build` this repo.
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ var extraPath = flag.String("prefix", "/", "url prefix at which gossa can be rea
|
||||||
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", false, "verbosity")
|
var verb = flag.Bool("verb", false, "verbosity")
|
||||||
var skipHidden = flag.Bool("k", true, "\nskip hidden files")
|
var skipHidden = flag.Bool("k", true, "\nskip hidden files")
|
||||||
|
var ro = flag.Bool("ro", false, "read only mode (no upload, rename, move, etc...)")
|
||||||
var initPath = "."
|
var initPath = "."
|
||||||
|
|
||||||
var fs http.Handler
|
var fs http.Handler
|
||||||
|
|
@ -40,6 +41,7 @@ type rowTemplate struct {
|
||||||
type pageTemplate struct {
|
type pageTemplate struct {
|
||||||
Title template.HTML
|
Title template.HTML
|
||||||
ExtraPath template.HTML
|
ExtraPath template.HTML
|
||||||
|
Ro bool
|
||||||
RowsFiles []rowTemplate
|
RowsFiles []rowTemplate
|
||||||
RowsFolders []rowTemplate
|
RowsFolders []rowTemplate
|
||||||
}
|
}
|
||||||
|
|
@ -92,6 +94,7 @@ func replyList(w http.ResponseWriter, fullPath string, path string) {
|
||||||
p.RowsFolders = append(p.RowsFolders, rowTemplate{"../", "../", "", "folder"})
|
p.RowsFolders = append(p.RowsFolders, rowTemplate{"../", "../", "", "folder"})
|
||||||
}
|
}
|
||||||
p.ExtraPath = template.HTML(html.EscapeString(*extraPath))
|
p.ExtraPath = template.HTML(html.EscapeString(*extraPath))
|
||||||
|
p.Ro = *ro
|
||||||
p.Title = template.HTML(html.EscapeString(title))
|
p.Title = template.HTML(html.EscapeString(title))
|
||||||
|
|
||||||
for _, el := range _files {
|
for _, el := range _files {
|
||||||
|
|
@ -190,8 +193,10 @@ func main() {
|
||||||
initPath, err = filepath.Abs(initPath)
|
initPath, err = filepath.Abs(initPath)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
http.HandleFunc(*extraPath+"rpc", rpc)
|
if !*ro {
|
||||||
http.HandleFunc(*extraPath+"post", upload)
|
http.HandleFunc(*extraPath+"rpc", rpc)
|
||||||
|
http.HandleFunc(*extraPath+"post", upload)
|
||||||
|
}
|
||||||
http.HandleFunc("/", doContent)
|
http.HandleFunc("/", doContent)
|
||||||
fs = http.StripPrefix(*extraPath, http.FileServer(http.Dir(initPath)))
|
fs = http.StripPrefix(*extraPath, http.FileServer(http.Dir(initPath)))
|
||||||
fmt.Printf("Gossa startig on directory %s\nListening on http://%s:%s%s\n", initPath, *host, *port, *extraPath)
|
fmt.Printf("Gossa startig on directory %s\nListening on http://%s:%s%s\n", initPath, *host, *port, *extraPath)
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,12 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func dieMaybe(t *testing.T, err error) {
|
func dieMaybe(t *testing.T, err error) {
|
||||||
|
|
@ -83,7 +86,7 @@ func fetchAndTestDefault(t *testing.T, url string) string {
|
||||||
return body0
|
return body0
|
||||||
}
|
}
|
||||||
|
|
||||||
func doTest(t *testing.T, url string, testExtra bool) {
|
func doTestRegular(t *testing.T, url string, testExtra bool) {
|
||||||
var payload, path, body0, body1, body2 string
|
var payload, path, body0, body1, body2 string
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
|
@ -228,16 +231,101 @@ func doTest(t *testing.T, url string, testExtra bool) {
|
||||||
if body0 != `ok` {
|
if body0 != `ok` {
|
||||||
t.Fatal("cleanup errored #2")
|
t.Fatal("cleanup errored #2")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Printf("\r\n=========\r\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormal(t *testing.T) {
|
func doTestReadonly(t *testing.T, url string) {
|
||||||
|
var payload, path, body0, body1 string
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
fmt.Println("\r\n~~~~~~~~~~ test fetching default path")
|
||||||
|
fetchAndTestDefault(t, url)
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
fmt.Println("\r\n~~~~~~~~~~ test fetching an invalid path - redirected to root")
|
||||||
|
fetchAndTestDefault(t, url+"../../")
|
||||||
|
fetchAndTestDefault(t, url+"hols/../../")
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
fmt.Println("\r\n~~~~~~~~~~ test fetching regular files")
|
||||||
|
body0 = get(t, url+"subdir_with%20space/file_with%20space.html")
|
||||||
|
body1 = get(t, url+"fancy-path/a")
|
||||||
|
if body0 != `<b>spacious!!</b> ` || body1 != `fancy! ` {
|
||||||
|
t.Fatal("fetching a regular file errored")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
fmt.Println("\r\n~~~~~~~~~~ test fetching a invalid file")
|
||||||
|
path = "../../../../../../../../../../etc/passwd"
|
||||||
|
if get(t, url+path) != `error` {
|
||||||
|
t.Fatal("fetching a invalid file didnt errored")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
fmt.Println("\r\n~~~~~~~~~~ test mkdir rpc")
|
||||||
|
body0 = postJSON(t, url+"rpc", `{"call":"mkdirp","args":["/AAA"]}`)
|
||||||
|
if body0 == `ok` {
|
||||||
|
t.Fatal("mkdir rpc passed - should not be allowed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
fmt.Println("\r\n~~~~~~~~~~ test post file")
|
||||||
|
path = "%2F%E1%84%92%E1%85%A1%20%E1%84%92%E1%85%A1" // "하 하" encoded
|
||||||
|
payload = "123 하"
|
||||||
|
body0 = postDummyFile(t, url, path, payload)
|
||||||
|
body1 = get(t, url+path)
|
||||||
|
if body0 == `ok` {
|
||||||
|
t.Fatal("post file passed - should not be allowed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
fmt.Println("\r\n~~~~~~~~~~ test mv rpc")
|
||||||
|
body0 = postJSON(t, url+"rpc", `{"call":"mv","args":["/AAA", "/hols/AAA"]}`)
|
||||||
|
body1 = fetchAndTestDefault(t, url)
|
||||||
|
if body0 == `ok` {
|
||||||
|
t.Fatal("mv rpc passed - should not be allowed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
fmt.Println("\r\n~~~~~~~~~~ test rm rpc & cleanup")
|
||||||
|
body0 = postJSON(t, url+"rpc", `{"call":"rm","args":["/hols/AAA"]}`)
|
||||||
|
if body0 == `ok` {
|
||||||
|
t.Fatal("cleanup passed - should not be allowed")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("\r\n=========\r\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func startGossa(what string) int {
|
||||||
|
cmd := exec.Command("/usr/bin/make", what)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stdout
|
||||||
|
cmd.Start()
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
return cmd.Process.Pid
|
||||||
|
}
|
||||||
|
|
||||||
|
func killallgossa() {
|
||||||
|
cmd := exec.Command("/usr/bin/killall", "gossa")
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stdout
|
||||||
|
cmd.Start()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGossa(t *testing.T) {
|
||||||
|
startGossa("run")
|
||||||
fmt.Println("========== testing normal path ============")
|
fmt.Println("========== testing normal path ============")
|
||||||
doTest(t, "http://127.0.0.1:8001/", false)
|
doTestRegular(t, "http://127.0.0.1:8001/", false)
|
||||||
fmt.Printf("\r\n=========\r\n")
|
killallgossa()
|
||||||
}
|
|
||||||
|
|
||||||
func TestExtra(t *testing.T) {
|
startGossa("run-extra")
|
||||||
fmt.Println("========== testing at fancy path ============")
|
fmt.Println("========== testing extras options ============")
|
||||||
doTest(t, "http://127.0.0.1:8001/fancy-path/", true)
|
doTestRegular(t, "http://127.0.0.1:8001/fancy-path/", true)
|
||||||
fmt.Printf("\r\n=========\r\n")
|
killallgossa()
|
||||||
|
|
||||||
|
startGossa("run-ro")
|
||||||
|
fmt.Println("========== testing read only ============")
|
||||||
|
doTestReadonly(t, "http://127.0.0.1:8001/")
|
||||||
|
killallgossa()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue