diff options
author | Andrei Rykov <[email protected]> | 2025-08-05 10:18:07 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2025-08-05 10:18:07 +0200 |
commit | e4501a8f37bdc5826001547e68daac136a9fe55c (patch) | |
tree | 629ba73422f9a657245b528be9afe43a03608680 | |
parent | 0c917181943247fc9c0cee5606ae1725dad0af9b (diff) |
meta forward authorize header (#22226)
-rw-r--r-- | ydb/mvp/core/core_ydb_impl.h | 61 | ||||
-rw-r--r-- | ydb/mvp/meta/meta_cp_databases.h | 53 | ||||
-rw-r--r-- | ydb/mvp/meta/mvp.cpp | 3 | ||||
-rw-r--r-- | ydb/mvp/meta/mvp.h | 1 |
4 files changed, 95 insertions, 23 deletions
diff --git a/ydb/mvp/core/core_ydb_impl.h b/ydb/mvp/core/core_ydb_impl.h index 26ec0295674..39dfc2279eb 100644 --- a/ydb/mvp/core/core_ydb_impl.h +++ b/ydb/mvp/core/core_ydb_impl.h @@ -860,6 +860,59 @@ struct THandlerActorYdb { return false; } + static void SetCORS(NHttp::THttpIncomingRequestPtr request, NHttp::THeadersBuilder* const headers) { + TString origin = TString(NHttp::THeaders(request->Headers)["Origin"]); + if (origin.empty()) { + origin = "*"; + } + headers->Set("Access-Control-Allow-Origin", origin); + headers->Set("Access-Control-Allow-Credentials", "true"); + headers->Set("Access-Control-Allow-Headers", "Content-Type,Authorization,Origin,Accept,X-Trace-Verbosity,X-Want-Trace,traceparent"); + headers->Set("Access-Control-Expose-Headers", "traceresponse,X-Worker-Name"); + headers->Set("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE"); + headers->Set("Allow", "OPTIONS,GET,POST,PUT,DELETE"); + } + + static NHttp::THttpOutgoingResponsePtr CreateResponse(NHttp::THttpIncomingRequestPtr request, TStringBuf status, TStringBuf message, TStringBuf contentType = TStringBuf(), TStringBuf body = TStringBuf(), TInstant lastModified = TInstant()) { + NHttp::THeadersBuilder headers; + if (!contentType.empty() && !body.empty()) { + headers.Set("Content-Type", contentType); + } + if (lastModified) { + headers.Set("Last-Modified", lastModified.FormatGmTime("%a, %d %b %Y %H:%M:%S GMT")); + } + SetCORS(request, &headers); + return request->CreateResponse(status, message, headers, body); + } + + static NHttp::THttpOutgoingResponsePtr CreateResponseOK(NHttp::THttpIncomingRequestPtr request, TStringBuf body, TStringBuf contentType, TInstant lastModified = TInstant()) { + return CreateResponse(request, "200", "OK", contentType, body, lastModified); + } + + static NHttp::THttpOutgoingResponsePtr CreateResponseBadRequest(NHttp::THttpIncomingRequestPtr request, TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html") { + if (html.empty() && request->IsError()) { + contentType = "text/plain"; + html = request->GetErrorText(); + } + return CreateResponse(request, "400", "Bad Request", contentType, html); + } + + static NHttp::THttpOutgoingResponsePtr CreateResponseNotFound(NHttp::THttpIncomingRequestPtr request, TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html") { + return CreateResponse(request, "404", "Not Found", contentType, html); + } + + static NHttp::THttpOutgoingResponsePtr CreateResponseTooManyRequests(NHttp::THttpIncomingRequestPtr request, TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html") { + return CreateResponse(request, "429", "Too Many Requests", contentType, html); + } + + static NHttp::THttpOutgoingResponsePtr CreateResponseServiceUnavailable(NHttp::THttpIncomingRequestPtr request, TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html") { + return CreateResponse(request, "503", "Service Unavailable", contentType, html); + } + + static NHttp::THttpOutgoingResponsePtr CreateResponseGatewayTimeout(NHttp::THttpIncomingRequestPtr request, TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html") { + return CreateResponse(request, "504", "Gateway Timeout", contentType, html); + } + static NHttp::THttpOutgoingResponsePtr CreateStatusResponseForQuery(NHttp::THttpIncomingRequestPtr request, const NYdb::TStatus& status, const TJsonSettings& jsonSettings = TJsonSettings()) { Ydb::Operations::Operation operation; operation.set_status(static_cast<Ydb::StatusIds_StatusCode>(status.GetStatus())); @@ -916,7 +969,7 @@ struct THandlerActorYdb { } TStringStream stream; TProtoToJson::ProtoToJson(stream, operation, jsonSettings); - return request->CreateResponse(status, message, "application/json", stream.Str()); + return CreateResponse(request, status, message, "application/json", stream.Str()); } static NHttp::THttpOutgoingResponsePtr CreateStatusResponse(NHttp::THttpIncomingRequestPtr request, const NYdb::TStatus& status, const TJsonSettings& jsonSettings = TJsonSettings()) { @@ -978,21 +1031,21 @@ struct THandlerActorYdb { } TStringStream stream; TProtoToJson::ProtoToJson(stream, operation, jsonSettings); - return request->CreateResponse(status, message, "application/json", stream.Str()); + return CreateResponse(request, status, message, "application/json", stream.Str()); } static NHttp::THttpOutgoingResponsePtr CreateErrorResponse(NHttp::THttpIncomingRequestPtr request, const TEvPrivate::TEvErrorResponse* error) { NJson::TJsonValue json; json["message"] = error->Message; TString body = NJson::WriteJson(json, false); - return request->CreateResponse(error->Status, error->Message, "application/json", body); + return CreateResponse(request, error->Status, error->Message, "application/json", body); } static NHttp::THttpOutgoingResponsePtr CreateErrorResponse(NHttp::THttpIncomingRequestPtr request, const TString& error) { NJson::TJsonValue json; json["message"] = error; TString body = NJson::WriteJson(json, false); - return request->CreateResponseServiceUnavailable(body, "application/json"); + return CreateResponseServiceUnavailable(request, body, "application/json"); } static TString ColumnPrimitiveValueToString(NYdb::TValueParser& valueParser) { diff --git a/ydb/mvp/meta/meta_cp_databases.h b/ydb/mvp/meta/meta_cp_databases.h index 5fe3318c5f4..c56ae806fc9 100644 --- a/ydb/mvp/meta/meta_cp_databases.h +++ b/ydb/mvp/meta/meta_cp_databases.h @@ -1,25 +1,30 @@ #pragma once -#include <random> -#include <util/generic/hash_set.h> -#include <ydb/library/actors/core/actorsystem.h> + +#include <ydb/mvp/core/core_ydb.h> +#include <ydb/mvp/core/core_ydb_impl.h> +#include <ydb/mvp/core/core_ydbc.h> +#include <ydb/mvp/core/core_ydbc_impl.h> +#include <ydb/mvp/core/merger.h> + +#include <ydb/core/ydb_convert/ydb_convert.h> + #include <ydb/library/actors/core/actor.h> -#include <ydb/library/actors/core/hfunc.h> -#include <ydb/library/actors/core/events.h> -#include <ydb/library/actors/core/event_local.h> #include <ydb/library/actors/core/actor_bootstrapped.h> +#include <ydb/library/actors/core/actorsystem.h> +#include <ydb/library/actors/core/event_local.h> +#include <ydb/library/actors/core/events.h> +#include <ydb/library/actors/core/hfunc.h> #include <ydb/library/actors/http/http.h> -#include <ydb/public/lib/deprecated/client/grpc_client.h> -#include <ydb/public/sdk/cpp/src/library/grpc/client/grpc_client_low.h> -#include <ydb/public/sdk/cpp/include/ydb-cpp-sdk/client/table/table.h> + #include <ydb/public/api/grpc/ydb_scripting_v1.grpc.pb.h> #include <ydb/public/api/protos/ydb_discovery.pb.h> +#include <ydb/public/lib/deprecated/client/grpc_client.h> #include <ydb/public/sdk/cpp/include/ydb-cpp-sdk/client/result/result.h> -#include <ydb/core/ydb_convert/ydb_convert.h> -#include <ydb/mvp/core/core_ydb.h> -#include <ydb/mvp/core/core_ydb_impl.h> -#include <ydb/mvp/core/core_ydbc.h> -#include <ydb/mvp/core/core_ydbc_impl.h> -#include <ydb/mvp/core/merger.h> +#include <ydb/public/sdk/cpp/include/ydb-cpp-sdk/client/table/table.h> +#include <ydb/public/sdk/cpp/src/library/grpc/client/grpc_client_low.h> + +#include <util/generic/hash_set.h> +#include <random> namespace NMVP { @@ -125,6 +130,16 @@ public: connection->DoRequest(cpRequest, std::move(responseCb), &yandex::cloud::priv::ydb::v1::DatabaseService::Stub::AsyncListAll, meta); } + TString GetAuthHeaderValue(const TString& tokenName) { + if (TMVP::DbUserTokenSource) { + NHttp::THeaders headers(Request.Request->Headers); + TStringBuf header = headers.Get("Authorization"); + return TString(header); + } else { + return ::GetAuthHeaderValue(tokenName); + } + } + void Handle(TEvPrivate::TEvDataQueryResult::TPtr event, const NActors::TActorContext& ctx) { NYdb::NTable::TDataQueryResult& result(event->Get()->Result); NHttp::THttpOutgoingResponsePtr response; @@ -209,9 +224,9 @@ public: if (event->Get()->Response && event->Get()->Response->Status.size() == 3) { ctx.Send(Request.Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(event->Get()->Response->Reverse(Request.Request))); } else if (!event->Get()->Error.empty()) { - ctx.Send(Request.Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(Request.Request->CreateResponseServiceUnavailable(event->Get()->Error, "text/plain"))); + ctx.Send(Request.Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(CreateResponseServiceUnavailable(Request.Request, event->Get()->Error, "text/plain"))); } else { - ctx.Send(Request.Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(Request.Request->CreateResponseServiceUnavailable("Endpoint returned unknown status", "text/plain"))); + ctx.Send(Request.Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(CreateResponseServiceUnavailable(Request.Request, "Endpoint returned unknown status", "text/plain"))); } return Die(ctx); } @@ -221,7 +236,7 @@ public: } void HandleTimeout(const NActors::TActorContext& ctx) { - ctx.Send(Request.Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(Request.Request->CreateResponseGatewayTimeout())); + ctx.Send(Request.Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(CreateResponseGatewayTimeout(Request.Request))); Die(ctx); } @@ -340,7 +355,7 @@ public: } TString body(NJson::WriteJson(root, false)); - NHttp::THttpOutgoingResponsePtr response = Request.Request->CreateResponseOK(body, "application/json; charset=utf-8"); + NHttp::THttpOutgoingResponsePtr response = CreateResponseOK(Request.Request, body, "application/json; charset=utf-8"); ctx.Send(Request.Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response)); Die(ctx); } diff --git a/ydb/mvp/meta/mvp.cpp b/ydb/mvp/meta/mvp.cpp index 2c9d8f2166e..50d4a0d55b6 100644 --- a/ydb/mvp/meta/mvp.cpp +++ b/ydb/mvp/meta/mvp.cpp @@ -136,6 +136,8 @@ TString TMVP::GetAppropriateEndpoint(const NHttp::THttpIncomingRequestPtr& req) NMvp::TTokensConfig TMVP::TokensConfig; TString TMVP::MetaDatabaseTokenName; +bool TMVP::DbUserTokenSource = false; + TMVP::TMVP(int argc, char** argv) : ActorSystemStoppingLock() , ActorSystemStopping(false) @@ -177,6 +179,7 @@ void TMVP::TryGetMetaOptionsFromConfig(const YAML::Node& config) { MetaDatabase = meta["meta_database"].as<std::string>(""); MetaCache = meta["meta_cache"].as<bool>(false); MetaDatabaseTokenName = meta["meta_database_token_name"].as<std::string>(""); + DbUserTokenSource = meta["db_user_token_access"].as<bool>(false); } void TMVP::TryGetGenericOptionsFromConfig( diff --git a/ydb/mvp/meta/mvp.h b/ydb/mvp/meta/mvp.h index d888124af27..3607c26020b 100644 --- a/ydb/mvp/meta/mvp.h +++ b/ydb/mvp/meta/mvp.h @@ -38,6 +38,7 @@ public: TString MetaDatabase; bool MetaCache = false; static TString MetaDatabaseTokenName; + static bool DbUserTokenSource; TMVP(int argc, char** argv); int Init(); |