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