From 3cf309a008d121b8c75da7b7b08e19c10b35ec46 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Fri, 3 Feb 2023 20:43:53 -0800 Subject: [PATCH] create update-license shell command --- src/License.cc | 13 +++++++-- src/License.hh | 1 + src/ServerShell.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 80 insertions(+), 4 deletions(-) diff --git a/src/License.cc b/src/License.cc index 29cd9080..8ef5d790 100644 --- a/src/License.cc +++ b/src/License.cc @@ -163,11 +163,18 @@ void LicenseManager::ban_until(uint32_t serial_number, uint64_t end_time) { } } +shared_ptr LicenseManager::get(uint32_t serial_number) const { + try { + return this->serial_number_to_license.at(serial_number); + } catch (const out_of_range&) { + throw missing_license(); + } +} + void LicenseManager::add(shared_ptr l) { - uint32_t serial_number = l->serial_number; - this->serial_number_to_license.emplace(serial_number, l); + this->serial_number_to_license[l->serial_number] = l; if (!l->username.empty()) { - this->bb_username_to_license.emplace(l->username, l); + this->bb_username_to_license[l->username] = l; } if (this->autosave) { this->save(); diff --git a/src/License.hh b/src/License.hh index 938beedc..838e2c78 100644 --- a/src/License.hh +++ b/src/License.hh @@ -82,6 +82,7 @@ public: size_t count() const; + std::shared_ptr get(uint32_t serial_number) const; void add(std::shared_ptr l); void remove(uint32_t serial_number); std::vector snapshot() const; diff --git a/src/ServerShell.cc b/src/ServerShell.cc index af95c9db..81733eae 100644 --- a/src/ServerShell.cc +++ b/src/ServerShell.cc @@ -114,6 +114,10 @@ Server commands:\n\ access-key= (DC/GC/PC access key)\n\ serial= (decimal serial number; required for all licenses)\n\ privileges= (can be normal, mod, admin, root, or numeric)\n\ + update-license \n\ + Update an existing license. specifies which license to\n\ + update. The options in are the same as for the add-license\n\ + command.\n\ delete-license \n\ Delete a license from the server.\n\ list-licenses\n\ @@ -310,7 +314,7 @@ session with ID 17205AE4, run the command `on 17205AE4 sc 1D 00 04 00`.\n\ } } else { - throw invalid_argument("incorrect field"); + throw invalid_argument("incorrect field: " + token); } } @@ -321,6 +325,70 @@ session with ID 17205AE4, run the command `on 17205AE4 sc 1D 00 04 00`.\n\ this->state->license_manager->add(l); fprintf(stderr, "license added\n"); + } else if (command_name == "update-license") { + auto tokens = split(command_args, ' '); + if (tokens.size() < 2) { + throw runtime_error("not enough arguments"); + } + uint32_t serial_number = stoul(tokens[0]); + tokens.erase(tokens.begin()); + auto orig_l = this->state->license_manager->get(serial_number); + shared_ptr l(new License(*orig_l)); + + for (const string& token : tokens) { + if (starts_with(token, "bb-username=")) { + if (token.size() >= 32) { + throw invalid_argument("username too long"); + } + l->username = token.substr(12); + + } else if (starts_with(token, "bb-password=")) { + if (token.size() >= 32) { + throw invalid_argument("bb-password too long"); + } + l->bb_password = token.substr(12); + + } else if (starts_with(token, "gc-password=")) { + if (token.size() > 20) { + throw invalid_argument("gc-password too long"); + } + l->gc_password = token.substr(12); + + } else if (starts_with(token, "access-key=")) { + if (token.size() > 23) { + throw invalid_argument("access-key is too long"); + } + l->access_key = token.substr(11); + + } else if (starts_with(token, "serial=")) { + l->serial_number = stoul(token.substr(7)); + + } else if (starts_with(token, "privileges=")) { + string mask = token.substr(11); + if (mask == "normal") { + l->privileges = 0; + } else if (mask == "mod") { + l->privileges = Privilege::MODERATOR; + } else if (mask == "admin") { + l->privileges = Privilege::ADMINISTRATOR; + } else if (mask == "root") { + l->privileges = Privilege::ROOT; + } else { + l->privileges = stoul(mask); + } + + } else { + throw invalid_argument("incorrect field: " + token); + } + } + + if (!l->serial_number) { + throw invalid_argument("license does not contain serial number"); + } + + this->state->license_manager->add(l); + fprintf(stderr, "license updated\n"); + } else if (command_name == "delete-license") { uint32_t serial_number = stoul(command_args); this->state->license_manager->remove(serial_number);