From bb088fbf654e01ee1d75257db65ba033e6b8dda8 Mon Sep 17 00:00:00 2001 From: Guillaume Tassery Date: Fri, 13 Sep 2019 10:22:34 +0200 Subject: [PATCH] Write dictionary permission on user instead of dictionary configuration --- dbms/src/Dictionaries/CacheDictionary.cpp | 5 +---- dbms/src/Dictionaries/CacheDictionary.h | 6 +----- .../ComplexKeyCacheDictionary.cpp | 5 +---- .../Dictionaries/ComplexKeyCacheDictionary.h | 6 +----- .../ComplexKeyHashedDictionary.cpp | 5 +---- .../Dictionaries/ComplexKeyHashedDictionary.h | 6 +----- dbms/src/Dictionaries/DictionaryFactory.cpp | 19 +------------------ dbms/src/Dictionaries/DictionaryFactory.h | 1 - dbms/src/Dictionaries/FlatDictionary.cpp | 5 +---- dbms/src/Dictionaries/FlatDictionary.h | 6 +----- dbms/src/Dictionaries/HashedDictionary.cpp | 5 +---- dbms/src/Dictionaries/HashedDictionary.h | 6 +----- dbms/src/Dictionaries/IDictionary.h | 9 --------- .../Dictionaries/RangeHashedDictionary.cpp | 5 +---- dbms/src/Dictionaries/RangeHashedDictionary.h | 6 +----- dbms/src/Dictionaries/TrieDictionary.cpp | 5 +---- dbms/src/Dictionaries/TrieDictionary.h | 6 +----- .../Functions/FunctionsExternalDictionaries.h | 14 +++++++------- dbms/src/Interpreters/Context.cpp | 7 +++++++ dbms/src/Interpreters/Context.h | 2 ++ dbms/src/Interpreters/IUsersManager.h | 3 +++ dbms/src/Interpreters/Users.cpp | 17 +++++++++++++++++ dbms/src/Interpreters/Users.h | 4 ++++ dbms/src/Interpreters/UsersManager.cpp | 11 +++++++++++ dbms/src/Interpreters/UsersManager.h | 1 + 25 files changed, 67 insertions(+), 98 deletions(-) diff --git a/dbms/src/Dictionaries/CacheDictionary.cpp b/dbms/src/Dictionaries/CacheDictionary.cpp index d6a9d20715..c3a78150f0 100644 --- a/dbms/src/Dictionaries/CacheDictionary.cpp +++ b/dbms/src/Dictionaries/CacheDictionary.cpp @@ -62,13 +62,11 @@ inline size_t CacheDictionary::getCellIdx(const Key id) const CacheDictionary::CacheDictionary( const std::string & name_, - const std::unordered_set & 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 & 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(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, size); + return std::make_unique(name, dict_struct, std::move(source_ptr), dict_lifetime, size); }; factory.registerLayout("cache", create_layout); } diff --git a/dbms/src/Dictionaries/CacheDictionary.h b/dbms/src/Dictionaries/CacheDictionary.h index e36cb5f118..750c51a7cf 100644 --- a/dbms/src/Dictionaries/CacheDictionary.h +++ b/dbms/src/Dictionaries/CacheDictionary.h @@ -26,7 +26,6 @@ class CacheDictionary final : public IDictionary public: CacheDictionary( const std::string & name_, - const std::unordered_set & 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 & 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 clone() const override { - return std::make_shared(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, size); + return std::make_shared(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 & child_ids, const AncestorType & ancestor_ids, PaddedPODArray & out) const; const std::string name; - const std::unordered_set allowed_databases; const DictionaryStructure dict_struct; mutable DictionarySourcePtr source_ptr; const DictionaryLifetime dict_lifetime; diff --git a/dbms/src/Dictionaries/ComplexKeyCacheDictionary.cpp b/dbms/src/Dictionaries/ComplexKeyCacheDictionary.cpp index 869c4b642d..3478e63107 100644 --- a/dbms/src/Dictionaries/ComplexKeyCacheDictionary.cpp +++ b/dbms/src/Dictionaries/ComplexKeyCacheDictionary.cpp @@ -52,13 +52,11 @@ inline UInt64 ComplexKeyCacheDictionary::getCellIdx(const StringRef key) const ComplexKeyCacheDictionary::ComplexKeyCacheDictionary( const std::string & name_, - const std::unordered_set & 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 & 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(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, size); + return std::make_unique(name, dict_struct, std::move(source_ptr), dict_lifetime, size); }; factory.registerLayout("complex_key_cache", create_layout); } diff --git a/dbms/src/Dictionaries/ComplexKeyCacheDictionary.h b/dbms/src/Dictionaries/ComplexKeyCacheDictionary.h index 6c389e4ee4..7c2ba75ba1 100644 --- a/dbms/src/Dictionaries/ComplexKeyCacheDictionary.h +++ b/dbms/src/Dictionaries/ComplexKeyCacheDictionary.h @@ -43,7 +43,6 @@ class ComplexKeyCacheDictionary final : public IDictionaryBase public: ComplexKeyCacheDictionary( const std::string & name_, - const std::unordered_set & 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 & 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 clone() const override { - return std::make_shared(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, size); + return std::make_shared(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 allowed_databases; const DictionaryStructure dict_struct; const DictionarySourcePtr source_ptr; const DictionaryLifetime dict_lifetime; diff --git a/dbms/src/Dictionaries/ComplexKeyHashedDictionary.cpp b/dbms/src/Dictionaries/ComplexKeyHashedDictionary.cpp index a786c35ccb..586fc5e89f 100644 --- a/dbms/src/Dictionaries/ComplexKeyHashedDictionary.cpp +++ b/dbms/src/Dictionaries/ComplexKeyHashedDictionary.cpp @@ -16,14 +16,12 @@ namespace ErrorCodes ComplexKeyHashedDictionary::ComplexKeyHashedDictionary( const std::string & name_, - const std::unordered_set & 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 & 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(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty); + return std::make_unique(name, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty); }; factory.registerLayout("complex_key_hashed", create_layout); } diff --git a/dbms/src/Dictionaries/ComplexKeyHashedDictionary.h b/dbms/src/Dictionaries/ComplexKeyHashedDictionary.h index 5b3daec845..68b8d9d0d3 100644 --- a/dbms/src/Dictionaries/ComplexKeyHashedDictionary.h +++ b/dbms/src/Dictionaries/ComplexKeyHashedDictionary.h @@ -24,7 +24,6 @@ class ComplexKeyHashedDictionary final : public IDictionaryBase public: ComplexKeyHashedDictionary( const std::string & name_, - const std::unordered_set & 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 & 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 clone() const override { - return std::make_shared(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty, saved_block); + return std::make_shared(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 getKeys(const Attribute & attribute) const; const std::string name; - const std::unordered_set allowed_databases; const DictionaryStructure dict_struct; const DictionarySourcePtr source_ptr; const DictionaryLifetime dict_lifetime; diff --git a/dbms/src/Dictionaries/DictionaryFactory.cpp b/dbms/src/Dictionaries/DictionaryFactory.cpp index 24dff408e9..43ae9d5623 100644 --- a/dbms/src/Dictionaries/DictionaryFactory.cpp +++ b/dbms/src/Dictionaries/DictionaryFactory.cpp @@ -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 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)); } } diff --git a/dbms/src/Dictionaries/DictionaryFactory.h b/dbms/src/Dictionaries/DictionaryFactory.h index c02dcafe0f..dbfdc563aa 100644 --- a/dbms/src/Dictionaries/DictionaryFactory.h +++ b/dbms/src/Dictionaries/DictionaryFactory.h @@ -31,7 +31,6 @@ public: using Creator = std::function & allowed_databases, const DictionaryStructure & dict_struct, const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix, diff --git a/dbms/src/Dictionaries/FlatDictionary.cpp b/dbms/src/Dictionaries/FlatDictionary.cpp index ce5775919b..d1c6a138c8 100644 --- a/dbms/src/Dictionaries/FlatDictionary.cpp +++ b/dbms/src/Dictionaries/FlatDictionary.cpp @@ -22,14 +22,12 @@ static const auto max_array_size = 500000; FlatDictionary::FlatDictionary( const std::string & name_, - const std::unordered_set & 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 & 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(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty); + return std::make_unique(name, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty); }; factory.registerLayout("flat", create_layout); } diff --git a/dbms/src/Dictionaries/FlatDictionary.h b/dbms/src/Dictionaries/FlatDictionary.h index 26ddca5977..d9ea141de2 100644 --- a/dbms/src/Dictionaries/FlatDictionary.h +++ b/dbms/src/Dictionaries/FlatDictionary.h @@ -23,7 +23,6 @@ class FlatDictionary final : public IDictionary public: FlatDictionary( const std::string & name_, - const std::unordered_set & 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 & 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 clone() const override { - return std::make_shared(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty, saved_block); + return std::make_shared(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 getIds() const; const std::string name; - const std::unordered_set allowed_databases; const DictionaryStructure dict_struct; const DictionarySourcePtr source_ptr; const DictionaryLifetime dict_lifetime; diff --git a/dbms/src/Dictionaries/HashedDictionary.cpp b/dbms/src/Dictionaries/HashedDictionary.cpp index 29e757b85d..9b853ac2df 100644 --- a/dbms/src/Dictionaries/HashedDictionary.cpp +++ b/dbms/src/Dictionaries/HashedDictionary.cpp @@ -17,14 +17,12 @@ namespace ErrorCodes HashedDictionary::HashedDictionary( const std::string & name_, - const std::unordered_set & 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 & 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(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty); + return std::make_unique(name, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty); }; factory.registerLayout("hashed", create_layout); } diff --git a/dbms/src/Dictionaries/HashedDictionary.h b/dbms/src/Dictionaries/HashedDictionary.h index 1700151c57..d1aa5a38d9 100644 --- a/dbms/src/Dictionaries/HashedDictionary.h +++ b/dbms/src/Dictionaries/HashedDictionary.h @@ -22,7 +22,6 @@ class HashedDictionary final : public IDictionary public: HashedDictionary( const std::string & name_, - const std::unordered_set & 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 & 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 clone() const override { - return std::make_shared(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty, saved_block); + return std::make_shared(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 & out) const; const std::string name; - const std::unordered_set allowed_databases; const DictionaryStructure dict_struct; const DictionarySourcePtr source_ptr; const DictionaryLifetime dict_lifetime; diff --git a/dbms/src/Dictionaries/IDictionary.h b/dbms/src/Dictionaries/IDictionary.h index 132d310283..a1c080ca6e 100644 --- a/dbms/src/Dictionaries/IDictionary.h +++ b/dbms/src/Dictionaries/IDictionary.h @@ -40,8 +40,6 @@ struct IDictionaryBase : public IExternalLoadable virtual bool isCached() const = 0; - virtual const std::unordered_set & 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(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(); - } }; diff --git a/dbms/src/Dictionaries/RangeHashedDictionary.cpp b/dbms/src/Dictionaries/RangeHashedDictionary.cpp index cc4aedb793..ab67ce5937 100644 --- a/dbms/src/Dictionaries/RangeHashedDictionary.cpp +++ b/dbms/src/Dictionaries/RangeHashedDictionary.cpp @@ -69,13 +69,11 @@ bool operator<(const RangeHashedDictionary::Range & left, const RangeHashedDicti RangeHashedDictionary::RangeHashedDictionary( const std::string & dictionary_name_, - const std::unordered_set & 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 & 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(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty); + return std::make_unique(name, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty); }; factory.registerLayout("range_hashed", create_layout); } diff --git a/dbms/src/Dictionaries/RangeHashedDictionary.h b/dbms/src/Dictionaries/RangeHashedDictionary.h index 214ac259cd..6e03fc3072 100644 --- a/dbms/src/Dictionaries/RangeHashedDictionary.h +++ b/dbms/src/Dictionaries/RangeHashedDictionary.h @@ -19,7 +19,6 @@ class RangeHashedDictionary final : public IDictionaryBase public: RangeHashedDictionary( const std::string & dictionary_name_, - const std::unordered_set & 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 & 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 clone() const override { - return std::make_shared(dictionary_name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty); + return std::make_shared(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 allowed_databases; const DictionaryStructure dict_struct; const DictionarySourcePtr source_ptr; const DictionaryLifetime dict_lifetime; diff --git a/dbms/src/Dictionaries/TrieDictionary.cpp b/dbms/src/Dictionaries/TrieDictionary.cpp index 5f15ae759c..7a5adee63b 100644 --- a/dbms/src/Dictionaries/TrieDictionary.cpp +++ b/dbms/src/Dictionaries/TrieDictionary.cpp @@ -36,13 +36,11 @@ namespace ErrorCodes TrieDictionary::TrieDictionary( const std::string & name_, - const std::unordered_set & 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 & 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(name, allowed_databases, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty); + return std::make_unique(name, dict_struct, std::move(source_ptr), dict_lifetime, require_nonempty); }; factory.registerLayout("ip_trie", create_layout); } diff --git a/dbms/src/Dictionaries/TrieDictionary.h b/dbms/src/Dictionaries/TrieDictionary.h index ba924164df..18b1b1c79b 100644 --- a/dbms/src/Dictionaries/TrieDictionary.h +++ b/dbms/src/Dictionaries/TrieDictionary.h @@ -24,7 +24,6 @@ class TrieDictionary final : public IDictionaryBase public: TrieDictionary( const std::string & name_, - const std::unordered_set & 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 & 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 clone() const override { - return std::make_shared(name, allowed_databases, dict_struct, source_ptr->clone(), dict_lifetime, require_nonempty); + return std::make_shared(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 allowed_databases; const DictionaryStructure dict_struct; const DictionarySourcePtr source_ptr; const DictionaryLifetime dict_lifetime; diff --git a/dbms/src/Functions/FunctionsExternalDictionaries.h b/dbms/src/Functions/FunctionsExternalDictionaries.h index 48b2c0b868..231a4be12b 100644 --- a/dbms/src/Functions/FunctionsExternalDictionaries.h +++ b/dbms/src/Functions/FunctionsExternalDictionaries.h @@ -127,7 +127,7 @@ private: auto dict = dictionaries.getDictionary(dict_name_col->getValue()); 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()); 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()); 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()); 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()); 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()); 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()); 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}; diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index f5fc1ecf5b..96bfd6e398 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -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")) diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 03d5465b94..5a8f41f2b3 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -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. diff --git a/dbms/src/Interpreters/IUsersManager.h b/dbms/src/Interpreters/IUsersManager.h index 340b36a4ad..5cfaa41397 100644 --- a/dbms/src/Interpreters/IUsersManager.h +++ b/dbms/src/Interpreters/IUsersManager.h @@ -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; }; } diff --git a/dbms/src/Interpreters/Users.cpp b/dbms/src/Interpreters/Users.cpp index 2dff8c32a6..be3021c3a4 100644 --- a/dbms/src/Interpreters/Users.cpp +++ b/dbms/src/Interpreters/Users.cpp @@ -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"; diff --git a/dbms/src/Interpreters/Users.h b/dbms/src/Interpreters/Users.h index 8baeec57e5..4c90f2c254 100644 --- a/dbms/src/Interpreters/Users.h +++ b/dbms/src/Interpreters/Users.h @@ -67,6 +67,10 @@ struct User using DatabaseSet = std::unordered_set; DatabaseSet databases; + /// List of allowed databases. + using DictionarySet = std::unordered_set; + DictionarySet dictionaries; + /// Table properties. using PropertyMap = std::unordered_map; using TableMap = std::unordered_map; diff --git a/dbms/src/Interpreters/UsersManager.cpp b/dbms/src/Interpreters/UsersManager.cpp index 123d4bd870..83682790ed 100644 --- a/dbms/src/Interpreters/UsersManager.cpp +++ b/dbms/src/Interpreters/UsersManager.cpp @@ -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); +} + } diff --git a/dbms/src/Interpreters/UsersManager.h b/dbms/src/Interpreters/UsersManager.h index 771372e7c9..94d35a8231 100644 --- a/dbms/src/Interpreters/UsersManager.h +++ b/dbms/src/Interpreters/UsersManager.h @@ -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; -- GitLab