}
} 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);
#include "rgw_op.h"
#include "rgw_rest.h"
#include "rgw_auth.h"
+#include "rgw_auth_keystone.h"
#define RGW_SWIFT_TOKEN_EXPIRATION (15 * 60)
};
+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() {}