mirror of
https://github.com/ceph/ceph
synced 2025-02-21 01:47:25 +00:00
rgw: s3: implement GetBucketPolicyStatus API
This API returns whether the Bucket Policies/ACLs are public. There are a couple of caveats: - AWS currently returns PolicyNotFound error in case a bucket policy doesn't exist, though a non existant bucket policy would mean the default ACLs apply where the bucket is private, so error return here seems like an error - the API spec mentions TRUE and FALSE as the response IsPublic element value, however in practice both boto/aws clients and AWS S3 return/expect a lowercase response. Signed-off-by: Abhishek Lekshmanan <abhishek@suse.com> Conflicts: src/rgw/rgw_rest_s3.h merge conflict after zipper rework, dropped a spurious newline in rgw_rest_s3.h after get_obj_op decl. src/rgw/rgw_common.h src/rgw/rgw_rest_s3.cc src/rgw/rgw_rest_s3.h: merge conflict after bucket replication merge, trivial conflicts
This commit is contained in:
parent
57baa84044
commit
e0b4562c61
@ -33,6 +33,7 @@ static const auto signed_subresources = {
|
||||
"notification",
|
||||
"partNumber",
|
||||
"policy",
|
||||
"policyStatus",
|
||||
"requestPayment",
|
||||
"response-cache-control",
|
||||
"response-content-disposition",
|
||||
|
@ -848,7 +848,8 @@ void RGWHTTPArgs::append(const string& name, const string& val)
|
||||
(name.compare("torrent") == 0) ||
|
||||
(name.compare("tagging") == 0) ||
|
||||
(name.compare("append") == 0) ||
|
||||
(name.compare("position") == 0)) {
|
||||
(name.compare("position") == 0) ||
|
||||
(name.compare("policyStatus") == 0)) {
|
||||
sub_resources[name] = val;
|
||||
} else if (name[0] == 'r') { // root of all evil
|
||||
if ((name.compare("response-content-type") == 0) ||
|
||||
|
@ -534,6 +534,8 @@ enum RGWOpType {
|
||||
RGW_OP_GET_BUCKET_REPLICATION,
|
||||
RGW_OP_PUT_BUCKET_REPLICATION,
|
||||
RGW_OP_DELETE_BUCKET_REPLICATION,
|
||||
|
||||
RGW_OP_GET_BUCKET_POLICY_STATUS
|
||||
};
|
||||
|
||||
class RGWAccessControlPolicy;
|
||||
|
@ -100,7 +100,8 @@ static constexpr std::uint64_t s3GetObjectRetention = 57;
|
||||
static constexpr std::uint64_t s3PutObjectLegalHold = 58;
|
||||
static constexpr std::uint64_t s3GetObjectLegalHold = 59;
|
||||
static constexpr std::uint64_t s3BypassGovernanceRetention = 60;
|
||||
static constexpr std::uint64_t s3All = 61;
|
||||
static constexpr std::uint64_t s3GetBucketPolicyStatus = 61;
|
||||
static constexpr std::uint64_t s3All = 62;
|
||||
|
||||
static constexpr std::uint64_t iamPutUserPolicy = s3All + 1;
|
||||
static constexpr std::uint64_t iamGetUserPolicy = s3All + 2;
|
||||
@ -190,6 +191,7 @@ inline int op_to_perm(std::uint64_t op) {
|
||||
case s3GetBucketLogging:
|
||||
case s3GetBucketNotification:
|
||||
case s3GetBucketPolicy:
|
||||
case s3GetBucketPolicyStatus:
|
||||
case s3GetBucketRequestPayment:
|
||||
case s3GetBucketTagging:
|
||||
case s3GetBucketVersioning:
|
||||
|
@ -8063,3 +8063,26 @@ void RGWGetClusterStat::execute()
|
||||
}
|
||||
|
||||
|
||||
int RGWGetBucketPolicyStatus::verify_permission()
|
||||
{
|
||||
if (!verify_bucket_permission(this, s, rgw::IAM::s3GetBucketPolicyStatus)) {
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RGWGetBucketPolicyStatus::execute()
|
||||
{
|
||||
static constexpr auto public_groups = {ACL_GROUP_ALL_USERS,
|
||||
ACL_GROUP_AUTHENTICATED_USERS};
|
||||
|
||||
const auto& bucket_acl = s->bucket_acl->get_acl();
|
||||
isPublic = std::any_of(public_groups.begin(), public_groups.end(),
|
||||
[&bucket_acl](ACLGroupTypeEnum g) {
|
||||
auto p = bucket_acl.get_group_perm(g, RGW_PERM_FULL_CONTROL);
|
||||
return (p != RGW_PERM_NONE) && (p != RGW_PERM_INVALID);
|
||||
}
|
||||
);
|
||||
ldout(s->cct,20) << __func__ << "ACL public status=" << isPublic << dendl;
|
||||
}
|
||||
|
@ -2384,6 +2384,18 @@ public:
|
||||
dmc::client_id dmclock_client() override { return dmc::client_id::admin; }
|
||||
};
|
||||
|
||||
class RGWGetBucketPolicyStatus : public RGWOp {
|
||||
protected:
|
||||
bool isPublic {false};
|
||||
public:
|
||||
int verify_permission() override;
|
||||
const char* name() const override { return "get_bucket_policy_status"; }
|
||||
virtual RGWOpType get_type() override { return RGW_OP_GET_BUCKET_POLICY_STATUS; }
|
||||
virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
|
||||
void execute() override;
|
||||
dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
|
||||
};
|
||||
|
||||
static inline int parse_value_and_bound(
|
||||
const string &input,
|
||||
int &output,
|
||||
|
@ -4163,6 +4163,25 @@ void RGWGetObjLegalHold_ObjStore_S3::send_response()
|
||||
rgw_flush_formatter_and_reset(s, s->formatter);
|
||||
}
|
||||
|
||||
void RGWGetBucketPolicyStatus_ObjStore_S3::send_response()
|
||||
{
|
||||
if (op_ret) {
|
||||
set_req_state_err(s, op_ret);
|
||||
}
|
||||
dump_errno(s);
|
||||
end_header(s, this, "application/xml");
|
||||
dump_start(s);
|
||||
|
||||
s->formatter->open_object_section_in_ns("PolicyStatus", XMLNS_AWS_S3);
|
||||
// https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETPolicyStatus.html
|
||||
// mentions TRUE and FALSE, but boto/aws official clients seem to want lower
|
||||
// case which is returned by AWS as well; so let's be bug to bug compatible
|
||||
// with the API
|
||||
s->formatter->dump_string("IsPublic", isPublic ? "true" : "false");
|
||||
s->formatter->close_section();
|
||||
rgw_flush_formatter_and_reset(s, s->formatter);
|
||||
|
||||
}
|
||||
|
||||
RGWOp *RGWHandler_REST_Service_S3::op_get()
|
||||
{
|
||||
@ -4283,6 +4302,8 @@ RGWOp *RGWHandler_REST_Bucket_S3::op_get()
|
||||
return RGWHandler_REST_PSNotifs_S3::create_get_op();
|
||||
} else if (is_replication_op()) {
|
||||
return new RGWGetBucketReplication_ObjStore_S3;
|
||||
} else if (is_policy_status_op()) {
|
||||
return new RGWGetBucketPolicyStatus_ObjStore_S3;
|
||||
}
|
||||
return get_obj_op(true);
|
||||
}
|
||||
|
@ -570,6 +570,11 @@ public:
|
||||
void send_response() override;
|
||||
};
|
||||
|
||||
class RGWGetBucketPolicyStatus_ObjStore_S3 : public RGWGetBucketPolicyStatus {
|
||||
public:
|
||||
void send_response() override;
|
||||
};
|
||||
|
||||
class RGW_Auth_S3 {
|
||||
public:
|
||||
static int authorize(const DoutPrefixProvider *dpp,
|
||||
@ -676,9 +681,11 @@ protected:
|
||||
bool is_replication_op() const {
|
||||
return s->info.args.exists("replication");
|
||||
}
|
||||
bool is_policy_status_op() {
|
||||
return s->info.args.exists("policyStatus");
|
||||
}
|
||||
|
||||
RGWOp *get_obj_op(bool get_data) const;
|
||||
|
||||
RGWOp *op_get() override;
|
||||
RGWOp *op_head() override;
|
||||
RGWOp *op_put() override;
|
||||
|
Loading…
Reference in New Issue
Block a user