]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/sal: add load_aclowner_by_email()
authorCasey Bodley <cbodley@redhat.com>
Sat, 16 Dec 2023 17:57:01 +0000 (12:57 -0500)
committerCasey Bodley <cbodley@redhat.com>
Fri, 12 Apr 2024 19:34:26 +0000 (15:34 -0400)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
(cherry picked from commit 01e51d8240db17b45c5325df601f14cb647cc0e1)

src/rgw/driver/rados/rgw_sal_rados.cc
src/rgw/driver/rados/rgw_sal_rados.h
src/rgw/rgw_acl_s3.cc
src/rgw/rgw_sal.h
src/rgw/rgw_sal_dbstore.cc
src/rgw/rgw_sal_dbstore.h
src/rgw/rgw_sal_filter.cc
src/rgw/rgw_sal_filter.h
src/rgw/services/svc_user.h
src/rgw/services/svc_user_rados.cc
src/rgw/services/svc_user_rados.h

index c9808d1a9c755a03875e55f288a14a0f340f068d..163b602bc90f0e5ac07abb1f682673f98c16e056 100644 (file)
@@ -23,6 +23,7 @@
 #include <boost/process.hpp>
 
 #include "common/async/blocked_completion.h"
+#include "include/function2.hpp"
 
 #include "common/Clock.h"
 #include "common/errno.h"
@@ -1156,6 +1157,21 @@ int RadosStore::complete_flush_stats(const DoutPrefixProvider* dpp,
   return rgwrados::buckets::complete_flush_stats(dpp, y, rados, obj);
 }
 
+int RadosStore::load_owner_by_email(const DoutPrefixProvider* dpp,
+                                    optional_yield y,
+                                    std::string_view email,
+                                    rgw_owner& owner)
+{
+  // the email index stores ids which can either be a user or account
+  RGWUID uid;
+  int r = svc()->user->read_email_index(dpp, y, email, uid);
+  if (r < 0) {
+    return r;
+  }
+  owner = parse_owner(uid.id);
+  return 0;
+}
+
 std::unique_ptr<Object> RadosStore::get_object(const rgw_obj_key& k)
 {
   return std::make_unique<RadosObject>(this, k);
index 7839a54c262419ff728e0bdf0df405d806ee2644..e429018e48761b9cf6c118db12936bbd0814c1b7 100644 (file)
@@ -191,6 +191,11 @@ class RadosStore : public StoreDriver {
                              optional_yield y,
                              const rgw_owner& owner) override;
 
+    int load_owner_by_email(const DoutPrefixProvider* dpp,
+                            optional_yield y,
+                            std::string_view email,
+                            rgw_owner& owner) override;
+
     virtual std::unique_ptr<Object> get_object(const rgw_obj_key& k) override;
     std::unique_ptr<Bucket> get_bucket(const RGWBucketInfo& i) override;
     int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b,
index 71114bb1bf896924b220119f9eac9a1da4060867..4f8050ab49dc50aca487dda999828351b7b0c420 100644 (file)
@@ -315,12 +315,12 @@ static int parse_grantee_str(const DoutPrefixProvider* dpp,
   string id_val = rgw_trim_quotes(id_val_quoted);
 
   if (strcasecmp(id_type.c_str(), "emailAddress") == 0) {
-    std::unique_ptr<rgw::sal::User> user;
-    ret = driver->get_user_by_email(dpp, id_val, null_yield, &user);
+    ACLOwner owner;
+    ret = driver->load_aclowner_by_email(dpp, null_yield, id_val, owner);
     if (ret < 0)
       return ret;
 
-    grant.set_canon(user->get_id(), user->get_display_name(), rgw_perm);
+    grant.set_canon(owner.id, owner.display_name, rgw_perm);
   } else if (strcasecmp(id_type.c_str(), "id") == 0) {
     std::unique_ptr<rgw::sal::User> user = driver->get_user(rgw_user(id_val));
     ret = user->load_user(dpp, null_yield);
@@ -454,17 +454,18 @@ static int resolve_grant(const DoutPrefixProvider* dpp, optional_yield y,
   const uint32_t perm = xml_grant.permission->flags;
 
   std::unique_ptr<rgw::sal::User> user;
+  ACLOwner owner;
   switch (xml_grant.type.get_type()) {
   case ACL_TYPE_EMAIL_USER:
     if (xml_grant.email.empty()) {
       return -EINVAL;
     }
-    if (driver->get_user_by_email(dpp, xml_grant.email, y, &user) < 0) {
+    if (driver->load_aclowner_by_email(dpp, y, xml_grant.email, owner) < 0) {
       ldpp_dout(dpp, 10) << "grant user email not found or other error" << dendl;
       err_msg = "The e-mail address you provided does not match any account on record.";
       return -ERR_UNRESOLVABLE_EMAIL;
     }
-    grant.set_canon(user->get_id(), user->get_display_name(), perm);
+    grant.set_canon(owner.id, owner.display_name, perm);
     return 0;
 
   case ACL_TYPE_CANON_USER:
index f43f261d2e98deef332db98c71e82aae7efc62b7..e05f321956bcc1a3f56f8d4a403cb62c615b5394 100644 (file)
@@ -336,6 +336,12 @@ class Driver {
                                      optional_yield y,
                                      const rgw_owner& owner) = 0;
 
+    /** Look up the owner (user or account) for the given email address */
+    virtual int load_owner_by_email(const DoutPrefixProvider* dpp,
+                                    optional_yield y,
+                                    std::string_view email,
+                                    rgw_owner& owner) = 0;
+
     /** Get a basic Object.  This Object is not looked up, and is incomplete, since is
      * does not have a bucket.  This should only be used when an Object is needed before
      * there is a Bucket, otherwise use the get_object() in the Bucket class. */
index 5bcb906e32a94835bc75d557a981aa2ec79e0c33..6aa9cfe15e9583b9c7aae24abb5739463d01ce06 100644 (file)
@@ -1602,6 +1602,21 @@ namespace rgw::sal {
     return 0;
   }
 
+  int DBStore::load_owner_by_email(const DoutPrefixProvider* dpp,
+                                   optional_yield y,
+                                   std::string_view email,
+                                   rgw_owner& owner)
+  {
+    RGWUserInfo uinfo;
+    int ret = getDB()->get_user(dpp, "email", std::string{email},
+                                uinfo, nullptr, nullptr);
+    if (ret < 0) {
+      return ret;
+    }
+    owner = std::move(uinfo.user_id);
+    return 0;
+  }
+
   std::string DBStore::get_cluster_id(const DoutPrefixProvider* dpp,  optional_yield y)
   {
     return "PLACEHOLDER"; // for instance unique identifier
index 67033ed9f70fe5c6fb8880506dd51188f1dbebe1..57a5cb18653b785736c1193880cd8ca7a622991f 100644 (file)
@@ -790,6 +790,10 @@ public:
                                optional_yield y,
                                const rgw_owner& owner) override;
 
+      int load_owner_by_email(const DoutPrefixProvider* dpp,
+                              optional_yield y,
+                              std::string_view email,
+                              rgw_owner& owner) override;
       virtual std::unique_ptr<Object> get_object(const rgw_obj_key& k) override;
       virtual std::string get_cluster_id(const DoutPrefixProvider* dpp, optional_yield y);
       std::unique_ptr<Bucket> get_bucket(const RGWBucketInfo& i) override;
index 3032bdbedadfd3d6acbb3c1c5c486cef95dff950..6a30e7e890fa3054ddcbe9262e992866eee95231 100644 (file)
@@ -235,6 +235,14 @@ int FilterDriver::complete_flush_stats(const DoutPrefixProvider* dpp,
   return next->complete_flush_stats(dpp, y, owner);
 }
 
+int FilterDriver::load_owner_by_email(const DoutPrefixProvider* dpp,
+                                      optional_yield y,
+                                      std::string_view email,
+                                      rgw_owner& owner)
+{
+  return next->load_owner_by_email(dpp, y, email, owner);
+}
+
 std::unique_ptr<Object> FilterDriver::get_object(const rgw_obj_key& k)
 {
   std::unique_ptr<Object> o = next->get_object(k);
index ffe7955c71cc61fc514c741065d0ddf9977c1b3a..7863834fd32bf402f8794615b6206f1178ba8959 100644 (file)
@@ -202,7 +202,10 @@ public:
   int complete_flush_stats(const DoutPrefixProvider* dpp,
                            optional_yield y,
                            const rgw_owner& owner) override;
-
+  int load_owner_by_email(const DoutPrefixProvider* dpp,
+                          optional_yield y,
+                          std::string_view email,
+                          rgw_owner& owner) override;
   virtual std::unique_ptr<Object> get_object(const rgw_obj_key& k) override;
   std::unique_ptr<Bucket> get_bucket(const RGWBucketInfo& i) override;
   int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b,
index 6cb377b7007f8958f282b1854dd733948a4a7af1..af6d7c37d22b7c55aa3869918516e3358ffca503 100644 (file)
@@ -22,7 +22,7 @@
 #include "rgw_service.h"
 #include "rgw_sal_fwd.h"
 
-class RGWUserBuckets;
+struct RGWUID;
 
 class RGWSI_User : public RGWServiceInstance
 {
@@ -90,5 +90,7 @@ public:
                                   real_time *pmtime,
                                   optional_yield y,
                                   const DoutPrefixProvider *dpp) = 0;
+  virtual int read_email_index(const DoutPrefixProvider* dpp, optional_yield y,
+                               std::string_view email, RGWUID& uid) = 0;
 };
 
index 83322b042496c1731f49858cb569503be388bea2..81a00d5f41d41f175091c00f140c3a20ac90136d 100644 (file)
@@ -517,6 +517,26 @@ int RGWSI_User_RADOS::remove_uid_index(RGWSI_MetaBackend::Context *ctx, const RG
   return 0;
 }
 
+static int read_index(const DoutPrefixProvider* dpp, optional_yield y,
+                      RGWSI_SysObj* svc_sysobj, const rgw_pool& pool,
+                      const std::string& key, ceph::real_time* mtime,
+                      RGWUID& uid)
+{
+  bufferlist bl;
+  int r = rgw_get_system_obj(svc_sysobj, pool, key, bl,
+                             nullptr, mtime, y, dpp);
+  if (r < 0) {
+    return r;
+  }
+  try {
+    auto iter = bl.cbegin();
+    decode(uid, iter);
+  } catch (const buffer::error&) {
+    return -EIO;
+  }
+  return 0;
+}
+
 int RGWSI_User_RADOS::get_user_info_from_index(RGWSI_MetaBackend::Context* ctx,
                                                const string& key,
                                                const rgw_pool& pool,
@@ -537,21 +557,11 @@ int RGWSI_User_RADOS::get_user_info_from_index(RGWSI_MetaBackend::Context* ctx,
   }
 
   user_info_cache_entry e;
-  bufferlist bl;
   RGWUID uid;
 
-  int ret = rgw_get_system_obj(svc.sysobj, pool, key, bl, nullptr, &e.mtime, y, dpp);
-  if (ret < 0)
+  int ret = read_index(dpp, y, svc.sysobj, pool, key, &e.mtime, uid);
+  if (ret < 0) {
     return ret;
-
-  rgw_cache_entry_info cache_info;
-
-  try {
-    auto iter = bl.cbegin();
-    decode(uid, iter);
-  } catch (const buffer::error&) {
-    ldpp_dout(dpp, 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl;
-    return -EIO;
   }
 
   if (rgw::account::validate_id(uid.id)) {
@@ -559,6 +569,7 @@ int RGWSI_User_RADOS::get_user_info_from_index(RGWSI_MetaBackend::Context* ctx,
     return -ENOENT;
   }
 
+  rgw_cache_entry_info cache_info;
   ret = read_user_info(ctx, rgw_user{uid.id}, &e.info, &e.objv_tracker,
                        nullptr, &cache_info, nullptr, y, dpp);
   if (ret < 0) {
@@ -623,3 +634,12 @@ int RGWSI_User_RADOS::get_user_info_by_access_key(RGWSI_MetaBackend::Context *ct
                                   svc.zone->get_zone_params().user_keys_pool,
                                   info, objv_tracker, pmtime, y, dpp);
 }
+
+int RGWSI_User_RADOS::read_email_index(const DoutPrefixProvider* dpp,
+                                       optional_yield y,
+                                       std::string_view email,
+                                       RGWUID& uid)
+{
+  const rgw_pool& pool = svc.zone->get_zone_params().user_email_pool;
+  return read_index(dpp, y, svc.sysobj, pool, std::string{email}, nullptr, uid);
+}
index 69851d1db75d0cedd4ee391cf31f92a6e6a9d02a..3df275d227c36ede427038733d0056f8fafe8e66 100644 (file)
@@ -144,4 +144,7 @@ public:
                                   real_time *pmtime,
                                   optional_yield y,
                                   const DoutPrefixProvider *dpp) override;
+
+  int read_email_index(const DoutPrefixProvider* dpp, optional_yield y,
+                       std::string_view email, RGWUID& uid) override;
 };