diff options
| author | auzhegov <[email protected]> | 2023-08-23 14:58:36 +0300 | 
|---|---|---|
| committer | auzhegov <[email protected]> | 2023-08-23 15:32:25 +0300 | 
| commit | 5ba6ac44dabe4ac45b7fe1430ec4eeeb35ce2124 (patch) | |
| tree | acc0666d995cbeb91a4d4cbb7592235caf490694 | |
| parent | 6e7d3a73ff044dd6bff7936fa9b8ec956e0568c7 (diff) | |
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 ca21f6f086d..eea91a2b5c3 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 c770cb1454a..add489ae065 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"));  | 
