]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/acl: ACLGrant uses variant for grantee types
authorCasey Bodley <cbodley@redhat.com>
Sat, 18 Nov 2023 16:27:50 +0000 (11:27 -0500)
committerCasey Bodley <cbodley@redhat.com>
Thu, 30 Nov 2023 16:25:02 +0000 (11:25 -0500)
use of `ACLGrant::get_id()` was awkward because most grantee types
returned nothing, but emails were returned as `struct rgw_user`. change
the internal representation into a variant, and expose getters for each
grantee type so callers can handle each type specifically. the encoded
format of `ACLGrant` remains unchanged

Signed-off-by: Casey Bodley <cbodley@redhat.com>
doc/radosgw/lua-scripting.rst
src/rgw/driver/rados/rgw_sync_module_es.cc
src/rgw/rgw_acl.cc
src/rgw/rgw_acl.h
src/rgw/rgw_acl_s3.cc
src/rgw/rgw_acl_swift.cc
src/rgw/rgw_acl_types.h
src/rgw/rgw_lua_request.cc
src/rgw/rgw_rest_client.cc
src/test/rgw/test_rgw_lua.cc

index 29cba258efecc87ae92f6b518fc18b20f2924e1d..8f95aea3c14a0bf9d83f4598f9483da92a8e1a90 100644 (file)
@@ -248,15 +248,15 @@ Request Fields
 +----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
 | ``Request.UserAcl.Grants["<name>"].Type``          | integer  | user ACL grant type                                          | no       | no        | no       |
 +----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
-| ``Request.UserAcl.Grants["<name>"].User``          | table    | user ACL grant user                                          | no       | no        | no       |
+| ``Request.UserAcl.Grants["<name>"].User``          | table    | user ACL grant user                                          | no       | no        | yes      |
 +----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
 | ``Request.UserAcl.Grants["<name>"].User.Tenant``   | table    | user ACL grant user tenant                                   | no       | no        | no       |
 +----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
 | ``Request.UserAcl.Grants["<name>"].User.Id``       | table    | user ACL grant user id                                       | no       | no        | no       |
 +----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
-| ``Request.UserAcl.Grants["<name>"].GroupType``     | integer  | user ACL grant group type                                    | no       | no        | no       |
+| ``Request.UserAcl.Grants["<name>"].GroupType``     | integer  | user ACL grant group type                                    | no       | no        | yes      |
 +----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
-| ``Request.UserAcl.Grants["<name>"].Referer``       | string   | user ACL grant referer                                       | no       | no        | no       |
+| ``Request.UserAcl.Grants["<name>"].Referer``       | string   | user ACL grant referer                                       | no       | no        | yes      |
 +----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
 | ``Request.BucketAcl``                              | table    | bucket ACL. See: ``Request.UserAcl``                         | no       | no        | no       |
 +----------------------------------------------------+----------+--------------------------------------------------------------+----------+-----------+----------+
index 1030d9dce351443fcfc3a2ae231c73888a8432d9..e3353dc1fc7c590c0aff96aaf20af9f5c78d2ac9 100644 (file)
@@ -502,14 +502,11 @@ struct es_obj_metadata {
         const RGWAccessControlList& acl = policy.get_acl();
 
         permissions.insert(policy.get_owner().id.to_str());
-        for (auto acliter : acl.get_grant_map()) {
+        for (const auto& acliter : acl.get_grant_map()) {
           const ACLGrant& grant = acliter.second;
-          if (grant.get_type().get_type() == ACL_TYPE_CANON_USER &&
-              ((uint32_t)grant.get_permission().get_permissions() & RGW_PERM_READ) != 0) {
-            rgw_user user;
-            if (grant.get_id(user)) {
-              permissions.insert(user.to_str());
-            }
+          const auto* user = grant.get_user();
+          if (user && (grant.get_permission().get_permissions() & RGW_PERM_READ) != 0) {
+            permissions.insert(user->id.to_str());
           }
         }
       } else if (attr_name == RGW_ATTR_TAGS) {
index 15b2067f2efe32acc38c0104c1732ea3838f1c4d..4369bedfc76b488a9b9e2ad95b76796a1306ce59 100644 (file)
@@ -33,10 +33,7 @@ bool operator!=(const ACLGranteeType& lhs, const ACLGranteeType& rhs) {
 }
 
 bool operator==(const ACLGrant& lhs, const ACLGrant& rhs) {
-  return lhs.type == rhs.type && lhs.id == rhs.id
-      && lhs.email == rhs.email && lhs.permission == rhs.permission
-      && lhs.name == rhs.name && lhs.group == rhs.group
-      && lhs.url_spec == rhs.url_spec;
+  return lhs.grantee == rhs.grantee && lhs.permission == rhs.permission;
 }
 bool operator!=(const ACLGrant& lhs, const ACLGrant& rhs) {
   return !(lhs == rhs);
@@ -73,49 +70,41 @@ bool operator!=(const RGWAccessControlPolicy& lhs,
 void RGWAccessControlList::register_grant(const ACLGrant& grant)
 {
   ACLPermission perm = grant.get_permission();
-  ACLGranteeType type = grant.get_type();
-  switch (type.get_type()) {
-  case ACL_TYPE_REFERER:
-    referer_list.emplace_back(grant.get_referer(), perm.get_permissions());
+
+  if (const auto* user = grant.get_user(); user) {
+    acl_user_map[user->id.to_str()] |= perm.get_permissions();
+  } else if (const auto* email = grant.get_email(); email) {
+    acl_user_map[email->address] |= perm.get_permissions();
+  } else if (const auto* group = grant.get_group(); group) {
+    acl_group_map[group->type] |= perm.get_permissions();
+  } else if (const auto* referer = grant.get_referer(); referer) {
+    referer_list.emplace_back(referer->url_spec, perm.get_permissions());
 
     /* We're specially handling the Swift's .r:* as the S3 API has a similar
      * concept and thus we can have a small portion of compatibility here. */
-     if (grant.get_referer() == RGW_REFERER_WILDCARD) {
+     if (referer->url_spec == RGW_REFERER_WILDCARD) {
        acl_group_map[ACL_GROUP_ALL_USERS] |= perm.get_permissions();
      }
-    break;
-  case ACL_TYPE_GROUP:
-    acl_group_map[grant.get_group()] |= perm.get_permissions();
-    break;
-  default:
-    {
-      rgw_user id;
-      grant.get_id(id);
-      acl_user_map[id.to_str()] |= perm.get_permissions();
-    }
   }
 }
 
 void RGWAccessControlList::add_grant(const ACLGrant& grant)
 {
-  rgw_user id;
-  grant.get_id(id); // note that this will return false for groups, but that's ok, we won't search groups
-  grant_map.emplace(id.to_str(), grant);
+  std::string id;
+  if (const auto* user = grant.get_user(); user) {
+    id = user->id.to_str();
+  } else if (const auto* email = grant.get_email(); email) {
+    id = email->address;
+  } // other types share the empty key in the grant multimap
+  grant_map.emplace(id, grant);
   register_grant(grant);
 }
 
-void RGWAccessControlList::remove_canon_user_grant(rgw_user& user_id)
+void RGWAccessControlList::remove_canon_user_grant(const rgw_user& user_id)
 {
-  auto multi_map_iter = grant_map.find(user_id.to_str());
-  if(multi_map_iter != grant_map.end()) {
-    auto grants = grant_map.equal_range(user_id.to_str());
-    grant_map.erase(grants.first, grants.second);
-  }
-
-  auto map_iter = acl_user_map.find(user_id.to_str());
-  if (map_iter != acl_user_map.end()){
-    acl_user_map.erase(map_iter);
-  }
+  const std::string& key = user_id.to_str();
+  grant_map.erase(key);
+  acl_user_map.erase(key);
 }
 
 uint32_t RGWAccessControlList::get_perm(const DoutPrefixProvider* dpp, 
@@ -277,31 +266,36 @@ void ACLGranteeType::dump(Formatter *f) const
 void ACLGrant::dump(Formatter *f) const
 {
   f->open_object_section("type");
-  type.dump(f);
+  get_type().dump(f);
   f->close_section();
 
-  f->dump_string("id", id.to_str());
-  f->dump_string("email", email);
+  struct dump_visitor {
+    Formatter* f;
 
-  f->open_object_section("permission");
-  permission.dump(f);
-  f->close_section();
+    void operator()(const ACLGranteeCanonicalUser& user) {
+      encode_json("id", user.id, f);
+      encode_json("name", user.name, f);
+    }
+    void operator()(const ACLGranteeEmailUser& email) {
+      encode_json("email", email.address, f);
+    }
+    void operator()(const ACLGranteeGroup& group) {
+      encode_json("group", static_cast<int>(group.type), f);
+    }
+    void operator()(const ACLGranteeUnknown&) {}
+    void operator()(const ACLGranteeReferer& r) {
+      encode_json("url_spec", r.url_spec, f);
+    }
+  };
+  std::visit(dump_visitor{f}, grantee);
 
-  f->dump_string("name", name);
-  f->dump_int("group", (int)group);
-  f->dump_string("url_spec", url_spec);
+  encode_json("permission", permission, f);
 }
 
 void ACLGrant::generate_test_instances(list<ACLGrant*>& o)
 {
-  rgw_user id("rgw");
-  string name, email;
-  name = "Mr. RGW";
-  email = "r@gw";
-
   ACLGrant *g1 = new ACLGrant;
-  g1->set_canon(id, name, RGW_PERM_READ);
-  g1->email = email;
+  g1->set_canon(rgw_user{"rgw"}, "Mr. RGW", RGW_PERM_READ);
   o.push_back(g1);
 
   ACLGrant *g2 = new ACLGrant;
@@ -313,9 +307,7 @@ void ACLGrant::generate_test_instances(list<ACLGrant*>& o)
 
 void ACLGranteeType::generate_test_instances(list<ACLGranteeType*>& o)
 {
-  ACLGranteeType *t = new ACLGranteeType;
-  t->set(ACL_TYPE_CANON_USER);
-  o.push_back(t);
+  o.push_back(new ACLGranteeType(ACL_TYPE_CANON_USER));
   o.push_back(new ACLGranteeType);
 }
 
index 52dfa0b66fda4a8efc4902544091f553ce661fdb..e2887a7049b6e3163315ac61705ea1aee474188d 100644 (file)
@@ -6,6 +6,7 @@
 #include <map>
 #include <string>
 #include <string_view>
+#include <variant>
 #include <include/types.h>
 
 #include <boost/optional.hpp>
 
 #include "rgw_basic_types.h" //includes rgw_acl_types.h
 
-class ACLGrant
-{
-protected:
-  ACLGranteeType type;
+// acl grantee types
+struct ACLGranteeCanonicalUser {
   rgw_user id;
-  std::string email;
-  mutable rgw_user email_id;
-  ACLPermission permission;
   std::string name;
-  ACLGroupTypeEnum group;
+
+  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 void to_xml(const ACLGrant& grant, std::ostream& out);
+  friend auto operator<=>(const ACLGranteeReferer&,
+                          const ACLGranteeReferer&) = default;
+};
+
+class ACLGrant
+{
+protected:
+  // acl grantee variant, where variant index matches ACLGranteeTypeEnum
+  using ACLGrantee = std::variant<
+    ACLGranteeCanonicalUser,
+    ACLGranteeEmailUser,
+    ACLGranteeGroup,
+    ACLGranteeUnknown,
+    ACLGranteeReferer>;
+
+  ACLGrantee grantee;
+  ACLPermission permission;
 
 public:
-  ACLGrant() : group(ACL_GROUP_NONE) {}
-
-  /* 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() const { return type; }
-  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);
   }
@@ -112,20 +180,16 @@ public:
 
   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);
   }
 
@@ -267,7 +331,7 @@ public:
   static void generate_test_instances(std::list<RGWAccessControlList*>& o);
 
   void add_grant(const ACLGrant& grant);
-  void remove_canon_user_grant(rgw_user& user_id);
+  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; }
index f4e4221f2c0b609ab6ba03eccf4d5f4d9a14873d..e45fb552aff601ce63ce39ed2d21bd851f5483d4 100644 (file)
@@ -253,28 +253,22 @@ void to_xml(const ACLGrant& grant, ostream& out)
   if (!(perm.get_permissions() & RGW_PERM_ALL_S3))
     return;
 
-  string uri;
+  const std::string type = ACLGranteeType_S3::to_string(grant.get_type());
 
   out << "<Grant>" <<
-         "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"" << ACLGranteeType_S3::to_string(grant.type) << "\">";
-  switch (grant.type.get_type()) {
-  case ACL_TYPE_CANON_USER:
-    out << "<ID>" << grant.id << "</ID>";
-    if (grant.name.size()) {
-      out << "<DisplayName>" << grant.name << "</DisplayName>";
-    }
-    break;
-  case ACL_TYPE_EMAIL_USER:
-    out << "<EmailAddress>" << grant.email << "</EmailAddress>";
-    break;
-  case ACL_TYPE_GROUP:
-    if (!rgw::s3::acl_group_to_uri(grant.group, uri)) {
-      break;
+         "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"" << type << "\">";
+
+  if (const auto* user = grant.get_user(); user) {
+    out << "<ID>" << user->id << "</ID>";
+    if (user->name.size()) {
+      out << "<DisplayName>" << user->name << "</DisplayName>";
     }
+  } else if (const auto* email = grant.get_email(); email) {
+    out << "<EmailAddress>" << email->address << "</EmailAddress>";
+  } else if (const auto* group = grant.get_group(); group) {
+    std::string uri;
+    rgw::s3::acl_group_to_uri(group->type, uri);
     out << "<URI>" << uri << "</URI>";
-    break;
-  default:
-    break;
   }
   out << "</Grantee>";
   to_xml(perm, out);
index 048f7b4915215c3de06230c17383314d5df7deb6..260f4530d41f77d468beb3186d7284e90975bb05 100644 (file)
@@ -222,16 +222,13 @@ void merge_policy(uint32_t rw_mask, const RGWAccessControlPolicy& src,
   for (const auto &iter: src.get_acl().get_grant_map()) {
     const ACLGrant& grant = iter.second;
     uint32_t perm = grant.get_permission().get_permissions();
-    rgw_user id;
-    if (!grant.get_id(id)) {
-      if (grant.get_group() != ACL_GROUP_ALL_USERS) {
-        if (string url_spec = grant.get_referer(); url_spec.empty()) {
-          continue;
-        }
-        if (perm == 0) {
-          /* We need to carry also negative, HTTP referrer-based ACLs. */
-          perm = SWIFT_PERM_READ;
-        }
+    if (const auto* referer = grant.get_referer(); referer) {
+      if (referer->url_spec.empty()) {
+        continue;
+      }
+      if (perm == 0) {
+        /* We need to carry also negative, HTTP referrer-based ACLs. */
+        perm = SWIFT_PERM_READ;
       }
     }
     if (perm & rw_mask) {
@@ -245,35 +242,37 @@ void format_container_acls(const RGWAccessControlPolicy& policy,
 {
   for (const auto& [k, grant] : policy.get_acl().get_grant_map()) {
     const uint32_t perm = grant.get_permission().get_permissions();
-    rgw_user id;
-    string url_spec;
-    if (!grant.get_id(id)) {
-      if (grant.get_group() == ACL_GROUP_ALL_USERS) {
+    std::string id;
+    std::string url_spec;
+    if (const auto user = grant.get_user(); user) {
+      id = user->id.to_str();
+    } else if (const auto group = grant.get_group(); group) {
+      if (group->type == ACL_GROUP_ALL_USERS) {
         id = SWIFT_GROUP_ALL_USERS;
-      } else {
-        url_spec = grant.get_referer();
-        if (url_spec.empty()) {
-          continue;
-        }
-        id = (perm != 0) ? ".r:" + url_spec : ".r:-" + url_spec;
       }
+    } else if (const auto referer = grant.get_referer(); referer) {
+      url_spec = referer->url_spec;
+      if (url_spec.empty()) {
+        continue;
+      }
+      id = (perm != 0) ? ".r:" + url_spec : ".r:-" + url_spec;
     }
     if (perm & SWIFT_PERM_READ) {
       if (!read.empty()) {
         read.append(",");
       }
-      read.append(id.to_str());
+      read.append(id);
     } else if (perm & SWIFT_PERM_WRITE) {
       if (!write.empty()) {
         write.append(",");
       }
-      write.append(id.to_str());
+      write.append(id);
     } else if (perm == 0 && !url_spec.empty()) {
       /* only X-Container-Read headers support referers */
       if (!read.empty()) {
         read.append(",");
       }
-      read.append(id.to_str());
+      read.append(id);
     }
   }
 }
@@ -338,22 +337,27 @@ auto format_account_acl(const RGWAccessControlPolicy& policy)
     const ACLGrant& grant = item.second;
     const uint32_t perm = grant.get_permission().get_permissions();
 
-    rgw_user id;
-    if (!grant.get_id(id)) {
-      if (grant.get_group() != ACL_GROUP_ALL_USERS) {
+    std::string id;
+    if (const auto user = grant.get_user(); user) {
+      if (owner.id == user->id) {
+        continue;
+      }
+      id = user->id.to_str();
+    } else if (const auto group = grant.get_group(); group) {
+      if (group->type != ACL_GROUP_ALL_USERS) {
         continue;
       }
       id = SWIFT_GROUP_ALL_USERS;
-    } else if (owner.id == id) {
+    } else {
       continue;
     }
 
     if (SWIFT_PERM_ADMIN == (perm & SWIFT_PERM_ADMIN)) {
-      admin.insert(admin.end(), id.to_str());
+      admin.insert(admin.end(), id);
     } else if (SWIFT_PERM_RWRT == (perm & SWIFT_PERM_RWRT)) {
-      readwrite.insert(readwrite.end(), id.to_str());
+      readwrite.insert(readwrite.end(), id);
     } else if (SWIFT_PERM_READ == (perm & SWIFT_PERM_READ)) {
-      readonly.insert(readonly.end(), id.to_str());
+      readonly.insert(readonly.end(), id);
     } else {
       // FIXME: print a warning
     }
index a257bb4c9e6d60ea76b16aa4e7bf5c80a567e6fe..11637dd360deeeedc9e49bb9fc1a6919ebd6b807 100644 (file)
@@ -181,12 +181,15 @@ class ACLGranteeType
 protected:
   __u32 type;
 public:
-  ACLGranteeType() : type(ACL_TYPE_UNKNOWN) {}
+  ACLGranteeType(ACLGranteeTypeEnum t = ACL_TYPE_UNKNOWN) : type(t) {}
   virtual ~ACLGranteeType() {}
-//  virtual const char *to_string() = 0;
+
   ACLGranteeTypeEnum get_type() const { return (ACLGranteeTypeEnum)type; }
+  operator ACLGranteeTypeEnum() const { return get_type(); }
+
   void set(ACLGranteeTypeEnum t) { type = t; }
-//  virtual void set(const char *s) = 0;
+  ACLGranteeType& operator=(ACLGranteeTypeEnum t) { set(t); return *this; }
+
   void encode(bufferlist& bl) const {
     ENCODE_START(2, 2, bl);
     encode(type, bl);
index 1fa44a0329ec1c70549c916143cf3dce417eddab..a36aad666f460eaa70e51209b52a6f22a9cb6084 100644 (file)
@@ -364,19 +364,26 @@ struct GrantMetaTable : public EmptyMetaTable {
     if (strcasecmp(index, "Type") == 0) {
       lua_pushinteger(L, grant->get_type().get_type());
     } else if (strcasecmp(index, "User") == 0) {
-      const auto id_ptr = grant->get_id();
-      if (id_ptr) {
+      if (const auto user = grant->get_user(); user) {
         create_metatable<UserMetaTable>(L, name, index, false, 
-            const_cast<rgw_user*>(id_ptr));
+            const_cast<rgw_user*>(&user->id));
       } else {
         lua_pushnil(L);
       }
     } else if (strcasecmp(index, "Permission") == 0) {
       lua_pushinteger(L, grant->get_permission().get_permissions());
     } else if (strcasecmp(index, "GroupType") == 0) {
-      lua_pushinteger(L, grant->get_group());
+      if (const auto group = grant->get_group(); group) {
+        lua_pushinteger(L, group->type);
+      } else {
+        lua_pushnil(L);
+      }
     } else if (strcasecmp(index, "Referer") == 0) {
-      pushstring(L, grant->get_referer());
+      if (const auto referer = grant->get_referer(); referer) {
+        pushstring(L, referer->url_spec);
+      } else {
+        lua_pushnil(L);
+      }
     } else {
       return error_unknown_field(L, index, name);
     }
index 71ead6a8b8923d84fbee52d1b2934ad7043c0f61..b1ee1a9340eb81b943d91d68c15ab654b6ef8eec 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "rgw_common.h"
 #include "rgw_rest_client.h"
+#include "rgw_acl_s3.h"
 #include "rgw_auth_s3.h"
 #include "rgw_http_errors.h"
 
@@ -504,21 +505,15 @@ static void grants_by_type_add_one_grant(map<int, string>& grants_by_type, int p
   if (!s.empty())
     s.append(", ");
 
-  string id_type_str;
-  ACLGranteeType type = grant.get_type();
-  switch (type.get_type()) {
-    case ACL_TYPE_GROUP:
-      id_type_str = "uri";
-      break;
-    case ACL_TYPE_EMAIL_USER:
-      id_type_str = "emailAddress";
-      break;
-    default:
-      id_type_str = "id";
-  }
-  rgw_user id;
-  grant.get_id(id);
-  s.append(id_type_str + "=\"" + id.to_str() + "\"");
+  if (const auto user = grant.get_user(); user) {
+    s.append("id=\"" + user->id.to_str() + "\"");
+  } else if (const auto email = grant.get_email(); email) {
+    s.append("emailAddress=\"" + email->address + "\"");
+  } else if (const auto group = grant.get_group(); group) {
+    std::string uri;
+    rgw::s3::acl_group_to_uri(group->type, uri);
+    s.append("uri=\"" + uri + "\"");
+  }
 }
 
 struct grant_type_to_header {
index 09f708309e5083af3913b18db2bdb0f9ec755d7a..0485e71ede37694fc7bff9f8f0f01bef4950b310 100644 (file)
@@ -635,8 +635,12 @@ TEST(TestRGWLua, Acl)
     function print_grant(k, g)
       print("Grant Key: " .. tostring(k))
       print("Grant Type: " .. g.Type)
-      print("Grant Group Type: " .. g.GroupType)
-      print("Grant Referer: " .. g.Referer)
+      if (g.GroupType) then
+        print("Grant Group Type: " .. g.GroupType)
+      end
+      if (g.Referer) then
+        print("Grant Referer: " .. g.Referer)
+      end
       if (g.User) then
         print("Grant User.Tenant: " .. g.User.Tenant)
         print("Grant User.Id: " .. g.User.Id)
@@ -666,8 +670,7 @@ TEST(TestRGWLua, Acl)
     .id = rgw_user("jack", "black"),
     .display_name = "jack black"
   };
-  s.user_acl.reset(new RGWAccessControlPolicy(g_cct));
-  s.user_acl->set_owner(owner);
+  s.user_acl.set_owner(owner);
   ACLGrant grant1, grant2, grant3, grant4, grant5, grant6_1, grant6_2;
   grant1.set_canon(rgw_user("jane", "doe"), "her grant", 1);
   grant2.set_group(ACL_GROUP_ALL_USERS ,2);
@@ -676,13 +679,13 @@ TEST(TestRGWLua, Acl)
   grant5.set_group(ACL_GROUP_AUTHENTICATED_USERS, 5);
   grant6_1.set_canon(rgw_user("kill", "bill"), "his grant", 6);
   grant6_2.set_canon(rgw_user("kill", "bill"), "her grant", 7);
-  s.user_acl->get_acl().add_grant(&grant1);
-  s.user_acl->get_acl().add_grant(&grant2);
-  s.user_acl->get_acl().add_grant(&grant3);
-  s.user_acl->get_acl().add_grant(&grant4);
-  s.user_acl->get_acl().add_grant(&grant5);
-  s.user_acl->get_acl().add_grant(&grant6_1);
-  s.user_acl->get_acl().add_grant(&grant6_2);
+  s.user_acl.get_acl().add_grant(grant1);
+  s.user_acl.get_acl().add_grant(grant2);
+  s.user_acl.get_acl().add_grant(grant3);
+  s.user_acl.get_acl().add_grant(grant4);
+  s.user_acl.get_acl().add_grant(grant5);
+  s.user_acl.get_acl().add_grant(grant6_1);
+  s.user_acl.get_acl().add_grant(grant6_2);
   const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script);
   ASSERT_EQ(rc, 0);
 }
@@ -733,15 +736,12 @@ TEST(TestRGWLua, UseFunction)
   DEFINE_REQ_STATE;
   s.owner.display_name = "user two";
   s.owner.id = rgw_user("tenant2", "user2");
-  s.user_acl.reset(new RGWAccessControlPolicy());
-  s.user_acl->get_owner().display_name = "user three";
-  s.user_acl->get_owner().id = rgw_user("tenant3", "user3");
-  s.bucket_acl.reset(new RGWAccessControlPolicy());
-  s.bucket_acl->get_owner().display_name = "user four";
-  s.bucket_acl->get_owner().id = rgw_user("tenant4", "user4");
-  s.object_acl.reset(new RGWAccessControlPolicy());
-  s.object_acl->get_owner().display_name = "user five";
-  s.object_acl->get_owner().id = rgw_user("tenant5", "user5");
+  s.user_acl.get_owner().display_name = "user three";
+  s.user_acl.get_owner().id = rgw_user("tenant3", "user3");
+  s.bucket_acl.get_owner().display_name = "user four";
+  s.bucket_acl.get_owner().id = rgw_user("tenant4", "user4");
+  s.object_acl.get_owner().display_name = "user five";
+  s.object_acl.get_owner().id = rgw_user("tenant5", "user5");
 
   const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script);
   ASSERT_EQ(rc, 0);