forked from electricdusk/rushlink
Make deleteTokens strings
This commit is contained in:
parent
1c926a4864
commit
f45c132b41
3
assets/templates/html/newRedirectPasteSuccess.html.tmpl
Normal file
3
assets/templates/html/newRedirectPasteSuccess.html.tmpl
Normal file
@ -0,0 +1,3 @@
|
||||
{{define "title"}}
|
||||
Success - rushlink
|
||||
{{end}}
|
1
assets/templates/txt/newRedirectPasteSuccess.txt.tmpl
Normal file
1
assets/templates/txt/newRedirectPasteSuccess.txt.tmpl
Normal file
@ -0,0 +1 @@
|
||||
{{.Request.Host}}/{{.Paste.Key}}?deleteToken={{.Paste.DeleteToken}}
|
@ -28,7 +28,7 @@ type storedPaste struct {
|
||||
State pasteState
|
||||
Content []byte
|
||||
Key string
|
||||
DeleteToken [16]byte
|
||||
DeleteToken string
|
||||
TimeCreated time.Time
|
||||
}
|
||||
|
||||
@ -126,13 +126,11 @@ func viewPasteHandlerInner(w http.ResponseWriter, r *http.Request, flags viewPas
|
||||
Bool bool
|
||||
String string
|
||||
}{Bool: false}
|
||||
deleteToken, err := getDeleteTokenFromRequest(r)
|
||||
if err != nil {
|
||||
canDelete.String = "invalid"
|
||||
} else if deleteToken == nil {
|
||||
deleteToken := getDeleteTokenFromRequest(r)
|
||||
if deleteToken == "" {
|
||||
canDelete.String = "undefined"
|
||||
} else {
|
||||
if subtle.ConstantTimeCompare(deleteToken[:], storedPaste.DeleteToken[:]) == 1 {
|
||||
if subtle.ConstantTimeCompare([]byte(deleteToken), []byte(storedPaste.DeleteToken)) == 1 {
|
||||
canDelete.Bool = true
|
||||
canDelete.String = "correct"
|
||||
} else {
|
||||
@ -162,7 +160,7 @@ func viewPasteHandlerInner(w http.ResponseWriter, r *http.Request, flags viewPas
|
||||
}
|
||||
w.Write(storedPaste.Content)
|
||||
case stateDeleted:
|
||||
renderError(w, r, http.StatusGone, "key has been deleted")
|
||||
renderError(w, r, http.StatusGone, "paste has been deleted")
|
||||
default:
|
||||
log.Printf("error: invalid storedPaste.State (%v) for key '%v'\n", storedPaste.State, storedPaste.Key)
|
||||
msg := fmt.Sprintf("internal server error: invalid storedPaste.State (%v\n)", storedPaste.State)
|
||||
@ -215,33 +213,16 @@ func newRedirectPasteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var storedPaste *storedPaste
|
||||
if err := db.DB.Update(func(tx *bolt.Tx) error {
|
||||
// Generate a new delete token for this paste
|
||||
deleteToken, err := generateDeleteToken()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "generating delete token")
|
||||
}
|
||||
|
||||
sp, err := shortenURL(tx, userURL, deleteToken)
|
||||
storedPaste = sp
|
||||
var err error
|
||||
storedPaste, err = shortenURL(tx, userURL)
|
||||
return err
|
||||
}); err != nil {
|
||||
log.Printf("error: %v\n", err)
|
||||
renderInternalServerError(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
deleteToken := hex.EncodeToString(storedPaste.DeleteToken[:])
|
||||
saveRawurl := fmt.Sprintf("%v/%v?deleteToken=%v", r.Host, string(storedPaste.Key), deleteToken)
|
||||
saveURL, err := r.URL.Parse(saveRawurl)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "parsing url")
|
||||
log.Printf("error: %v\n", err)
|
||||
renderInternalServerError(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(dsprenkels) Put this into a template
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintf(w, "%v\n", saveURL)
|
||||
data := map[string]interface{}{"Paste": storedPaste}
|
||||
render(w, r, "newRedirectPasteSuccess", data)
|
||||
}
|
||||
|
||||
// Delete a URL from the database
|
||||
@ -250,11 +231,8 @@ func deletePasteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
key := vars["key"]
|
||||
|
||||
deleteToken, err := getDeleteTokenFromRequest(r)
|
||||
if err != nil {
|
||||
renderError(w, r, http.StatusBadRequest, "invalid delete token")
|
||||
return
|
||||
} else if deleteToken == nil {
|
||||
deleteToken := getDeleteTokenFromRequest(r)
|
||||
if deleteToken == "" {
|
||||
renderError(w, r, http.StatusBadRequest, "no delete token provided")
|
||||
return
|
||||
}
|
||||
@ -266,7 +244,7 @@ func deletePasteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
errorCode = http.StatusNotFound
|
||||
return err
|
||||
}
|
||||
if subtle.ConstantTimeCompare(deleteToken[:], paste.DeleteToken[:]) == 1 {
|
||||
if subtle.ConstantTimeCompare([]byte(deleteToken), []byte(paste.DeleteToken)) == 1 {
|
||||
// Replace the old paste with a new empty paste
|
||||
return savePaste(tx, key, storedPaste{
|
||||
Key: paste.Key,
|
||||
@ -301,7 +279,7 @@ func getURL(tx *bolt.Tx, key string) (*storedPaste, error) {
|
||||
// Add a new URL to the database
|
||||
//
|
||||
// Returns the new ID if the url was successfully shortened
|
||||
func shortenURL(tx *bolt.Tx, userURL *url.URL, deleteToken [16]byte) (*storedPaste, error) {
|
||||
func shortenURL(tx *bolt.Tx, userURL *url.URL) (*storedPaste, error) {
|
||||
pastesBucket := tx.Bucket([]byte(db.BUCKET_PASTES))
|
||||
if pastesBucket == nil {
|
||||
return nil, errors.Errorf("bucket %v does not exist", db.BUCKET_PASTES)
|
||||
@ -337,6 +315,12 @@ func shortenURL(tx *bolt.Tx, userURL *url.URL, deleteToken [16]byte) (*storedPas
|
||||
epoch++
|
||||
}
|
||||
|
||||
// Also generate a deleteToken
|
||||
deleteToken, err := generateDeleteToken()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "generating delete token")
|
||||
}
|
||||
|
||||
// Store the new key
|
||||
storedPaste := storedPaste{
|
||||
Type: typeRedirect,
|
||||
@ -403,26 +387,15 @@ func generateURLKey(epoch int) (string, error) {
|
||||
return string(urlKey), nil
|
||||
}
|
||||
|
||||
func generateDeleteToken() ([16]byte, error) {
|
||||
func generateDeleteToken() (string, error) {
|
||||
var deleteToken [16]byte
|
||||
_, err := rand.Read(deleteToken[:])
|
||||
if err != nil {
|
||||
return deleteToken, err
|
||||
return "", err
|
||||
}
|
||||
return deleteToken, nil
|
||||
return hex.EncodeToString(deleteToken[:]), nil
|
||||
}
|
||||
|
||||
func getDeleteTokenFromRequest(r *http.Request) (*[16]byte, error) {
|
||||
deleteTokenQuery := r.URL.Query().Get("deleteToken")
|
||||
if deleteTokenQuery == "" {
|
||||
return nil, nil
|
||||
}
|
||||
var deleteToken [16]byte
|
||||
n, err := hex.Decode(deleteToken[:], []byte(deleteTokenQuery))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "decoding hex")
|
||||
} else if n != 16 {
|
||||
return nil, errors.Errorf("invalid deleteToken length (%v bytes)", n)
|
||||
}
|
||||
return &deleteToken, nil
|
||||
func getDeleteTokenFromRequest(r *http.Request) string {
|
||||
return r.URL.Query().Get("deleteToken")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user