(app *App, w http.ResponseWriter, r *http.Request)
| 831 | } |
| 832 | |
| 833 | func deletePost(app *App, w http.ResponseWriter, r *http.Request) error { |
| 834 | vars := mux.Vars(r) |
| 835 | friendlyID := vars["post"] |
| 836 | editToken := r.FormValue("token") |
| 837 | |
| 838 | var ownerID int64 |
| 839 | var u *User |
| 840 | accessToken := r.Header.Get("Authorization") |
| 841 | if accessToken == "" && editToken == "" { |
| 842 | u = getUserSession(app, r) |
| 843 | if u == nil { |
| 844 | return ErrNoAccessToken |
| 845 | } |
| 846 | } |
| 847 | |
| 848 | var res sql.Result |
| 849 | var t *sql.Tx |
| 850 | var err error |
| 851 | var collID sql.NullInt64 |
| 852 | var coll *Collection |
| 853 | var pp *PublicPost |
| 854 | if editToken != "" { |
| 855 | // TODO: SELECT owner_id, as well, and return appropriate error if NULL instead of running two queries |
| 856 | var dummy int64 |
| 857 | err = app.db.QueryRow("SELECT 1 FROM posts WHERE id = ?", friendlyID).Scan(&dummy) |
| 858 | switch { |
| 859 | case err == sql.ErrNoRows: |
| 860 | return impart.HTTPError{http.StatusNotFound, "Post not found."} |
| 861 | } |
| 862 | err = app.db.QueryRow("SELECT 1 FROM posts WHERE id = ? AND owner_id IS NULL", friendlyID).Scan(&dummy) |
| 863 | switch { |
| 864 | case err == sql.ErrNoRows: |
| 865 | // Post already has an owner. This could provide a bad experience |
| 866 | // for the user, but it's more important to ensure data isn't lost |
| 867 | // unexpectedly. So prevent deletion via token. |
| 868 | return impart.HTTPError{http.StatusConflict, "This post belongs to some user (hopefully yours). Please log in and delete it from that user's account."} |
| 869 | } |
| 870 | res, err = app.db.Exec("DELETE FROM posts WHERE id = ? AND modify_token = ? AND owner_id IS NULL", friendlyID, editToken) |
| 871 | } else if accessToken != "" || u != nil { |
| 872 | // Caller provided some way to authenticate; assume caller expects the |
| 873 | // post to be deleted based on a specific post owner, thus we should |
| 874 | // return corresponding errors. |
| 875 | if accessToken != "" { |
| 876 | ownerID = app.db.GetUserID(accessToken) |
| 877 | if ownerID == -1 { |
| 878 | return ErrBadAccessToken |
| 879 | } |
| 880 | } else { |
| 881 | ownerID = u.ID |
| 882 | } |
| 883 | |
| 884 | // TODO: don't make two queries |
| 885 | var realOwnerID sql.NullInt64 |
| 886 | err = app.db.QueryRow("SELECT collection_id, owner_id FROM posts WHERE id = ?", friendlyID).Scan(&collID, &realOwnerID) |
| 887 | if err != nil { |
| 888 | return err |
| 889 | } |
| 890 | if !collID.Valid { |
nothing calls this directly
no test coverage detected