mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-04 21:42:39 +00:00
168 lines
6.2 KiB
C++
168 lines
6.2 KiB
C++
#pragma once
|
|
|
|
#include <base/types.h>
|
|
#include <Common/typeid_cast.h>
|
|
#include <Common/quoteString.h>
|
|
#include <boost/algorithm/string.hpp>
|
|
#include <memory>
|
|
|
|
|
|
namespace DB
|
|
{
|
|
namespace ErrorCodes
|
|
{
|
|
extern const int UNKNOWN_USER;
|
|
extern const int UNKNOWN_ROLE;
|
|
extern const int UNKNOWN_ROW_POLICY;
|
|
extern const int UNKNOWN_QUOTA;
|
|
extern const int THERE_IS_NO_PROFILE;
|
|
extern const int LOGICAL_ERROR;
|
|
}
|
|
|
|
|
|
/// Access entity is a set of data which have a name and a type. Access entity control something related to the access control.
|
|
/// Entities can be stored to a file or another storage, see IAccessStorage.
|
|
struct IAccessEntity
|
|
{
|
|
IAccessEntity() = default;
|
|
IAccessEntity(const IAccessEntity &) = default;
|
|
virtual ~IAccessEntity() = default;
|
|
virtual std::shared_ptr<IAccessEntity> clone() const = 0;
|
|
|
|
enum class Type
|
|
{
|
|
USER,
|
|
ROLE,
|
|
SETTINGS_PROFILE,
|
|
ROW_POLICY,
|
|
QUOTA,
|
|
|
|
MAX,
|
|
};
|
|
|
|
virtual Type getType() const = 0;
|
|
|
|
struct TypeInfo
|
|
{
|
|
const char * const raw_name;
|
|
const char * const plural_raw_name;
|
|
const String name; /// Uppercased with spaces instead of underscores, e.g. "SETTINGS PROFILE".
|
|
const String alias; /// Alias of the keyword or empty string, e.g. "PROFILE".
|
|
const String plural_name; /// Uppercased with spaces plural name, e.g. "SETTINGS PROFILES".
|
|
const String plural_alias; /// Uppercased with spaces plural name alias, e.g. "PROFILES".
|
|
const String name_for_output_with_entity_name; /// Lowercased with spaces instead of underscores, e.g. "settings profile".
|
|
const char unique_char; /// Unique character for this type. E.g. 'P' for SETTINGS_PROFILE.
|
|
const int not_found_error_code;
|
|
|
|
static const TypeInfo & get(Type type_);
|
|
String outputWithEntityName(const String & entity_name) const;
|
|
};
|
|
|
|
const TypeInfo & getTypeInfo() const { return TypeInfo::get(getType()); }
|
|
String outputTypeAndName() const { return getTypeInfo().outputWithEntityName(getName()); }
|
|
|
|
template <typename EntityClassT>
|
|
bool isTypeOf() const { return isTypeOf(EntityClassT::TYPE); }
|
|
bool isTypeOf(Type type) const { return type == getType(); }
|
|
|
|
virtual void setName(const String & name_) { name = name_; }
|
|
const String & getName() const { return name; }
|
|
|
|
friend bool operator ==(const IAccessEntity & lhs, const IAccessEntity & rhs) { return lhs.equal(rhs); }
|
|
friend bool operator !=(const IAccessEntity & lhs, const IAccessEntity & rhs) { return !(lhs == rhs); }
|
|
|
|
struct LessByName
|
|
{
|
|
bool operator()(const IAccessEntity & lhs, const IAccessEntity & rhs) const { return (lhs.getName() < rhs.getName()); }
|
|
bool operator()(const std::shared_ptr<const IAccessEntity> & lhs, const std::shared_ptr<const IAccessEntity> & rhs) const { return operator()(*lhs, *rhs); }
|
|
};
|
|
|
|
struct LessByTypeAndName
|
|
{
|
|
bool operator()(const IAccessEntity & lhs, const IAccessEntity & rhs) const { return (lhs.getType() < rhs.getType()) || ((lhs.getType() == rhs.getType()) && (lhs.getName() < rhs.getName())); }
|
|
bool operator()(const std::shared_ptr<const IAccessEntity> & lhs, const std::shared_ptr<const IAccessEntity> & rhs) const { return operator()(*lhs, *rhs); }
|
|
};
|
|
|
|
protected:
|
|
String name;
|
|
|
|
virtual bool equal(const IAccessEntity & other) const;
|
|
|
|
/// Helper function to define clone() in the derived classes.
|
|
template <typename EntityClassT>
|
|
std::shared_ptr<IAccessEntity> cloneImpl() const
|
|
{
|
|
return std::make_shared<EntityClassT>(typeid_cast<const EntityClassT &>(*this));
|
|
}
|
|
};
|
|
|
|
using AccessEntityPtr = std::shared_ptr<const IAccessEntity>;
|
|
|
|
|
|
inline const IAccessEntity::TypeInfo & IAccessEntity::TypeInfo::get(Type type_)
|
|
{
|
|
static constexpr auto make_info = [](const char * raw_name_, const char * plural_raw_name_, char unique_char_, int not_found_error_code_)
|
|
{
|
|
String init_names[2] = {raw_name_, plural_raw_name_};
|
|
String init_aliases[2];
|
|
for (size_t i = 0; i != std::size(init_names); ++i)
|
|
{
|
|
String & init_name = init_names[i];
|
|
String & init_alias = init_aliases[i];
|
|
boost::to_upper(init_name);
|
|
boost::replace_all(init_name, "_", " ");
|
|
if (auto underscore_pos = init_name.find_first_of(" "); underscore_pos != String::npos)
|
|
init_alias = init_name.substr(underscore_pos + 1);
|
|
}
|
|
String init_name_for_output_with_entity_name = init_names[0];
|
|
boost::to_lower(init_name_for_output_with_entity_name);
|
|
return TypeInfo{raw_name_, plural_raw_name_, std::move(init_names[0]), std::move(init_aliases[0]), std::move(init_names[1]), std::move(init_aliases[1]), std::move(init_name_for_output_with_entity_name), unique_char_, not_found_error_code_};
|
|
};
|
|
|
|
switch (type_)
|
|
{
|
|
case Type::USER:
|
|
{
|
|
static const auto info = make_info("USER", "USERS", 'U', ErrorCodes::UNKNOWN_USER);
|
|
return info;
|
|
}
|
|
case Type::ROLE:
|
|
{
|
|
static const auto info = make_info("ROLE", "ROLES", 'R', ErrorCodes::UNKNOWN_ROLE);
|
|
return info;
|
|
}
|
|
case Type::SETTINGS_PROFILE:
|
|
{
|
|
static const auto info = make_info("SETTINGS_PROFILE", "SETTINGS_PROFILES", 'S', ErrorCodes::THERE_IS_NO_PROFILE);
|
|
return info;
|
|
}
|
|
case Type::ROW_POLICY:
|
|
{
|
|
static const auto info = make_info("ROW_POLICY", "ROW_POLICIES", 'P', ErrorCodes::UNKNOWN_ROW_POLICY);
|
|
return info;
|
|
}
|
|
case Type::QUOTA:
|
|
{
|
|
static const auto info = make_info("QUOTA", "QUOTAS", 'Q', ErrorCodes::UNKNOWN_QUOTA);
|
|
return info;
|
|
}
|
|
case Type::MAX: break;
|
|
}
|
|
throw Exception("Unknown type: " + std::to_string(static_cast<size_t>(type_)), ErrorCodes::LOGICAL_ERROR);
|
|
}
|
|
|
|
inline String IAccessEntity::TypeInfo::outputWithEntityName(const String & entity_name) const
|
|
{
|
|
String msg = name_for_output_with_entity_name;
|
|
msg += " ";
|
|
msg += backQuote(entity_name);
|
|
return msg;
|
|
}
|
|
|
|
inline String toString(IAccessEntity::Type type)
|
|
{
|
|
return IAccessEntity::TypeInfo::get(type).name;
|
|
}
|
|
|
|
}
|