From 01e51d8240db17b45c5325df601f14cb647cc0e1 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Sat, 16 Dec 2023 12:57:01 -0500 Subject: [PATCH] rgw/sal: add load_aclowner_by_email() Signed-off-by: Casey Bodley --- src/rgw/driver/rados/rgw_sal_rados.cc | 16 ++++++++++ src/rgw/driver/rados/rgw_sal_rados.h | 5 +++ src/rgw/rgw_acl_s3.cc | 11 ++++--- src/rgw/rgw_sal.h | 6 ++++ src/rgw/rgw_sal_dbstore.cc | 15 +++++++++ src/rgw/rgw_sal_dbstore.h | 4 +++ src/rgw/rgw_sal_filter.cc | 8 +++++ src/rgw/rgw_sal_filter.h | 5 ++- src/rgw/services/svc_user.h | 4 ++- src/rgw/services/svc_user_rados.cc | 44 +++++++++++++++++++-------- src/rgw/services/svc_user_rados.h | 3 ++ 11 files changed, 102 insertions(+), 19 deletions(-) diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc index c9808d1a9c7..163b602bc90 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.cc +++ b/src/rgw/driver/rados/rgw_sal_rados.cc @@ -23,6 +23,7 @@ #include #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 RadosStore::get_object(const rgw_obj_key& k) { return std::make_unique(this, k); diff --git a/src/rgw/driver/rados/rgw_sal_rados.h b/src/rgw/driver/rados/rgw_sal_rados.h index 7839a54c262..e429018e487 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.h +++ b/src/rgw/driver/rados/rgw_sal_rados.h @@ -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 get_object(const rgw_obj_key& k) override; std::unique_ptr get_bucket(const RGWBucketInfo& i) override; int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b, diff --git a/src/rgw/rgw_acl_s3.cc b/src/rgw/rgw_acl_s3.cc index 71114bb1bf8..4f8050ab49d 100644 --- a/src/rgw/rgw_acl_s3.cc +++ b/src/rgw/rgw_acl_s3.cc @@ -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 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 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 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: diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index f43f261d2e9..e05f321956b 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -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. */ diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc index 5bcb906e32a..6aa9cfe15e9 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -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 diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h index 67033ed9f70..57a5cb18653 100644 --- a/src/rgw/rgw_sal_dbstore.h +++ b/src/rgw/rgw_sal_dbstore.h @@ -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 get_object(const rgw_obj_key& k) override; virtual std::string get_cluster_id(const DoutPrefixProvider* dpp, optional_yield y); std::unique_ptr get_bucket(const RGWBucketInfo& i) override; diff --git a/src/rgw/rgw_sal_filter.cc b/src/rgw/rgw_sal_filter.cc index 3032bdbedad..6a30e7e890f 100644 --- a/src/rgw/rgw_sal_filter.cc +++ b/src/rgw/rgw_sal_filter.cc @@ -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 FilterDriver::get_object(const rgw_obj_key& k) { std::unique_ptr o = next->get_object(k); diff --git a/src/rgw/rgw_sal_filter.h b/src/rgw/rgw_sal_filter.h index ffe7955c71c..7863834fd32 100644 --- a/src/rgw/rgw_sal_filter.h +++ b/src/rgw/rgw_sal_filter.h @@ -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 get_object(const rgw_obj_key& k) override; std::unique_ptr get_bucket(const RGWBucketInfo& i) override; int load_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b, diff --git a/src/rgw/services/svc_user.h b/src/rgw/services/svc_user.h index 6cb377b7007..af6d7c37d22 100644 --- a/src/rgw/services/svc_user.h +++ b/src/rgw/services/svc_user.h @@ -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; }; diff --git a/src/rgw/services/svc_user_rados.cc b/src/rgw/services/svc_user_rados.cc index 83322b04249..81a00d5f41d 100644 --- a/src/rgw/services/svc_user_rados.cc +++ b/src/rgw/services/svc_user_rados.cc @@ -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); +} diff --git a/src/rgw/services/svc_user_rados.h b/src/rgw/services/svc_user_rados.h index 69851d1db75..3df275d227c 100644 --- a/src/rgw/services/svc_user_rados.h +++ b/src/rgw/services/svc_user_rados.h @@ -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; }; -- 2.39.5