From 76daba3d03ca90c4155d394e308e8c3482c7eaa0 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Wed, 1 Nov 2023 18:11:58 -0400 Subject: [PATCH] rgw: define account ids and names Signed-off-by: Casey Bodley (cherry picked from commit f678c780195c81d86533740456d843c08c7db1c0) --- src/rgw/CMakeLists.txt | 1 + src/rgw/rgw_account.cc | 99 ++++++++++++++++++++++++++++++++++++++ src/rgw/rgw_account.h | 32 ++++++++++++ src/rgw/rgw_basic_types.cc | 11 +++++ src/rgw/rgw_user_types.h | 11 ++++- 5 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 src/rgw/rgw_account.cc create mode 100644 src/rgw/rgw_account.h diff --git a/src/rgw/CMakeLists.txt b/src/rgw/CMakeLists.txt index fd656502a78..3de10300444 100644 --- a/src/rgw/CMakeLists.txt +++ b/src/rgw/CMakeLists.txt @@ -57,6 +57,7 @@ set(librgw_common_srcs services/svc_user_rados.cc services/svc_zone.cc services/svc_zone_utils.cc + rgw_account.cc rgw_acl.cc rgw_acl_s3.cc rgw_acl_swift.cc diff --git a/src/rgw/rgw_account.cc b/src/rgw/rgw_account.cc new file mode 100644 index 00000000000..a895b9bcfee --- /dev/null +++ b/src/rgw/rgw_account.cc @@ -0,0 +1,99 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab ft=cpp + +/* + * Ceph - scalable distributed file system + * + * Copyright contributors to the Ceph project + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "rgw_account.h" + +#include +#include + +#include "common/random_string.h" +#include "common/utf8.h" + +#define dout_subsys ceph_subsys_rgw + +namespace rgw::account { + +// account ids start with 'RGW' followed by 17 numeric digits +static constexpr std::string_view id_prefix = "RGW"; +static constexpr std::size_t id_len = 20; + +std::string generate_id(CephContext* cct) +{ + // fill with random numeric digits + std::string id = gen_rand_numeric(cct, id_len); + // overwrite the prefix bytes + std::copy(id_prefix.begin(), id_prefix.end(), id.begin()); + return id; +} + +bool validate_id(std::string_view id, std::string* err_msg) +{ + if (id.size() != id_len) { + if (err_msg) { + *err_msg = fmt::format("account id must be {} bytes long", id_len); + } + return false; + } + if (id.compare(0, id_prefix.size(), id_prefix) != 0) { + if (err_msg) { + *err_msg = fmt::format("account id must start with {}", id_prefix); + } + return false; + } + auto suffix = id.substr(id_prefix.size()); + // all remaining bytes must be digits + constexpr auto digit = [] (int c) { return std::isdigit(c); }; + if (!std::all_of(suffix.begin(), suffix.end(), digit)) { + if (err_msg) { + *err_msg = "account id must end with numeric digits"; + } + return false; + } + return true; +} + +bool validate_name(std::string_view name, std::string* err_msg) +{ + if (name.empty()) { + if (err_msg) { + *err_msg = "account name must not be empty"; + } + return false; + } + // must not contain the tenant delimiter $ + if (name.find('$') != name.npos) { + if (err_msg) { + *err_msg = "account name must not contain $"; + } + return false; + } + // must not contain the metadata section delimeter : + if (name.find(':') != name.npos) { + if (err_msg) { + *err_msg = "account name must not contain :"; + } + return false; + } + // must be valid utf8 + if (check_utf8(name.data(), name.size()) != 0) { + if (err_msg) { + *err_msg = "account name must be valid utf8"; + } + return false; + } + return true; +} + +} // namespace rgw::account diff --git a/src/rgw/rgw_account.h b/src/rgw/rgw_account.h new file mode 100644 index 00000000000..17ed0c06210 --- /dev/null +++ b/src/rgw/rgw_account.h @@ -0,0 +1,32 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab ft=cpp + +/* + * Ceph - scalable distributed file system + * + * Copyright contributors to the Ceph project + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#pragma once + +#include +#include "include/common_fwd.h" + +namespace rgw::account { + +/// generate a randomized account id in a specific format +std::string generate_id(CephContext* cct); + +/// validate that an account id matches the generated format +bool validate_id(std::string_view id, std::string* err_msg = nullptr); + +/// check an account name for any invalid characters +bool validate_name(std::string_view name, std::string* err_msg = nullptr); + +} // namespace rgw::account diff --git a/src/rgw/rgw_basic_types.cc b/src/rgw/rgw_basic_types.cc index 5a09c017f3d..88a510175d4 100644 --- a/src/rgw/rgw_basic_types.cc +++ b/src/rgw/rgw_basic_types.cc @@ -178,3 +178,14 @@ ostream& operator <<(ostream& m, const Principal& p) { } } } + +// rgw_account_id +void encode_json_impl(const char* name, const rgw_account_id& id, Formatter* f) +{ + f->dump_string(name, id); +} + +void decode_json_obj(rgw_account_id& id, JSONObj* obj) +{ + decode_json_obj(static_cast(id), obj); +} diff --git a/src/rgw/rgw_user_types.h b/src/rgw/rgw_user_types.h index 1aaf4cfa5d3..afd0d930a67 100644 --- a/src/rgw/rgw_user_types.h +++ b/src/rgw/rgw_user_types.h @@ -19,12 +19,21 @@ #pragma once -#include +#include #include #include "common/dout.h" #include "common/Formatter.h" +// strong typedef to std::string +struct rgw_account_id : std::string { + using std::string::string; + using std::string::operator=; + explicit rgw_account_id(const std::string& s) : std::string(s) {} +}; +void encode_json_impl(const char* name, const rgw_account_id& id, Formatter* f); +void decode_json_obj(rgw_account_id& id, JSONObj* obj); + struct rgw_user { // note: order of member variables matches the sort order of operator<=> std::string tenant; -- 2.39.5