summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_acl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rgw/rgw_acl.h')
-rw-r--r--src/rgw/rgw_acl.h290
1 files changed, 159 insertions, 131 deletions
diff --git a/src/rgw/rgw_acl.h b/src/rgw/rgw_acl.h
index c520501583b..e2887a7049b 100644
--- a/src/rgw/rgw_acl.h
+++ b/src/rgw/rgw_acl.h
@@ -6,6 +6,7 @@
#include <map>
#include <string>
#include <string_view>
+#include <variant>
#include <include/types.h>
#include <boost/optional.hpp>
@@ -15,118 +16,180 @@
#include "rgw_basic_types.h" //includes rgw_acl_types.h
+// acl grantee types
+struct ACLGranteeCanonicalUser {
+ rgw_user id;
+ std::string name;
+
+ friend auto operator<=>(const ACLGranteeCanonicalUser&,
+ const ACLGranteeCanonicalUser&) = default;
+};
+struct ACLGranteeEmailUser {
+ std::string address;
+
+ friend auto operator<=>(const ACLGranteeEmailUser&,
+ const ACLGranteeEmailUser&) = default;
+};
+struct ACLGranteeGroup {
+ ACLGroupTypeEnum type = ACL_GROUP_NONE;
+
+ friend auto operator<=>(const ACLGranteeGroup&,
+ const ACLGranteeGroup&) = default;
+};
+struct ACLGranteeUnknown {
+ friend auto operator<=>(const ACLGranteeUnknown&,
+ const ACLGranteeUnknown&) = default;
+};
+struct ACLGranteeReferer {
+ std::string url_spec;
+
+ friend auto operator<=>(const ACLGranteeReferer&,
+ const ACLGranteeReferer&) = default;
+};
+
class ACLGrant
{
protected:
- ACLGranteeType type;
- rgw_user id;
- std::string email;
- mutable rgw_user email_id;
+ // acl grantee variant, where variant index matches ACLGranteeTypeEnum
+ using ACLGrantee = std::variant<
+ ACLGranteeCanonicalUser,
+ ACLGranteeEmailUser,
+ ACLGranteeGroup,
+ ACLGranteeUnknown,
+ ACLGranteeReferer>;
+
+ ACLGrantee grantee;
ACLPermission permission;
- std::string name;
- ACLGroupTypeEnum group;
- std::string url_spec;
public:
- ACLGrant() : group(ACL_GROUP_NONE) {}
- virtual ~ACLGrant() {}
-
- /* there's an assumption here that email/uri/id encodings are
- different and there can't be any overlap */
- bool get_id(rgw_user& _id) const {
- switch(type.get_type()) {
- case ACL_TYPE_EMAIL_USER:
- _id = email; // implies from_str() that parses the 't:u' syntax
- return true;
- case ACL_TYPE_GROUP:
- case ACL_TYPE_REFERER:
- return false;
- default:
- _id = id;
- return true;
- }
+ ACLGranteeType get_type() const {
+ return static_cast<ACLGranteeTypeEnum>(grantee.index());
}
+ ACLPermission get_permission() const { return permission; }
- const rgw_user* get_id() const {
- switch(type.get_type()) {
- case ACL_TYPE_EMAIL_USER:
- email_id.from_str(email);
- return &email_id;
- case ACL_TYPE_GROUP:
- case ACL_TYPE_REFERER:
- return nullptr;
- default:
- return &id;
- }
+ // return the user grantee, or nullptr
+ const ACLGranteeCanonicalUser* get_user() const {
+ return std::get_if<ACLGranteeCanonicalUser>(&grantee);
+ }
+ // return the email grantee, or nullptr
+ const ACLGranteeEmailUser* get_email() const {
+ return std::get_if<ACLGranteeEmailUser>(&grantee);
+ }
+ // return the group grantee, or nullptr
+ const ACLGranteeGroup* get_group() const {
+ return std::get_if<ACLGranteeGroup>(&grantee);
+ }
+ // return the referer grantee, or nullptr
+ const ACLGranteeReferer* get_referer() const {
+ return std::get_if<ACLGranteeReferer>(&grantee);
}
-
- ACLGranteeType& get_type() { return type; }
- const ACLGranteeType& get_type() const { return type; }
- ACLPermission& get_permission() { return permission; }
- const ACLPermission& get_permission() const { return permission; }
- ACLGroupTypeEnum get_group() const { return group; }
- const std::string& get_referer() const { return url_spec; }
void encode(bufferlist& bl) const {
ENCODE_START(5, 3, bl);
+ ACLGranteeType type = get_type();
encode(type, bl);
- std::string s;
- id.to_str(s);
- encode(s, bl);
- std::string uri;
+
+ if (const ACLGranteeCanonicalUser* user = get_user(); user) {
+ encode(user->id.to_str(), bl);
+ } else {
+ encode(std::string{}, bl); // encode empty id
+ }
+
+ std::string uri; // always empty, v2 converted to 'ACLGroupTypeEnum g' below
encode(uri, bl);
- encode(email, bl);
+
+ if (const ACLGranteeEmailUser* email = get_email(); email) {
+ encode(email->address, bl);
+ } else {
+ encode(std::string{}, bl); // encode empty email address
+ }
encode(permission, bl);
- encode(name, bl);
- __u32 g = (__u32)group;
+ if (const ACLGranteeCanonicalUser* user = get_user(); user) {
+ encode(user->name, bl);
+ } else {
+ encode(std::string{}, bl); // encode empty name
+ }
+
+ __u32 g;
+ if (const ACLGranteeGroup* group = get_group(); group) {
+ g = static_cast<__u32>(group->type);
+ } else {
+ g = static_cast<__u32>(ACL_GROUP_NONE);
+ }
encode(g, bl);
- encode(url_spec, bl);
+
+ if (const ACLGranteeReferer* referer = get_referer(); referer) {
+ encode(referer->url_spec, bl);
+ } else {
+ encode(std::string{}, bl); // encode empty referer
+ }
ENCODE_FINISH(bl);
}
void decode(bufferlist::const_iterator& bl) {
DECODE_START_LEGACY_COMPAT_LEN(5, 3, 3, bl);
+ ACLGranteeType type;
decode(type, bl);
+
+ ACLGranteeCanonicalUser user;
std::string s;
decode(s, bl);
- id.from_str(s);
+ user.id.from_str(s);
+
std::string uri;
decode(uri, bl);
- decode(email, bl);
+
+ ACLGranteeEmailUser email;
+ decode(email.address, bl);
+
decode(permission, bl);
- decode(name, bl);
- if (struct_v > 1) {
- __u32 g;
- decode(g, bl);
- group = (ACLGroupTypeEnum)g;
- } else {
- group = uri_to_group(uri);
- }
+ decode(user.name, bl);
+
+ ACLGranteeGroup group;
+ __u32 g;
+ decode(g, bl);
+ group.type = static_cast<ACLGroupTypeEnum>(g);
+
+ ACLGranteeReferer referer;
if (struct_v >= 5) {
- decode(url_spec, bl);
- } else {
- url_spec.clear();
+ decode(referer.url_spec, bl);
+ }
+
+ // construct the grantee type
+ switch (type) {
+ case ACL_TYPE_CANON_USER:
+ grantee = std::move(user);
+ break;
+ case ACL_TYPE_EMAIL_USER:
+ grantee = std::move(email);
+ break;
+ case ACL_TYPE_GROUP:
+ grantee = std::move(group);
+ break;
+ case ACL_TYPE_REFERER:
+ grantee = std::move(referer);
+ break;
+ case ACL_TYPE_UNKNOWN:
+ default:
+ grantee = ACLGranteeUnknown{};
+ break;
}
DECODE_FINISH(bl);
}
void dump(Formatter *f) const;
static void generate_test_instances(std::list<ACLGrant*>& o);
- ACLGroupTypeEnum uri_to_group(std::string& uri);
+ static ACLGroupTypeEnum uri_to_group(std::string_view uri);
- void set_canon(const rgw_user& _id, const std::string& _name, const uint32_t perm) {
- type.set(ACL_TYPE_CANON_USER);
- id = _id;
- name = _name;
+ void set_canon(const rgw_user& id, const std::string& name, uint32_t perm) {
+ grantee = ACLGranteeCanonicalUser{id, name};
permission.set_permissions(perm);
}
- void set_group(ACLGroupTypeEnum _group, const uint32_t perm) {
- type.set(ACL_TYPE_GROUP);
- group = _group;
+ void set_group(ACLGroupTypeEnum group, uint32_t perm) {
+ grantee = ACLGranteeGroup{group};
permission.set_permissions(perm);
}
- void set_referer(const std::string& _url_spec, const uint32_t perm) {
- type.set(ACL_TYPE_REFERER);
- url_spec = _url_spec;
+ void set_referer(const std::string& url_spec, uint32_t perm) {
+ grantee = ACLGranteeReferer{url_spec};
permission.set_permissions(perm);
}
@@ -219,31 +282,22 @@ using ACLGrantMap = std::multimap<std::string, ACLGrant>;
class RGWAccessControlList
{
protected:
- CephContext *cct;
/* FIXME: in the feature we should consider switching to uint32_t also
* in data structures. */
std::map<std::string, int> acl_user_map;
std::map<uint32_t, int> acl_group_map;
std::list<ACLReferer> referer_list;
ACLGrantMap grant_map;
- void _add_grant(ACLGrant *grant);
+ // register a grant in the correspoding acl_user/group_map
+ void register_grant(const ACLGrant& grant);
public:
- explicit RGWAccessControlList(CephContext *_cct) : cct(_cct) {}
- RGWAccessControlList() : cct(NULL) {}
-
- void set_ctx(CephContext *ctx) {
- cct = ctx;
- }
-
- virtual ~RGWAccessControlList() {}
-
uint32_t get_perm(const DoutPrefixProvider* dpp,
const rgw::auth::Identity& auth_identity,
- uint32_t perm_mask);
+ uint32_t perm_mask) const;
uint32_t get_group_perm(const DoutPrefixProvider *dpp, ACLGroupTypeEnum group, uint32_t perm_mask) const;
uint32_t get_referer_perm(const DoutPrefixProvider *dpp, uint32_t current_perm,
std::string http_referer,
- uint32_t perm_mask);
+ uint32_t perm_mask) const;
void encode(bufferlist& bl) const {
ENCODE_START(4, 3, bl);
bool maps_initialized = true;
@@ -263,10 +317,9 @@ public:
if (struct_v >= 2) {
decode(acl_group_map, bl);
} else if (!maps_initialized) {
- ACLGrantMap::iterator iter;
- for (iter = grant_map.begin(); iter != grant_map.end(); ++iter) {
- ACLGrant& grant = iter->second;
- _add_grant(&grant);
+ // register everything in the grant_map
+ for (const auto& [id, grant] : grant_map) {
+ register_grant(grant);
}
}
if (struct_v >= 4) {
@@ -277,20 +330,20 @@ public:
void dump(Formatter *f) const;
static void generate_test_instances(std::list<RGWAccessControlList*>& o);
- void add_grant(ACLGrant *grant);
- void remove_canon_user_grant(rgw_user& user_id);
+ void add_grant(const ACLGrant& grant);
+ void remove_canon_user_grant(const rgw_user& user_id);
ACLGrantMap& get_grant_map() { return grant_map; }
const ACLGrantMap& get_grant_map() const { return grant_map; }
- void create_default(const rgw_user& id, std::string name) {
+ void create_default(const rgw_user& id, const std::string& name) {
acl_user_map.clear();
acl_group_map.clear();
referer_list.clear();
ACLGrant grant;
grant.set_canon(id, name, RGW_PERM_FULL_CONTROL);
- add_grant(&grant);
+ add_grant(grant);
}
friend bool operator==(const RGWAccessControlList& lhs, const RGWAccessControlList& rhs);
@@ -298,15 +351,9 @@ public:
};
WRITE_CLASS_ENCODER(RGWAccessControlList)
-class ACLOwner
-{
-protected:
+struct ACLOwner {
rgw_user id;
std::string display_name;
-public:
- ACLOwner() {}
- ACLOwner(const rgw_user& _id) : id(_id) {}
- ~ACLOwner() {}
void encode(bufferlist& bl) const {
ENCODE_START(3, 2, bl);
@@ -327,46 +374,29 @@ public:
void dump(Formatter *f) const;
void decode_json(JSONObj *obj);
static void generate_test_instances(std::list<ACLOwner*>& o);
- void set_id(const rgw_user& _id) { id = _id; }
- void set_name(const std::string& name) { display_name = name; }
-
- rgw_user& get_id() { return id; }
- const rgw_user& get_id() const { return id; }
- std::string& get_display_name() { return display_name; }
- const std::string& get_display_name() const { return display_name; }
- friend bool operator==(const ACLOwner& lhs, const ACLOwner& rhs);
- friend bool operator!=(const ACLOwner& lhs, const ACLOwner& rhs);
+
+ auto operator<=>(const ACLOwner&) const = default;
};
WRITE_CLASS_ENCODER(ACLOwner)
class RGWAccessControlPolicy
{
protected:
- CephContext *cct;
RGWAccessControlList acl;
ACLOwner owner;
public:
- explicit RGWAccessControlPolicy(CephContext *_cct) : cct(_cct), acl(_cct) {}
- RGWAccessControlPolicy() : cct(NULL), acl(NULL) {}
- virtual ~RGWAccessControlPolicy() {}
-
- void set_ctx(CephContext *ctx) {
- cct = ctx;
- acl.set_ctx(ctx);
- }
-
uint32_t get_perm(const DoutPrefixProvider* dpp,
const rgw::auth::Identity& auth_identity,
uint32_t perm_mask,
const char * http_referer,
- bool ignore_public_acls=false);
+ bool ignore_public_acls=false) const;
bool verify_permission(const DoutPrefixProvider* dpp,
const rgw::auth::Identity& auth_identity,
uint32_t user_perm_mask,
uint32_t perm,
const char * http_referer = nullptr,
- bool ignore_public_acls=false);
+ bool ignore_public_acls=false) const;
void encode(bufferlist& bl) const {
ENCODE_START(2, 2, bl);
@@ -388,15 +418,14 @@ public:
DECODE_FINISH(bl);
}
- void set_owner(ACLOwner& o) { owner = o; }
- ACLOwner& get_owner() {
- return owner;
- }
+ void set_owner(const ACLOwner& o) { owner = o; }
+ const ACLOwner& get_owner() const { return owner; }
+ ACLOwner& get_owner() { return owner; }
- void create_default(const rgw_user& id, std::string& name) {
+ void create_default(const rgw_user& id, const std::string& name) {
acl.create_default(id, name);
- owner.set_id(id);
- owner.set_name(name);
+ owner.id = id;
+ owner.display_name = name;
}
RGWAccessControlList& get_acl() {
return acl;
@@ -405,7 +434,6 @@ public:
return acl;
}
- virtual bool compare_group_name(std::string& id, ACLGroupTypeEnum group) { return false; }
bool is_public(const DoutPrefixProvider *dpp) const;
friend bool operator==(const RGWAccessControlPolicy& lhs, const RGWAccessControlPolicy& rhs);