local-server/cmd/dkl-local-server/ws-public.go

167 lines
2.5 KiB
Go
Raw Normal View History

2023-02-07 20:29:19 +00:00
package main
import (
2023-02-13 12:03:42 +00:00
"archive/tar"
"bytes"
"io"
"io/fs"
"log"
2023-02-07 20:29:19 +00:00
"net/http"
2023-02-13 12:03:42 +00:00
"os"
"path/filepath"
2023-02-07 20:29:19 +00:00
restful "github.com/emicklei/go-restful"
"m.cluseau.fr/go/httperr"
2023-02-07 20:29:19 +00:00
)
func wsUnlockStore(req *restful.Request, resp *restful.Response) {
var passphrase string
err := req.ReadEntity(&passphrase)
if err != nil {
resp.WriteError(http.StatusBadRequest, err)
return
}
2023-02-13 12:03:42 +00:00
if err := unlockSecretStore([]byte(passphrase)); err.Any() {
2023-02-07 20:29:19 +00:00
err.WriteJSON(resp.ResponseWriter)
return
}
2023-05-18 17:55:52 +00:00
resp.WriteEntity(adminToken)
2023-02-07 20:29:19 +00:00
}
2023-02-13 12:03:42 +00:00
func wsStoreDownload(req *restful.Request, resp *restful.Response) {
token := req.QueryParameter("token")
if token != wState.Get().Store.DownloadToken {
wsError(resp, ErrInvalidToken)
return
}
buf := new(bytes.Buffer)
arch := tar.NewWriter(buf)
root := os.DirFS(secStoreRoot())
err := fs.WalkDir(root, ".", func(path string, d fs.DirEntry, readErr error) (err error) {
if readErr != nil {
err = readErr
return
}
if path == "." {
return
}
fi, err := d.Info()
if err != nil {
return
}
hdr, err := tar.FileInfoHeader(fi, "")
if err != nil {
return
}
hdr.Name = path
hdr.Uid = 0
hdr.Gid = 0
err = arch.WriteHeader(hdr)
if err != nil {
return
}
if fi.IsDir() {
return
}
f, err := root.Open(path)
if err != nil {
return
}
defer f.Close()
io.Copy(arch, f)
return
})
if err != nil {
wsError(resp, err)
return
}
err = arch.Close()
if err != nil {
wsError(resp, err)
return
}
buf.WriteTo(resp)
}
func wsStoreUpload(req *restful.Request, resp *restful.Response) {
if !secStore.IsNew() {
wsError(resp, httperr.BadRequest("store is not new"))
return
}
buf := new(bytes.Buffer)
_, err := io.Copy(buf, req.Request.Body)
if err != nil {
wsError(resp, err)
return
}
arch := tar.NewReader(buf)
root := secStoreRoot()
for {
hdr, err := arch.Next()
if err == io.EOF {
err = nil
break
} else if err != nil {
wsError(resp, err)
return
}
log.Print(hdr.Name)
fullPath := filepath.Join(root, hdr.Name)
switch {
case hdr.FileInfo().IsDir():
err = os.MkdirAll(fullPath, 0700)
if err != nil {
wsError(resp, err)
return
}
default:
content, err := io.ReadAll(io.LimitReader(arch, hdr.Size))
if err != nil {
wsError(resp, err)
return
}
err = os.WriteFile(fullPath, content, 0600)
if err != nil {
wsError(resp, err)
return
}
}
}
if err != nil {
wsError(resp, err)
return
}
openSecretStore()
resp.WriteEntity(map[string]any{"ok": true})
}