|
|
|
@ -11,7 +11,7 @@ import (
|
|
|
|
|
"strings" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"gitea.hashru.nl/dsprenkels/rushlink/internal/db" |
|
|
|
|
"gitea.hashru.nl/dsprenkels/rushlink/internal/boltdb" |
|
|
|
|
"github.com/google/uuid" |
|
|
|
|
"github.com/gorilla/mux" |
|
|
|
|
"github.com/pkg/errors" |
|
|
|
@ -96,18 +96,18 @@ func (rl *rushlink) viewPasteHandlerMeta(w http.ResponseWriter, r *http.Request)
|
|
|
|
|
func (rl *rushlink) viewPasteHandlerFlags(w http.ResponseWriter, r *http.Request, flags viewPaste) { |
|
|
|
|
vars := mux.Vars(r) |
|
|
|
|
key := vars["key"] |
|
|
|
|
var p *db.Paste |
|
|
|
|
var fu *db.FileUpload |
|
|
|
|
var p *boltdb.Paste |
|
|
|
|
var fu *boltdb.FileUpload |
|
|
|
|
err := rl.db.Bolt.View(func(tx *bolt.Tx) error { |
|
|
|
|
var err error |
|
|
|
|
p, err = db.GetPaste(tx, key) |
|
|
|
|
p, err = boltdb.GetPaste(tx, key) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
if p != nil && p.Type == db.PasteTypeFileUpload { |
|
|
|
|
if p != nil && p.Type == boltdb.PasteTypeFileUpload { |
|
|
|
|
var id uuid.UUID |
|
|
|
|
copy(id[:], p.Content) |
|
|
|
|
fu, err = db.GetFileUpload(tx, id) |
|
|
|
|
fu, err = boltdb.GetFileUpload(tx, id) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
@ -115,7 +115,7 @@ func (rl *rushlink) viewPasteHandlerFlags(w http.ResponseWriter, r *http.Request
|
|
|
|
|
return nil |
|
|
|
|
}) |
|
|
|
|
if err != nil { |
|
|
|
|
status := db.ErrHTTPStatusCode(err) |
|
|
|
|
status := boltdb.ErrHTTPStatusCode(err) |
|
|
|
|
if status == http.StatusInternalServerError { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
@ -126,22 +126,22 @@ func (rl *rushlink) viewPasteHandlerFlags(w http.ResponseWriter, r *http.Request
|
|
|
|
|
rl.viewPasteHandlerInner(w, r, flags, p, fu) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (rl *rushlink) viewPasteHandlerInner(w http.ResponseWriter, r *http.Request, flags viewPaste, p *db.Paste, fu *db.FileUpload) { |
|
|
|
|
func (rl *rushlink) viewPasteHandlerInner(w http.ResponseWriter, r *http.Request, flags viewPaste, p *boltdb.Paste, fu *boltdb.FileUpload) { |
|
|
|
|
if flags&viewShowMeta != 0 { |
|
|
|
|
rl.viewPasteHandlerInnerMeta(w, r, p, fu) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch p.State { |
|
|
|
|
case db.PasteStatePresent: |
|
|
|
|
case boltdb.PasteStatePresent: |
|
|
|
|
switch p.Type { |
|
|
|
|
case db.PasteTypeFileUpload: |
|
|
|
|
case boltdb.PasteTypeFileUpload: |
|
|
|
|
if fu == nil { |
|
|
|
|
panic(fmt.Sprintf("file for id %v does not exist in database\n", string(p.Content))) |
|
|
|
|
} |
|
|
|
|
rl.viewFileUploadHandler(w, r, fu) |
|
|
|
|
return |
|
|
|
|
case db.PasteTypeRedirect: |
|
|
|
|
case boltdb.PasteTypeRedirect: |
|
|
|
|
if flags&viewNoRedirect != 0 { |
|
|
|
|
w.Write([]byte(p.RedirectURL().String())) |
|
|
|
|
return |
|
|
|
@ -152,7 +152,7 @@ func (rl *rushlink) viewPasteHandlerInner(w http.ResponseWriter, r *http.Request
|
|
|
|
|
panic("paste type unsupported") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case db.PasteStateDeleted: |
|
|
|
|
case boltdb.PasteStateDeleted: |
|
|
|
|
rl.renderError(w, r, http.StatusGone, "paste has been deleted\n") |
|
|
|
|
return |
|
|
|
|
default: |
|
|
|
@ -160,7 +160,7 @@ func (rl *rushlink) viewPasteHandlerInner(w http.ResponseWriter, r *http.Request
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (rl *rushlink) viewFileUploadHandler(w http.ResponseWriter, r *http.Request, fu *db.FileUpload) { |
|
|
|
|
func (rl *rushlink) viewFileUploadHandler(w http.ResponseWriter, r *http.Request, fu *boltdb.FileUpload) { |
|
|
|
|
filePath := fu.Path(rl.fs) |
|
|
|
|
file, err := os.Open(filePath) |
|
|
|
|
if err != nil { |
|
|
|
@ -191,7 +191,7 @@ func (rl *rushlink) viewFileUploadHandler(w http.ResponseWriter, r *http.Request
|
|
|
|
|
http.ServeContent(w, r, fu.FileName, modtime, file) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (rl *rushlink) viewPasteHandlerInnerMeta(w http.ResponseWriter, r *http.Request, p *db.Paste, fu *db.FileUpload) { |
|
|
|
|
func (rl *rushlink) viewPasteHandlerInnerMeta(w http.ResponseWriter, r *http.Request, p *boltdb.Paste, fu *boltdb.FileUpload) { |
|
|
|
|
var cd canDelete |
|
|
|
|
deleteToken := getDeleteTokenFromRequest(r) |
|
|
|
|
if deleteToken != "" { |
|
|
|
@ -213,7 +213,7 @@ func (rl *rushlink) viewPasteHandlerInnerMeta(w http.ResponseWriter, r *http.Req
|
|
|
|
|
"CanDeleteBool": cd.Bool(), |
|
|
|
|
} |
|
|
|
|
var status int |
|
|
|
|
if p.State == db.PasteStateDeleted { |
|
|
|
|
if p.State == boltdb.PasteStateDeleted { |
|
|
|
|
status = http.StatusGone |
|
|
|
|
} else { |
|
|
|
|
status = http.StatusOK |
|
|
|
@ -222,7 +222,7 @@ func (rl *rushlink) viewPasteHandlerInnerMeta(w http.ResponseWriter, r *http.Req
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (rl *rushlink) viewActionSuccess(w http.ResponseWriter, r *http.Request, p *db.Paste, fu *db.FileUpload) { |
|
|
|
|
func (rl *rushlink) viewActionSuccess(w http.ResponseWriter, r *http.Request, p *boltdb.Paste, fu *boltdb.FileUpload) { |
|
|
|
|
var fileExt string |
|
|
|
|
if fu != nil { |
|
|
|
|
fileExt = fu.Ext() |
|
|
|
@ -280,11 +280,11 @@ func (rl *rushlink) newPasteHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (rl *rushlink) newFileUploadPasteHandler(w http.ResponseWriter, r *http.Request, file multipart.File, header multipart.FileHeader) { |
|
|
|
|
var fu *db.FileUpload |
|
|
|
|
var paste *db.Paste |
|
|
|
|
var fu *boltdb.FileUpload |
|
|
|
|
var paste *boltdb.Paste |
|
|
|
|
if err := rl.db.Bolt.Update(func(tx *bolt.Tx) error { |
|
|
|
|
var err error |
|
|
|
|
fu, err = db.NewFileUpload(rl.fs, file, header.Filename) |
|
|
|
|
fu, err = boltdb.NewFileUpload(rl.fs, file, header.Filename) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(errors.Wrap(err, "creating fileUpload")) |
|
|
|
|
} |
|
|
|
@ -316,7 +316,7 @@ func (rl *rushlink) newRedirectPasteHandler(w http.ResponseWriter, r *http.Reque
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var paste *db.Paste |
|
|
|
|
var paste *boltdb.Paste |
|
|
|
|
if err := rl.db.Bolt.Update(func(tx *bolt.Tx) error { |
|
|
|
|
var err error |
|
|
|
|
paste, err = shortenURL(tx, userURL) |
|
|
|
@ -339,15 +339,15 @@ func (rl *rushlink) deletePasteHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var errorCode int |
|
|
|
|
var paste *db.Paste |
|
|
|
|
var paste *boltdb.Paste |
|
|
|
|
if err := rl.db.Bolt.Update(func(tx *bolt.Tx) error { |
|
|
|
|
var err error |
|
|
|
|
paste, err = db.GetPaste(tx, key) |
|
|
|
|
paste, err = boltdb.GetPaste(tx, key) |
|
|
|
|
if err != nil { |
|
|
|
|
errorCode = http.StatusNotFound |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
if paste.State == db.PasteStateDeleted { |
|
|
|
|
if paste.State == boltdb.PasteStateDeleted { |
|
|
|
|
errorCode = http.StatusGone |
|
|
|
|
return errors.New("already deleted") |
|
|
|
|
} |
|
|
|
@ -372,39 +372,39 @@ func (rl *rushlink) deletePasteHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
//
|
|
|
|
|
// Returns the new paste key if the fileUpload was successfully added to the
|
|
|
|
|
// database
|
|
|
|
|
func shortenFileUploadID(tx *bolt.Tx, id uuid.UUID) (*db.Paste, error) { |
|
|
|
|
return shorten(tx, db.PasteTypeFileUpload, id[:]) |
|
|
|
|
func shortenFileUploadID(tx *bolt.Tx, id uuid.UUID) (*boltdb.Paste, error) { |
|
|
|
|
return shorten(tx, boltdb.PasteTypeFileUpload, id[:]) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Add a new URL to the database
|
|
|
|
|
//
|
|
|
|
|
// Returns the new paste key if the url was successfully shortened
|
|
|
|
|
func shortenURL(tx *bolt.Tx, userURL *url.URL) (*db.Paste, error) { |
|
|
|
|
return shorten(tx, db.PasteTypeRedirect, []byte(userURL.String())) |
|
|
|
|
func shortenURL(tx *bolt.Tx, userURL *url.URL) (*boltdb.Paste, error) { |
|
|
|
|
return shorten(tx, boltdb.PasteTypeRedirect, []byte(userURL.String())) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Add a paste (of any kind) to the database with arbitrary content.
|
|
|
|
|
func shorten(tx *bolt.Tx, ty db.PasteType, content []byte) (*db.Paste, error) { |
|
|
|
|
func shorten(tx *bolt.Tx, ty boltdb.PasteType, content []byte) (*boltdb.Paste, error) { |
|
|
|
|
// Generate the paste key
|
|
|
|
|
var keyEntropy int |
|
|
|
|
if ty == db.PasteTypeFileUpload || ty == db.PasteTypePaste { |
|
|
|
|
if ty == boltdb.PasteTypeFileUpload || ty == boltdb.PasteTypePaste { |
|
|
|
|
keyEntropy = highOnlineEntropy |
|
|
|
|
} |
|
|
|
|
pasteKey, err := db.GeneratePasteKey(tx, keyEntropy) |
|
|
|
|
pasteKey, err := boltdb.GeneratePasteKey(tx, keyEntropy) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, errors.Wrap(err, "generating paste key") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Also generate a deleteToken
|
|
|
|
|
deleteToken, err := db.GenerateDeleteToken() |
|
|
|
|
deleteToken, err := boltdb.GenerateDeleteToken() |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, errors.Wrap(err, "generating delete token") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Store the new key
|
|
|
|
|
p := db.Paste{ |
|
|
|
|
p := boltdb.Paste{ |
|
|
|
|
Type: ty, |
|
|
|
|
State: db.PasteStatePresent, |
|
|
|
|
State: boltdb.PasteStatePresent, |
|
|
|
|
Content: content, |
|
|
|
|
Key: pasteKey, |
|
|
|
|
DeleteToken: deleteToken, |
|
|
|
|