smr/src/lua/endpoints/edit_post.lua

120 lines
4.4 KiB
Lua

local sql = require("lsqlite3")
local zlib = require("zlib")
local db = require("db")
local queries = require("queries")
local pages = require("pages")
local parsers = require("parsers")
local util = require("util")
local tagslib = require("tags")
local cache = require("cache")
local config = require("config")
local session = require("session")
local stmnt_author_of, stmnt_update_raw, stmnt_update, stmnt_hash
local oldconfigure = configure
function configure(...)
stmnt_author_of = assert(db.conn:prepare(queries.select_author_of_post))
stmnt_update_raw = assert(db.conn:prepare(queries.update_raw))
stmnt_update = assert(db.conn:prepare(queries.update_post))
stmnt_hash = assert(db.conn:prepare(queries.select_post_hash))
return oldconfigure(...)
end
local function edit_post(req)
local host = http_request_get_host(req)
local path = http_request_get_path(req)
local author, author_id = session.get(req)
http_request_populate_post(req)
local storyid = tonumber(assert(http_argument_get_string(req,"story")))
local title = assert(http_argument_get_string(req,"title"))
local text = assert(http_argument_get_string(req,"text"))
local pasteas = assert(http_argument_get_string(req,"pasteas"))
local markup = assert(http_argument_get_string(req,"markup"))
local unlisted = http_argument_get_string(req,"unlisted") == "on"
local tags_str = http_argument_get_string(req,"tags")
stmnt_author_of:bind_names{
id = storyid
}
local err = db.do_sql(stmnt_author_of)
if err ~= sql.ROW then
stmnt_author_of:reset()
local msg = string.format("No author found for story: %d", storyid)
log(LOG_ERR,msg)
local response = pages.error{
errcode = 404,
errcodemsg = "Not Found",
explanation = msg,
should_traceback = true,
}
http_response(req,404,response)
return
end
local data = stmnt_author_of:get_values()
stmnt_author_of:reset()
local realauthor = data[1]
if realauthor ~= author_id then
local response = pages.error{
errcode = 401,
errcodemsg = "Unauthorized",
explanation = string.format("You are trying to edit post %d, but it is another user's post. You are %s.",storyid, author_id),
should_traceback = true,
}
http_response(req,401,response)
return
end
local parsed = parsers[markup](text)
local compr_raw = zlib.compress(text)
local compr = zlib.compress(parsed)
local tags = {}
if tags_str then
tags = util.parse_tags(tags_str)
end
assert(stmnt_update_raw:bind_blob(1,compr_raw) == sql.OK)
assert(stmnt_update_raw:bind(2,markup) == sql.OK)
assert(stmnt_update_raw:bind(3,storyid) == sql.OK)
assert(db.do_sql(stmnt_update_raw) == sql.DONE, "Failed to update raw")
stmnt_update_raw:reset()
assert(stmnt_update:bind(1,title) == sql.OK)
assert(stmnt_update:bind_blob(2,compr) == sql.OK)
assert(stmnt_update:bind(3,pasteas == "anonymous" and 1 or 0) == sql.OK)
assert(stmnt_update:bind(4,unlisted) == sql.OK)
assert(stmnt_update:bind(5,storyid) == sql.OK)
assert(db.do_sql(stmnt_update) == sql.DONE, "Failed to update text")
stmnt_update:reset()
tagslib.set(storyid,tags)
local id_enc = util.encode_id(storyid)
local hash
local loc = string.format("https://%s/%s",config.domain,id_enc)
if unlisted then
stmnt_hash:bind_names{id=storyid}
local err = db.do_sql(stmnt_hash)
if err ~= sql.ROW then
error("Failed to get a post's hash while trying to make it unlisted")
end
local hash = stmnt_hash:get_value(0)
-- TODO: Remove this
-- Posts added before the unlisted feature will throw errors
-- when their hash is used to display them, or their url's.
-- when proper database migration tools are in place, remove
-- this bit of code.
if hash == -1 then
error("This post was created before the unlisting feature was added. Temporarily, this breaks. You will be able to unlist it in the future.")
end
loc = loc .. "?pwd=" .. util.encode_unlisted(hash)
end
--Turning something from not unlisted to unlisted should dirty all these
--places anyway, so the post can now be hidden.
cache.dirty(string.format("%s/%s",config.domain,id_enc)) -- This place to read this post
cache.dirty(string.format("%s",config.domain)) -- The site index (ex, if the author changed the paste from their's to "Anonymous", the cache should reflect that).
cache.dirty(string.format("%s.%s",author,config.domain)) -- The author's index, same reasoning as above.
cache.dirty(string.format("%s-logout",config.domain))
http_response_header(req,"Location",loc)
http_response(req,303,"")
return
end
return edit_post