]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/sal: remove virtual class RGWOIDCProvider
authorCasey Bodley <cbodley@redhat.com>
Tue, 6 Feb 2024 14:32:27 +0000 (09:32 -0500)
committerCasey Bodley <cbodley@redhat.com>
Wed, 10 Apr 2024 17:09:15 +0000 (13:09 -0400)
class RGWOIDCProvider was doing a lot of different things, so i've split
out its responsibilities:

* move data members and encoding into new struct RGWOIDCProviderInfo,
  and add ceph-dencoder hooks for regression testing
* remove RGWOIDCProvider class and add load/store/delete/list functions
  to the sal::Driver interface
* rgw_rest_oidc_provider.cc handles most of the parameter validation,
  ARN parsing, and json formatting

Signed-off-by: Casey Bodley <cbodley@redhat.com>
19 files changed:
src/rgw/driver/d4n/rgw_sal_d4n.h
src/rgw/driver/daos/rgw_sal_daos.cc
src/rgw/driver/daos/rgw_sal_daos.h
src/rgw/driver/motr/rgw_sal_motr.cc
src/rgw/driver/motr/rgw_sal_motr.h
src/rgw/driver/rados/rgw_sal_rados.cc
src/rgw/driver/rados/rgw_sal_rados.h
src/rgw/rgw_oidc_provider.cc
src/rgw/rgw_oidc_provider.h
src/rgw/rgw_rest_oidc_provider.cc
src/rgw/rgw_rest_oidc_provider.h
src/rgw/rgw_rest_sts.cc
src/rgw/rgw_rest_sts.h
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/tools/ceph-dencoder/rgw_types.h

index 8210496219cfcbe36f3c2cdbb55719885f94bc9d..42436b92d1d51766ec48de7de9b811797008c4a8 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "rgw_sal_filter.h"
 #include "rgw_sal.h"
-#include "rgw_oidc_provider.h"
 #include "rgw_role.h"
 #include "common/dout.h" 
 #include "rgw_aio_throttle.h"
index ed50697113ec1659cdc237b1af82abbe1b223016..f8f60d82d0294ea49ab6558be5fbc420e64473bf 100644 (file)
@@ -2105,14 +2105,32 @@ int DaosStore::list_roles(const DoutPrefixProvider *dpp,
   return DAOS_NOT_IMPLEMENTED_LOG(dpp);
 }
 
-std::unique_ptr<RGWOIDCProvider> DaosStore::get_oidc_provider() {
-  RGWOIDCProvider* p = nullptr;
-  return std::unique_ptr<RGWOIDCProvider>(p);
+int DaosStore::store_oidc_provider(const DoutPrefixProvider* dpp,
+                                   optional_yield y,
+                                   const RGWOIDCProviderInfo& info,
+                                   bool exclusive) {
+  return DAOS_NOT_IMPLEMENTED_LOG(dpp);
+}
+
+int DaosStore::load_oidc_provider(const DoutPrefixProvider* dpp,
+                                  optional_yield y,
+                                  std::string_view tenant,
+                                  std::string_view url,
+                                  RGWOIDCProviderInfo& info) {
+  return DAOS_NOT_IMPLEMENTED_LOG(dpp);
+}
+
+int DaosStore::delete_oidc_provider(const DoutPrefixProvider* dpp,
+                                    optional_yield y,
+                                    std::string_view tenant,
+                                    std::string_view url) {
+  return DAOS_NOT_IMPLEMENTED_LOG(dpp);
 }
 
-int DaosStore::get_oidc_providers(
-    const DoutPrefixProvider* dpp, const std::string& tenant,
-    vector<std::unique_ptr<RGWOIDCProvider>>& providers) {
+int DaosStore::get_oidc_providers(const DoutPrefixProvider* dpp,
+                                  optional_yield y,
+                                  std::string_view tenant,
+                                  std::vector<RGWOIDCProviderInfo>& providers) {
   return DAOS_NOT_IMPLEMENTED_LOG(dpp);
 }
 
index c823d00992b90046989b557af18f17b77dca7aed..cf1583fc174713c06d4b0f9607d99f972468ffb5 100644 (file)
@@ -28,7 +28,6 @@
 
 #include "rgw_multi.h"
 #include "rgw_notify.h"
-#include "rgw_oidc_provider.h"
 #include "rgw_putobj_processor.h"
 #include "rgw_rados.h"
 #include "rgw_role.h"
@@ -1006,10 +1005,23 @@ class DaosStore : public StoreDriver {
                  const std::string& marker,
                  uint32_t max_items,
                  RoleList& listing) override;
-  virtual std::unique_ptr<RGWOIDCProvider> get_oidc_provider() override;
-  virtual int get_oidc_providers(
-      const DoutPrefixProvider* dpp, const std::string& tenant,
-      std::vector<std::unique_ptr<RGWOIDCProvider>>& providers) override;
+  int store_oidc_provider(const DoutPrefixProvider* dpp,
+                          optional_yield y,
+                          const RGWOIDCProviderInfo& info,
+                          bool exclusive) override;
+  int load_oidc_provider(const DoutPrefixProvider* dpp,
+                         optional_yield y,
+                         std::string_view tenant,
+                         std::string_view url,
+                         RGWOIDCProviderInfo& info) override;
+  int delete_oidc_provider(const DoutPrefixProvider* dpp,
+                           optional_yield y,
+                           std::string_view tenant,
+                           std::string_view url) override;
+  int get_oidc_providers(const DoutPrefixProvider* dpp,
+                         optional_yield y,
+                         std::string_view tenant,
+                         std::vector<RGWOIDCProviderInfo>& providers) override;
   virtual std::unique_ptr<Writer> get_append_writer(
       const DoutPrefixProvider* dpp, optional_yield y,
       rgw::sal::Object* obj, const ACLOwner& owner,
index 455151e0e7b07c37252e3acf2ba5e4912dbee3a1..ae86ec9e7d352641b2b8ded929cab16e140d3c92 100644 (file)
@@ -3063,17 +3063,37 @@ int MotrStore::list_roles(const DoutPrefixProvider *dpp,
   return 0;
 }
 
-std::unique_ptr<RGWOIDCProvider> MotrStore::get_oidc_provider()
+int DaosStore::store_oidc_provider(const DoutPrefixProvider* dpp,
+                                   optional_yield y,
+                                   const RGWOIDCProviderInfo& info,
+                                   bool exclusive)
 {
-  RGWOIDCProvider* p = nullptr;
-  return std::unique_ptr<RGWOIDCProvider>(p);
+  return -ENOTSUP;
 }
 
-int MotrStore::get_oidc_providers(const DoutPrefixProvider *dpp,
-    const std::string& tenant,
-    vector<std::unique_ptr<RGWOIDCProvider>>& providers)
+int DaosStore::load_oidc_provider(const DoutPrefixProvider* dpp,
+                                  optional_yield y,
+                                  std::string_view tenant,
+                                  std::string_view url,
+                                  RGWOIDCProviderInfo& info)
 {
-  return 0;
+  return -ENOTSUP;
+}
+
+int DaosStore::delete_oidc_provider(const DoutPrefixProvider* dpp,
+                                    optional_yield y,
+                                    std::string_view tenant,
+                                    std::string_view url)
+{
+  return -ENOTSUP;
+}
+
+int DaosStore::get_oidc_providers(const DoutPrefixProvider* dpp,
+                                  optional_yield y,
+                                  std::string_view tenant,
+                                  std::vector<RGWOIDCProviderInfo>& providers)
+{
+  return -ENOTSUP;
 }
 
 std::unique_ptr<MultipartUpload> MotrBucket::get_multipart_upload(const std::string& oid,
index 852becf521b9cceee2f6822a34bdf39930275523..e278728c7e7fd9962f156cf191f4b6b2f7a1da50 100644 (file)
@@ -29,7 +29,6 @@ extern "C" {
 #include "rgw_sal_store.h"
 #include "rgw_rados.h"
 #include "rgw_notify.h"
-#include "rgw_oidc_provider.h"
 #include "rgw_role.h"
 #include "rgw_multi.h"
 #include "rgw_putobj_processor.h"
@@ -561,24 +560,6 @@ class MotrLuaManager : public StoreLuaManager {
   virtual int reload_packages(const DoutPrefixProvider* dpp, optional_yield y) override;
 };
 
-class MotrOIDCProvider : public RGWOIDCProvider {
-  MotrStore* store;
-  public:
-  MotrOIDCProvider(MotrStore* _store) : store(_store) {}
-  ~MotrOIDCProvider() = default;
-
-  virtual int store_url(const DoutPrefixProvider *dpp, const std::string& url, bool exclusive, optional_yield y) override { return 0; }
-  virtual int read_url(const DoutPrefixProvider *dpp, const std::string& url, const std::string& tenant) override { return 0; }
-  virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) override { return 0;}
-
-  void encode(bufferlist& bl) const {
-    RGWOIDCProvider::encode(bl);
-  }
-  void decode(bufferlist::const_iterator& bl) {
-    RGWOIDCProvider::decode(bl);
-  }
-};
-
 class MotrObject : public StoreObject {
   private:
     MotrStore *store;
@@ -1073,10 +1054,23 @@ class MotrStore : public StoreDriver {
                    const std::string& marker,
                    uint32_t max_items,
                    RoleList& listing) override;
-    virtual std::unique_ptr<RGWOIDCProvider> get_oidc_provider() override;
-    virtual int get_oidc_providers(const DoutPrefixProvider *dpp,
-        const std::string& tenant,
-        std::vector<std::unique_ptr<RGWOIDCProvider>>& providers) override;
+    int store_oidc_provider(const DoutPrefixProvider* dpp,
+                            optional_yield y,
+                            const RGWOIDCProviderInfo& info,
+                            bool exclusive) override;
+    int load_oidc_provider(const DoutPrefixProvider* dpp,
+                           optional_yield y,
+                           std::string_view tenant,
+                           std::string_view url,
+                           RGWOIDCProviderInfo& info) override;
+    int delete_oidc_provider(const DoutPrefixProvider* dpp,
+                             optional_yield y,
+                             std::string_view tenant,
+                             std::string_view url) override;
+    int get_oidc_providers(const DoutPrefixProvider* dpp,
+                           optional_yield y,
+                           std::string_view tenant,
+                           std::vector<RGWOIDCProviderInfo>& providers) override;
     virtual std::unique_ptr<Writer> get_append_writer(const DoutPrefixProvider *dpp,
         optional_yield y,
         rgw::sal::Object* obj,
index fd9d6f90ad3748221dceca93daa844e970a31863..f2ea4078b5377fc396e4dc11990405af85a9c92f 100644 (file)
@@ -38,6 +38,7 @@
 #include "rgw_aio_throttle.h"
 #include "rgw_tools.h"
 #include "rgw_tracer.h"
+#include "rgw_oidc_provider.h"
 
 #include "rgw_zone.h"
 #include "rgw_rest_conn.h"
@@ -1849,16 +1850,82 @@ int RadosStore::list_roles(const DoutPrefixProvider *dpp,
   return 0;
 }
 
-std::unique_ptr<RGWOIDCProvider> RadosStore::get_oidc_provider()
+static constexpr std::string_view oidc_url_oid_prefix = "oidc_url.";
+
+static std::string oidc_provider_oid(std::string_view account,
+                                     std::string_view prefix,
+                                     std::string_view url)
+{
+  return string_cat_reserve(account, prefix, url);
+}
+
+int RadosStore::store_oidc_provider(const DoutPrefixProvider *dpp,
+                                    optional_yield y,
+                                    const RGWOIDCProviderInfo& info,
+                                    bool exclusive)
+{
+  auto sysobj = svc()->sysobj;
+  std::string oid = oidc_provider_oid(info.tenant, oidc_url_oid_prefix,
+                                      url_remove_prefix(info.provider_url));
+
+  // TODO: add support for oidc metadata sync
+  bufferlist bl;
+  using ceph::encode;
+  encode(info, bl);
+  return rgw_put_system_obj(dpp, sysobj, svc()->zone->get_zone_params().oidc_pool, oid, bl, exclusive, nullptr, real_time(), y);
+}
+
+int RadosStore::load_oidc_provider(const DoutPrefixProvider *dpp,
+                                   optional_yield y,
+                                   std::string_view account,
+                                   std::string_view url,
+                                   RGWOIDCProviderInfo& info)
+{
+  auto sysobj = svc()->sysobj;
+  auto& pool = svc()->zone->get_zone_params().oidc_pool;
+  std::string oid = oidc_provider_oid(account, oidc_url_oid_prefix, url);
+  bufferlist bl;
+
+  int ret = rgw_get_system_obj(sysobj, pool, oid, bl, nullptr, nullptr, y, dpp);
+  if (ret < 0) {
+    return ret;
+  }
+
+  try {
+    using ceph::decode;
+    auto iter = bl.cbegin();
+    decode(info, iter);
+  } catch (buffer::error& err) {
+    ldpp_dout(dpp, 0) << "ERROR: failed to decode oidc provider info from pool: " << pool.name <<
+                  ": " << url << dendl;
+    return -EIO;
+  }
+
+  return 0;
+}
+
+int RadosStore::delete_oidc_provider(const DoutPrefixProvider *dpp,
+                                     optional_yield y,
+                                     std::string_view account,
+                                     std::string_view url)
 {
-  return std::make_unique<RadosOIDCProvider>(this);
+  auto& pool = svc()->zone->get_zone_params().oidc_pool;
+  std::string oid = oidc_provider_oid(account, oidc_url_oid_prefix, url);
+  int ret = rgw_delete_system_obj(dpp, svc()->sysobj, pool, oid, nullptr, y);
+  if (ret < 0) {
+    ldpp_dout(dpp, 0) << "ERROR: deleting oidc url from pool: " << pool.name << ": "
+                  << url << ": " << cpp_strerror(-ret) << dendl;
+  }
+
+  return ret;
 }
 
-int RadosStore::get_oidc_providers(const DoutPrefixProvider *dpp,
-                                  const std::string& tenant,
-                                  vector<std::unique_ptr<RGWOIDCProvider>>& providers, optional_yield y)
+int RadosStore::get_oidc_providers(const DoutPrefixProvider* dpp,
+                                  optional_yield y,
+                                  std::string_view tenant,
+                                  vector<RGWOIDCProviderInfo>& providers)
 {
-  std::string prefix = tenant + RGWOIDCProvider::oidc_url_oid_prefix;
+  std::string prefix = string_cat_reserve(tenant, oidc_url_oid_prefix);
   auto pool = svc()->zone->get_zone_params().oidc_pool;
 
   //Get the filtered objects
@@ -1868,31 +1935,33 @@ int RadosStore::get_oidc_providers(const DoutPrefixProvider *dpp,
   do {
     list<std::string> oids;
     int r = rados->list_raw_objects(dpp, pool, prefix, 1000, ctx, oids, &is_truncated);
+    if (r == -ENOENT) {
+      return 0;
+    }
     if (r < 0) {
       ldpp_dout(dpp, 0) << "ERROR: listing filtered objects failed: OIDC pool: "
                   << pool.name << ": " << prefix << ": " << cpp_strerror(-r) << dendl;
       return r;
     }
     for (const auto& iter : oids) {
-      std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = get_oidc_provider();
       bufferlist bl;
-
       r = rgw_get_system_obj(svc()->sysobj, pool, iter, bl, nullptr, nullptr, y, dpp);
       if (r < 0) {
         return r;
       }
 
+      RGWOIDCProviderInfo info;
       try {
         using ceph::decode;
         auto iter = bl.cbegin();
-        decode(*provider, iter);
+        decode(info, iter);
       } catch (buffer::error& err) {
         ldpp_dout(dpp, 0) << "ERROR: failed to decode oidc provider info from pool: "
          << pool.name << ": " << iter << dendl;
         return -EIO;
       }
 
-      providers.push_back(std::move(provider));
+      providers.push_back(std::move(info));
     }
   } while (is_truncated);
 
@@ -3901,70 +3970,6 @@ std::ostream& RadosLuaManager::PackagesWatcher::gen_prefix(std::ostream& out) co
   return out << "rgw lua package reloader: ";
 }
 
-int RadosOIDCProvider::store_url(const DoutPrefixProvider *dpp, const std::string& url, bool exclusive, optional_yield y)
-{
-  auto sysobj = store->svc()->sysobj;
-  std::string oid = tenant + get_url_oid_prefix() + url;
-
-  bufferlist bl;
-  using ceph::encode;
-  encode(*this, bl);
-  return rgw_put_system_obj(dpp, sysobj, store->svc()->zone->get_zone_params().oidc_pool, oid, bl, exclusive, nullptr, real_time(), y);
-}
-
-int RadosOIDCProvider::read_url(const DoutPrefixProvider *dpp, const std::string& url, const std::string& tenant, optional_yield y)
-{
-  auto sysobj = store->svc()->sysobj;
-  auto& pool = store->svc()->zone->get_zone_params().oidc_pool;
-  std::string oid = tenant + get_url_oid_prefix() + url;
-  bufferlist bl;
-
-  int ret = rgw_get_system_obj(sysobj, pool, oid, bl, nullptr, nullptr, y, dpp);
-  if (ret < 0) {
-    return ret;
-  }
-
-  try {
-    using ceph::decode;
-    auto iter = bl.cbegin();
-    decode(*this, iter);
-  } catch (buffer::error& err) {
-    ldpp_dout(dpp, 0) << "ERROR: failed to decode oidc provider info from pool: " << pool.name <<
-                  ": " << url << dendl;
-    return -EIO;
-  }
-
-  return 0;
-}
-
-int RadosOIDCProvider::delete_obj(const DoutPrefixProvider *dpp, optional_yield y)
-{
-  auto& pool = store->svc()->zone->get_zone_params().oidc_pool;
-
-  std::string url, tenant;
-  auto ret = get_tenant_url_from_arn(tenant, url);
-  if (ret < 0) {
-    ldpp_dout(dpp, 0) << "ERROR: failed to parse arn" << dendl;
-    return -EINVAL;
-  }
-
-  if (this->tenant != tenant) {
-    ldpp_dout(dpp, 0) << "ERROR: tenant in arn doesn't match that of user " << this->tenant << ", "
-                  << tenant << ": " << dendl;
-    return -EINVAL;
-  }
-
-  // Delete url
-  std::string oid = tenant + get_url_oid_prefix() + url;
-  ret = rgw_delete_system_obj(dpp, store->svc()->sysobj, pool, oid, nullptr, y);
-  if (ret < 0) {
-    ldpp_dout(dpp, 0) << "ERROR: deleting oidc url from pool: " << pool.name << ": "
-                  << provider_url << ": " << cpp_strerror(-ret) << dendl;
-  }
-
-  return ret;
-}
-
 int RadosRole::store_info(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y)
 {
   using ceph::encode;
index 7ba21ead5a18227586ce581d63e23aeb0fbbfd1e..07eeeb4618a3c86b750921d3184fccb460c391f2 100644 (file)
@@ -22,7 +22,6 @@
 #include "rgw_sal_store.h"
 #include "rgw_rados.h"
 #include "rgw_notify.h"
-#include "rgw_oidc_provider.h"
 #include "rgw_role.h"
 #include "rgw_multi.h"
 #include "rgw_putobj_processor.h"
@@ -341,10 +340,23 @@ class RadosStore : public StoreDriver {
                    const std::string& marker,
                    uint32_t max_items,
                    RoleList& listing) override;
-    virtual std::unique_ptr<RGWOIDCProvider> get_oidc_provider() override;
-    virtual int get_oidc_providers(const DoutPrefixProvider *dpp,
-                                  const std::string& tenant,
-                                  std::vector<std::unique_ptr<RGWOIDCProvider>>& providers, optional_yield y) override;
+    int store_oidc_provider(const DoutPrefixProvider* dpp,
+                            optional_yield y,
+                            const RGWOIDCProviderInfo& info,
+                            bool exclusive) override;
+    int load_oidc_provider(const DoutPrefixProvider* dpp,
+                           optional_yield y,
+                           std::string_view tenant,
+                           std::string_view url,
+                           RGWOIDCProviderInfo& info) override;
+    int delete_oidc_provider(const DoutPrefixProvider* dpp,
+                             optional_yield y,
+                             std::string_view tenant,
+                             std::string_view url) override;
+    int get_oidc_providers(const DoutPrefixProvider* dpp,
+                           optional_yield y,
+                           std::string_view tenant,
+                           std::vector<RGWOIDCProviderInfo>& providers) override;
     virtual std::unique_ptr<Writer> get_append_writer(const DoutPrefixProvider *dpp,
                                  optional_yield y,
                                  rgw::sal::Object* obj,
@@ -1054,23 +1066,6 @@ public:
   int unwatch_reload(const DoutPrefixProvider* dpp);
 };
 
-class RadosOIDCProvider : public RGWOIDCProvider {
-  RadosStore* store;
-public:
-  RadosOIDCProvider(RadosStore* _store) : store(_store) {}
-  ~RadosOIDCProvider() = default;
-
-  virtual int store_url(const DoutPrefixProvider *dpp, const std::string& url, bool exclusive, optional_yield y) override;
-  virtual int read_url(const DoutPrefixProvider *dpp, const std::string& url, const std::string& tenant, optional_yield y) override;
-  virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) override;
-  void encode(bufferlist& bl) const {
-    RGWOIDCProvider::encode(bl);
-  }
-  void decode(bufferlist::const_iterator& bl) {
-    RGWOIDCProvider::decode(bl);
-  }
-};
-
 class RadosRole : public RGWRole {
   RadosStore* store;
 public:
@@ -1098,5 +1093,3 @@ public:
   virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) override;
 };
 }} // namespace rgw::sal
-
-WRITE_CLASS_ENCODER(rgw::sal::RadosOIDCProvider)
index 5b78c45518912574afad332733a49bce73caa2c1..734c9a8788e9a83cb3769712edd9f9e9600eb1d1 100644 (file)
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab ft=cpp
 
-#include <errno.h>
-#include <ctime>
-#include <regex>
-
-#include "common/errno.h"
-#include "common/Formatter.h"
-#include "common/ceph_json.h"
-#include "common/ceph_time.h"
-#include "rgw_rados.h"
-#include "rgw_zone.h"
-
-#include "include/types.h"
-#include "rgw_string.h"
-
-#include "rgw_common.h"
-#include "rgw_tools.h"
 #include "rgw_oidc_provider.h"
 
-#include "services/svc_zone.h"
-#include "services/svc_sys_obj.h"
-
 #define dout_subsys ceph_subsys_rgw
 
-using namespace std;
-
-namespace rgw { namespace sal {
-
-const string RGWOIDCProvider::oidc_url_oid_prefix = "oidc_url.";
-const string RGWOIDCProvider::oidc_arn_prefix = "arn:aws:iam::";
-
-int RGWOIDCProvider::get_tenant_url_from_arn(string& tenant, string& url)
-{
-  auto provider_arn = rgw::ARN::parse(arn);
-  if (!provider_arn) {
-    return -EINVAL;
-  }
-  url = provider_arn->resource;
-  tenant = provider_arn->account;
-  auto pos = url.find("oidc-provider/");
-  if (pos != std::string::npos) {
-    url.erase(pos, 14);
-  }
-  return 0;
-}
-
-int RGWOIDCProvider::create(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y)
-{
-  int ret;
-
-  if (! validate_input(dpp)) {
-    return -EINVAL;
-  }
-
-  string idp_url = url_remove_prefix(provider_url);
-
-  /* check to see the name is not used */
-  ret = read_url(dpp, idp_url, tenant, y);
-  if (exclusive && ret == 0) {
-    ldpp_dout(dpp, 0) << "ERROR: url " << provider_url << " already in use"
-                    << id << dendl;
-    return -EEXIST;
-  } else if ( ret < 0 && ret != -ENOENT) {
-    ldpp_dout(dpp, 0) << "failed reading provider url  " << provider_url << ": "
-                  << cpp_strerror(-ret) << dendl;
-    return ret;
-  }
-
-  //arn
-  arn = oidc_arn_prefix + tenant + ":oidc-provider/" + idp_url;
-
-  // Creation time
-  real_clock::time_point t = real_clock::now();
-
-  struct timeval tv;
-  real_clock::to_timeval(t, tv);
-
-  char buf[30];
-  struct tm result;
-  gmtime_r(&tv.tv_sec, &result);
-  strftime(buf,30,"%Y-%m-%dT%H:%M:%S", &result);
-  sprintf(buf + strlen(buf),".%03dZ",(int)tv.tv_usec/1000);
-  creation_date.assign(buf, strlen(buf));
-
-  ret = store_url(dpp, idp_url, exclusive, y);
-  if (ret < 0) {
-    ldpp_dout(dpp, 0) << "ERROR:  storing role info in OIDC pool: "
-                  << provider_url << ": " << cpp_strerror(-ret) << dendl;
-    return ret;
-  }
-
-  return 0;
-}
-
-int RGWOIDCProvider::get(const DoutPrefixProvider *dpp, optional_yield y)
-{
-  string url, tenant;
-  auto ret = get_tenant_url_from_arn(tenant, url);
-  if (ret < 0) {
-    ldpp_dout(dpp, 0) << "ERROR: failed to parse arn" << dendl;
-    return -EINVAL;
-  }
-
-  if (this->tenant != tenant) {
-    ldpp_dout(dpp, 0) << "ERROR: tenant in arn doesn't match that of user " << this->tenant << ", "
-                  << tenant << ": " << dendl;
-    return -EINVAL;
-  }
-
-  ret = read_url(dpp, url, tenant, y);
-  if (ret < 0) {
-    return ret;
-  }
-
-  return 0;
-}
-
-void RGWOIDCProvider::dump(Formatter *f) const
+void RGWOIDCProviderInfo::dump(Formatter *f) const
 {
-  encode_json("OpenIDConnectProviderArn", arn, f);
+  encode_json("id", id, f);
+  encode_json("provider_url", provider_url, f);
+  encode_json("arn", arn, f);
+  encode_json("creation_date", creation_date, f);
+  encode_json("tenant", tenant, f);
+  encode_json("client_ids", client_ids, f);
+  encode_json("thumbprints", thumbprints, f);
 }
 
-void RGWOIDCProvider::dump_all(Formatter *f) const
+void RGWOIDCProviderInfo::decode_json(JSONObj *obj)
 {
-  f->open_object_section("ClientIDList");
-  for (auto it : client_ids) {
-    encode_json("member", it, f);
-  }
-  f->close_section();
-  encode_json("CreateDate", creation_date, f);
-  f->open_object_section("ThumbprintList");
-  for (auto it : thumbprints) {
-    encode_json("member", it, f);
-  }
-  f->close_section();
-  encode_json("Url", provider_url, f);
+  JSONDecoder::decode_json("id", id, obj);
+  JSONDecoder::decode_json("provider_url", provider_url, obj);
+  JSONDecoder::decode_json("arn", arn, obj);
+  JSONDecoder::decode_json("creation_date", creation_date, obj);
+  JSONDecoder::decode_json("tenant", tenant, obj);
+  JSONDecoder::decode_json("client_ids", client_ids, obj);
+  JSONDecoder::decode_json("thumbprints", thumbprints, obj);
 }
 
-void RGWOIDCProvider::decode_json(JSONObj *obj)
+void RGWOIDCProviderInfo::generate_test_instances(std::list<RGWOIDCProviderInfo*>& l)
 {
-  JSONDecoder::decode_json("OpenIDConnectProviderArn", arn, obj);
+  auto p = new RGWOIDCProviderInfo;
+  p->id = "id";
+  p->provider_url = "server.example.com";
+  p->arn = "arn:aws:iam::acct:oidc-provider/server.example.com";
+  p->creation_date = "someday";
+  p->client_ids = {"a", "b"};
+  p->thumbprints = {"c", "d"};
+  l.push_back(p);
+  l.push_back(new RGWOIDCProviderInfo);
 }
-
-bool RGWOIDCProvider::validate_input(const DoutPrefixProvider *dpp)
-{
-  if (provider_url.length() > MAX_OIDC_URL_LEN) {
-    ldpp_dout(dpp, 0) << "ERROR: Invalid length of url " << dendl;
-    return false;
-  }
-  if (client_ids.size() > MAX_OIDC_NUM_CLIENT_IDS) {
-    ldpp_dout(dpp, 0) << "ERROR: Invalid number of client ids " << dendl;
-    return false;
-  }
-
-  for (auto& it : client_ids) {
-    if (it.length() > MAX_OIDC_CLIENT_ID_LEN) {
-      return false;
-    }
-  }
-
-  if (thumbprints.size() > MAX_OIDC_NUM_THUMBPRINTS) {
-    ldpp_dout(dpp, 0) << "ERROR: Invalid number of thumbprints " << thumbprints.size() << dendl;
-    return false;
-  }
-
-  for (auto& it : thumbprints) {
-    if (it.length() > MAX_OIDC_THUMBPRINT_LEN) {
-      return false;
-    }
-  }
-  
-  return true;
-}
-
-const string& RGWOIDCProvider::get_url_oid_prefix()
-{
-  return oidc_url_oid_prefix;
-}
-
-} } // namespace rgw::sal
index f317bcf9e364f049831b287850803d95206a01c4..3e8600af9db8a4e41d338d5fce480d40f0dc9292 100644 (file)
@@ -3,27 +3,14 @@
 
 #pragma once
 
+#include <list>
 #include <string>
+#include <vector>
 
-#include "common/ceph_context.h"
 #include "common/ceph_json.h"
 
-#include "rgw/rgw_sal.h"
-
-namespace rgw { namespace sal {
-
-class RGWOIDCProvider
+struct RGWOIDCProviderInfo
 {
-public:
-  static const std::string oidc_url_oid_prefix;
-  static const std::string oidc_arn_prefix;
-  static constexpr int MAX_OIDC_NUM_CLIENT_IDS = 100;
-  static constexpr int MAX_OIDC_CLIENT_ID_LEN = 255;
-  static constexpr int MAX_OIDC_NUM_THUMBPRINTS = 5;
-  static constexpr int MAX_OIDC_THUMBPRINT_LEN = 40;
-  static constexpr int MAX_OIDC_URL_LEN = 255;
-
-protected:
   std::string id;
   std::string provider_url;
   std::string arn;
@@ -32,51 +19,6 @@ protected:
   std::vector<std::string> client_ids;
   std::vector<std::string> thumbprints;
 
-  int get_tenant_url_from_arn(std::string& tenant, std::string& url);
-  virtual int store_url(const DoutPrefixProvider *dpp, const std::string& url, bool exclusive, optional_yield y) = 0;
-  virtual int read_url(const DoutPrefixProvider *dpp, const std::string& url, const std::string& tenant, optional_yield y) = 0;
-  bool validate_input(const DoutPrefixProvider *dpp);
-
-public:
-  void set_arn(std::string _arn) {
-    arn = _arn;
-  }
-  void set_url(std::string _provider_url) {
-    provider_url = _provider_url;
-  }
-  void set_tenant(std::string _tenant) {
-    tenant = _tenant;
-  }
-  void set_client_ids(std::vector<std::string>& _client_ids) {
-    client_ids = std::move(_client_ids);
-  }
-  void set_thumbprints(std::vector<std::string>& _thumbprints) {
-    thumbprints = std::move(_thumbprints);
-  }
-
-  RGWOIDCProvider(std::string provider_url,
-                    std::string tenant,
-                    std::vector<std::string> client_ids,
-                    std::vector<std::string> thumbprints)
-  : provider_url(std::move(provider_url)),
-    tenant(std::move(tenant)),
-    client_ids(std::move(client_ids)),
-    thumbprints(std::move(thumbprints)) {
-  }
-
-  RGWOIDCProvider( std::string arn,
-                    std::string tenant)
-  : arn(std::move(arn)),
-    tenant(std::move(tenant)) {
-  }
-
-  RGWOIDCProvider(std::string tenant)
-  : tenant(std::move(tenant)) {}
-
-  RGWOIDCProvider() {}
-
-  virtual ~RGWOIDCProvider() = default;
-
   void encode(bufferlist& bl) const {
     ENCODE_START(3, 1, bl);
     encode(id, bl);
@@ -90,7 +32,7 @@ public:
   }
 
   void decode(bufferlist::const_iterator& bl) {
-    DECODE_START(2, bl);
+    DECODE_START(3, bl);
     decode(id, bl);
     decode(provider_url, bl);
     decode(arn, bl);
@@ -101,21 +43,8 @@ public:
     DECODE_FINISH(bl);
   }
 
-  const std::string& get_provider_url() const { return provider_url; }
-  const std::string& get_arn() const { return arn; }
-  const std::string& get_create_date() const { return creation_date; }
-  const std::vector<std::string>& get_client_ids() const { return client_ids;}
-  const std::vector<std::string>& get_thumbprints() const { return thumbprints; }
-
-  int create(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
-  virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) = 0;
-  int get(const DoutPrefixProvider *dpp, optional_yield y);
   void dump(Formatter *f) const;
-  void dump_all(Formatter *f) const;
   void decode_json(JSONObj *obj);
-
-  static const std::string& get_url_oid_prefix();
+  static void generate_test_instances(std::list<RGWOIDCProviderInfo*>& l);
 };
-WRITE_CLASS_ENCODER(RGWOIDCProvider)
-
-} } // namespace rgw::sal
+WRITE_CLASS_ENCODER(RGWOIDCProviderInfo)
index e47239a67512e0735c4a4c6263ed00cd4a0ca198..4699f1d41be7c4130a14156fc4a10141fcec07b7 100644 (file)
@@ -46,52 +46,97 @@ void RGWRestOIDCProvider::send_response()
 }
 
 
+static std::string format_creation_date(ceph::real_time now)
+{
+  struct timeval tv;
+  real_clock::to_timeval(now, tv);
+
+  struct tm result;
+  gmtime_r(&tv.tv_sec, &result);
+  char buf[30];
+  strftime(buf,30,"%Y-%m-%dT%H:%M:%S", &result);
+  sprintf(buf + strlen(buf),".%03dZ",(int)tv.tv_usec/1000);
+  return buf;
+}
+
+
 RGWCreateOIDCProvider::RGWCreateOIDCProvider()
   : RGWRestOIDCProvider(rgw::IAM::iamCreateOIDCProvider, RGW_CAP_WRITE)
 {
 }
 
+inline constexpr int MAX_OIDC_NUM_CLIENT_IDS = 100;
+inline constexpr int MAX_OIDC_CLIENT_ID_LEN = 255;
+inline constexpr int MAX_OIDC_NUM_THUMBPRINTS = 5;
+inline constexpr int MAX_OIDC_THUMBPRINT_LEN = 40;
+inline constexpr int MAX_OIDC_URL_LEN = 255;
+
 int RGWCreateOIDCProvider::init_processing(optional_yield y)
 {
-  provider_url = s->info.args.get("Url");
-  if (provider_url.empty()) {
+  info.provider_url = s->info.args.get("Url");
+  if (info.provider_url.empty()) {
     s->err.message = "Missing required element Url";
     return -EINVAL;
   }
+  if (info.provider_url.size() > MAX_OIDC_URL_LEN) {
+    s->err.message = "Url cannot exceed the maximum length of "
+        + std::to_string(MAX_OIDC_URL_LEN);
+    return -EINVAL;
+  }
 
   auto val_map = s->info.args.get_params();
   for (auto& it : val_map) {
-      if (it.first.find("ClientIDList.member.") != string::npos) {
-          client_ids.emplace_back(it.second);
+    if (it.first.find("ClientIDList.member.") != string::npos) {
+      if (it.second.size() > MAX_OIDC_CLIENT_ID_LEN) {
+        s->err.message = "ClientID cannot exceed the maximum length of "
+            + std::to_string(MAX_OIDC_CLIENT_ID_LEN);
+        return -EINVAL;
       }
-      if (it.first.find("ThumbprintList.member.") != string::npos) {
-          thumbprints.emplace_back(it.second);
+      info.client_ids.emplace_back(it.second);
+    }
+    if (it.first.find("ThumbprintList.member.") != string::npos) {
+      if (it.second.size() > MAX_OIDC_THUMBPRINT_LEN) {
+        s->err.message = "Thumbprint cannot exceed the maximum length of "
+            + std::to_string(MAX_OIDC_THUMBPRINT_LEN);
+        return -EINVAL;
       }
+      info.thumbprints.emplace_back(it.second);
+    }
   }
 
-  if (thumbprints.empty()) {
+  if (info.thumbprints.empty()) {
     s->err.message = "Missing required element ThumbprintList";
     return -EINVAL;
   }
+  if (info.thumbprints.size() > MAX_OIDC_NUM_THUMBPRINTS) {
+    s->err.message = "ThumbprintList cannot exceed the maximum size of "
+        + std::to_string(MAX_OIDC_NUM_THUMBPRINTS);
+    return -EINVAL;
+  }
+
+  if (info.client_ids.size() > MAX_OIDC_NUM_CLIENT_IDS) {
+    s->err.message = "ClientIDList cannot exceed the maximum size of "
+        + std::to_string(MAX_OIDC_NUM_CLIENT_IDS);
+    return -EINVAL;
+  }
+
+  info.tenant = s->user->get_tenant();
+  resource = rgw::ARN(url_remove_prefix(info.provider_url),
+                      "oidc-provider/", info.tenant, true);
+  info.arn = resource.to_string();
+  info.creation_date = format_creation_date(real_clock::now());
 
-  string idp_url = url_remove_prefix(provider_url);
-  resource = rgw::ARN(idp_url, "oidc-provider/", s->user->get_tenant(), true);
   return 0;
 }
 
 void RGWCreateOIDCProvider::execute(optional_yield y)
 {
-  std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = driver->get_oidc_provider();
-  provider->set_url(provider_url);
-  provider->set_tenant(s->user->get_tenant());
-  provider->set_client_ids(client_ids);
-  provider->set_thumbprints(thumbprints);
-  op_ret = provider->create(s, true, y);
-
+  constexpr bool exclusive = true;
+  op_ret = driver->store_oidc_provider(this, y, info, exclusive);
   if (op_ret == 0) {
     s->formatter->open_object_section("CreateOpenIDConnectProviderResponse");
     s->formatter->open_object_section("CreateOpenIDConnectProviderResult");
-    provider->dump(s->formatter);
+    encode_json("OpenIDConnectProviderArn", info.arn, s->formatter);
     s->formatter->close_section();
     s->formatter->open_object_section("ResponseMetadata");
     s->formatter->dump_string("RequestId", s->trans_id);
@@ -102,19 +147,60 @@ void RGWCreateOIDCProvider::execute(optional_yield y)
 
 
 static int validate_provider_arn(const std::string& provider_arn,
-                                 rgw::ARN& resource, std::string& message)
+                                 std::string_view tenant,
+                                 rgw::ARN& resource, std::string& url,
+                                 std::string& message)
 {
   if (provider_arn.empty()) {
     message = "Missing required element OpenIDConnectProviderArn";
     return -EINVAL;
   }
 
-  auto arn = rgw::ARN::parse(provider_arn, true);
-  if (!arn) {
+  // teuthology runs keycloak on localhost:8080, and rgw::ARN::parse() rejects
+  // that extra colon. aws docs say "The URL should not contain a port number."
+  // but we'll be less strict about parsing
+
+  std::string_view str = provider_arn;
+
+  constexpr std::string_view arn_prefix = "arn:";
+  if (!str.starts_with(arn_prefix)) {
     message = "Invalid value for OpenIDConnectProviderArn";
     return -EINVAL;
   }
-  resource = std::move(*arn);
+  str.remove_prefix(arn_prefix.size());
+
+  constexpr std::string_view partition = "aws:";
+  if (!str.starts_with(partition)) {
+    message = "OpenIDConnectProviderArn partition must be aws";
+    return -EINVAL;
+  }
+  resource.partition = rgw::Partition::aws;
+  str.remove_prefix(partition.size());
+
+  constexpr std::string_view service = "iam::";
+  if (!str.starts_with(service)) {
+    message = "OpenIDConnectProviderArn service must be iam";
+    return -EINVAL;
+  }
+  resource.service = rgw::Service::iam;
+  str.remove_prefix(service.size());
+
+  if (!str.starts_with(tenant)) {
+    message = "OpenIDConnectProviderArn account must match user tenant";
+    return -EINVAL;
+  }
+  resource.account = tenant;
+  str.remove_prefix(tenant.size());
+
+  constexpr std::string_view resource_prefix = ":oidc-provider/";
+  if (!str.starts_with(resource_prefix)) {
+    message = "Invalid ARN resource for OpenIDConnectProviderArn";
+    return -EINVAL;
+  }
+  resource.resource = str.substr(1); // trim leading :
+  str.remove_prefix(resource_prefix.size());
+  url = str;
+
   return 0;
 }
 
@@ -126,16 +212,14 @@ RGWDeleteOIDCProvider::RGWDeleteOIDCProvider()
 
 int RGWDeleteOIDCProvider::init_processing(optional_yield y)
 {
-  provider_arn = s->info.args.get("OpenIDConnectProviderArn");
-  return validate_provider_arn(provider_arn, resource, s->err.message);
+  std::string provider_arn = s->info.args.get("OpenIDConnectProviderArn");
+  return validate_provider_arn(provider_arn, s->user->get_tenant(),
+                               resource, url, s->err.message);
 }
 
 void RGWDeleteOIDCProvider::execute(optional_yield y)
 {
-  std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = driver->get_oidc_provider();
-  provider->set_arn(provider_arn);
-  provider->set_tenant(s->user->get_tenant());
-  op_ret = provider->delete_obj(s, y);
+  op_ret = driver->delete_oidc_provider(this, y, s->user->get_tenant(), url);
 
   if (op_ret < 0 && op_ret != -ENOENT && op_ret != -EINVAL) {
     op_ret = ERR_INTERNAL_ERROR;
@@ -157,16 +241,32 @@ RGWGetOIDCProvider::RGWGetOIDCProvider()
 
 int RGWGetOIDCProvider::init_processing(optional_yield y)
 {
-  provider_arn = s->info.args.get("OpenIDConnectProviderArn");
-  return validate_provider_arn(provider_arn, resource, s->err.message);
+  std::string provider_arn = s->info.args.get("OpenIDConnectProviderArn");
+  return validate_provider_arn(provider_arn, s->user->get_tenant(),
+                               resource, url, s->err.message);
+}
+
+static void dump_oidc_provider(const RGWOIDCProviderInfo& info, Formatter *f)
+{
+  f->open_object_section("ClientIDList");
+  for (const auto& it : info.client_ids) {
+    encode_json("member", it, f);
+  }
+  f->close_section();
+  encode_json("CreateDate", info.creation_date, f);
+  f->open_object_section("ThumbprintList");
+  for (const auto& it : info.thumbprints) {
+    encode_json("member", it, f);
+  }
+  f->close_section();
+  encode_json("Url", info.provider_url, f);
 }
 
 void RGWGetOIDCProvider::execute(optional_yield y)
 {
-  std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = driver->get_oidc_provider();
-  provider->set_arn(provider_arn);
-  provider->set_tenant(s->user->get_tenant());
-  op_ret = provider->get(s, y);
+  RGWOIDCProviderInfo info;
+  op_ret = driver->load_oidc_provider(this, y, s->user->get_tenant(),
+                                      url, info);
 
   if (op_ret < 0 && op_ret != -ENOENT && op_ret != -EINVAL) {
     op_ret = ERR_INTERNAL_ERROR;
@@ -178,7 +278,7 @@ void RGWGetOIDCProvider::execute(optional_yield y)
     s->formatter->dump_string("RequestId", s->trans_id);
     s->formatter->close_section();
     s->formatter->open_object_section("GetOpenIDConnectProviderResult");
-    provider->dump_all(s->formatter);
+    dump_oidc_provider(info, s->formatter);
     s->formatter->close_section();
     s->formatter->close_section();
   }
@@ -192,8 +292,8 @@ RGWListOIDCProviders::RGWListOIDCProviders()
 
 void RGWListOIDCProviders::execute(optional_yield y)
 {
-  vector<std::unique_ptr<rgw::sal::RGWOIDCProvider>> result;
-  op_ret = driver->get_oidc_providers(s, s->user->get_tenant(), result, y);
+  vector<RGWOIDCProviderInfo> result;
+  op_ret = driver->get_oidc_providers(this, y, s->user->get_tenant(), result);
 
   if (op_ret == 0) {
     s->formatter->open_array_section("ListOpenIDConnectProvidersResponse");
@@ -204,9 +304,7 @@ void RGWListOIDCProviders::execute(optional_yield y)
     s->formatter->open_array_section("OpenIDConnectProviderList");
     for (const auto& it : result) {
       s->formatter->open_object_section("member");
-      auto& arn = it->get_arn();
-      ldpp_dout(s, 0) << "ARN: " << arn << dendl;
-      s->formatter->dump_string("Arn", arn);
+      s->formatter->dump_string("Arn", it.arn);
       s->formatter->close_section();
     }
     s->formatter->close_section();
index 14f71af17eb1594ff236b1ed6c6de4c8d49a9000..192906ab4985b3af4815c6c311c48dc7272ab68e 100644 (file)
@@ -22,9 +22,7 @@ public:
 };
 
 class RGWCreateOIDCProvider : public RGWRestOIDCProvider {
-  std::vector<std::string> client_ids;
-  std::vector<std::string> thumbprints;
-  std::string provider_url; //'iss' field in JWT
+  RGWOIDCProviderInfo info;
  public:
   RGWCreateOIDCProvider();
 
@@ -35,7 +33,7 @@ class RGWCreateOIDCProvider : public RGWRestOIDCProvider {
 };
 
 class RGWDeleteOIDCProvider : public RGWRestOIDCProvider {
-  std::string provider_arn;
+  std::string url;
  public:
   RGWDeleteOIDCProvider();
 
@@ -46,7 +44,7 @@ class RGWDeleteOIDCProvider : public RGWRestOIDCProvider {
 };
 
 class RGWGetOIDCProvider : public RGWRestOIDCProvider {
-  std::string provider_arn;
+  std::string url;
  public:
   RGWGetOIDCProvider();
 
index 84284a587f980b0b3abf556565935d689d9de448..111ca7c1e87b7c2aa56c1253d57ca0a7847c1893 100644 (file)
@@ -80,8 +80,9 @@ WebTokenEngine::get_role_name(const string& role_arn) const
   return role_name;
 }
 
-std::unique_ptr<rgw::sal::RGWOIDCProvider>
-WebTokenEngine::get_provider(const DoutPrefixProvider *dpp, const string& role_arn, const string& iss, optional_yield y) const
+int WebTokenEngine::load_provider(const DoutPrefixProvider* dpp, optional_yield y,
+                                  const string& role_arn, const string& iss,
+                                  RGWOIDCProviderInfo& info) const
 {
   string tenant = get_role_tenant(role_arn);
 
@@ -100,16 +101,8 @@ WebTokenEngine::get_provider(const DoutPrefixProvider *dpp, const string& role_a
   } else {
     idp_url.erase(pos, 7);
   }
-  auto provider_arn = rgw::ARN(idp_url, "oidc-provider", tenant);
-  string p_arn = provider_arn.to_string();
-  std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = driver->get_oidc_provider();
-  provider->set_arn(p_arn);
-  provider->set_tenant(tenant);
-  auto ret = provider->get(dpp, y);
-  if (ret < 0) {
-    return nullptr;
-  }
-  return provider;
+
+  return driver->load_oidc_provider(dpp, y, tenant, idp_url, info);
 }
 
 bool
@@ -249,8 +242,9 @@ WebTokenEngine::get_from_jwt(const DoutPrefixProvider* dpp, const std::string& t
     }
 
     string role_arn = s->info.args.get("RoleArn");
-    auto provider = get_provider(dpp, role_arn, iss, y);
-    if (! provider) {
+    RGWOIDCProviderInfo provider;
+    int r = load_provider(dpp, y, role_arn, iss, provider);
+    if (r < 0) {
       ldpp_dout(dpp, 0) << "Couldn't get oidc provider info using input iss" << iss << dendl;
       throw -EACCES;
     }
@@ -266,17 +260,15 @@ WebTokenEngine::get_from_jwt(const DoutPrefixProvider* dpp, const std::string& t
         throw -EINVAL;
       }
     }
-    vector<string> client_ids = provider->get_client_ids();
-    vector<string> thumbprints = provider->get_thumbprints();
-    if (! client_ids.empty()) {
+    if (! provider.client_ids.empty()) {
       bool found = false;
       for (auto& it : aud) {
-        if (is_client_id_valid(client_ids, it)) {
+        if (is_client_id_valid(provider.client_ids, it)) {
           found = true;
           break;
         }
       }
-      if (! found && ! is_client_id_valid(client_ids, client_id) && ! is_client_id_valid(client_ids, azp)) {
+      if (! found && ! is_client_id_valid(provider.client_ids, client_id) && ! is_client_id_valid(provider.client_ids, azp)) {
         ldpp_dout(dpp, 0) << "Client id in token doesn't match with that registered with oidc provider" << dendl;
         throw -EACCES;
       }
@@ -285,7 +277,7 @@ WebTokenEngine::get_from_jwt(const DoutPrefixProvider* dpp, const std::string& t
     if (decoded.has_algorithm()) {
       auto& algorithm = decoded.get_algorithm();
       try {
-        validate_signature(dpp, decoded, algorithm, iss, thumbprints, y);
+        validate_signature(dpp, decoded, algorithm, iss, provider.thumbprints, y);
       } catch (...) {
         throw -EACCES;
       }
index 91b9e98d3036d16c4e03374fcaf430795032b1f8..aa66972943995acd9102373f78441cfeaeac2965 100644 (file)
@@ -40,7 +40,9 @@ class WebTokenEngine : public rgw::auth::Engine {
 
   bool is_cert_valid(const std::vector<std::string>& thumbprints, const std::string& cert) const;
 
-  std::unique_ptr<rgw::sal::RGWOIDCProvider> get_provider(const DoutPrefixProvider *dpp, const std::string& role_arn, const std::string& iss, optional_yield y) const;
+  int load_provider(const DoutPrefixProvider *dpp, optional_yield y,
+                    const std::string& role_arn, const std::string& iss,
+                    RGWOIDCProviderInfo& info) const;
 
   std::string get_role_tenant(const std::string& role_arn) const;
 
index b453e9881fabe9b430a15dd1c4f63e346db4eab5..8f0ec5228b97cca81dbc245f5aeb3686676889d6 100644 (file)
@@ -45,6 +45,7 @@ struct rgw_pubsub_topics;
 struct rgw_pubsub_bucket_topics;
 class RGWZonePlacementInfo;
 struct rgw_pubsub_topic;
+struct RGWOIDCProviderInfo;
 
 using RGWBucketListNameFilter = std::function<bool (const std::string&)>;
 
@@ -182,7 +183,6 @@ namespace rgw { namespace sal {
 
 struct MPSerializer;
 class GCChain;
-class RGWOIDCProvider;
 class RGWRole;
 
 enum AttrsMod {
@@ -576,12 +576,24 @@ class Driver {
                           const std::string& marker,
                           uint32_t max_items,
                           RoleList& listing) = 0;
-    /** Get an empty Open ID Connector provider */
-    virtual std::unique_ptr<RGWOIDCProvider> get_oidc_provider() = 0;
+    virtual int store_oidc_provider(const DoutPrefixProvider* dpp,
+                                    optional_yield y,
+                                    const RGWOIDCProviderInfo& info,
+                                    bool exclusive) = 0;
+    virtual int load_oidc_provider(const DoutPrefixProvider* dpp,
+                                   optional_yield y,
+                                   std::string_view tenant,
+                                   std::string_view url,
+                                   RGWOIDCProviderInfo& info) = 0;
+    virtual int delete_oidc_provider(const DoutPrefixProvider* dpp,
+                                     optional_yield y,
+                                     std::string_view tenant,
+                                     std::string_view url) = 0;
     /** Get all Open ID Connector providers, optionally filtered by tenant  */
-    virtual int get_oidc_providers(const DoutPrefixProvider *dpp,
-                                  const std::string& tenant,
-                                  std::vector<std::unique_ptr<RGWOIDCProvider>>& providers, optional_yield y) = 0;
+    virtual int get_oidc_providers(const DoutPrefixProvider* dpp,
+                                   optional_yield y,
+                                   std::string_view tenant,
+                                   std::vector<RGWOIDCProviderInfo>& providers) = 0;
     /** Get a Writer that appends to an object */
     virtual std::unique_ptr<Writer> get_append_writer(const DoutPrefixProvider *dpp,
                                  optional_yield y,
index e1175c86a25639797813ec8ac2f28944eb66fded..e5518e21432d359ac8c34235a589643b119e6de7 100644 (file)
@@ -1424,15 +1424,34 @@ namespace rgw::sal {
     return 0;
   }
 
-  std::unique_ptr<RGWOIDCProvider> DBStore::get_oidc_provider()
+  int DBStore::store_oidc_provider(const DoutPrefixProvider *dpp,
+                                   optional_yield y,
+                                   const RGWOIDCProviderInfo& info,
+                                   bool exclusive)
+  {
+    return -ENOTSUP;
+  }
+
+  int DBStore::load_oidc_provider(const DoutPrefixProvider *dpp,
+                                  optional_yield y,
+                                  std::string_view account,
+                                  std::string_view url,
+                                  RGWOIDCProviderInfo& info)
   {
-    RGWOIDCProvider* p = nullptr;
-    return std::unique_ptr<RGWOIDCProvider>(p);
+    return -ENOTSUP;
+  }
+
+  int DBStore::delete_oidc_provider(const DoutPrefixProvider *dpp,
+                                    optional_yield y,
+                                    std::string_view account,
+                                    std::string_view url)
+  {
+    return -ENOTSUP;
   }
 
   int DBStore::get_oidc_providers(const DoutPrefixProvider *dpp,
-      const std::string& tenant,
-      vector<std::unique_ptr<RGWOIDCProvider>>& providers, optional_yield y)
+      optional_yield y, std::string_view tenant,
+      vector<RGWOIDCProviderInfo>& providers)
   {
     return 0;
   }
index d645a1a84779d401a966c0f9ca5bba08534e1726..378ad90bf4acd0878c305598eeeff94c9c3d0a12 100644 (file)
@@ -16,7 +16,6 @@
 #pragma once
 
 #include "rgw_sal_store.h"
-#include "rgw_oidc_provider.h"
 #include "rgw_role.h"
 #include "rgw_lc.h"
 #include "rgw_multi.h"
@@ -333,24 +332,6 @@ protected:
     virtual int reload_packages(const DoutPrefixProvider* dpp, optional_yield y) override;
   };
 
-  class DBOIDCProvider : public RGWOIDCProvider {
-    DBStore* store;
-    public:
-    DBOIDCProvider(DBStore* _store) : store(_store) {}
-    ~DBOIDCProvider() = default;
-
-    virtual int store_url(const DoutPrefixProvider *dpp, const std::string& url, bool exclusive, optional_yield y) override { return 0; }
-    virtual int read_url(const DoutPrefixProvider *dpp, const std::string& url, const std::string& tenant, optional_yield y) override { return 0; }
-    virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) override { return 0;}
-
-    void encode(bufferlist& bl) const {
-      RGWOIDCProvider::encode(bl);
-    }
-    void decode(bufferlist::const_iterator& bl) {
-      RGWOIDCProvider::decode(bl);
-    }
-  };
-
   /*
    * For multipart upload, below is the process flow -
    *
@@ -914,10 +895,23 @@ public:
                      const std::string& marker,
                      uint32_t max_items,
                      RoleList& listing) override;
-      virtual std::unique_ptr<RGWOIDCProvider> get_oidc_provider() override;
-      virtual int get_oidc_providers(const DoutPrefixProvider *dpp,
-          const std::string& tenant,
-          std::vector<std::unique_ptr<RGWOIDCProvider>>& providers, optional_yield y) override;
+      int store_oidc_provider(const DoutPrefixProvider *dpp,
+                              optional_yield y,
+                              const RGWOIDCProviderInfo& info,
+                              bool exclusive) override;
+      int load_oidc_provider(const DoutPrefixProvider *dpp,
+                             optional_yield y,
+                             std::string_view tenant,
+                             std::string_view url,
+                             RGWOIDCProviderInfo& info) override;
+      int delete_oidc_provider(const DoutPrefixProvider *dpp,
+                               optional_yield y,
+                               std::string_view tenant,
+                               std::string_view url) override;
+      virtual int get_oidc_providers(const DoutPrefixProvider* dpp,
+          optional_yield y,
+          std::string_view tenant,
+          std::vector<RGWOIDCProviderInfo>& providers) override;
       virtual std::unique_ptr<Writer> get_append_writer(const DoutPrefixProvider *dpp,
                                  optional_yield y,
                                  rgw::sal::Object* obj,
index 039734ea589b4bff986a303dcd0d843c96e5c7ef..780f445710d3aba9424b8729d8ddad8e33b34f72 100644 (file)
@@ -575,16 +575,37 @@ int FilterDriver::list_roles(const DoutPrefixProvider *dpp,
                           marker, max_items, listing);
 }
 
-std::unique_ptr<RGWOIDCProvider> FilterDriver::get_oidc_provider()
+int FilterDriver::store_oidc_provider(const DoutPrefixProvider* dpp,
+                                      optional_yield y,
+                                      const RGWOIDCProviderInfo& info,
+                                      bool exclusive)
 {
-  return next->get_oidc_provider();
+  return next->store_oidc_provider(dpp, y, info, exclusive);
 }
 
-int FilterDriver::get_oidc_providers(const DoutPrefixProvider *dpp,
-                                   const std::string& tenant,
-                                   std::vector<std::unique_ptr<RGWOIDCProvider>>& providers, optional_yield y)
+int FilterDriver::load_oidc_provider(const DoutPrefixProvider* dpp,
+                                     optional_yield y,
+                                     std::string_view tenant,
+                                     std::string_view url,
+                                     RGWOIDCProviderInfo& info)
+{
+  return next->load_oidc_provider(dpp, y, tenant, url, info);
+}
+
+int FilterDriver::delete_oidc_provider(const DoutPrefixProvider* dpp,
+                                       optional_yield y,
+                                       std::string_view tenant,
+                                       std::string_view url)
+{
+  return next->delete_oidc_provider(dpp, y, tenant, url);
+}
+
+int FilterDriver::get_oidc_providers(const DoutPrefixProvider* dpp,
+                                     optional_yield y,
+                                     std::string_view tenant,
+                                     std::vector<RGWOIDCProviderInfo>& providers)
 {
-  return next->get_oidc_providers(dpp, tenant, providers, y);
+  return next->get_oidc_providers(dpp, y, tenant, providers);
 }
 
 std::unique_ptr<Writer> FilterDriver::get_append_writer(const DoutPrefixProvider *dpp,
index be04a7a0acbfdabfc18edd055d67a3e0b3a05806..91724854a8710017cf5584be0c65b87784bfb7e0 100644 (file)
@@ -16,7 +16,6 @@
 #pragma once
 
 #include "rgw_sal.h"
-#include "rgw_oidc_provider.h"
 #include "rgw_role.h"
 
 namespace rgw { namespace sal {
@@ -399,11 +398,23 @@ public:
                         const std::string& marker,
                         uint32_t max_items,
                         RoleList& listing) override;
-  virtual std::unique_ptr<RGWOIDCProvider> get_oidc_provider() override;
-  virtual int get_oidc_providers(const DoutPrefixProvider *dpp,
-                                const std::string& tenant,
-                                std::vector<std::unique_ptr<RGWOIDCProvider>>&
-                                providers, optional_yield y) override;
+  int store_oidc_provider(const DoutPrefixProvider* dpp,
+                          optional_yield y,
+                          const RGWOIDCProviderInfo& info,
+                          bool exclusive) override;
+  int load_oidc_provider(const DoutPrefixProvider* dpp,
+                         optional_yield y,
+                         std::string_view tenant,
+                         std::string_view url,
+                         RGWOIDCProviderInfo& info) override;
+  int delete_oidc_provider(const DoutPrefixProvider* dpp,
+                           optional_yield y,
+                           std::string_view tenant,
+                           std::string_view url) override;
+  int get_oidc_providers(const DoutPrefixProvider* dpp,
+                         optional_yield y,
+                         std::string_view tenant,
+                         std::vector<RGWOIDCProviderInfo>& providers) override;
   virtual std::unique_ptr<Writer> get_append_writer(const DoutPrefixProvider *dpp,
                                  optional_yield y,
                                  rgw::sal::Object* obj,
index c57210db7562c65a00c526fe938c290b4f93f8c5..dde159087180deee93b637a0775b413eaf0ff28b 100644 (file)
@@ -246,6 +246,9 @@ TYPE(RGWUID)
 #include "rgw_user_types.h"
 TYPE(rgw_user)
 
+#include "rgw_oidc_provider.h"
+TYPE(RGWOIDCProviderInfo)
+
 #include "driver/rados/roles.h"
 TYPE(rgwrados::roles::resource_metadata)