summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Rykov <[email protected]>2025-08-05 10:18:07 +0200
committerGitHub <[email protected]>2025-08-05 10:18:07 +0200
commite4501a8f37bdc5826001547e68daac136a9fe55c (patch)
tree629ba73422f9a657245b528be9afe43a03608680
parent0c917181943247fc9c0cee5606ae1725dad0af9b (diff)
meta forward authorize header (#22226)
-rw-r--r--ydb/mvp/core/core_ydb_impl.h61
-rw-r--r--ydb/mvp/meta/meta_cp_databases.h53
-rw-r--r--ydb/mvp/meta/mvp.cpp3
-rw-r--r--ydb/mvp/meta/mvp.h1
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();