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
|
State pasteState
|
||||||
Content []byte
|
Content []byte
|
||||||
Key string
|
Key string
|
||||||
DeleteToken [16]byte
|
DeleteToken string
|
||||||
TimeCreated time.Time
|
TimeCreated time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,13 +126,11 @@ func viewPasteHandlerInner(w http.ResponseWriter, r *http.Request, flags viewPas
|
|||||||
Bool bool
|
Bool bool
|
||||||
String string
|
String string
|
||||||
}{Bool: false}
|
}{Bool: false}
|
||||||
deleteToken, err := getDeleteTokenFromRequest(r)
|
deleteToken := getDeleteTokenFromRequest(r)
|
||||||
if err != nil {
|
if deleteToken == "" {
|
||||||
canDelete.String = "invalid"
|
|
||||||
} else if deleteToken == nil {
|
|
||||||
canDelete.String = "undefined"
|
canDelete.String = "undefined"
|
||||||
} else {
|
} else {
|
||||||
if subtle.ConstantTimeCompare(deleteToken[:], storedPaste.DeleteToken[:]) == 1 {
|
if subtle.ConstantTimeCompare([]byte(deleteToken), []byte(storedPaste.DeleteToken)) == 1 {
|
||||||
canDelete.Bool = true
|
canDelete.Bool = true
|
||||||
canDelete.String = "correct"
|
canDelete.String = "correct"
|
||||||
} else {
|
} else {
|
||||||
@ -162,7 +160,7 @@ func viewPasteHandlerInner(w http.ResponseWriter, r *http.Request, flags viewPas
|
|||||||
}
|
}
|
||||||
w.Write(storedPaste.Content)
|
w.Write(storedPaste.Content)
|
||||||
case stateDeleted:
|
case stateDeleted:
|
||||||
renderError(w, r, http.StatusGone, "key has been deleted")
|
renderError(w, r, http.StatusGone, "paste has been deleted")
|
||||||
default:
|
default:
|
||||||
log.Printf("error: invalid storedPaste.State (%v) for key '%v'\n", storedPaste.State, storedPaste.Key)
|
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)
|
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
|
var storedPaste *storedPaste
|
||||||
if err := db.DB.Update(func(tx *bolt.Tx) error {
|
if err := db.DB.Update(func(tx *bolt.Tx) error {
|
||||||
// Generate a new delete token for this paste
|
// Generate a new delete token for this paste
|
||||||
deleteToken, err := generateDeleteToken()
|
var err error
|
||||||
if err != nil {
|
storedPaste, err = shortenURL(tx, userURL)
|
||||||
return errors.Wrap(err, "generating delete token")
|
|
||||||
}
|
|
||||||
|
|
||||||
sp, err := shortenURL(tx, userURL, deleteToken)
|
|
||||||
storedPaste = sp
|
|
||||||
return err
|
return err
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Printf("error: %v\n", err)
|
log.Printf("error: %v\n", err)
|
||||||
renderInternalServerError(w, r, err)
|
renderInternalServerError(w, r, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
data := map[string]interface{}{"Paste": storedPaste}
|
||||||
deleteToken := hex.EncodeToString(storedPaste.DeleteToken[:])
|
render(w, r, "newRedirectPasteSuccess", data)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete a URL from the database
|
// Delete a URL from the database
|
||||||
@ -250,11 +231,8 @@ func deletePasteHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
key := vars["key"]
|
key := vars["key"]
|
||||||
|
|
||||||
deleteToken, err := getDeleteTokenFromRequest(r)
|
deleteToken := getDeleteTokenFromRequest(r)
|
||||||
if err != nil {
|
if deleteToken == "" {
|
||||||
renderError(w, r, http.StatusBadRequest, "invalid delete token")
|
|
||||||
return
|
|
||||||
} else if deleteToken == nil {
|
|
||||||
renderError(w, r, http.StatusBadRequest, "no delete token provided")
|
renderError(w, r, http.StatusBadRequest, "no delete token provided")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -266,7 +244,7 @@ func deletePasteHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
errorCode = http.StatusNotFound
|
errorCode = http.StatusNotFound
|
||||||
return err
|
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
|
// Replace the old paste with a new empty paste
|
||||||
return savePaste(tx, key, storedPaste{
|
return savePaste(tx, key, storedPaste{
|
||||||
Key: paste.Key,
|
Key: paste.Key,
|
||||||
@ -301,7 +279,7 @@ func getURL(tx *bolt.Tx, key string) (*storedPaste, error) {
|
|||||||
// Add a new URL to the database
|
// Add a new URL to the database
|
||||||
//
|
//
|
||||||
// Returns the new ID if the url was successfully shortened
|
// 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))
|
pastesBucket := tx.Bucket([]byte(db.BUCKET_PASTES))
|
||||||
if pastesBucket == nil {
|
if pastesBucket == nil {
|
||||||
return nil, errors.Errorf("bucket %v does not exist", db.BUCKET_PASTES)
|
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++
|
epoch++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Also generate a deleteToken
|
||||||
|
deleteToken, err := generateDeleteToken()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "generating delete token")
|
||||||
|
}
|
||||||
|
|
||||||
// Store the new key
|
// Store the new key
|
||||||
storedPaste := storedPaste{
|
storedPaste := storedPaste{
|
||||||
Type: typeRedirect,
|
Type: typeRedirect,
|
||||||
@ -403,26 +387,15 @@ func generateURLKey(epoch int) (string, error) {
|
|||||||
return string(urlKey), nil
|
return string(urlKey), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateDeleteToken() ([16]byte, error) {
|
func generateDeleteToken() (string, error) {
|
||||||
var deleteToken [16]byte
|
var deleteToken [16]byte
|
||||||
_, err := rand.Read(deleteToken[:])
|
_, err := rand.Read(deleteToken[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return deleteToken, err
|
return "", err
|
||||||
}
|
}
|
||||||
return deleteToken, nil
|
return hex.EncodeToString(deleteToken[:]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDeleteTokenFromRequest(r *http.Request) (*[16]byte, error) {
|
func getDeleteTokenFromRequest(r *http.Request) string {
|
||||||
deleteTokenQuery := r.URL.Query().Get("deleteToken")
|
return 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
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user