Skip to content

Commit

Permalink
rgw: introduce rgw::auth::Strategy::apply() to deduplicate code.
Browse files Browse the repository at this point in the history
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
  • Loading branch information
rzarzynski committed Jun 7, 2017
1 parent f3317f6 commit bd81c21
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 118 deletions.
48 changes: 48 additions & 0 deletions src/rgw/rgw_auth.cc
Expand Up @@ -252,6 +252,54 @@ rgw::auth::Strategy::authenticate(const req_state* const s) const
return strategy_result;
}

int
rgw::auth::Strategy::apply(const rgw::auth::Strategy& auth_strategy,
req_state* const s) noexcept
{
try {
auto result = auth_strategy.authenticate(s);
if (result.get_status() != decltype(result)::Status::GRANTED) {
/* Access denied is acknowledged by returning a std::unique_ptr with
* nullptr inside. */
ldout(s->cct, 5) << "Failed the auth strategy, reason="
<< result.get_reason() << dendl;
return result.get_reason();
}

try {
rgw::auth::IdentityApplier::aplptr_t applier = result.get_applier();
rgw::auth::Completer::cmplptr_t completer = result.get_completer();

/* 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);
if (completer) {
completer->modify_request_state(s);
}

s->auth.identity = std::move(applier);
s->auth.completer = std::move(completer);

return 0;
} catch (const int err) {
ldout(s->cct, 5) << "applier throwed err=" << err << dendl;
return err;
}
} catch (const int err) {
ldout(s->cct, 5) << "auth engine throwed err=" << err << dendl;
return err;
}

/* We never should be here. */
return -EPERM;
}

void
rgw::auth::Strategy::add_engine(const Control ctrl_flag,
const Engine& engine) noexcept
Expand Down
2 changes: 2 additions & 0 deletions src/rgw/rgw_auth.h
Expand Up @@ -323,6 +323,8 @@ class Strategy : public Engine {
return auth_stack.empty();
}

static int apply(const Strategy& auth_strategy, req_state* s) noexcept;

private:
/* Using the reference wrapper here to explicitly point out we are not
* interested in storing nulls while preserving the dynamic polymorphism. */
Expand Down
88 changes: 13 additions & 75 deletions src/rgw/rgw_rest_s3.cc
Expand Up @@ -1564,43 +1564,16 @@ int RGWPostObj_ObjStore_S3::get_policy()
/* FIXME: this is a makeshift solution. The browser upload authentication will be
* handled by an instance of rgw::auth::Completer spawned in Handler's authorize()
* method. */
const auto& strategy = auth_registry_ptr->get_s3_post();
try {
auto result = strategy.authenticate(s);
if (result.get_status() != decltype(result)::Status::GRANTED) {
return -EACCES;
}

try {
auto applier = result.get_applier();
auto completer = result.get_completer();

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);
if (completer) {
completer->modify_request_state(s);
}

s->auth.identity = std::move(applier);
s->auth.completer = std::move(completer);

s->owner.set_id(s->user->user_id);
s->owner.set_name(s->user->display_name);
/* OK, fall through. */
} catch (int err) {
return -EACCES;
}
} catch (int err) {
const int ret = rgw::auth::Strategy::apply(auth_registry_ptr->get_s3_post(), s);
if (ret != 0) {
return -EACCES;
} else {
/* Populate the owner info. */
s->owner.set_id(s->user->user_id);
s->owner.set_name(s->user->display_name);
ldout(s->cct, 0) << "Successful Signature Verification!" << dendl;
}

ldout(s->cct, 0) << "Successful Signature Verification!" << dendl;

ceph::bufferlist decoded_policy;
try {
decoded_policy.decode_base64(s->auth.s3_postobj_creds.encoded_policy);
Expand Down Expand Up @@ -3192,48 +3165,13 @@ int RGW_Auth_S3::authorize_v2(RGWRados* const store,
const rgw::auth::StrategyRegistry& auth_registry,
struct req_state* const s)
{
const auto& auth_strategy = auth_registry.get_s3_main();
try {
auto result = auth_strategy.authenticate(s);
if (result.get_status() != decltype(result)::Status::GRANTED) {
ldout(s->cct, 5) << "Failed the S3 auth strategy, reason="
<< result.get_reason() << dendl;
return result.get_reason();
}
try {
auto applier = result.get_applier();
auto completer = result.get_completer();

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);
if (completer) {
completer->modify_request_state(s);
}

s->auth.identity = std::move(applier);
s->auth.completer = std::move(completer);

/* Populate the owner info. */
s->owner.set_id(s->user->user_id);
s->owner.set_name(s->user->display_name);

/* Success - not throwed. */
return 0;
} catch (const int err) {
ldout(s->cct, 5) << "applier threw err=" << err << dendl;
return err;
}
} catch (const int err) {
ldout(s->cct, 5) << "local auth engine threw err=" << err << dendl;
return err;
const auto ret = rgw::auth::Strategy::apply(auth_registry.get_s3_main(), s);
if (ret == 0) {
/* Populate the owner info. */
s->owner.set_id(s->user->user_id);
s->owner.set_name(s->user->display_name);
}

return -ERR_SIGNATURE_NO_MATCH;
return ret;
}

int RGWHandler_Auth_S3::init(RGWRados *store, struct req_state *state,
Expand Down
44 changes: 1 addition & 43 deletions src/rgw/rgw_rest_swift.cc
Expand Up @@ -2471,49 +2471,7 @@ RGWOp *RGWHandler_REST_Obj_SWIFT::op_options()

int RGWHandler_REST_SWIFT::authorize()
{
try {
auto result = auth_strategy.authenticate(s);

if (result.get_status() != decltype(result)::Status::GRANTED) {
/* 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 {
rgw::auth::IdentityApplier::aplptr_t applier = result.get_applier();
rgw::auth::Completer::cmplptr_t completer = result.get_completer();

/* 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);
if (completer) {
completer->modify_request_state(s);
}

s->auth.identity = std::move(applier);
s->auth.completer = std::move(completer);

return 0;
} 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;
}

/* All engines refused to handle this authentication request by
* returning RGWAuthEngine::Status::UNKKOWN. Rather rare case. */
return -EPERM;
return rgw::auth::Strategy::apply(auth_strategy, s);
}

int RGWHandler_REST_SWIFT::postauth_init()
Expand Down

0 comments on commit bd81c21

Please sign in to comment.