campaignd: Add strict version check on uploads

This makes it so by default campaignd will reject uploads of existing
add-ons without a version bump. A server-side configuration flag
(strict_versions) can be optionally enabled to lower the strictness and
allow re-uploading the same version -- while still disallowing going
backwards.

The reason for making it possible to lower the strictness is that very
often while testing campaignd itself it becomes necessary to reupload
the same add-on over and over. We don't want to get rid of *that*
particular use case.

The server does not currently have a mechanism to advertise the
different strictness levels, unfortunately, so clients may in fact need
to send a 100 MB rock before finding out it's not good enough for
upload. Such is life. This might be solved after #5338 is merged into
mainline.

Closes #5079.
This commit is contained in:
Iris Morelle 2020-12-08 18:15:13 -03:00
parent ae277b434e
commit 85e935e6f2
4 changed files with 20 additions and 0 deletions

View file

@ -537,6 +537,10 @@ std::string addon_check_status_desc(unsigned int code)
ADDON_CHECK_STATUS::BAD_TYPE,
N_("Invalid or unspecified add-on type.")
},
{
ADDON_CHECK_STATUS::VERSION_NOT_INCREMENTED,
N_("Version number not greater than the latest uploaded version.")
},
{
ADDON_CHECK_STATUS::INVALID_UTF8_ATTRIBUTE,
N_("The add-on publish information contains an invalid UTF-8 sequence.")

View file

@ -58,6 +58,7 @@ enum class ADDON_CHECK_STATUS : unsigned int
NO_PASSPHRASE = 0x205, /**< No passphrase specified */
TITLE_HAS_MARKUP = 0x206, /**< Markup in add-on title */
BAD_TYPE = 0x207, /**< Bad add-on type */
VERSION_NOT_INCREMENTED = 0x208, /**< Version number is not an increment */
INVALID_UTF8_ATTRIBUTE = 0x2FF, /**< Invalid UTF-8 sequence in add-on metadata */
//
// Server errors

View file

@ -240,6 +240,7 @@ server::server(const std::string& cfg_file, unsigned short port)
, read_only_(false)
, compress_level_(0)
, update_pack_lifespan_(0)
, strict_versions_(true)
, hooks_()
, handlers_()
, feedback_url_format_()
@ -292,6 +293,8 @@ void server::load_config()
LOG_CS << "READ-ONLY MODE ACTIVE\n";
}
strict_versions_ = cfg_["strict_versions"].to_bool(true);
// Seems like compression level above 6 is a waste of CPU cycles.
compress_level_ = cfg_["compress_level"].to_int(6);
// One month probably will be fine (#TODO: testing needed)
@ -1218,6 +1221,16 @@ ADDON_CHECK_STATUS server::validate_addon(const server::request& req, config*& e
return ADDON_CHECK_STATUS::NO_VERSION;
}
if(existing_addon) {
version_info new_version{upload["version"].str()};
version_info old_version{(*existing_addon)["version"].str()};
if(strict_versions_ ? new_version <= old_version : new_version < old_version) {
LOG_CS << "Validation error: add-on version not incremented\n";
return ADDON_CHECK_STATUS::VERSION_NOT_INCREMENTED;
}
}
if(upload["description"].empty()) {
LOG_CS << "Validation error: no add-on description specified\n";
return ADDON_CHECK_STATUS::NO_DESCRIPTION;

View file

@ -101,6 +101,8 @@ private:
int compress_level_; /**< Used for add-on archives. */
time_t update_pack_lifespan_;
bool strict_versions_;
/** Default upload size limit in bytes. */
static const std::size_t default_document_size_limit = 100 * 1024 * 1024;