]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: define account ids and names
authorCasey Bodley <cbodley@redhat.com>
Wed, 1 Nov 2023 22:11:58 +0000 (18:11 -0400)
committerCasey Bodley <cbodley@redhat.com>
Wed, 10 Apr 2024 16:53:04 +0000 (12:53 -0400)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/rgw/CMakeLists.txt
src/rgw/rgw_account.cc [new file with mode: 0644]
src/rgw/rgw_account.h [new file with mode: 0644]
src/rgw/rgw_basic_types.cc
src/rgw/rgw_user_types.h

index 91c020a8a1e34a38d487c796336b1d2d4a7c837b..73678164e2a60d3d220d53a8eece30fb8053eaba 100644 (file)
@@ -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 (file)
index 0000000..a895b9b
--- /dev/null
@@ -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 <algorithm>
+#include <fmt/format.h>
+
+#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 (file)
index 0000000..17ed0c0
--- /dev/null
@@ -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 <string>
+#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
index 5a09c017f3def3c6f63cad51021a0a131d3b7f05..88a510175d417db780368d925a62f249d6eb3549 100644 (file)
@@ -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<std::string&>(id), obj);
+}
index 1aaf4cfa5d34826645e29cd452960078b9d168f5..afd0d930a67fa254b6002d86fed8c81ad8f22bc1 100644 (file)
 
 #pragma once
 
-#include <string_view>
+#include <string>
 #include <fmt/format.h>
 
 #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;