提交 bb088fbf 编写于 作者: G Guillaume Tassery

Write dictionary permission on user instead of dictionary configuration

上级 d15d5827
......@@ -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>;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册