From 9a3900114be815e77496de60ceecd837abaa4998 Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Mon, 10 Oct 2022 13:19:51 +0200 Subject: [PATCH] Other: implemented tokens in bridge-gui-tester. --- .../bridge-gui-tester/CMakeLists.txt | 2 + .../bridge-gui/bridge-gui-tester/Cert.cpp | 74 +++++++++++++++++ .../bridge-gui/bridge-gui-tester/Cert.h | 27 +++++++ .../GRPCMetaDataProcessor.cpp | 81 +++++++++++++++++++ .../bridge-gui-tester/GRPCMetaDataProcessor.h | 50 ++++++++++++ .../bridge-gui-tester/GRPCServerWorker.cpp | 46 +++++------ .../bridge-gui-tester/GRPCServerWorker.h | 2 + .../bridge-gui-tester/GRPCService.cpp | 23 ++++++ .../bridge-gui-tester/GRPCService.h | 2 +- .../bridge-gui/bridge-gui-tester/main.cpp | 1 + .../bridgepp/bridgepp/GRPC/GRPCClient.cpp | 2 +- .../bridgepp/bridgepp/GRPC/GRPCUtils.cpp | 3 + .../bridgepp/bridgepp/GRPC/GRPCUtils.h | 3 + 13 files changed, 287 insertions(+), 29 deletions(-) create mode 100644 internal/frontend/bridge-gui/bridge-gui-tester/Cert.cpp create mode 100644 internal/frontend/bridge-gui/bridge-gui-tester/Cert.h create mode 100644 internal/frontend/bridge-gui/bridge-gui-tester/GRPCMetaDataProcessor.cpp create mode 100644 internal/frontend/bridge-gui/bridge-gui-tester/GRPCMetaDataProcessor.h diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/CMakeLists.txt b/internal/frontend/bridge-gui/bridge-gui-tester/CMakeLists.txt index 705d0c8c..a22ba038 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/CMakeLists.txt +++ b/internal/frontend/bridge-gui/bridge-gui-tester/CMakeLists.txt @@ -65,8 +65,10 @@ endif() add_executable(bridge-gui-tester AppController.cpp AppController.h + Cert.cpp Cert.h main.cpp MainWindow.cpp MainWindow.h + GRPCMetaDataProcessor.cpp GRPCMetaDataProcessor.h GRPCQtProxy.cpp GRPCQtProxy.h GRPCService.cpp GRPCService.h GRPCServerWorker.cpp GRPCServerWorker.h diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Cert.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/Cert.cpp new file mode 100644 index 00000000..12839c43 --- /dev/null +++ b/internal/frontend/bridge-gui/bridge-gui-tester/Cert.cpp @@ -0,0 +1,74 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + + +#include "Cert.h" + + +// The following test TLS certificate and key are self-signed, and valid until October 2042. + +QString const testTLSCert = R"(-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIRANAfjBkSRx8LY96XwVNGT4MwDQYJKoZIhvcNAQELBQAw +SzELMAkGA1UEBhMCQ0gxEjAQBgNVBAoTCVByb3RvbiBBRzEUMBIGA1UECxMLUHJv +dG9uIE1haWwxEjAQBgNVBAMTCTEyNy4wLjAuMTAeFw0yMjEwMTAwNzI1MjFaFw00 +MjEwMDUwNzI1MjFaMEsxCzAJBgNVBAYTAkNIMRIwEAYDVQQKEwlQcm90b24gQUcx +FDASBgNVBAsTC1Byb3RvbiBNYWlsMRIwEAYDVQQDEwkxMjcuMC4wLjEwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3jJiMtwQMzsASB51LwWTd9TIXqh1U +F0rz+wugBPMRzoc4NfOjHpP/w6fey7Kc3wdM9wfhCQ7WgJaI+u3w5muL+ypLD1wB +KdBSiTp8pBRTvpJpaoGbl86gxsB6Rpimh+u/+1Dgh0A/b6cfvoa0gYk3PHR79oqS +Wy5EG0jCqqC9lGNBlCurAIbmY+pEF+9WKWhl+SfCOXJL+Z+rOdmhWlnWArONoKQ7 +qhOSwfJj+5xudE0s5tZL7C7XKEUCNufyXt5WhMfggEzHxFdoihpkF6VOR3d60aVW +OoTbmGYCqYFlW4omWMfstj/y5FchphwnZhZoJd8bSHNtKVc8OQNhauzFAgMBAAGj +cjBwMA4GA1UdDwEB/wQEAwICpDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH +AwIwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUI2canlIJDLw770sb2YlveYlX +SyIwDwYDVR0RBAgwBocEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAsdYfNSOLoJRf +GhQ6iS6Fue8IKwdskgTjqkBFR6xeEiGVhMCouEyQR/d+j7TwSfriWFCIsYhx8tFj +fLAawQfiU1FaLClhkdWXDndg/09mngS5r7xl6ZJZJccJ9NOo2Cq0q52iJQr1kIkm +79D6l02fvt9TbttQU5lpU9kcpRg/1YS9v1Tpi+5HUtRK/aN0C7A0zHD7uARJwjip +urUmty4xKsVtYNtJX0OUbmJkafZe9Kfb33C6ih0DwfUKuB5B32kzIVugk+DplK8j +02NiWsxh0wrw57N5iO1yLxHwNrMSvy2UI8In8QcPzGulyJDBVw/RpA4NQP4UOzoV +AZku+LvYcw== +-----END CERTIFICATE-----)"; + + +QString const testTLSKey = R"(-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAt4yYjLcEDM7AEgedS8Fk3fUyF6odVBdK8/sLoATzEc6HODXz +ox6T/8On3suynN8HTPcH4QkO1oCWiPrt8OZri/sqSw9cASnQUok6fKQUU76SaWqB +m5fOoMbAekaYpofrv/tQ4IdAP2+nH76GtIGJNzx0e/aKklsuRBtIwqqgvZRjQZQr +qwCG5mPqRBfvViloZfknwjlyS/mfqznZoVpZ1gKzjaCkO6oTksHyY/ucbnRNLObW +S+wu1yhFAjbn8l7eVoTH4IBMx8RXaIoaZBelTkd3etGlVjqE25hmAqmBZVuKJljH +7LY/8uRXIaYcJ2YWaCXfG0hzbSlXPDkDYWrsxQIDAQABAoIBAEL7P8A6GXRDDryF +otU+YfzNudYA8mr5hRS8DGX86GcbIyVUKvDf+8peMCiR1UCB8zwW+f0ZPRzyF/0s +9R/wNlcC9VAm7sBN7gPwqDNL/U8CQJPPljSdlX3+iccVdCdxeoq4v67wLHX53Ncs +xCOjEdviZ+/E7JS0SZH5EvhXJAmKOsKRlz0XU55Ra7N2SToz9j8WhX/do6RcufOY +Pxmdg9A2sm48Ps5dTl2RZvy/yDTt41U2YeXM+EAuYCmBmRyw/dWMB9q3h0a5+Gx7 +pkb0SvmUCfaN/WK3wlxJ+rfOp+xJSM5aA9zeSjQpAIif3poEsafENEG9sdpWDVtl +UrDwHQECgYEA4l79b5krz5c0bpRHYN+GnLkBrDOR+ZMiNBR5UVYDUJ769PvdMmbK +fhFBsU5diG/+6GZRbYPrXP1jcXHRHeJMwQFxbwOXU5YCJfoSLxSUyk6u5wGiMC5H +p2+WCd6w6mIe23PzgHlCbccAFDVZzC+R0pYsRj/jMsfuLNtGLz1tyLECgYEAz5LG +abRrrfUsjM3OyywJbAig8bSOV/IrOvIkTxJNQi9sw1rYEjG9wEqnz44H3hSSgY7c +aJuoS8ehHR/FdMpiwP4jWHK7T0Y2Jjrqo07iW8U/YedwPVvJiRKlwic13Px1h/Op +Hp2wdYh4L2Gcbi0krYd/RSFATmOjIJndp6w+alUCgYEAroSnBEtlEES1Am9EXDXX +lKm41WZoqq05GEeUhBU4twXp2cb28C14/RoWuDf/OfmF3utK6ZBjeqxK5yHlIxHd +NIsFRZ3SI3mprFePf0Zxs0pX4vZKcLStPzNyy6coY3pD6dIJr0lM4k8iC3JaCWW/ +GUf3WC1W3kZuo5xlDnRgV/ECgYEAnvZLZrYZ5I2nAWm3XVarHIX7Iz9f5y/5NVos +vjVI30/MXksav8xCAZnqq4OcuNFOZVOPrbjPCMGnu9MR91/qgtvdG6Y5lfsyCtMB +z/DgXuFOqd6A0SySyZtzP52hnUvlgijyshSXB1tslvSMxL9joFTs/Xb6dU3Opm/P +FNJOtkUCgYEAjxBLJt2cbE7LjAM2GA5txILUFJBh6Q2U7M922rzr+C7p9oUlx00Z +ZD7atctAQGMqhfBTL1Lxu2gJ3rr5NGVCFDUv1SaYC68nuRkbRD6mHbB8IGpUcmCi +YBADKClADQt7+Nn+ufSsypTpAo9X2gMGQqplSQlmPgoP8wCGbycC5iQ= +-----END RSA PRIVATE KEY-----)"; diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Cert.h b/internal/frontend/bridge-gui/bridge-gui-tester/Cert.h new file mode 100644 index 00000000..66a0be52 --- /dev/null +++ b/internal/frontend/bridge-gui/bridge-gui-tester/Cert.h @@ -0,0 +1,27 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + + +#ifndef BRIDGE_GUI_TESTER_CERT_H +#define BRIDGE_GUI_TESTER_CERT_H + + +extern QString const testTLSCert; ///< The test TLS Cert used by the app, in PEM format. +extern QString const testTLSKey; ///< The test TLS Key used by the app, in PEM format. + + +#endif //BRIDGE_GUI_TESTER_CERT_H diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCMetaDataProcessor.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCMetaDataProcessor.cpp new file mode 100644 index 00000000..78185015 --- /dev/null +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCMetaDataProcessor.cpp @@ -0,0 +1,81 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + + +#include "GRPCMetaDataProcessor.h" +#include +#include + + +using namespace bridgepp; +using namespace grpc; + + +//**************************************************************************************************************************************************** +/// \param[in] The server token expected from gRPC calls +//**************************************************************************************************************************************************** +GRPCMetadataProcessor::GRPCMetadataProcessor(QString const &serverToken) + : serverToken_(serverToken.toStdString()) +{ + +} + + +//**************************************************************************************************************************************************** +/// \return false. +//**************************************************************************************************************************************************** +bool GRPCMetadataProcessor::IsBlocking() const +{ + return false; +} + + +//**************************************************************************************************************************************************** +/// \param[in] inputMeta +/// \return the result of the metadata processing. +//**************************************************************************************************************************************************** +Status GRPCMetadataProcessor::Process(AuthMetadataProcessor::InputMetadata const &auth_metadata, AuthContext *, + AuthMetadataProcessor::OutputMetadata *, AuthMetadataProcessor::OutputMetadata *) +{ + try + { + AuthMetadataProcessor::InputMetadata::const_iterator pathIt = auth_metadata.find(":path"); + QString const callName = (pathIt == auth_metadata.end()) ? ("unkown gRPC call") : QString::fromLocal8Bit(pathIt->second); + + AuthMetadataProcessor::InputMetadata::size_type const count = auth_metadata.count(grpcMetadataServerTokenKey); + if (count == 0) + throw Exception(QString("Missing server token in gRPC client call '%1'.").arg(callName)); + + if (count > 1) + throw Exception(QString("Several server tokens were provided in gRPC client call '%1'.").arg(callName)); + + if (auth_metadata.find(grpcMetadataServerTokenKey)->second != serverToken_) + throw Exception(QString("Invalid server token provided by gRPC client call '%1'.").arg(callName)); + + app().log().trace(QString("Server token for gRPC call '%1' was validated.").arg(callName)); + return Status::OK; + } + catch (Exception const &e) + { + app().log().error(e.qwhat()); + return Status(StatusCode::UNAUTHENTICATED, e.qwhat().toStdString()); + } +} + + + + diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCMetaDataProcessor.h b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCMetaDataProcessor.h new file mode 100644 index 00000000..04864c87 --- /dev/null +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCMetaDataProcessor.h @@ -0,0 +1,50 @@ +// Copyright (c) 2022 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + + +#ifndef BRIDGE_GUI_TESTER_GRPC_METADATA_PROCESSOR_H +#define BRIDGE_GUI_TESTER_GRPC_METADATA_PROCESSOR_H + + +#include + + +//**************************************************************************************************************************************************** +/// \brief Metadata processor class in charge of checking the server token provided by client calls and stream requests. +//**************************************************************************************************************************************************** +class GRPCMetadataProcessor: public grpc::AuthMetadataProcessor +{ +public: // member functions. + GRPCMetadataProcessor(QString const &serverToken); ///< Default constructor. + GRPCMetadataProcessor(GRPCMetadataProcessor const&) = delete; ///< Disabled copy-constructor. + GRPCMetadataProcessor(GRPCMetadataProcessor&&) = delete; ///< Disabled assignment copy-constructor. + ~GRPCMetadataProcessor() = default; ///< Destructor. + GRPCMetadataProcessor& operator=(GRPCMetadataProcessor const&) = delete; ///< Disabled assignment operator. + GRPCMetadataProcessor& operator=(GRPCMetadataProcessor&&) = delete; ///< Disabled move assignment operator. + bool IsBlocking() const override; ///< Is the processor blocking? + grpc::Status Process(InputMetadata const &auth_metadata, grpc::AuthContext *context, OutputMetadata *consumed_auth_metadata, + OutputMetadata *response_metadata) override; ///< Process the metadata + +private: + std::string serverToken_; ///< The server token, as a std::string. +}; + + +typedef std::shared_ptr SPMetadataProcessor; ///< Type definition for shared pointer to MetadataProcessor. + + +#endif //BRIDGE_GUI_TESTER_GRPC_METADATA_PROCESSOR_H diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCServerWorker.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCServerWorker.cpp index f15ae895..fb7af161 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCServerWorker.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCServerWorker.cpp @@ -17,31 +17,17 @@ #include "GRPCServerWorker.h" +#include "Cert.h" #include "GRPCService.h" #include #include +#include using namespace bridgepp; using namespace grpc; -namespace -{ - - -//**************************************************************************************************************************************************** -/// \return The content of the file. -//**************************************************************************************************************************************************** -QString loadAsciiTextFile(QString const &path) { - QFile file(path); - return file.open(QIODevice::ReadOnly | QIODevice::Text) ? QString::fromLocal8Bit(file.readAll()) : QString(); -} - - -} - - //**************************************************************************************************************************************************** // //**************************************************************************************************************************************************** @@ -61,30 +47,34 @@ void GRPCServerWorker::run() { emit started(); - QString cert = loadAsciiTextFile(serverCertificatePath()); - if (cert.isEmpty()) - throw Exception("Could not locate server certificate. Make sure to launch bridge once before starting this application"); - - QString key = loadAsciiTextFile(serverKeyPath()); - if (key.isEmpty()) - throw Exception("Could not locate server key. Make sure to launch bridge once before starting this application"); - SslServerCredentialsOptions::PemKeyCertPair pair; - pair.private_key = key.toStdString(); - pair.cert_chain = cert.toStdString(); + pair.private_key = testTLSKey.toStdString(); + pair.cert_chain = testTLSCert.toStdString(); SslServerCredentialsOptions ssl_opts; ssl_opts.pem_root_certs=""; ssl_opts.pem_key_cert_pairs.push_back(pair); std::shared_ptr credentials = grpc::SslServerCredentials(ssl_opts); + GRPCConfig config; + config.cert = testTLSCert; + config.token = QUuid::createUuid().toString(); + processor_ = std::make_shared(config.token); + credentials->SetAuthMetadataProcessor(processor_); // gRPC interceptors are still experimental in C++, so we use AuthMetadataProcessor ServerBuilder builder; - builder.AddListeningPort("127.0.0.1:9292", credentials); + int port = 0; // Port will not be known until ServerBuilder::BuildAndStart() is called + builder.AddListeningPort("127.0.0.1:0", credentials, &port); builder.RegisterService(&app().grpc()); server_ = builder.BuildAndStart(); + if (!server_) throw Exception("Could not create gRPC server."); app().log().debug("gRPC Server started."); + config.port = port; + QString err; + if (!config.save(grpcServerConfigPath(), &err)) + throw Exception(QString("Could not save gRPC server config. %1").arg(err)); + server_->Wait(); emit finished(); app().log().debug("gRPC Server exited."); @@ -107,3 +97,5 @@ void GRPCServerWorker::stop() if (server_) server_->Shutdown(); } + + diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCServerWorker.h b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCServerWorker.h index 8a881ba8..5df58309 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCServerWorker.h +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCServerWorker.h @@ -21,6 +21,7 @@ #include +#include "GRPCMetaDataProcessor.h" #include "GRPCService.h" #include @@ -44,6 +45,7 @@ public: // member functions. private: // data members std::unique_ptr server_ { nullptr }; ///< The gRPC server. + SPMetadataProcessor processor_; }; diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp index 90c7704f..3628210b 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp @@ -20,6 +20,7 @@ #include "MainWindow.h" #include #include +#include using namespace grpc; @@ -55,6 +56,28 @@ bool GRPCService::isStreaming() const } +//**************************************************************************************************************************************************** +/// \param[in] request The request. +/// \param[out] response The response. +//**************************************************************************************************************************************************** +Status GRPCService::CheckTokens(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::StringValue *response) +{ + Log& log = app().log(); + log.debug(__FUNCTION__); + GRPCConfig config; + QString error; + if (!config.load(QString::fromStdString(request->value()), &error)) + { + QString const err = "Could not load gRPC client config"; + log.error(err); + return grpc::Status(StatusCode::UNAUTHENTICATED, err.toStdString()); + } + + response->set_value(config.token.toStdString()); + return grpc::Status::OK; +} + + //**************************************************************************************************************************************************** /// \param[in] request the request. /// \return The status for the call. diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h index af9c5181..fb19786d 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h @@ -40,7 +40,7 @@ public: // member functions. GRPCService &operator=(GRPCService &&) = delete; ///< Disabled move assignment operator. void connectProxySignals(); ///< Connect the signals of the Qt Proxy to the GUI components bool isStreaming() const; ///< Check if the service is currently streaming events. - + grpc::Status CheckTokens(::grpc::ServerContext *context, ::google::protobuf::StringValue const *request, ::google::protobuf::StringValue *response) override; grpc::Status AddLogEntry(::grpc::ServerContext *, ::grpc::AddLogEntryRequest const *request, ::google::protobuf::Empty *) override; grpc::Status GuiReady(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::Empty *) override; grpc::Status Quit(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::Empty *) override; diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/main.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/main.cpp index 9e828eb8..53056edd 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/main.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/main.cpp @@ -59,6 +59,7 @@ int main(int argc, char **argv) Log& log = app().log(); log.setEchoInConsole(true); + log.setLevel(Log::Level::Debug); log.info(QString("%1 started.").arg(applicationName)); MainWindow window(nullptr); diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp index d161953a..2178486e 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp @@ -1443,7 +1443,7 @@ void GRPCClient::processUserEvent(UserEvent const &event) UPClientContext GRPCClient::clientContext() const { auto ctx = std::make_unique(); - ctx->AddMetadata("server-token", serverToken_); + ctx->AddMetadata(grpcMetadataServerTokenKey, serverToken_); return ctx; } diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCUtils.cpp b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCUtils.cpp index 2cd8ca2b..afdc3fb0 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCUtils.cpp +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCUtils.cpp @@ -26,6 +26,9 @@ namespace bridgepp { +std::string const grpcMetadataServerTokenKey = "server-token"; + + namespace { diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCUtils.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCUtils.h index dfbd8aa1..b106b304 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCUtils.h +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCUtils.h @@ -29,6 +29,9 @@ namespace bridgepp { +extern std::string const grpcMetadataServerTokenKey; ///< The key for the server token stored in the gRPC calls context metadata. + + typedef std::shared_ptr SPStreamEvent; ///< Type definition for shared pointer to grpc::StreamEvent. QString grpcServerConfigPath(); ///< Return the path of the gRPC server config file.