return id == acct_id;
}
+ bool is_identity(const idset_t& ids) const override {
+ for (auto& p : ids) {
+ if (p.is_wildcard()) {
+ return true;
+ } else if (p.is_tenant() && p.get_tenant() == id.tenant) {
+ return true;
+ } else if (p.is_user() &&
+ (p.get_tenant() == id.tenant) &&
+ (p.get_id() == id.id)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
uint32_t get_perm_mask() const override {
return perm_mask;
}
return info.acct_user == uid;
}
+bool rgw::auth::RemoteApplier::is_identity(const idset_t& ids) const {
+ for (auto& id : ids) {
+ if (id.is_wildcard()) {
+ return true;
+
+ // We also need to cover cases where rgw_keystone_implicit_tenants
+ // was enabled. */
+ } else if (id.is_tenant() &&
+ (info.acct_user.tenant.empty() ?
+ info.acct_user.id :
+ info.acct_user.tenant) == id.get_tenant()) {
+ return true;
+ } else if (id.is_user() &&
+ info.acct_user.id == id.get_id() &&
+ (info.acct_user.tenant.empty() ?
+ info.acct_user.id :
+ info.acct_user.tenant) == id.get_tenant()) {
+ return true;
+ }
+ }
+ return false;
+}
+
void rgw::auth::RemoteApplier::to_str(std::ostream& out) const
{
out << "rgw::auth::RemoteApplier(acct_user=" << info.acct_user
return uid == user_info.user_id;
}
-void rgw::auth::LocalApplier::to_str(std::ostream& out) const
-{
+bool rgw::auth::LocalApplier::is_identity(const idset_t& ids) const {
+ for (auto& id : ids) {
+ if (id.is_wildcard()) {
+ return true;
+ } else if (id.is_tenant() &&
+ id.get_tenant() == user_info.user_id.tenant) {
+ return true;
+ } else if (id.is_user() &&
+ (id.get_tenant() == user_info.user_id.tenant) &&
+ (id.get_id() == user_info.user_id.id)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+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
#define RGW_USER_ANON_ID "anonymous"
-
namespace rgw {
namespace auth {
class Identity {
public:
typedef std::map<std::string, int> aclspec_t;
+ using idset_t = boost::container::flat_set<Principal>;
virtual ~Identity() = default;
}
virtual void to_str(std::ostream& out) const = 0;
+
+ /* Verify whether a given identity corresponds to an identity in the
+ provided set */
+ virtual bool is_identity(const idset_t& ids) const = 0;
};
inline std::ostream& operator<<(std::ostream& out,
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;
+ bool is_identity(const idset_t& ids) const override;
+
uint32_t get_perm_mask() const override { return info.perm_mask; }
void to_str(std::ostream& out) const override;
void load_acct_info(RGWUserInfo& user_info) const override; /* out */
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;
+ bool is_identity(const idset_t& ids) const override;
uint32_t get_perm_mask() const override {
return get_perm_mask(subuser, user_info);
}
return get_decoratee().get_perm_mask();
}
+ bool is_identity(
+ const boost::container::flat_set<Principal>& ids) const override {
+ return get_decoratee().is_identity(ids);
+ }
+
void to_str(std::ostream& out) const override {
get_decoratee().to_str(out);
}
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
#ifndef CEPH_RGW_BASIC_TYPES_H
#define CEPH_RGW_BASIC_TYPES_H
: tenant(tenant),
id(id) {
}
+ rgw_user(std::string&& tenant, std::string&& id)
+ : tenant(std::move(tenant)),
+ id(std::move(id)) {
+ }
void encode(bufferlist& bl) const {
ENCODE_START(1, 1, bl);
};
WRITE_CLASS_ENCODER(rgw_user)
+// Represents an identity. This is more wide-ranging than a
+// 'User'. Its purposes is to be matched against by an
+// IdentityApplier. The internal representation will doubtless change as
+// more types are added. We may want to expose the type enum and make
+// the member public so people can switch/case on it.
+
+namespace rgw {
+namespace auth {
+class Principal {
+ enum types { User, Role, Tenant, Wildcard };
+ types t;
+ rgw_user u;
+
+ Principal(types t)
+ : t(t) {}
+
+ Principal(types t, std::string&& n, std::string i)
+ : t(t), u(std::move(n), std::move(i)) {}
+
+public:
+
+ static Principal wildcard() {
+ return Principal(Wildcard);
+ }
+
+ static Principal user(std::string&& t, std::string&& u) {
+ return Principal(User, std::move(t), std::move(u));
+ }
+
+ static Principal role(std::string&& t, std::string&& u) {
+ return Principal(Role, std::move(t), std::move(u));
+ }
+
+ static Principal tenant(std::string&& t) {
+ return Principal(Tenant, std::move(t), {});
+ }
+
+ bool is_wildcard() const {
+ return t == Wildcard;
+ }
+
+ bool is_user() const {
+ return t == User;
+ }
+
+ bool is_role() const {
+ return t == Role;
+ }
+
+ bool is_tenant() const {
+ return t == Tenant;
+ }
+
+ const std::string& get_tenant() const {
+ ceph_assert(t != Wildcard);
+ return u.tenant;
+ }
+
+ const std::string& get_id() const {
+ ceph_assert(t != Wildcard && t != Tenant);
+ return u.id;
+ }
+
+ bool operator ==(const Principal& o) const {
+ return (t == o.t) && (u == o.u);
+ }
+
+ bool operator <(const Principal& o) const {
+ return (t < o.t) || ((t == o.t) && (u < o.u));
+ }
+};
+}
+}
class JSONObj;