diff options
| author | Shulhan <ms@kilabit.info> | 2023-11-15 02:22:37 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-11-16 00:54:55 +0700 |
| commit | 622bd72e6f2d3bd848963fc486fef1b39760e2ac (patch) | |
| tree | 476d90b90a906f4222017b2842de8d763367d66f /http_server.go | |
| parent | 79ac55824fc969ec3a773e46e450f6ba410bee1a (diff) | |
| download | awwan-622bd72e6f2d3bd848963fc486fef1b39760e2ac.tar.xz | |
all: implement HTTP API to decrypt file
Similar to the CLI, the HTTP API accept the path of vault file
and return the path to decrypted file.
Diffstat (limited to 'http_server.go')
| -rw-r--r-- | http_server.go | 100 |
1 files changed, 97 insertions, 3 deletions
diff --git a/http_server.go b/http_server.go index b823204..30dd52a 100644 --- a/http_server.go +++ b/http_server.go @@ -21,7 +21,9 @@ import ( "git.sr.ht/~shulhan/awwan/internal" ) +// List of available HTTP API. const ( + pathAwwanApiDecrypt = `/awwan/api/decrypt` pathAwwanApiEncrypt = `/awwan/api/encrypt` pathAwwanApiExecute = `/awwan/api/execute` pathAwwanApiFs = `/awwan/api/fs` @@ -136,16 +138,28 @@ func (httpd *httpServer) registerEndpoints() (err error) { return fmt.Errorf("%s: %w", logp, err) } - var ep = libhttp.Endpoint{ + var epDecrypt = libhttp.Endpoint{ + Method: libhttp.RequestMethodPost, + Path: pathAwwanApiDecrypt, + RequestType: libhttp.RequestTypeJSON, + ResponseType: libhttp.ResponseTypeJSON, + Call: httpd.Decrypt, + } + err = httpd.RegisterEndpoint(&epDecrypt) + if err != nil { + return fmt.Errorf(`%s %q: %w`, logp, epDecrypt.Path, err) + } + + var epEncrypt = libhttp.Endpoint{ Method: libhttp.RequestMethodPost, Path: pathAwwanApiEncrypt, RequestType: libhttp.RequestTypeJSON, ResponseType: libhttp.ResponseTypeJSON, Call: httpd.Encrypt, } - err = httpd.RegisterEndpoint(&ep) + err = httpd.RegisterEndpoint(&epEncrypt) if err != nil { - return fmt.Errorf(`%s %q: %w`, logp, ep.Path, err) + return fmt.Errorf(`%s %q: %w`, logp, epEncrypt.Path, err) } err = httpd.RegisterEndpoint(&libhttp.Endpoint{ @@ -169,6 +183,86 @@ func (httpd *httpServer) start() (err error) { return httpd.Server.Start() } +// Decrypt the file by path. +// +// Request format, +// +// POST /awwan/api/decrypt +// Content-Type: application/json +// +// {"path_vault":<string>} +// +// On success it will return the path to decrypted file. +// +// Content-Type: application/json +// +// { +// "code": 200, +// "data": { +// "path": <string>, +// "path_vault": <string>, +// } +// } +func (httpd *httpServer) Decrypt(epr *libhttp.EndpointRequest) (resb []byte, err error) { + var ( + logp = `Decrypt` + httpRes = &libhttp.EndpointResponse{} + + decRes encryptResponse + ) + + err = json.Unmarshal(epr.RequestBody, &decRes) + if err != nil { + return nil, fmt.Errorf(`%s: %w`, logp, err) + } + + httpRes.Code = http.StatusBadRequest + + decRes.PathVault = strings.TrimSpace(decRes.PathVault) + if len(decRes.PathVault) == 0 { + httpRes.Message = fmt.Sprintf(`%s: empty path_vault`, logp) + return nil, httpRes + } + + var nodeVault *memfs.Node + + nodeVault, err = httpd.memfsBase.Get(decRes.PathVault) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + httpRes.Message = fmt.Sprintf(`%s %q: %s`, logp, decRes.PathVault, fs.ErrNotExist) + } else { + httpRes.Message = fmt.Sprintf(`%s: %s`, logp, err) + } + return nil, httpRes + } + if nodeVault.IsDir() { + httpRes.Message = fmt.Sprintf(`%s: %q is a directory`, logp, decRes.PathVault) + return nil, httpRes + } + + httpRes.Code = http.StatusInternalServerError + + decRes.Path, err = httpd.aww.Decrypt(nodeVault.SysPath) + if err != nil { + httpRes.Message = fmt.Sprintf(`%s: %s`, logp, err) + return nil, httpRes + } + + nodeVault.Parent.Update(nil, 0) + + decRes.Path, _ = strings.CutPrefix(decRes.Path, httpd.aww.BaseDir) + + httpRes.Code = http.StatusOK + httpRes.Data = decRes + + resb, err = json.Marshal(&httpRes) + if err != nil { + return nil, err + } + + return resb, nil +} + // Encrypt the file by path. // // Request format, |
