diff options
author | auzhegov <auzhegov@yandex-team.com> | 2023-08-23 14:58:36 +0300 |
---|---|---|
committer | auzhegov <auzhegov@yandex-team.com> | 2023-08-23 15:32:25 +0300 |
commit | 5ba6ac44dabe4ac45b7fe1430ec4eeeb35ce2124 (patch) | |
tree | acc0666d995cbeb91a4d4cbb7592235caf490694 | |
parent | 6e7d3a73ff044dd6bff7936fa9b8ec956e0568c7 (diff) | |
download | ydb-5ba6ac44dabe4ac45b7fe1430ec4eeeb35ce2124.tar.gz |
Allowlist validation
-rw-r--r-- | ydb/core/fq/libs/control_plane_storage/request_validators.cpp | 45 | ||||
-rw-r--r-- | ydb/core/fq/libs/control_plane_storage/request_validators.h | 12 |
2 files changed, 50 insertions, 7 deletions
diff --git a/ydb/core/fq/libs/control_plane_storage/request_validators.cpp b/ydb/core/fq/libs/control_plane_storage/request_validators.cpp index ca21f6f086..eea91a2b5c 100644 --- a/ydb/core/fq/libs/control_plane_storage/request_validators.cpp +++ b/ydb/core/fq/libs/control_plane_storage/request_validators.cpp @@ -370,4 +370,49 @@ NYql::TIssues ValidateProjection(const FederatedQuery::Schema& schema, const TSt return issues; } +NYql::TIssues ValidateEntityName(const TString& name) { + NYql::TIssues issues; + + if (!name) { + issues.AddIssue( + MakeErrorIssue(TIssuesIds::BAD_REQUEST, "name field is not specified")); + } + + if (name.Size() > 255) { + issues.AddIssue( + MakeErrorIssue(TIssuesIds::BAD_REQUEST, + TStringBuilder{} + << "Incorrect connection name: " << name + << ". Name length must not exceed 255 symbols. Current length is " + << name.Size() << " symbol(s)")); + } + + if (name != to_lower(name)) { + issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, + TStringBuilder{} + << "Incorrect binding name: " << name + << ". Please use only lower case")); + } + + if (AllOf(name, [](auto& ch) { return ch == '.'; })) { + issues.AddIssue( + MakeErrorIssue(TIssuesIds::BAD_REQUEST, + TStringBuilder{} + << "Incorrect connection name: " << name + << ". Name is not allowed path part contains only dots")); + } + + static const std::regex allowListRegexp( + "(?:[a-z0-9]|!|\\\\|#|\\$|%|&|\\(|\\)|\\*|\\+|,|-|\\.|:|;|<|=|>|\\?|@|\\[|\\]|\\^|_|\\{|\\||\\}|~)+"); + if (!std::regex_match(name.c_str(), allowListRegexp)) { + issues.AddIssue(MakeErrorIssue( + TIssuesIds::BAD_REQUEST, + TStringBuilder{} + << "Incorrect connection name: " << name + << ". Please make sure that name consists of following symbols: ['a'-'z'], ['0'-'9'], '!', '\\', '#', '$', '%'. '&', '(', ')', '*', '+', ',', '-', '.', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^', '_', '{', '|', '}', '~'")); + } + + return issues; +} + } // namespace NFq diff --git a/ydb/core/fq/libs/control_plane_storage/request_validators.h b/ydb/core/fq/libs/control_plane_storage/request_validators.h index c770cb1454..add489ae06 100644 --- a/ydb/core/fq/libs/control_plane_storage/request_validators.h +++ b/ydb/core/fq/libs/control_plane_storage/request_validators.h @@ -7,12 +7,13 @@ #include <ydb/library/yql/public/issue/yql_issue.h> #include <ydb/public/api/protos/draft/fq.pb.h> +#include <library/cpp/scheme/scheme.h> #include <util/generic/fwd.h> #include <util/generic/set.h> #include <util/string/builder.h> #include <util/string/cast.h> -#include <library/cpp/scheme/scheme.h> +#include <regex> namespace NFq { @@ -82,6 +83,7 @@ NYql::TIssues ValidateFormatSetting(const TString& format, const google::protobu NYql::TIssues ValidateDateFormatSetting(const google::protobuf::Map<TString, TString>& formatSetting, bool matchAllSettings = false); NYql::TIssues ValidateProjectionColumns(const FederatedQuery::Schema& schema, const TVector<TString>& partitionedBy); NYql::TIssues ValidateProjection(const FederatedQuery::Schema& schema, const TString& projection, const TVector<TString>& partitionedBy, size_t pathsLimit); +NYql::TIssues ValidateEntityName(const TString& name); template<typename T> NYql::TIssues ValidateBinding(const T& ev, size_t maxSize, const TSet<FederatedQuery::BindingSetting::BindingCase>& availableBindings, size_t pathsLimit) @@ -95,9 +97,7 @@ NYql::TIssues ValidateBinding(const T& ev, size_t maxSize, const TSet<FederatedQ issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, "binding.acl.visibility field is not specified")); } - if (content.name() != to_lower(content.name())) { - issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, TStringBuilder{} << "Incorrect binding name: " << content.name() << ". Please use only lower case")); - } + issues.AddIssues(ValidateEntityName(content.name())); if (!content.has_setting()) { issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, "binding.setting field is not specified")); @@ -179,9 +179,7 @@ NYql::TIssues ValidateConnection( issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, "content.acl.visibility field is not specified")); } - if (content.name() != to_lower(content.name())) { - issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, TStringBuilder{} << "Incorrect connection name: " << content.name() << ". Please use only lower case")); - } + issues.AddIssues(ValidateEntityName(content.name())); if (!content.has_setting()) { issues.AddIssue(MakeErrorIssue(TIssuesIds::BAD_REQUEST, "content.setting field is not specified")); |