all iam/sns/sts requests wrap the s3 <Error> xml response in another
<ErrorResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
without this, boto3 fails to fully parse error responses, leading to
generic Unknown ClientError exceptions of the form:
botocore.exceptions.ClientError: An error occurred (Unknown) when calling the PutUserPolicy operation: Unknown
with the ErrorResponse part, boto3 throws more specific exceptions that
include the error Code and Message:
botocore.errorfactory.NoSuchEntityException: An error occurred (NoSuchEntity) when calling the PutUserPolicy operation: No such UserName in the account
Signed-off-by: Casey Bodley <cbodley@redhat.com>
(cherry picked from commit
195ecb3732e0d7f78dc74cc9b7f2ac3d7ed919a0)
void dump(req_state* s)
{
+ std::optional<Formatter::ObjectSection> error_response;
+ if (s->prot_flags & RGW_REST_IAM) {
+ error_response.emplace(*s->formatter, "ErrorResponse", RGW_REST_IAM_XMLNS);
+ } else if (s->prot_flags & RGW_REST_SNS) {
+ error_response.emplace(*s->formatter, "ErrorResponse", RGW_REST_SNS_XMLNS);
+ } else if (s->prot_flags & RGW_REST_STS) {
+ error_response.emplace(*s->formatter, "ErrorResponse", RGW_REST_STS_XMLNS);
+ }
+
if (s->format != RGWFormat::HTML)
s->formatter->open_object_section("Error");
if (!s->err.err_code.empty())
s->formatter->dump_string("RequestId", s->trans_id);
s->formatter->dump_string("HostId", s->host_id);
if (s->format != RGWFormat::HTML)
- s->formatter->close_section();
+ s->formatter->close_section(); // Error
}
struct str_len {
#define RGW_REST_WEBSITE 0x8
#define RGW_REST_STS 0x10
#define RGW_REST_IAM 0x20
-#define RGW_REST_SNS 0x30
+#define RGW_REST_SNS 0x40
+
+inline constexpr const char* RGW_REST_IAM_XMLNS =
+ "https://iam.amazonaws.com/doc/2010-05-08/";
+
+inline constexpr const char* RGW_REST_SNS_XMLNS =
+ "https://sns.amazonaws.com/doc/2010-03-31/";
+
+inline constexpr const char* RGW_REST_STS_XMLNS =
+ "https://sts.amazonaws.com/doc/2011-06-15/";
#define RGW_SUSPENDED_USER_AUID (uint64_t)-2
#include "rgw_auth_filters.h"
#include "rgw_rest.h"
+
class RGWHandler_REST_IAM : public RGWHandler_REST {
const rgw::auth::StrategyRegistry& auth_registry;
bufferlist bl_post_body;
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_rgw
-static const char* AWS_SNS_NS("https://sns.amazonaws.com/doc/2010-03-31/");
-
bool verify_transport_security(CephContext *cct, const RGWEnv& env) {
const auto is_secure = rgw_transport_is_secure(cct, env);
if (!is_secure && g_conf().get_val<bool>("rgw_allow_notification_secrets_in_cleartext")) {
}
const auto f = s->formatter;
- f->open_object_section_in_ns("CreateTopicResponse", AWS_SNS_NS);
+ f->open_object_section_in_ns("CreateTopicResponse", RGW_REST_SNS_XMLNS);
f->open_object_section("CreateTopicResult");
encode_xml("TopicArn", topic_arn, f);
f->close_section(); // CreateTopicResult
}
const auto f = s->formatter;
- f->open_object_section_in_ns("ListTopicsResponse", AWS_SNS_NS);
+ f->open_object_section_in_ns("ListTopicsResponse", RGW_REST_SNS_XMLNS);
f->open_object_section("ListTopicsResult");
encode_xml("Topics", result, f);
f->close_section(); // ListTopicsResult
}
const auto f = s->formatter;
- f->open_object_section_in_ns("GetTopicAttributesResponse", AWS_SNS_NS);
+ f->open_object_section_in_ns("GetTopicAttributesResponse", RGW_REST_SNS_XMLNS);
f->open_object_section("GetTopicAttributesResult");
result.dump_xml_as_attributes(f);
f->close_section(); // GetTopicAttributesResult
}
const auto f = s->formatter;
- f->open_object_section_in_ns("SetTopicAttributesResponse", AWS_SNS_NS);
+ f->open_object_section_in_ns("SetTopicAttributesResponse", RGW_REST_SNS_XMLNS);
f->open_object_section("ResponseMetadata");
encode_xml("RequestId", s->req_id, f);
f->close_section(); // ResponseMetadata
}
const auto f = s->formatter;
- f->open_object_section_in_ns("DeleteTopicResponse", AWS_SNS_NS);
+ f->open_object_section_in_ns("DeleteTopicResponse", RGW_REST_SNS_XMLNS);
f->open_object_section("ResponseMetadata");
encode_xml("RequestId", s->req_id, f);
f->close_section(); // ResponseMetadata
op_ret = std::move(ret);
//Dump the output
if (op_ret == 0) {
- s->formatter->open_object_section("GetSessionTokenResponse");
+ s->formatter->open_object_section_in_ns("GetSessionTokenResponse", RGW_REST_STS_XMLNS);
s->formatter->open_object_section("GetSessionTokenResult");
s->formatter->open_object_section("Credentials");
creds.dump(s->formatter);
//Dump the output
if (op_ret == 0) {
- s->formatter->open_object_section("AssumeRoleWithWebIdentityResponse");
+ s->formatter->open_object_section_in_ns("AssumeRoleWithWebIdentityResponse", RGW_REST_STS_XMLNS);
s->formatter->open_object_section("AssumeRoleWithWebIdentityResult");
encode_json("SubjectFromWebIdentityToken", response.sub , s->formatter);
encode_json("Audience", response.aud , s->formatter);
op_ret = std::move(response.retCode);
//Dump the output
if (op_ret == 0) {
- s->formatter->open_object_section("AssumeRoleResponse");
+ s->formatter->open_object_section_in_ns("AssumeRoleResponse", RGW_REST_STS_XMLNS);
s->formatter->open_object_section("AssumeRoleResult");
s->formatter->open_object_section("Credentials");
response.creds.dump(s->formatter);