mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 16:50:48 +00:00
Write dictionary permission on user instead of dictionary configuration
This commit is contained in:
parent
d15d5827ef
commit
bb088fbf65
@ -62,13 +62,11 @@ inline size_t CacheDictionary::getCellIdx(const Key id) const
|
||||
|
||||
CacheDictionary::CacheDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
const size_t size_)
|
||||
: name{name_}
|
||||
, allowed_databases{allowed_databases_}
|
||||
, dict_struct(dict_struct_)
|
||||
, source_ptr{std::move(source_ptr_)}
|
||||
, dict_lifetime(dict_lifetime_)
|
||||
@ -587,7 +585,6 @@ std::exception_ptr CacheDictionary::getLastException() const
|
||||
void registerDictionaryCache(DictionaryFactory & factory)
|
||||
{
|
||||
auto create_layout = [=](const std::string & name,
|
||||
const std::unordered_set<std::string> & allowed_databases,
|
||||
const DictionaryStructure & dict_struct,
|
||||
const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_prefix,
|
||||
@ -612,7 +609,7 @@ void registerDictionaryCache(DictionaryFactory & factory)
|
||||
ErrorCodes::BAD_ARGUMENTS};
|
||||
|
||||
const DictionaryLifetime dict_lifetime{config, config_prefix + ".lifetime"};
|
||||
return std::make_unique<CacheDictionary>(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, size);
|
||||
return std::make_unique<CacheDictionary>(name, dict_struct, std::move(source_ptr), dict_lifetime, size);
|
||||
};
|
||||
factory.registerLayout("cache", create_layout);
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ class CacheDictionary final : public IDictionary
|
||||
public:
|
||||
CacheDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
@ -34,8 +33,6 @@ public:
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
const std::unordered_set<std::string> & getAllowedDatabases() const override { return allowed_databases; }
|
||||
|
||||
std::string getTypeName() const override { return "Cache"; }
|
||||
|
||||
size_t getBytesAllocated() const override { return bytes_allocated + (string_arena ? string_arena->size() : 0); }
|
||||
@ -55,7 +52,7 @@ public:
|
||||
|
||||
std::shared_ptr<const IExternalLoadable> clone() const override
|
||||
{
|
||||
return std::make_shared<CacheDictionary>(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, size);
|
||||
return std::make_shared<CacheDictionary>(name, dict_struct, source_ptr->clone(), dict_lifetime, size);
|
||||
}
|
||||
|
||||
const IDictionarySource * getSource() const override { return source_ptr.get(); }
|
||||
@ -258,7 +255,6 @@ private:
|
||||
void isInImpl(const PaddedPODArray<Key> & child_ids, const AncestorType & ancestor_ids, PaddedPODArray<UInt8> & out) const;
|
||||
|
||||
const std::string name;
|
||||
const std::unordered_set<std::string> allowed_databases;
|
||||
const DictionaryStructure dict_struct;
|
||||
mutable DictionarySourcePtr source_ptr;
|
||||
const DictionaryLifetime dict_lifetime;
|
||||
|
@ -52,13 +52,11 @@ inline UInt64 ComplexKeyCacheDictionary::getCellIdx(const StringRef key) const
|
||||
|
||||
ComplexKeyCacheDictionary::ComplexKeyCacheDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
const size_t size_)
|
||||
: name{name_}
|
||||
, allowed_databases{allowed_databases_}
|
||||
, dict_struct(dict_struct_)
|
||||
, source_ptr{std::move(source_ptr_)}
|
||||
, dict_lifetime(dict_lifetime_)
|
||||
@ -397,7 +395,6 @@ BlockInputStreamPtr ComplexKeyCacheDictionary::getBlockInputStream(const Names &
|
||||
void registerDictionaryComplexKeyCache(DictionaryFactory & factory)
|
||||
{
|
||||
auto create_layout = [=](const std::string & name,
|
||||
const std::unordered_set<std::string> & allowed_databases,
|
||||
const DictionaryStructure & dict_struct,
|
||||
const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_prefix,
|
||||
@ -416,7 +413,7 @@ void registerDictionaryComplexKeyCache(DictionaryFactory & factory)
|
||||
ErrorCodes::BAD_ARGUMENTS};
|
||||
|
||||
const DictionaryLifetime dict_lifetime{config, config_prefix + ".lifetime"};
|
||||
return std::make_unique<ComplexKeyCacheDictionary>(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, size);
|
||||
return std::make_unique<ComplexKeyCacheDictionary>(name, dict_struct, std::move(source_ptr), dict_lifetime, size);
|
||||
};
|
||||
factory.registerLayout("complex_key_cache", create_layout);
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ class ComplexKeyCacheDictionary final : public IDictionaryBase
|
||||
public:
|
||||
ComplexKeyCacheDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
@ -53,8 +52,6 @@ public:
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
const std::unordered_set<std::string> & getAllowedDatabases() const override { return allowed_databases; }
|
||||
|
||||
std::string getTypeName() const override { return "ComplexKeyCache"; }
|
||||
|
||||
size_t getBytesAllocated() const override
|
||||
@ -78,7 +75,7 @@ public:
|
||||
|
||||
std::shared_ptr<const IExternalLoadable> clone() const override
|
||||
{
|
||||
return std::make_shared<ComplexKeyCacheDictionary>(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, size);
|
||||
return std::make_shared<ComplexKeyCacheDictionary>(name, dict_struct, source_ptr->clone(), dict_lifetime, size);
|
||||
}
|
||||
|
||||
const IDictionarySource * getSource() const override { return source_ptr.get(); }
|
||||
@ -672,7 +669,6 @@ private:
|
||||
bool isEmptyCell(const UInt64 idx) const;
|
||||
|
||||
const std::string name;
|
||||
const std::unordered_set<std::string> allowed_databases;
|
||||
const DictionaryStructure dict_struct;
|
||||
const DictionarySourcePtr source_ptr;
|
||||
const DictionaryLifetime dict_lifetime;
|
||||
|
@ -16,14 +16,12 @@ namespace ErrorCodes
|
||||
|
||||
ComplexKeyHashedDictionary::ComplexKeyHashedDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
bool require_nonempty_,
|
||||
BlockPtr saved_block_)
|
||||
: name{name_}
|
||||
, allowed_databases{allowed_databases_}
|
||||
, dict_struct(dict_struct_)
|
||||
, source_ptr{std::move(source_ptr_)}
|
||||
, dict_lifetime(dict_lifetime_)
|
||||
@ -745,7 +743,6 @@ BlockInputStreamPtr ComplexKeyHashedDictionary::getBlockInputStream(const Names
|
||||
void registerDictionaryComplexKeyHashed(DictionaryFactory & factory)
|
||||
{
|
||||
auto create_layout = [=](const std::string & name,
|
||||
const std::unordered_set<std::string> & allowed_databases,
|
||||
const DictionaryStructure & dict_struct,
|
||||
const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_prefix,
|
||||
@ -756,7 +753,7 @@ void registerDictionaryComplexKeyHashed(DictionaryFactory & factory)
|
||||
|
||||
const DictionaryLifetime dict_lifetime{config, config_prefix + ".lifetime"};
|
||||
const bool require_nonempty = config.getBool(config_prefix + ".require_nonempty", false);
|
||||
return std::make_unique<ComplexKeyHashedDictionary>(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty);
|
||||
return std::make_unique<ComplexKeyHashedDictionary>(name, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty);
|
||||
};
|
||||
factory.registerLayout("complex_key_hashed", create_layout);
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ class ComplexKeyHashedDictionary final : public IDictionaryBase
|
||||
public:
|
||||
ComplexKeyHashedDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
@ -35,8 +34,6 @@ public:
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
const std::unordered_set<std::string> & getAllowedDatabases() const override { return allowed_databases; }
|
||||
|
||||
std::string getTypeName() const override { return "ComplexKeyHashed"; }
|
||||
|
||||
size_t getBytesAllocated() const override { return bytes_allocated; }
|
||||
@ -53,7 +50,7 @@ public:
|
||||
|
||||
std::shared_ptr<const IExternalLoadable> clone() const override
|
||||
{
|
||||
return std::make_shared<ComplexKeyHashedDictionary>(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty, saved_block);
|
||||
return std::make_shared<ComplexKeyHashedDictionary>(name, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty, saved_block);
|
||||
}
|
||||
|
||||
const IDictionarySource * getSource() const override { return source_ptr.get(); }
|
||||
@ -239,7 +236,6 @@ private:
|
||||
std::vector<StringRef> getKeys(const Attribute & attribute) const;
|
||||
|
||||
const std::string name;
|
||||
const std::unordered_set<std::string> allowed_databases;
|
||||
const DictionaryStructure dict_struct;
|
||||
const DictionarySourcePtr source_ptr;
|
||||
const DictionaryLifetime dict_lifetime;
|
||||
|
@ -33,23 +33,6 @@ DictionaryPtr DictionaryFactory::create(
|
||||
|
||||
auto source_ptr = DictionarySourceFactory::instance().create(name, config, config_prefix + ".source", dict_struct, context);
|
||||
|
||||
/// Fill list of allowed databases.
|
||||
std::unordered_set<std::string> allowed_databases;
|
||||
|
||||
const auto config_sub_elem = config_prefix + ".allow_databases";
|
||||
if (config.has(config_sub_elem))
|
||||
{
|
||||
Poco::Util::AbstractConfiguration::Keys config_keys;
|
||||
config.keys(config_sub_elem, config_keys);
|
||||
|
||||
allowed_databases.reserve(config_keys.size());
|
||||
for (const auto & key : config_keys)
|
||||
{
|
||||
const auto database_name = config.getString(config_sub_elem + "." + key);
|
||||
allowed_databases.insert(database_name);
|
||||
}
|
||||
}
|
||||
|
||||
const auto & layout_type = keys.front();
|
||||
|
||||
{
|
||||
@ -57,7 +40,7 @@ DictionaryPtr DictionaryFactory::create(
|
||||
if (found != registered_layouts.end())
|
||||
{
|
||||
const auto & create_layout = found->second;
|
||||
return create_layout(name, allowed_databases, dict_struct, config, config_prefix, std::move(source_ptr));
|
||||
return create_layout(name, dict_struct, config, config_prefix, std::move(source_ptr));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,6 @@ public:
|
||||
|
||||
using Creator = std::function<DictionaryPtr(
|
||||
const std::string & name,
|
||||
const std::unordered_set<std::string> & allowed_databases,
|
||||
const DictionaryStructure & dict_struct,
|
||||
const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_prefix,
|
||||
|
@ -22,14 +22,12 @@ static const auto max_array_size = 500000;
|
||||
|
||||
FlatDictionary::FlatDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
bool require_nonempty_,
|
||||
BlockPtr saved_block_)
|
||||
: name{name_}
|
||||
, allowed_databases{allowed_databases_}
|
||||
, dict_struct(dict_struct_)
|
||||
, source_ptr{std::move(source_ptr_)}
|
||||
, dict_lifetime(dict_lifetime_)
|
||||
@ -709,7 +707,6 @@ BlockInputStreamPtr FlatDictionary::getBlockInputStream(const Names & column_nam
|
||||
void registerDictionaryFlat(DictionaryFactory & factory)
|
||||
{
|
||||
auto create_layout = [=](const std::string & name,
|
||||
const std::unordered_set<std::string> & allowed_databases,
|
||||
const DictionaryStructure & dict_struct,
|
||||
const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_prefix,
|
||||
@ -725,7 +722,7 @@ void registerDictionaryFlat(DictionaryFactory & factory)
|
||||
ErrorCodes::BAD_ARGUMENTS};
|
||||
const DictionaryLifetime dict_lifetime{config, config_prefix + ".lifetime"};
|
||||
const bool require_nonempty = config.getBool(config_prefix + ".require_nonempty", false);
|
||||
return std::make_unique<FlatDictionary>(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty);
|
||||
return std::make_unique<FlatDictionary>(name, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty);
|
||||
};
|
||||
factory.registerLayout("flat", create_layout);
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ class FlatDictionary final : public IDictionary
|
||||
public:
|
||||
FlatDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
@ -32,8 +31,6 @@ public:
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
const std::unordered_set<std::string> & getAllowedDatabases() const override { return allowed_databases; }
|
||||
|
||||
std::string getTypeName() const override { return "Flat"; }
|
||||
|
||||
size_t getBytesAllocated() const override { return bytes_allocated; }
|
||||
@ -50,7 +47,7 @@ public:
|
||||
|
||||
std::shared_ptr<const IExternalLoadable> clone() const override
|
||||
{
|
||||
return std::make_shared<FlatDictionary>(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty, saved_block);
|
||||
return std::make_shared<FlatDictionary>(name, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty, saved_block);
|
||||
}
|
||||
|
||||
const IDictionarySource * getSource() const override { return source_ptr.get(); }
|
||||
@ -228,7 +225,6 @@ private:
|
||||
PaddedPODArray<Key> getIds() const;
|
||||
|
||||
const std::string name;
|
||||
const std::unordered_set<std::string> allowed_databases;
|
||||
const DictionaryStructure dict_struct;
|
||||
const DictionarySourcePtr source_ptr;
|
||||
const DictionaryLifetime dict_lifetime;
|
||||
|
@ -17,14 +17,12 @@ namespace ErrorCodes
|
||||
|
||||
HashedDictionary::HashedDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
bool require_nonempty_,
|
||||
BlockPtr saved_block_)
|
||||
: name{name_}
|
||||
, allowed_databases{allowed_databases_}
|
||||
, dict_struct(dict_struct_)
|
||||
, source_ptr{std::move(source_ptr_)}
|
||||
, dict_lifetime(dict_lifetime_)
|
||||
@ -701,7 +699,6 @@ BlockInputStreamPtr HashedDictionary::getBlockInputStream(const Names & column_n
|
||||
void registerDictionaryHashed(DictionaryFactory & factory)
|
||||
{
|
||||
auto create_layout = [=](const std::string & name,
|
||||
const std::unordered_set<std::string> & allowed_databases,
|
||||
const DictionaryStructure & dict_struct,
|
||||
const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_prefix,
|
||||
@ -717,7 +714,7 @@ void registerDictionaryHashed(DictionaryFactory & factory)
|
||||
ErrorCodes::BAD_ARGUMENTS};
|
||||
const DictionaryLifetime dict_lifetime{config, config_prefix + ".lifetime"};
|
||||
const bool require_nonempty = config.getBool(config_prefix + ".require_nonempty", false);
|
||||
return std::make_unique<HashedDictionary>(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty);
|
||||
return std::make_unique<HashedDictionary>(name, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty);
|
||||
};
|
||||
factory.registerLayout("hashed", create_layout);
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ class HashedDictionary final : public IDictionary
|
||||
public:
|
||||
HashedDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
@ -31,8 +30,6 @@ public:
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
const std::unordered_set<std::string> & getAllowedDatabases() const override { return allowed_databases; }
|
||||
|
||||
std::string getTypeName() const override { return "Hashed"; }
|
||||
|
||||
size_t getBytesAllocated() const override { return bytes_allocated; }
|
||||
@ -49,7 +46,7 @@ public:
|
||||
|
||||
std::shared_ptr<const IExternalLoadable> clone() const override
|
||||
{
|
||||
return std::make_shared<HashedDictionary>(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty, saved_block);
|
||||
return std::make_shared<HashedDictionary>(name, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty, saved_block);
|
||||
}
|
||||
|
||||
const IDictionarySource * getSource() const override { return source_ptr.get(); }
|
||||
@ -233,7 +230,6 @@ private:
|
||||
void isInImpl(const ChildType & child_ids, const AncestorType & ancestor_ids, PaddedPODArray<UInt8> & out) const;
|
||||
|
||||
const std::string name;
|
||||
const std::unordered_set<std::string> allowed_databases;
|
||||
const DictionaryStructure dict_struct;
|
||||
const DictionarySourcePtr source_ptr;
|
||||
const DictionaryLifetime dict_lifetime;
|
||||
|
@ -40,8 +40,6 @@ struct IDictionaryBase : public IExternalLoadable
|
||||
|
||||
virtual bool isCached() const = 0;
|
||||
|
||||
virtual const std::unordered_set<std::string> & getAllowedDatabases() const = 0;
|
||||
|
||||
virtual const IDictionarySource * getSource() const = 0;
|
||||
|
||||
virtual const DictionaryStructure & getStructure() const = 0;
|
||||
@ -69,13 +67,6 @@ struct IDictionaryBase : public IExternalLoadable
|
||||
{
|
||||
return std::static_pointer_cast<const IDictionaryBase>(IExternalLoadable::shared_from_this());
|
||||
}
|
||||
|
||||
bool isAllowed(const std::string & database_name) const
|
||||
{
|
||||
auto allowed_databases = getAllowedDatabases();
|
||||
|
||||
return allowed_databases.size() == 0 || allowed_databases.find(database_name) != allowed_databases.end();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -69,13 +69,11 @@ bool operator<(const RangeHashedDictionary::Range & left, const RangeHashedDicti
|
||||
|
||||
RangeHashedDictionary::RangeHashedDictionary(
|
||||
const std::string & dictionary_name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
bool require_nonempty_)
|
||||
: dictionary_name{dictionary_name_}
|
||||
, allowed_databases{allowed_databases_}
|
||||
, dict_struct(dict_struct_)
|
||||
, source_ptr{std::move(source_ptr_)}
|
||||
, dict_lifetime(dict_lifetime_)
|
||||
@ -677,7 +675,6 @@ BlockInputStreamPtr RangeHashedDictionary::getBlockInputStream(const Names & col
|
||||
void registerDictionaryRangeHashed(DictionaryFactory & factory)
|
||||
{
|
||||
auto create_layout = [=](const std::string & name,
|
||||
const std::unordered_set<std::string> & allowed_databases,
|
||||
const DictionaryStructure & dict_struct,
|
||||
const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_prefix,
|
||||
@ -692,7 +689,7 @@ void registerDictionaryRangeHashed(DictionaryFactory & factory)
|
||||
|
||||
const DictionaryLifetime dict_lifetime{config, config_prefix + ".lifetime"};
|
||||
const bool require_nonempty = config.getBool(config_prefix + ".require_nonempty", false);
|
||||
return std::make_unique<RangeHashedDictionary>(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty);
|
||||
return std::make_unique<RangeHashedDictionary>(name, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty);
|
||||
};
|
||||
factory.registerLayout("range_hashed", create_layout);
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ class RangeHashedDictionary final : public IDictionaryBase
|
||||
public:
|
||||
RangeHashedDictionary(
|
||||
const std::string & dictionary_name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
@ -27,8 +26,6 @@ public:
|
||||
|
||||
std::string getName() const override { return dictionary_name; }
|
||||
|
||||
const std::unordered_set<std::string> & getAllowedDatabases() const override { return allowed_databases; }
|
||||
|
||||
std::string getTypeName() const override { return "RangeHashed"; }
|
||||
|
||||
size_t getBytesAllocated() const override { return bytes_allocated; }
|
||||
@ -45,7 +42,7 @@ public:
|
||||
|
||||
std::shared_ptr<const IExternalLoadable> clone() const override
|
||||
{
|
||||
return std::make_shared<RangeHashedDictionary>(dictionary_name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty);
|
||||
return std::make_shared<RangeHashedDictionary>(dictionary_name, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty);
|
||||
}
|
||||
|
||||
const IDictionarySource * getSource() const override { return source_ptr.get(); }
|
||||
@ -214,7 +211,6 @@ private:
|
||||
friend struct RangeHashedDIctionaryCallGetBlockInputStreamImpl;
|
||||
|
||||
const std::string dictionary_name;
|
||||
const std::unordered_set<std::string> allowed_databases;
|
||||
const DictionaryStructure dict_struct;
|
||||
const DictionarySourcePtr source_ptr;
|
||||
const DictionaryLifetime dict_lifetime;
|
||||
|
@ -36,13 +36,11 @@ namespace ErrorCodes
|
||||
|
||||
TrieDictionary::TrieDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
bool require_nonempty_)
|
||||
: name{name_}
|
||||
, allowed_databases{allowed_databases_}
|
||||
, dict_struct(dict_struct_)
|
||||
, source_ptr{std::move(source_ptr_)}
|
||||
, dict_lifetime(dict_lifetime_)
|
||||
@ -756,7 +754,6 @@ BlockInputStreamPtr TrieDictionary::getBlockInputStream(const Names & column_nam
|
||||
void registerDictionaryTrie(DictionaryFactory & factory)
|
||||
{
|
||||
auto create_layout = [=](const std::string & name,
|
||||
const std::unordered_set<std::string> & allowed_databases,
|
||||
const DictionaryStructure & dict_struct,
|
||||
const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_prefix,
|
||||
@ -768,7 +765,7 @@ void registerDictionaryTrie(DictionaryFactory & factory)
|
||||
const DictionaryLifetime dict_lifetime{config, config_prefix + ".lifetime"};
|
||||
const bool require_nonempty = config.getBool(config_prefix + ".require_nonempty", false);
|
||||
// This is specialised trie for storing IPv4 and IPv6 prefixes.
|
||||
return std::make_unique<TrieDictionary>(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty);
|
||||
return std::make_unique<TrieDictionary>(name, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty);
|
||||
};
|
||||
factory.registerLayout("ip_trie", create_layout);
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ class TrieDictionary final : public IDictionaryBase
|
||||
public:
|
||||
TrieDictionary(
|
||||
const std::string & name_,
|
||||
const std::unordered_set<std::string> & allowed_databases,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
@ -36,8 +35,6 @@ public:
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
const std::unordered_set<std::string> & getAllowedDatabases() const override { return allowed_databases; }
|
||||
|
||||
std::string getTypeName() const override { return "Trie"; }
|
||||
|
||||
size_t getBytesAllocated() const override { return bytes_allocated; }
|
||||
@ -54,7 +51,7 @@ public:
|
||||
|
||||
std::shared_ptr<const IExternalLoadable> clone() const override
|
||||
{
|
||||
return std::make_shared<TrieDictionary>(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty);
|
||||
return std::make_shared<TrieDictionary>(name, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty);
|
||||
}
|
||||
|
||||
const IDictionarySource * getSource() const override { return source_ptr.get(); }
|
||||
@ -238,7 +235,6 @@ private:
|
||||
Columns getKeyColumns() const;
|
||||
|
||||
const std::string name;
|
||||
const std::unordered_set<std::string> allowed_databases;
|
||||
const DictionaryStructure dict_struct;
|
||||
const DictionarySourcePtr source_ptr;
|
||||
const DictionaryLifetime dict_lifetime;
|
||||
|
@ -127,7 +127,7 @@ private:
|
||||
auto dict = dictionaries.getDictionary(dict_name_col->getValue<String>());
|
||||
const auto dict_ptr = dict.get();
|
||||
|
||||
if (!dict->isAllowed(context.getCurrentDatabase()))
|
||||
if (!context.hasDictionaryAccessRights(dict_ptr->getName()))
|
||||
{
|
||||
throw Exception{"For function " + getName() + ", cannot access dictionary "
|
||||
+ dict->getName() + " on database " + context.getCurrentDatabase(), ErrorCodes::DICTIONARY_ACCESS_DENIED};
|
||||
@ -302,7 +302,7 @@ private:
|
||||
auto dict = dictionaries.getDictionary(dict_name_col->getValue<String>());
|
||||
const auto dict_ptr = dict.get();
|
||||
|
||||
if (!dict->isAllowed(context.getCurrentDatabase()))
|
||||
if (!context.hasDictionaryAccessRights(dict_ptr->getName()))
|
||||
{
|
||||
throw Exception{"For function " + getName() + ", cannot access dictionary "
|
||||
+ dict->getName() + " on database " + context.getCurrentDatabase(), ErrorCodes::DICTIONARY_ACCESS_DENIED};
|
||||
@ -488,7 +488,7 @@ private:
|
||||
auto dict = dictionaries.getDictionary(dict_name_col->getValue<String>());
|
||||
const auto dict_ptr = dict.get();
|
||||
|
||||
if (!dict->isAllowed(context.getCurrentDatabase()))
|
||||
if (!context.hasDictionaryAccessRights(dict_ptr->getName()))
|
||||
{
|
||||
throw Exception{"For function " + getName() + ", cannot access dictionary "
|
||||
+ dict->getName() + " on database " + context.getCurrentDatabase(), ErrorCodes::DICTIONARY_ACCESS_DENIED};
|
||||
@ -830,7 +830,7 @@ private:
|
||||
auto dict = dictionaries.getDictionary(dict_name_col->getValue<String>());
|
||||
const auto dict_ptr = dict.get();
|
||||
|
||||
if (!dict->isAllowed(context.getCurrentDatabase()))
|
||||
if (!context.hasDictionaryAccessRights(dict_ptr->getName()))
|
||||
{
|
||||
throw Exception{"For function " + getName() + ", cannot access dictionary "
|
||||
+ dict->getName() + " on database " + context.getCurrentDatabase(), ErrorCodes::DICTIONARY_ACCESS_DENIED};
|
||||
@ -1094,7 +1094,7 @@ private:
|
||||
auto dict = dictionaries.getDictionary(dict_name_col->getValue<String>());
|
||||
const auto dict_ptr = dict.get();
|
||||
|
||||
if (!dict->isAllowed(context.getCurrentDatabase()))
|
||||
if (!context.hasDictionaryAccessRights(dict_ptr->getName()))
|
||||
{
|
||||
throw Exception{"For function " + getName() + ", cannot access dictionary "
|
||||
+ dict->getName() + " on database " + context.getCurrentDatabase(), ErrorCodes::DICTIONARY_ACCESS_DENIED};
|
||||
@ -1671,7 +1671,7 @@ private:
|
||||
auto dict = dictionaries.getDictionary(dict_name_col->getValue<String>());
|
||||
const auto dict_ptr = dict.get();
|
||||
|
||||
if (!dict->isAllowed(context.getCurrentDatabase()))
|
||||
if (!context.hasDictionaryAccessRights(dict_ptr->getName()))
|
||||
{
|
||||
throw Exception{"For function " + getName() + ", cannot access dictionary "
|
||||
+ dict->getName() + " on database " + context.getCurrentDatabase(), ErrorCodes::DICTIONARY_ACCESS_DENIED};
|
||||
@ -1840,7 +1840,7 @@ private:
|
||||
auto dict = dictionaries.getDictionary(dict_name_col->getValue<String>());
|
||||
const auto dict_ptr = dict.get();
|
||||
|
||||
if (!dict->isAllowed(context.getCurrentDatabase()))
|
||||
if (!context.hasDictionaryAccessRights(dict_ptr->getName()))
|
||||
{
|
||||
throw Exception{"For function " + getName() + ", cannot access dictionary "
|
||||
+ dict->getName() + " on database " + context.getCurrentDatabase(), ErrorCodes::DICTIONARY_ACCESS_DENIED};
|
||||
|
@ -704,6 +704,13 @@ bool Context::hasDatabaseAccessRights(const String & database_name) const
|
||||
shared->users_manager->hasAccessToDatabase(client_info.current_user, database_name);
|
||||
}
|
||||
|
||||
bool Context::hasDictionaryAccessRights(const String & dictionary_name) const
|
||||
{
|
||||
auto lock = getLock();
|
||||
return client_info.current_user.empty() ||
|
||||
shared->users_manager->hasAccessToDictionary(client_info.current_user, dictionary_name);
|
||||
}
|
||||
|
||||
void Context::checkDatabaseAccessRightsImpl(const std::string & database_name) const
|
||||
{
|
||||
if (client_info.current_user.empty() || (database_name == "system"))
|
||||
|
@ -253,6 +253,8 @@ public:
|
||||
bool hasDatabaseAccessRights(const String & database_name) const;
|
||||
void assertTableExists(const String & database_name, const String & table_name) const;
|
||||
|
||||
bool hasDictionaryAccessRights(const String & dictionary_name) const;
|
||||
|
||||
/** The parameter check_database_access_rights exists to not check the permissions of the database again,
|
||||
* when assertTableDoesntExist or assertDatabaseExists is called inside another function that already
|
||||
* made this check.
|
||||
|
@ -30,6 +30,9 @@ public:
|
||||
|
||||
/// Check if the user has access to the database.
|
||||
virtual bool hasAccessToDatabase(const String & user_name, const String & database_name) const = 0;
|
||||
|
||||
// Check if the user has access to the dictionary
|
||||
virtual bool hasAccessToDictionary(const String & user_name, const String & dictionary_name) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -326,6 +326,23 @@ User::User(const String & name_, const String & config_elem, const Poco::Util::A
|
||||
}
|
||||
}
|
||||
|
||||
/// Fill list of allowed databases.
|
||||
const auto config_dictionary_sub_elem = config_elem + ".allow_dictionaries";
|
||||
if (config.has(config_dictionary_sub_elem))
|
||||
{
|
||||
Poco::Util::AbstractConfiguration::Keys config_keys;
|
||||
config.keys(config_dictionary_sub_elem, config_keys);
|
||||
|
||||
dictionaries.reserve(config_keys.size());
|
||||
for (const auto & key : config_keys)
|
||||
{
|
||||
const auto dictionary_name = config.getString(config_dictionary_sub_elem + "." + key);
|
||||
dictionaries.insert(dictionary_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Read properties per "database.table"
|
||||
/// Only tables are expected to have properties, so that all the keys inside "database" are table names.
|
||||
const auto config_databases = config_elem + ".databases";
|
||||
|
@ -67,6 +67,10 @@ struct User
|
||||
using DatabaseSet = std::unordered_set<std::string>;
|
||||
DatabaseSet databases;
|
||||
|
||||
/// List of allowed databases.
|
||||
using DictionarySet = std::unordered_set<std::string>;
|
||||
DictionarySet dictionaries;
|
||||
|
||||
/// Table properties.
|
||||
using PropertyMap = std::unordered_map<std::string /* name */, std::string /* value */>;
|
||||
using TableMap = std::unordered_map<std::string /* table */, PropertyMap /* properties */>;
|
||||
|
@ -138,4 +138,15 @@ bool UsersManager::hasAccessToDatabase(const std::string & user_name, const std:
|
||||
return user->databases.empty() || user->databases.count(database_name);
|
||||
}
|
||||
|
||||
bool UsersManager::hasAccessToDictionary(const std::string & user_name, const std::string & dictionary_name) const
|
||||
{
|
||||
auto it = users.find(user_name);
|
||||
|
||||
if (users.end() == it)
|
||||
throw Exception("Unknown user " + user_name, ErrorCodes::UNKNOWN_USER);
|
||||
|
||||
auto user = it->second;
|
||||
return user->dictionaries.empty() || user->dictionaries.count(dictionary_name);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ public:
|
||||
UserPtr getUser(const String & user_name) const override;
|
||||
|
||||
bool hasAccessToDatabase(const String & user_name, const String & database_name) const override;
|
||||
bool hasAccessToDictionary(const String & user_name, const String & dictionary_name) const override;
|
||||
|
||||
private:
|
||||
using Container = std::map<String, UserPtr>;
|
||||
|
Loading…
Reference in New Issue
Block a user