]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: implement rgw::auth::swift::DefaultStrategy.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Tue, 13 Dec 2016 14:28:10 +0000 (15:28 +0100)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Fri, 24 Mar 2017 15:54:33 +0000 (16:54 +0100)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_rest_swift.cc
src/rgw/rgw_rest_swift.h
src/rgw/rgw_swift_auth.h

index 1af9612e888ea9c8ba28bfab53c704f7015317df..99ab54653c09779d02c1726bf04845ecbb348674 100644 (file)
@@ -2077,6 +2077,44 @@ int RGWHandler_REST_SWIFT::authorize()
     }
   } aplfact(store, s->account_name);
 
+
+  auto strategy = rgw::auth::swift::DefaultStrategy::get_instance();
+  rgw::auth::Applier::aplptr_t applier;
+  rgw::auth::Completer::cmplptr_t completer;
+
+  std::tie(applier, completer) = strategy.authenticate(s);
+
+  try {
+    if (! applier) {
+      /* Access denied is acknowledged by returning a std::unique_ptr with
+       * nullptr inside. */
+      ldout(s->cct, 5) << "auth engine refused to authenicate" << dendl;
+      return -EPERM;
+    }
+
+    try {
+      /* Account used by a given RGWOp is decoupled from identity employed
+       * in the authorization phase (RGWOp::verify_permissions). */
+      applier->load_acct_info(*s->user);
+      //s->perm_mask = applier->get_perm_mask();
+
+      /* This is the signle place where we pass req_state as a pointer
+       * to non-const and thus its modification is allowed. In the time
+       * of writing only RGWTempURLEngine needed that feature. */
+      applier->modify_request_state(s);
+
+      // FIXME
+      //applier->load_identity();
+      //s->auth_identity = std::move(applier);
+    } catch (int err) {
+      ldout(s->cct, 5) << "applier throwed err=" << err << dendl;
+      return err;
+    }
+  } catch (int err) {
+    ldout(s->cct, 5) << "auth engine throwed err=" << err << dendl;
+    return err;
+  }
+
   /* Extractors. */
   RGWXAuthTokenExtractor token_extr(s);
 
index f8713be5a17059f5ed793598cc143791100a8f3c..c5c5e335965cf84aa201780c08ee11bcedffbf51 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "rgw_op.h"
 #include "rgw_rest.h"
+#include "rgw_swift_auth.h"
 
 class RGWGetObj_ObjStore_SWIFT : public RGWGetObj_ObjStore {
   int custom_http_ret = 0;
index 1619d9bb7c59eefff762f5c6d40e0ec73dd22be8..3a0d950f098a822820dd6e9eb18fbd6c3cbca114 100644 (file)
@@ -7,6 +7,7 @@
 #include "rgw_op.h"
 #include "rgw_rest.h"
 #include "rgw_auth.h"
+#include "rgw_auth_keystone.h"
 
 #define RGW_SWIFT_TOKEN_EXPIRATION (15 * 60)
 
@@ -124,6 +125,108 @@ public:
 };
 
 
+namespace rgw {
+namespace auth {
+namespace swift {
+
+class DefaultStrategy : public rgw::auth::Strategy,
+                        public rgw::auth::TokenExtractor,
+                        public rgw::auth::RemoteApplier::Factory,
+                        public rgw::auth::LocalApplier::Factory,
+                        public rgw::auth::swift::TempURLApplier::Factory {
+  RGWRados* const store;
+
+  /* The engines. */
+  const rgw::auth::swift::TempURLEngine tempurl_engine;
+  const rgw::auth::swift::SignedTokenEngine signed_engine;
+  const rgw::auth::keystone::TokenEngine keystone_engine;
+  const rgw::auth::swift::ExternalTokenEngine external_engine;
+  const rgw::auth::AnonymousEngine anon_engine;
+
+  using keystone_config_t = rgw::keystone::CephCtxConfig;
+  using keystone_cache_t = rgw::keystone::TokenCache;
+  using aplptr_t = rgw::auth::IdentityApplier::aplptr_t;
+  using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
+
+  /* The method implements TokenExtractor for X-Auth-Token present in req_state. */
+  std::string get_token(const req_state* const s) const override {
+    /* Returning a reference here would end in GCC complaining about a reference
+     * to temporary. */
+    return s->info.env->get("HTTP_X_AUTH_TOKEN", "");
+  }
+
+  aplptr_t create_apl_remote(CephContext* const cct,
+                             acl_strategy_t&& extra_acl_strategy,
+                             const rgw::auth::RemoteApplier::AuthInfo info) const override {
+    return aplptr_t(
+      new rgw::auth::RemoteApplier(cct, store, std::move(extra_acl_strategy), info));
+  }
+
+  aplptr_t create_apl_local(CephContext* const cct,
+                            const RGWUserInfo& user_info,
+                            const std::string& subuser) const override {
+    return aplptr_t(new rgw::auth::LocalApplier(cct, user_info, subuser));
+  }
+
+  aplptr_t create_apl_turl(CephContext* const cct,
+                           const RGWUserInfo& user_info) const override {
+    /* TempURL doesn't need any user account override. It's a Swift-specific
+     * mechanism that requires  account name internally, so there is no
+     * business with delegating the responsibility outside. */
+    return aplptr_t(new rgw::auth::swift::TempURLApplier(cct, user_info));
+  }
+
+public:
+  DefaultStrategy(CephContext* const cct,
+                  RGWRados* const store)
+    : store(store),
+      tempurl_engine(cct,
+                     store,
+                     static_cast<rgw::auth::swift::TempURLApplier::Factory*>(this)),
+      signed_engine(cct,
+                    store,
+                    static_cast<rgw::auth::TokenExtractor*>(this),
+                    static_cast<rgw::auth::LocalApplier::Factory*>(this)),
+      keystone_engine(cct,
+                      static_cast<rgw::auth::TokenExtractor*>(this),
+                      static_cast<rgw::auth::RemoteApplier::Factory*>(this),
+                      keystone_config_t::get_instance(),
+                      keystone_cache_t::get_instance<keystone_config_t>()),
+      external_engine(cct,
+                      store,
+                      static_cast<rgw::auth::TokenExtractor*>(this),
+                      static_cast<rgw::auth::LocalApplier::Factory*>(this)),
+      anon_engine(cct,
+                  static_cast<rgw::auth::LocalApplier::Factory*>(this)) {
+    /* When the constructor's body is being executed, all member engines
+     * should be initialized. Thus, we can safely add them. */
+    using Control = rgw::auth::Strategy::Control;
+
+    add_engine(Control::SUFFICIENT, tempurl_engine);
+    add_engine(Control::SUFFICIENT, signed_engine);
+
+    /* The auth strategy is responsible for deciding whether a parcular
+     * engine is disabled or not. */
+    if (! cct->_conf->rgw_keystone_url.empty()) {
+      add_engine(Control::SUFFICIENT, keystone_engine);
+    }
+    if (! cct->_conf->rgw_swift_auth_url.empty()) {
+      add_engine(Control::SUFFICIENT, external_engine);
+    }
+
+    add_engine(Control::SUFFICIENT, anon_engine);
+  }
+
+  const char* get_name() const noexcept override {
+    return "rgw::auth::swift::DefaultStrategy";
+  }
+};
+
+} /* namespace swift */
+} /* namespace auth */
+} /* namespace rgw */
+
+
 class RGW_SWIFT_Auth_Get : public RGWOp {
 public:
   RGW_SWIFT_Auth_Get() {}