mirror of
https://codeberg.org/scip/ephemerup.git
synced 2025-12-17 04:30:57 +01:00
changes:
- added unit tests
- put all subcmds into one file
- use io.Writer for output, better for testing
- added upload form support
- added api docs
- generalized db engine
- added mail notify support for forms
- enhanced server/SetupAuthStore() to also look up form ids
- added form template (put into .go file by Makefile
- renamed project
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
module github.com/tlinden/cenophane/common
|
||||
module github.com/tlinden/ephemerup/common
|
||||
|
||||
go 1.18
|
||||
|
||||
140
common/types.go
140
common/types.go
@@ -17,6 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// used to return to the api client
|
||||
type Result struct {
|
||||
Success bool `json:"success"`
|
||||
@@ -24,20 +29,137 @@ type Result struct {
|
||||
Code int `json:"code"`
|
||||
}
|
||||
|
||||
// upload or form structs
|
||||
type Dbentry interface {
|
||||
Getcontext(j []byte) (string, error)
|
||||
Marshal() ([]byte, error)
|
||||
}
|
||||
|
||||
type Upload struct {
|
||||
Id string `json:"id"`
|
||||
Expire string `json:"expire"`
|
||||
File string `json:"file"` // final filename (visible to the downloader)
|
||||
Members []string `json:"members"` // contains multiple files, so File is an archive
|
||||
Uploaded Timestamp `json:"uploaded"`
|
||||
Context string `json:"context"`
|
||||
Url string `json:"url"`
|
||||
Id string `json:"id"`
|
||||
Expire string `json:"expire"`
|
||||
File string `json:"file"` // final filename (visible to the downloader)
|
||||
Members []string `json:"members"` // contains multiple files, so File is an archive
|
||||
Created Timestamp `json:"uploaded"`
|
||||
Context string `json:"context"`
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
// this one is also used for marshalling to the client
|
||||
type Uploads struct {
|
||||
Entries []*Upload `json:"uploads"`
|
||||
type Response struct {
|
||||
Uploads []*Upload `json:"uploads"`
|
||||
Forms []*Form `json:"forms"`
|
||||
|
||||
// integrate the Result struct so we can signal success
|
||||
Result
|
||||
}
|
||||
|
||||
type Form struct {
|
||||
// Note the dual use of the Id: it will be used as onetime api key
|
||||
// from generated upload forms and stored in the session store so
|
||||
// that the upload handler is able to check if the form object has
|
||||
// to be deleted immediately (if its expire field has been set to
|
||||
// asap)
|
||||
Id string `json:"id"`
|
||||
Expire string `json:"expire"`
|
||||
Description string `json:"description"`
|
||||
Created Timestamp `json:"uploaded"`
|
||||
Context string `json:"context"`
|
||||
Url string `json:"url"`
|
||||
Notify string `json:"notify"`
|
||||
}
|
||||
|
||||
const (
|
||||
TypeUpload = iota
|
||||
TypeForm
|
||||
)
|
||||
|
||||
/*
|
||||
implement Dbentry interface
|
||||
*/
|
||||
func (upload Upload) Getcontext(j []byte) (string, error) {
|
||||
if err := json.Unmarshal(j, &upload); err != nil {
|
||||
return "", fmt.Errorf("unable to unmarshal json: %s", err)
|
||||
}
|
||||
|
||||
return upload.Context, nil
|
||||
}
|
||||
|
||||
func (form Form) Getcontext(j []byte) (string, error) {
|
||||
if err := json.Unmarshal(j, &form); err != nil {
|
||||
return "", fmt.Errorf("unable to unmarshal json: %s", err)
|
||||
}
|
||||
|
||||
return form.Context, nil
|
||||
}
|
||||
|
||||
func (upload Upload) Marshal() ([]byte, error) {
|
||||
jsonentry, err := json.Marshal(upload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("json marshalling failure: %s", err)
|
||||
}
|
||||
|
||||
return jsonentry, nil
|
||||
}
|
||||
|
||||
func (form Form) Marshal() ([]byte, error) {
|
||||
jsonentry, err := json.Marshal(form)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("json marshalling failure: %s", err)
|
||||
}
|
||||
|
||||
return jsonentry, nil
|
||||
}
|
||||
|
||||
/*
|
||||
Response methods
|
||||
*/
|
||||
func (r *Response) Append(entry Dbentry) {
|
||||
switch entry.(type) {
|
||||
case *Upload:
|
||||
r.Uploads = append(r.Uploads, entry.(*Upload))
|
||||
case Upload:
|
||||
r.Uploads = append(r.Uploads, entry.(*Upload))
|
||||
case Form:
|
||||
r.Forms = append(r.Forms, entry.(*Form))
|
||||
case *Form:
|
||||
r.Forms = append(r.Forms, entry.(*Form))
|
||||
default:
|
||||
panic("unknown type!")
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Extract context, whatever kind entry is, but we don't know in
|
||||
advance, only after unmarshalling. So try Upload first, if that
|
||||
fails, try Form.
|
||||
*/
|
||||
func GetContext(j []byte) (string, error) {
|
||||
upload := &Upload{}
|
||||
entryContext, err := upload.Getcontext(j)
|
||||
if err != nil {
|
||||
form := &Form{}
|
||||
entryContext, err = form.Getcontext(j)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to unmarshal json: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
return entryContext, nil
|
||||
}
|
||||
|
||||
func Unmarshal(j []byte, t int) (Dbentry, error) {
|
||||
if t == TypeUpload {
|
||||
upload := &Upload{}
|
||||
if err := json.Unmarshal(j, &upload); err != nil {
|
||||
return upload, fmt.Errorf("unable to unmarshal json: %s", err)
|
||||
}
|
||||
return upload, nil
|
||||
} else {
|
||||
form := &Form{}
|
||||
if err := json.Unmarshal(j, &form); err != nil {
|
||||
return form, fmt.Errorf("unable to unmarshal json: %s", err)
|
||||
}
|
||||
return form, nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user