campaignd: Refactor add-on deletion code into its own method
This changes the order in which the hook_post_erase hook (currently
unused in production and fully untested) is fired so it will be run
*before* displaying the confirmation message to clients. This might need
to be changed at a later point if the hook functionality ever gets used
again, but for now it'll do.
(cherry-picked from commit 957be8b53e
)
This commit is contained in:
parent
33be7d5a8c
commit
ddb0f29a99
2 changed files with 46 additions and 24 deletions
|
@ -493,6 +493,45 @@ void server::send_error(const std::string& msg, const std::string& extra_data, s
|
|||
async_send_doc(sock, doc, std::bind(&server::handle_new_client, this, _1), null_handler);
|
||||
}
|
||||
|
||||
void server::delete_campaign(const std::string& id)
|
||||
{
|
||||
config::child_itors itors = campaigns().child_range("campaign");
|
||||
|
||||
std::size_t pos = 0;
|
||||
bool found = false;
|
||||
std::string fn;
|
||||
|
||||
for(config& cfg : itors) {
|
||||
if(cfg["name"] == id) {
|
||||
fn = cfg["filename"].str();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
++pos;
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
ERR_CS << "Cannot delete unrecognized add-on '" << id << "'\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if(fn.empty()) {
|
||||
ERR_CS << "Add-on '" << id << "' does not have an associated filename, cannot delete\n";
|
||||
}
|
||||
|
||||
filesystem::write_file(fn, {});
|
||||
if(std::remove(fn.c_str()) != 0) {
|
||||
ERR_CS << "Could not delete archive for campaign '" << id
|
||||
<< "' (" << fn << "): " << strerror(errno) << '\n';
|
||||
}
|
||||
|
||||
campaigns().remove_child("campaign", pos);
|
||||
write_config();
|
||||
|
||||
fire("hook_post_erase", id);
|
||||
}
|
||||
|
||||
#define REGISTER_CAMPAIGND_HANDLER(req_id) \
|
||||
handlers_[#req_id] = std::bind(&server::handle_##req_id, \
|
||||
std::placeholders::_1, std::placeholders::_2)
|
||||
|
@ -853,16 +892,17 @@ void server::handle_upload(const server::request& req)
|
|||
void server::handle_delete(const server::request& req)
|
||||
{
|
||||
const config& erase = req.cfg;
|
||||
const std::string& id = erase["name"].str();
|
||||
|
||||
if(read_only_) {
|
||||
LOG_CS << "in read-only mode, request to delete '" << erase["name"] << "' from " << req.addr << " denied\n";
|
||||
LOG_CS << "in read-only mode, request to delete '" << id << "' from " << req.addr << " denied\n";
|
||||
send_error("Cannot delete add-on: The server is currently in read-only mode.", req.sock);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_CS << "deleting campaign '" << erase["name"] << "' requested from " << req.addr << "\n";
|
||||
LOG_CS << "deleting campaign '" << id << "' requested from " << req.addr << "\n";
|
||||
|
||||
config& campaign = get_campaign(erase["name"]);
|
||||
config& campaign = get_campaign(id);
|
||||
|
||||
if(!campaign) {
|
||||
send_error("The add-on does not exist.", req.sock);
|
||||
|
@ -884,29 +924,9 @@ void server::handle_delete(const server::request& req)
|
|||
return;
|
||||
}
|
||||
|
||||
// Erase the campaign.
|
||||
filesystem::write_file(campaign["filename"], std::string());
|
||||
if(remove(campaign["filename"].str().c_str()) != 0) {
|
||||
ERR_CS << "failed to delete archive for campaign '" << erase["name"]
|
||||
<< "' (" << campaign["filename"] << "): " << strerror(errno)
|
||||
<< '\n';
|
||||
}
|
||||
|
||||
config::child_itors itors = campaigns().child_range("campaign");
|
||||
for(std::size_t index = 0; !itors.empty(); ++index, itors.pop_front())
|
||||
{
|
||||
if(&campaign == &itors.front()) {
|
||||
campaigns().remove_child("campaign", index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
write_config();
|
||||
delete_campaign(id);
|
||||
|
||||
send_message("Add-on deleted.", req.sock);
|
||||
|
||||
fire("hook_post_erase", erase["name"]);
|
||||
|
||||
}
|
||||
|
||||
void server::handle_change_passphrase(const server::request& req)
|
||||
|
|
|
@ -143,6 +143,8 @@ private:
|
|||
/** Retrieves a campaign by id if found, or a null config otherwise. */
|
||||
config& get_campaign(const std::string& id) { return campaigns().find_child("campaign", "name", id); }
|
||||
|
||||
void delete_campaign(const std::string& id);
|
||||
|
||||
/** Retrieves the contents of the [server_info] WML node. */
|
||||
const config& server_info() const { return cfg_.child("server_info"); }
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue