]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: implement rgw::auth::LocalApplier.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Mon, 12 Dec 2016 11:25:06 +0000 (12:25 +0100)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Fri, 24 Mar 2017 15:54:32 +0000 (16:54 +0100)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_auth.cc
src/rgw/rgw_auth.h

index 8b189d13aff2d47199958dc09254ee11d3f4b185..f60cb95771536262e9f8cf56d8a22886da68994b 100644 (file)
@@ -684,3 +684,57 @@ void rgw::auth::RemoteApplier::load_acct_info(RGWUserInfo& user_info) const
 
   /* Succeeded if we are here (create_account() hasn't throwed). */
 }
+
+
+/* rgw::auth::LocalApplier */
+/* static declaration */
+const std::string rgw::auth::LocalApplier::NO_SUBUSER;
+
+uint32_t rgw::auth::LocalApplier::get_perms_from_aclspec(const aclspec_t& aclspec) const
+{
+  return rgw_perms_from_aclspec_default_strategy(user_info.user_id, aclspec);
+}
+
+bool rgw::auth::LocalApplier::is_admin_of(const rgw_user& uid) const
+{
+  return user_info.admin || user_info.system;
+}
+
+bool rgw::auth::LocalApplier::is_owner_of(const rgw_user& uid) const
+{
+  return uid == user_info.user_id;
+}
+
+void rgw::auth::LocalApplier::to_str(std::ostream& out) const
+{
+  out << "rgw::auth::LocalApplier(acct_user=" << user_info.user_id
+      << ", acct_name=" << user_info.display_name
+      << ", subuser=" << subuser
+      << ", perm_mask=" << get_perm_mask()
+      << ", is_admin=" << user_info.admin << ")";
+}
+
+uint32_t rgw::auth::LocalApplier::get_perm_mask(const std::string& subuser_name,
+                                                const RGWUserInfo &uinfo) const
+{
+  if (! subuser_name.empty() && subuser_name != NO_SUBUSER) {
+    const auto iter = uinfo.subusers.find(subuser_name);
+
+    if (iter != std::end(uinfo.subusers)) {
+      return iter->second.perm_mask;
+    } else {
+      /* Subuser specified but not found. */
+      return RGW_PERM_NONE;
+    }
+  } else {
+    /* Due to backward compatibility. */
+    return RGW_PERM_FULL_CONTROL;
+  }
+}
+
+void rgw::auth::LocalApplier::load_acct_info(RGWUserInfo& user_info) const /* out */
+{
+  /* Load the account that belongs to the authenticated identity. An extra call
+   * to RADOS may be safely skipped in this case. */
+  user_info = this->user_info;
+}
index f24eeb09bd8a6e3299ed28309d5d676ed350dc03..cf1a2343adb9b3cc63eb205b2cf8e8eb0b598b72 100644 (file)
@@ -647,6 +647,49 @@ public:
   };
 };
 
+
+/* rgw::auth::LocalApplier targets those auth engines that base on the data
+ * enclosed in the RGWUserInfo control structure. As a side effect of doing
+ * the authentication process, they must have it loaded. Leveraging this is
+ * a way to avoid unnecessary calls to underlying RADOS store. */
+class LocalApplier : public IdentityApplier {
+  using aclspec_t = RGWIdentityApplier::aclspec_t;
+
+protected:
+  const RGWUserInfo user_info;
+  const std::string subuser;
+
+  uint32_t get_perm_mask(const std::string& subuser_name,
+                         const RGWUserInfo &uinfo) const;
+
+public:
+  static const std::string NO_SUBUSER;
+
+  LocalApplier(CephContext* const cct,
+               const RGWUserInfo& user_info,
+               std::string subuser)
+    : user_info(user_info),
+      subuser(std::move(subuser)) {
+  }
+
+
+  uint32_t get_perms_from_aclspec(const aclspec_t& aclspec) const override;
+  bool is_admin_of(const rgw_user& uid) const override;
+  bool is_owner_of(const rgw_user& uid) const override;
+  uint32_t get_perm_mask() const override {
+    return get_perm_mask(subuser, user_info);
+  }
+  void to_str(std::ostream& out) const override;
+  void load_acct_info(RGWUserInfo& user_info) const override; /* out */
+
+  struct Factory {
+    virtual ~Factory() {}
+    virtual aplptr_t create_apl_local(CephContext* const cct,
+                                      const RGWUserInfo& user_info,
+                                      const std::string& subuser) const = 0;
+    };
+};
+
 } /* namespace auth */
 } /* namespace rgw */