diff --git a/internal/frontend/bridge-gui/AppController.cpp b/internal/frontend/bridge-gui/AppController.cpp
index 579a9005..0d6fe09d 100644
--- a/internal/frontend/bridge-gui/AppController.cpp
+++ b/internal/frontend/bridge-gui/AppController.cpp
@@ -16,13 +16,15 @@
// along with Proton Mail Bridge. If not, see .
-#include "Pch.h"
#include "AppController.h"
#include "QMLBackend.h"
-#include "GRPC/GRPCClient.h"
-#include "Log.h"
#include "BridgeMonitor.h"
-#include "Exception.h"
+#include
+#include
+#include
+
+
+using namespace bridgepp;
//****************************************************************************************************************************************************
@@ -43,7 +45,6 @@ AppController::AppController()
, grpc_(std::make_unique())
, log_(std::make_unique())
{
-
}
diff --git a/internal/frontend/bridge-gui/AppController.h b/internal/frontend/bridge-gui/AppController.h
index b8117a64..82e93972 100644
--- a/internal/frontend/bridge-gui/AppController.h
+++ b/internal/frontend/bridge-gui/AppController.h
@@ -21,10 +21,16 @@
class QMLBackend;
-class GRPCClient;
+class BridgeMonitor;
+
+
+namespace bridgepp
+{
class Log;
class Overseer;
-class BridgeMonitor;
+class GRPCClient;
+}
+
//****************************************************************************************************************************************************
/// \brief App controller class.
@@ -41,9 +47,9 @@ public: // member functions.
AppController& operator=(AppController const&) = delete; ///< Disabled assignment operator.
AppController& operator=(AppController&&) = delete; ///< Disabled move assignment operator.
QMLBackend& backend() { return *backend_; } ///< Return a reference to the backend.
- GRPCClient& grpc() { return *grpc_; } ///< Return a reference to the GRPC client.
- Log& log() { return *log_; } ///< Return a reference to the log.
- std::unique_ptr& bridgeOverseer() { return bridgeOverseer_; }; ///< Returns a reference the bridge overseer
+ bridgepp::GRPCClient& grpc() { return *grpc_; } ///< Return a reference to the GRPC client.
+ bridgepp::Log& log() { return *log_; } ///< Return a reference to the log.
+ std::unique_ptr& bridgeOverseer() { return bridgeOverseer_; }; ///< Returns a reference the bridge overseer
BridgeMonitor* bridgeMonitor() const; ///< Return the bridge worker.
private: // member functions
@@ -51,9 +57,9 @@ private: // member functions
private: // data members
std::unique_ptr backend_; ///< The backend.
- std::unique_ptr grpc_; ///< The RPC client.
- std::unique_ptr log_; ///< The log.
- std::unique_ptr bridgeOverseer_; ///< The overseer for the bridge monitor worker.
+ std::unique_ptr grpc_; ///< The RPC client.
+ std::unique_ptr log_; ///< The log.
+ std::unique_ptr bridgeOverseer_; ///< The overseer for the bridge monitor worker.
};
diff --git a/internal/frontend/bridge-gui/BridgeMonitor.cpp b/internal/frontend/bridge-gui/BridgeMonitor.cpp
index 9750e2db..435ebd6e 100644
--- a/internal/frontend/bridge-gui/BridgeMonitor.cpp
+++ b/internal/frontend/bridge-gui/BridgeMonitor.cpp
@@ -17,7 +17,10 @@
#include "BridgeMonitor.h"
-#include "Exception.h"
+#include
+
+
+using namespace bridgepp;
namespace
diff --git a/internal/frontend/bridge-gui/BridgeMonitor.h b/internal/frontend/bridge-gui/BridgeMonitor.h
index be6aee3f..f3e1f640 100644
--- a/internal/frontend/bridge-gui/BridgeMonitor.h
+++ b/internal/frontend/bridge-gui/BridgeMonitor.h
@@ -21,13 +21,13 @@
#define BRIDGE_GUI_BRIDGE_MONITOR_H
-#include "Worker/Worker.h"
+#include
//**********************************************************************************************************************
/// \brief Bridge process launcher and monitor class.
//**********************************************************************************************************************
-class BridgeMonitor: public Worker
+class BridgeMonitor: public bridgepp::Worker
{
Q_OBJECT
public: // static member functions
diff --git a/internal/frontend/bridge-gui/CMakeLists.txt b/internal/frontend/bridge-gui/CMakeLists.txt
index e07cc397..6740109f 100644
--- a/internal/frontend/bridge-gui/CMakeLists.txt
+++ b/internal/frontend/bridge-gui/CMakeLists.txt
@@ -17,41 +17,16 @@
cmake_minimum_required(VERSION 3.22)
-# We rely on vcpkg for to get gRPC / Protobuf
-# run build.sh / build.ps1 to get gRPC / Protobuf and dependencies installed.
+include_guard()
set(VCPKG_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../../extern/vcpkg")
-message(STATUS "VCPKG_ROOT is ${VCPKG_ROOT}")
-if (WIN32)
- find_program(VCPKG_EXE "${VCPKG_ROOT}/vcpkg.exe")
-else()
- find_program(VCPKG_EXE "${VCPKG_ROOT}/vcpkg")
-endif()
+include(../bridgepp/bridge_setup.cmake)
-# For now we support only a single architecture for macOS (ARM64 or x86_64). We need to investigate how to build universal binaries with vcpkg.
-if (APPLE)
- if (NOT DEFINED CMAKE_OSX_ARCHITECTURES)
- execute_process(COMMAND "uname" "-m" OUTPUT_VARIABLE UNAME_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
- set(CMAKE_OSX_ARCHITECTURES ${UNAME_RESULT} CACHE STRING "osx_architectures")
- endif()
+#*****************************************************************************************************************************************************
+# Project
+#*****************************************************************************************************************************************************
- if (CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
- message(STATUS "Building for Apple Silicon Mac computers")
- set(VCPKG_TARGET_TRIPLET arm64-osx)
- elseif (CMAKE_OSX_ARCHITECTURES STREQUAL "x86_64")
- message(STATUS "Building for Intel based Mac computers")
- set(VCPKG_TARGET_TRIPLET x64-osx)
- else ()
- message(FATAL_ERROR "Unknown value for CMAKE_OSX_ARCHITECTURE. Please use one of \"arm64\" and \"x86_64\". Multiple architectures are not supported.")
- endif ()
-endif()
-
-if (WIN32)
- message(STATUS "Building for Intel x64 Windows computers")
- set(VCPKG_TARGET_TRIPLET x64-windows)
-endif()
-set(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "toolchain")
project(bridge-gui LANGUAGES CXX)
@@ -61,116 +36,70 @@ else()
message(STATUS "Bridge version is ${BRIDGE_APP_VERSION}")
endif()
-configure_file(Version.h.in ${CMAKE_SOURCE_DIR}/Version.h)
if (APPLE) # On macOS, we have some Objective-C++ code in DockIcon to deal with the dock icon.
enable_language(OBJC OBJCXX)
endif()
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+if (APPLE) # We need to link the Cocoa framework for the dock icon.
+ find_library(COCOA_LIBRARY Cocoa REQUIRED)
+endif()
+
+
+#*****************************************************************************************************************************************************
+# Qt
+#*****************************************************************************************************************************************************
+
+
if (NOT DEFINED ENV{QT6DIR})
message(FATAL_ERROR "QT6DIR needs to be defined and point to the root of your Qt 6 folder (e.g. /Users/MyName/Qt/6.3.1/clang_64).")
endif()
set(CMAKE_PREFIX_PATH $ENV{QT6DIR} ${CMAKE_PREFIX_PATH})
-set(CMAKE_CXX_STANDARD 20)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_AUTOMOC ON)
+find_package(Qt6 COMPONENTS Core Quick Qml QuickControls2 REQUIRED)
+qt_standard_project_setup()
set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-find_package(Protobuf CONFIG REQUIRED)
-message(STATUS "Using protobuf ${Protobuf_VERSION}")
-
-
-find_package(gRPC CONFIG REQUIRED)
-message(STATUS "Using gRPC ${gRPC_VERSION}")
-
-
-if (APPLE) # We need to link the Cocoa framework for the dock icon.
- find_library(COCOA_LIBRARY Cocoa REQ UIRED)
-endif()
-
-
-find_package(Qt6 COMPONENTS
- Core
- Quick
- Qml
- QuickControls2
- REQUIRED)
message(STATUS "Using Qt ${Qt6_VERSION}")
-find_program(PROTOC_EXE protoc REQUIRED)
-message(STATUS "protoc found ${PROTOC_EXE}")
-message(STATUS "grpc_cpp_plugin ${grpc_cpp_plugin}")
+#*****************************************************************************************************************************************************
+# Source files and output
+#*****************************************************************************************************************************************************
-find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin)
-if(GRPC_CPP_PLUGIN STREQUAL GRPC_CPP_PLUGIN-NOTFOUND)
-message(FATAL_ERROR "grpc_cpp_plugin exe could not be found. Please add it to your path. it should be located in \${VCPKG_ROOT}/installed/arm64-osx/tools/grpc")
-else()
- message(STATUS "grpc_cpp_plugin found at ${GRPC_CPP_PLUGIN}")
-endif()
-set(PROTO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../grpc")
-set(PROTO_FILE "${PROTO_DIR}/bridge.proto")
-set(GRPC_OUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/GRPC")
-set(PROTO_CPP_FILE "${GRPC_OUT_DIR}/bridge.pb.cc")
-set(PROTO_H_FILE "${GRPC_OUT_DIR}/bridge.pb.h")
-set(GRPC_CPP_FILE "${GRPC_OUT_DIR}/bridge.grpc.pb.cc")
-set(GRPC_H_FILE "${GRPC_OUT_DIR}/bridge.grpc.pb.h")
+configure_file(Version.h.in ${CMAKE_SOURCE_DIR}/Version.h)
+
+add_subdirectory(../bridgepp bridgepp)
+
if (APPLE)
set(DOCK_ICON_SRC_FILE DockIcon/DockIcon.mm)
else()
set(DOCK_ICON_SRC_FILE DockIcon/DockIcon.cpp)
endif()
-add_custom_command(
- OUTPUT
- ${PROTO_CPP_FILE}
- ${PROTO_H_FILE}
- ${GRPC_CPP_FILE}
- ${GRPC_H_FILE}
- COMMAND
- ${PROTOC_EXE}
- ARGS
- --proto_path=${PROTO_DIR}
- --plugin=protoc-gen-grpc="${GRPC_CPP_PLUGIN}"
- --cpp_out=${GRPC_OUT_DIR}
- --grpc_out=${GRPC_OUT_DIR}
- ${PROTO_FILE}
- DEPENDS
- ${PROTO_FILE}
- COMMENT "Generating gPRC/Protobuf C++ code"
-)
-
add_executable(bridge-gui
Resources.qrc
- ${PROTO_CPP_FILE} ${PROTO_H_FILE} ${GRPC_CPP_FILE} ${GRPC_H_FILE}
AppController.cpp AppController.h
BridgeMonitor.cpp BridgeMonitor.h
EventStreamWorker.cpp EventStreamWorker.h
- Exception.cpp Exception.h
- Log.cpp Log.h
main.cpp
Pch.h
Version.h
QMLBackend.cpp QMLBackend.h
+ UserList.cpp UserList.h
${DOCK_ICON_SRC_FILE} DockIcon/DockIcon.h
- GRPC/GRPCClient.cpp GRPC/GRPCClient.h
- GRPC/GRPCUtils.cpp GRPC/GRPCUtils.h
- User/User.cpp User/User.h User/UserList.cpp User/UserList.h
- Worker/Overseer.cpp Worker/Overseer.h
- Worker/Worker.h)
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+ )
target_precompile_headers(bridge-gui PRIVATE Pch.h)
-
+target_include_directories(bridge-gui PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(bridge-gui
Qt6::Core
Qt6::Quick
Qt6::Qml
Qt6::QuickControls2
- protobuf::libprotobuf
- gRPC::grpc++
+ bridgepp
)
if (APPLE)
diff --git a/internal/frontend/bridge-gui/DockIcon/DockIcon.cpp b/internal/frontend/bridge-gui/DockIcon/DockIcon.cpp
index d9901910..f7df4372 100644
--- a/internal/frontend/bridge-gui/DockIcon/DockIcon.cpp
+++ b/internal/frontend/bridge-gui/DockIcon/DockIcon.cpp
@@ -16,7 +16,6 @@
// along with Proton Mail Bridge. If not, see .
-#include "Pch.h"
#ifndef Q_OS_MACOS
diff --git a/internal/frontend/bridge-gui/DockIcon/DockIcon.mm b/internal/frontend/bridge-gui/DockIcon/DockIcon.mm
index 0b2bfd4f..471dc77f 100644
--- a/internal/frontend/bridge-gui/DockIcon/DockIcon.mm
+++ b/internal/frontend/bridge-gui/DockIcon/DockIcon.mm
@@ -16,7 +16,6 @@
// along with Proton Mail Bridge. If not, see .
-#include "Pch.h"
#include
#include "DockIcon.h"
diff --git a/internal/frontend/bridge-gui/EventStreamWorker.cpp b/internal/frontend/bridge-gui/EventStreamWorker.cpp
index c133582f..63012df3 100644
--- a/internal/frontend/bridge-gui/EventStreamWorker.cpp
+++ b/internal/frontend/bridge-gui/EventStreamWorker.cpp
@@ -16,11 +16,13 @@
// along with Proton Mail Bridge. If not, see .
-#include "Pch.h"
#include "EventStreamWorker.h"
-#include "GRPC/GRPCClient.h"
-#include "Log.h"
-#include "Exception.h"
+#include
+#include
+#include
+
+
+using namespace bridgepp;
//****************************************************************************************************************************************************
diff --git a/internal/frontend/bridge-gui/EventStreamWorker.h b/internal/frontend/bridge-gui/EventStreamWorker.h
index 293dceb1..e9976b19 100644
--- a/internal/frontend/bridge-gui/EventStreamWorker.h
+++ b/internal/frontend/bridge-gui/EventStreamWorker.h
@@ -20,14 +20,13 @@
#define BRIDGE_GUI_EVENT_STREAM_WORKER_H
-#include "GRPC/bridge.grpc.pb.h"
-#include "Worker/Worker.h"
+#include
//****************************************************************************************************************************************************
/// \brief Stream reader class.
//****************************************************************************************************************************************************
-class EventStreamReader: public Worker
+class EventStreamReader: public bridgepp::Worker
{
Q_OBJECT
public: // member functions
diff --git a/internal/frontend/bridge-gui/GRPC/GRPCUtils.cpp b/internal/frontend/bridge-gui/GRPC/GRPCUtils.cpp
deleted file mode 100644
index 729e1af2..00000000
--- a/internal/frontend/bridge-gui/GRPC/GRPCUtils.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-// 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 "Pch.h"
-#include "Exception.h"
-#include "GRPCUtils.h"
-
-
-//****************************************************************************************************************************************************
-/// \param[in] status The status
-/// \param[in] callName The call name.
-//****************************************************************************************************************************************************
-void logGRPCCallStatus(grpc::Status const& status, QString const &callName)
-{
- if (status.ok())
- app().log().debug(QString("%1()").arg(callName));
- else
- app().log().error(QString("%1() FAILED").arg(callName));
-}
-
-
-//****************************************************************************************************************************************************
-/// \param[in] grpcUser the gRPC user struct
-/// \return a user.
-//****************************************************************************************************************************************************
-SPUser parsegrpcUser(grpc::User const &grpcUser)
-{
- // As we want to use shared pointers here, we do not want to use the Qt ownership system, so we set parent to nil.
- // But: From https://doc.qt.io/qt-5/qtqml-cppintegration-data.html:
- // " When data is transferred from C++ to QML, the ownership of the data always remains with C++. The exception to this rule
- // is when a QObject is returned from an explicit C++ method call: in this case, the QML engine assumes ownership of the object. "
- // This is the case here, so we explicitely indicate that the object is owned by C++.
- SPUser user = std::make_shared(nullptr);
- QQmlEngine::setObjectOwnership(user.get(), QQmlEngine::CppOwnership);
- user->setProperty("username", QString::fromStdString(grpcUser.username()));
- user->setProperty("avatarText", QString::fromStdString(grpcUser.avatartext()));
- user->setProperty("loggedIn", grpcUser.loggedin());
- user->setProperty("splitMode", grpcUser.splitmode());
- user->setProperty("setupGuideSeen", grpcUser.setupguideseen());
- user->setProperty("usedBytes", float(grpcUser.usedbytes()));
- user->setProperty("totalBytes", float(grpcUser.totalbytes()));
- user->setProperty("password", QString::fromStdString(grpcUser.password()));
- QStringList addresses;
- for (int j = 0; j < grpcUser.addresses_size(); ++j)
- addresses.append(QString::fromStdString(grpcUser.addresses(j)));
- user->setProperty("addresses", addresses);
- user->setProperty("id", QString::fromStdString(grpcUser.id()));
- return user;
-}
-
-
-//****************************************************************************************************************************************************
-/// \param[in] level The log level
-//****************************************************************************************************************************************************
-grpc::LogLevel logLevelToGRPC(Log::Level level)
-{
- switch (level)
- {
- case Log::Level::Panic: return grpc::LogLevel::PANIC;
- case Log::Level::Fatal: return grpc::LogLevel::FATAL;
- case Log::Level::Error: return grpc::LogLevel::ERROR;
- case Log::Level::Warn: return grpc::LogLevel::WARN;
- case Log::Level::Info: return grpc::LogLevel::INFO;
- case Log::Level::Debug: return grpc::LogLevel::DEBUG;
- case Log::Level::Trace: return grpc::LogLevel::TRACE;
- default:
- throw Exception(QString("unknown log level %1.").arg(qint32(level)));
- }
-}
diff --git a/internal/frontend/bridge-gui/Pch.h b/internal/frontend/bridge-gui/Pch.h
index a6f1bfcc..d18a9fb3 100644
--- a/internal/frontend/bridge-gui/Pch.h
+++ b/internal/frontend/bridge-gui/Pch.h
@@ -27,11 +27,4 @@
#include
-#if defined(Q_OS_WIN32) && defined(ERROR)
-// The folks at Microsoft have decided that it was OK to `#define ERROR 0` in wingdi.h. It is not OK, because
-// any occurrence of ERROR, even scoped, will be substituted. For instance Log::Level::ERROR (case imposed by gRPC).
-#undef ERROR
-#endif
-
-
#endif // BRIDGE_GUI_PCH_H
diff --git a/internal/frontend/bridge-gui/QMLBackend.cpp b/internal/frontend/bridge-gui/QMLBackend.cpp
index 355edcc4..21fbd80c 100644
--- a/internal/frontend/bridge-gui/QMLBackend.cpp
+++ b/internal/frontend/bridge-gui/QMLBackend.cpp
@@ -16,13 +16,15 @@
// along with Proton Mail Bridge. If not, see .
-#include "Pch.h"
#include "QMLBackend.h"
-#include "Exception.h"
-#include "GRPC/GRPCClient.h"
-#include "Worker/Overseer.h"
#include "EventStreamWorker.h"
#include "Version.h"
+#include
+#include
+#include
+
+
+using namespace bridgepp;
//****************************************************************************************************************************************************
@@ -30,7 +32,6 @@
//****************************************************************************************************************************************************
QMLBackend::QMLBackend()
: QObject()
- , users_(new UserList(this))
{
}
@@ -40,6 +41,9 @@ QMLBackend::QMLBackend()
//****************************************************************************************************************************************************
void QMLBackend::init()
{
+ users_ = new UserList(this);
+
+ app().grpc().setLog(&app().log());
this->connectGrpcEvents();
QString error;
@@ -47,10 +51,11 @@ void QMLBackend::init()
app().log().info("Connected to backend via gRPC service.");
else
throw Exception(QString("Cannot connectToServer to go backend via gRPC: %1").arg(error));
+
QString bridgeVer;
app().grpc().version(bridgeVer);
if (bridgeVer != PROJECT_VER)
- throw Exception(QString("Version Mismatched from Bridge (%1) and Bridge-GUI (%2)").arg(bridgeVer).arg(PROJECT_VER));
+ throw Exception(QString("Version Mismatched from Bridge (%1) and Bridge-GUI (%2)").arg(bridgeVer, PROJECT_VER));
eventStreamOverseer_ = std::make_unique(new EventStreamReader(nullptr), nullptr);
eventStreamOverseer_->startWorker(true);
@@ -60,10 +65,10 @@ void QMLBackend::init()
});
// Grab from bridge the value that will not change during the execution of this app (or that will only change locally
- logGRPCCallStatus(app().grpc().showSplashScreen(showSplashScreen_), "showSplashScreen");
- logGRPCCallStatus(app().grpc().goos(goos_), "goos");
- logGRPCCallStatus(app().grpc().logsPath(logsPath_), "logsPath");
- logGRPCCallStatus(app().grpc().licensePath(licensePath_), "licensePath");
+ app().grpc().showSplashScreen(showSplashScreen_);
+ app().grpc().goos(goos_);
+ app().grpc().logsPath(logsPath_);
+ app().grpc().licensePath(licensePath_);
this->retrieveUserList();
}
@@ -147,7 +152,16 @@ void QMLBackend::connectGrpcEvents()
void QMLBackend::retrieveUserList()
{
QList users;
- logGRPCCallStatus(app().grpc().getUserList(users), "getUserList");
+ app().grpc().getUserList(users);
+
+ // As we want to use shared pointers here, we do not want to use the Qt ownership system, so we set parent to nil.
+ // But: From https://doc.qt.io/qt-5/qtqml-cppintegration-data.html:
+ // " When data is transferred from C++ to QML, the ownership of the data always remains with C++. The exception to this rule
+ // is when a QObject is returned from an explicit C++ method call: in this case, the QML engine assumes ownership of the object. "
+ // This is the case here, so we explicitly indicate that the object is owned by C++.
+ for (SPUser const& user: users)
+ QQmlEngine::setObjectOwnership(user.get(), QQmlEngine::CppOwnership);
+
users_->reset(users);
}
@@ -176,7 +190,7 @@ QPoint QMLBackend::getCursorPos()
bool QMLBackend::isPortFree(int port)
{
bool isFree = false;
- logGRPCCallStatus(app().grpc().isPortFree(port, isFree), "isPortFree");
+ app().grpc().isPortFree(port, isFree);
return isFree;
}
@@ -186,7 +200,7 @@ bool QMLBackend::isPortFree(int port)
//****************************************************************************************************************************************************
void QMLBackend::guiReady()
{
- logGRPCCallStatus(app().grpc().guiReady(), "guiReady");
+ app().grpc().guiReady();
}
@@ -195,7 +209,7 @@ void QMLBackend::guiReady()
//****************************************************************************************************************************************************
void QMLBackend::quit()
{
- logGRPCCallStatus(app().grpc().quit(), "quit");
+ app().grpc().quit();
qApp->exit(0);
}
@@ -205,7 +219,7 @@ void QMLBackend::quit()
//****************************************************************************************************************************************************
void QMLBackend::restart()
{
- logGRPCCallStatus(app().grpc().restart(), "restart");
+ app().grpc().restart();
app().log().error("RESTART is not implemented"); /// \todo GODT-1671 implement restart.
}
@@ -215,7 +229,7 @@ void QMLBackend::restart()
//****************************************************************************************************************************************************
void QMLBackend::toggleAutostart(bool active)
{
- logGRPCCallStatus(app().grpc().setIsAutostartOn(active), "setIsAutostartOn");
+ app().grpc().setIsAutostartOn(active);
emit isAutostartOnChanged(this->isAutostartOn());
}
@@ -225,7 +239,7 @@ void QMLBackend::toggleAutostart(bool active)
//****************************************************************************************************************************************************
void QMLBackend::toggleBeta(bool active)
{
- logGRPCCallStatus(app().grpc().setisBetaEnabled(active), "setIsBetaEnabled");
+ app().grpc().setIsBetaEnabled(active);
emit isBetaEnabledChanged(this->isBetaEnabled());
}
@@ -235,7 +249,7 @@ void QMLBackend::toggleBeta(bool active)
//****************************************************************************************************************************************************
void QMLBackend::changeColorScheme(QString const &scheme)
{
- logGRPCCallStatus(app().grpc().setColorSchemeName(scheme), "setIsBetaEnabled");
+ app().grpc().setColorSchemeName(scheme);
emit colorSchemeNameChanged(this->colorSchemeName());
}
@@ -245,9 +259,7 @@ void QMLBackend::changeColorScheme(QString const &scheme)
//****************************************************************************************************************************************************
void QMLBackend::toggleUseSSLforSMTP(bool makeItActive)
{
- grpc::Status status = app().grpc().setUseSSLForSMTP(makeItActive);
- logGRPCCallStatus(status, "setUseSSLForSMTP");
- if (status.ok())
+ if (app().grpc().setUseSSLForSMTP(makeItActive).ok())
emit useSSLforSMTPChanged(makeItActive);
}
@@ -258,9 +270,7 @@ void QMLBackend::toggleUseSSLforSMTP(bool makeItActive)
//****************************************************************************************************************************************************
void QMLBackend::changePorts(int imapPort, int smtpPort)
{
- grpc::Status status = app().grpc().changePorts(imapPort, smtpPort);
- logGRPCCallStatus(status, "changePorts");
- if (status.ok())
+ if (app().grpc().changePorts(imapPort, smtpPort).ok())
{
emit portIMAPChanged(imapPort);
emit portSMTPChanged(smtpPort);
@@ -273,9 +283,7 @@ void QMLBackend::changePorts(int imapPort, int smtpPort)
//****************************************************************************************************************************************************
void QMLBackend::toggleDoH(bool active)
{
- grpc::Status status = app().grpc().setIsDoHEnabled(active);
- logGRPCCallStatus(status, "toggleDoH");
- if (status.ok())
+ if (app().grpc().setIsDoHEnabled(active).ok())
emit isDoHEnabledChanged(active);
}
@@ -285,9 +293,7 @@ void QMLBackend::toggleDoH(bool active)
//****************************************************************************************************************************************************
void QMLBackend::changeKeychain(QString const &keychain)
{
- grpc::Status status = app().grpc().setCurrentKeychain(keychain);
- logGRPCCallStatus(status, "setCurrentKeychain");
- if (status.ok())
+ if (app().grpc().setCurrentKeychain(keychain).ok())
emit currentKeychainChanged(keychain);
}
@@ -297,9 +303,7 @@ void QMLBackend::changeKeychain(QString const &keychain)
//****************************************************************************************************************************************************
void QMLBackend::toggleAutomaticUpdate(bool active)
{
- grpc::Status status = app().grpc().setIsAutomaticUpdateOn(active);
- logGRPCCallStatus(status, "toggleAutomaticUpdate");
- if (status.ok())
+ if (app().grpc().setIsAutomaticUpdateOn(active).ok())
emit isAutomaticUpdateOnChanged(active);
}
@@ -309,7 +313,7 @@ void QMLBackend::toggleAutomaticUpdate(bool active)
//****************************************************************************************************************************************************
void QMLBackend::checkUpdates()
{
- logGRPCCallStatus(app().grpc().checkUpdate(), "checkUpdate");
+ app().grpc().checkUpdate();
}
@@ -318,7 +322,7 @@ void QMLBackend::checkUpdates()
//****************************************************************************************************************************************************
void QMLBackend::installUpdate()
{
- logGRPCCallStatus(app().grpc().installUpdate(), "installUpdate");
+ app().grpc().installUpdate();
}
@@ -327,5 +331,5 @@ void QMLBackend::installUpdate()
//****************************************************************************************************************************************************
void QMLBackend::triggerReset()
{
- logGRPCCallStatus(app().grpc().triggerReset(), "triggerReset");
+ app().grpc().triggerReset();
}
diff --git a/internal/frontend/bridge-gui/QMLBackend.h b/internal/frontend/bridge-gui/QMLBackend.h
index b586d30e..204b99c5 100644
--- a/internal/frontend/bridge-gui/QMLBackend.h
+++ b/internal/frontend/bridge-gui/QMLBackend.h
@@ -16,16 +16,15 @@
// along with Proton Mail Bridge. If not, see .
-#ifndef BRIDGE_GUI_QMLBACKEND_H
-#define BRIDGE_GUI_QMLBACKEND_H
+#ifndef BRIDGE_GUI_QML_BACKEND_H
+#define BRIDGE_GUI_QML_BACKEND_H
-#include
#include "DockIcon/DockIcon.h"
-#include "GRPC/GRPCClient.h"
-#include "GRPC/GRPCUtils.h"
-#include "Worker/Overseer.h"
-#include "User/UserList.h"
+#include "UserList.h"
+#include
+#include
+#include
//****************************************************************************************************************************************************
@@ -78,31 +77,31 @@ public: // Qt/QML properties. Note that the NOTIFY-er signal is required even fo
Q_PROPERTY(bool dockIconVisible READ dockIconVisible WRITE setDockIconVisible NOTIFY dockIconVisibleChanged) // _ bool `property:dockIconVisible`
// Qt Property system setters & getters.
- bool showOnStartup() const { bool v = false; logGRPCCallStatus(app().grpc().showOnStartup(v), "showOnStartup"); return v; };
+ bool showOnStartup() const { bool v = false; app().grpc().showOnStartup(v); return v; };
bool showSplashScreen() const { return showSplashScreen_; };
void setShowSplashScreen(bool show) { if (show != showSplashScreen_) { showSplashScreen_ = show; emit showSplashScreenChanged(show); } }
QString goos() { return goos_; }
QUrl logsPath() const { return logsPath_; }
QUrl licensePath() const { return licensePath_; }
- QUrl releaseNotesLink() const { QUrl link; logGRPCCallStatus(app().grpc().releaseNotesPageLink(link), "releaseNotesPageLink"); return link; }
- QUrl dependencyLicensesLink() const { QUrl link; logGRPCCallStatus(app().grpc().dependencyLicensesLink(link), "dependencyLicensesLink"); return link; }
- QUrl landingPageLink() const { QUrl link; logGRPCCallStatus(app().grpc().landingPageLink(link), "landingPageLink"); return link; }
- QString version() const { QString version; logGRPCCallStatus(app().grpc().version(version), "version"); return version; }
- QString hostname() const { QString hostname; logGRPCCallStatus(app().grpc().hostname(hostname), "hostname"); return hostname; }
- bool isAutostartOn() const { bool v; logGRPCCallStatus(app().grpc().isAutostartOn(v), "isAutostartOn"); return v; };
- bool isBetaEnabled() const { bool v; logGRPCCallStatus(app().grpc().isBetaEnabled(v), "isBetaEnabled"); return v; }
- QString colorSchemeName() const { QString name; logGRPCCallStatus(app().grpc().colorSchemeName(name), "colorSchemeName"); return name; }
- bool isDiskCacheEnabled() const { bool enabled; logGRPCCallStatus(app().grpc().isCacheOnDiskEnabled(enabled), "isCacheOnDiskEnabled"); return enabled;}
- QUrl diskCachePath() const { QUrl path; logGRPCCallStatus(app().grpc().diskCachePath(path), "diskCachePath"); return path; }
- bool useSSLForSMTP() const{ bool useSSL; logGRPCCallStatus(app().grpc().useSSLForSMTP(useSSL), "useSSLForSMTP"); return useSSL; }
- int portIMAP() const { int port; logGRPCCallStatus(app().grpc().portIMAP(port), "portIMAP"); return port; }
- int portSMTP() const { int port; logGRPCCallStatus(app().grpc().portSMTP(port), "portSMTP"); return port; }
- bool isDoHEnabled() const { bool isEnabled; logGRPCCallStatus(app().grpc().isDoHEnabled(isEnabled), "isDoHEnabled"); return isEnabled;}
- bool isFirstGUIStart() const { bool v; logGRPCCallStatus(app().grpc().isFirstGUIStart(v), "isFirstGUIStart"); return v; };
- bool isAutomaticUpdateOn() const { bool isOn = false; logGRPCCallStatus(app().grpc().isAutomaticUpdateOn(isOn), "isAutomaticUpdateOn"); return isOn; }
- QString currentEmailClient() { QString client; logGRPCCallStatus(app().grpc().currentEmailClient(client), "currentEmailClient"); return client;}
- QStringList availableKeychain() const { QStringList keychains; logGRPCCallStatus(app().grpc().availableKeychains(keychains), "availableKeychain"); return keychains; }
- QString currentKeychain() const { QString keychain; logGRPCCallStatus(app().grpc().currentKeychain(keychain), "currentKeychain"); return keychain; }
+ QUrl releaseNotesLink() const { QUrl link; app().grpc().releaseNotesPageLink(link); return link; }
+ QUrl dependencyLicensesLink() const { QUrl link; app().grpc().dependencyLicensesLink(link); return link; }
+ QUrl landingPageLink() const { QUrl link; app().grpc().landingPageLink(link); return link; }
+ QString version() const { QString version; app().grpc().version(version); return version; }
+ QString hostname() const { QString hostname; app().grpc().hostname(hostname); return hostname; }
+ bool isAutostartOn() const { bool v; app().grpc().isAutostartOn(v); return v; };
+ bool isBetaEnabled() const { bool v; app().grpc().isBetaEnabled(v); return v; }
+ QString colorSchemeName() const { QString name; app().grpc().colorSchemeName(name); return name; }
+ bool isDiskCacheEnabled() const { bool enabled; app().grpc().isCacheOnDiskEnabled(enabled); return enabled;}
+ QUrl diskCachePath() const { QUrl path; app().grpc().diskCachePath(path); return path; }
+ bool useSSLForSMTP() const{ bool useSSL; app().grpc().useSSLForSMTP(useSSL); return useSSL; }
+ int portIMAP() const { int port; app().grpc().portIMAP(port); return port; }
+ int portSMTP() const { int port; app().grpc().portSMTP(port); return port; }
+ bool isDoHEnabled() const { bool isEnabled; app().grpc().isDoHEnabled(isEnabled); return isEnabled;}
+ bool isFirstGUIStart() const { bool v; app().grpc().isFirstGUIStart(v); return v; };
+ bool isAutomaticUpdateOn() const { bool isOn = false; app().grpc().isAutomaticUpdateOn(isOn); return isOn; }
+ QString currentEmailClient() { QString client; app().grpc().currentEmailClient(client); return client;}
+ QStringList availableKeychain() const { QStringList keychains; app().grpc().availableKeychains(keychains); return keychains; }
+ QString currentKeychain() const { QString keychain; app().grpc().currentKeychain(keychain); return keychain; }
bool dockIconVisible() const { return getDockIconVisibleState(); };
void setDockIconVisible(bool visible) { setDockIconVisibleState(visible); emit dockIconVisibleChanged(visible); }
@@ -137,12 +136,11 @@ public slots: // slot for signals received from QML -> To be forwarded to Bridge
void toggleAutostart(bool active); // _ func(makeItActive bool) `slot:"toggleAutostart"`
void toggleBeta(bool active); // _ func(makeItActive bool) `slot:"toggleBeta"`
void changeColorScheme(QString const &scheme); // _ func(string) `slot:"changeColorScheme"`
- void changeLocalCache(bool enable, QUrl const& path) { logGRPCCallStatus(app().grpc().changeLocalCache(enable, path), "changeLocalCache"); } // _ func(enableDiskCache bool, diskCachePath core.QUrl) `slot:"changeLocalCache"`
- void login(QString const& username, QString const& password) { logGRPCCallStatus(app().grpc().login(username, password), "login");} // _ func(username, password string) `slot:"login"`
- void login2FA(QString const& username, QString const& code) { logGRPCCallStatus(app().grpc().login2FA(username, code), "login2FA");} // _ func(username, code string) `slot:"login2FA"`
- void login2Password(QString const& username, QString const& password) { logGRPCCallStatus(app().grpc().login2Passwords(username, password),
- "login2Passwords");} // _ func(username, password string) `slot:"login2Password"`
- void loginAbort(QString const& username){ logGRPCCallStatus(app().grpc().loginAbort(username), "loginAbort");} // _ func(username string) `slot:"loginAbort"`
+ void changeLocalCache(bool enable, QUrl const& path) { app().grpc().changeLocalCache(enable, path); } // _ func(enableDiskCache bool, diskCachePath core.QUrl) `slot:"changeLocalCache"`
+ void login(QString const& username, QString const& password) { app().grpc().login(username, password);} // _ func(username, password string) `slot:"login"`
+ void login2FA(QString const& username, QString const& code) { app().grpc().login2FA(username, code);} // _ func(username, code string) `slot:"login2FA"`
+ void login2Password(QString const& username, QString const& password) { app().grpc().login2Passwords(username, password);} // _ func(username, password string) `slot:"login2Password"`
+ void loginAbort(QString const& username){ app().grpc().loginAbort(username);} // _ func(username string) `slot:"loginAbort"`
void toggleUseSSLforSMTP(bool makeItActive); // _ func(makeItActive bool) `slot:"toggleUseSSLforSMTP"`
void changePorts(int imapPort, int smtpPort); // _ func(imapPort, smtpPort int) `slot:"changePorts"`
void toggleDoH(bool active); // _ func(makeItActive bool) `slot:"toggleDoH"`
@@ -156,7 +154,7 @@ public slots: // slot for signals received from QML -> To be forwarded to Bridge
void installUpdate(); // _ func() `slot:"installUpdate"`
void triggerReset(); // _ func() `slot:"triggerReset"`
void reportBug(QString const &description, QString const& address, QString const &emailClient, bool includeLogs) {
- logGRPCCallStatus(app().grpc().reportBug(description, address, emailClient, includeLogs), "reportBug"); } // _ func(description, address, emailClient string, includeLogs bool) `slot:"reportBug"`
+ app().grpc().reportBug(description, address, emailClient, includeLogs); } // _ func(description, address, emailClient string, includeLogs bool) `slot:"reportBug"`
signals: // Signals received from the Go backend, to be forwarded to QML
void toggleAutostartFinished(); // _ func() `signal:"toggleAutostartFinished"`
@@ -211,7 +209,7 @@ private: // member functions
private: // data members
UserList* users_ { nullptr }; ///< The user list. Owned by backend.
- std::unique_ptr eventStreamOverseer_; ///< The event stream overseer.
+ std::unique_ptr eventStreamOverseer_; ///< The event stream overseer.
bool showSplashScreen_ { false }; ///< The cached version of show splash screen. Retrieved on startup from bridge, and potentially modified locally.
QString goos_; ///< The cached version of the GOOS variable.
QUrl logsPath_; ///< The logs path. Retrieved from bridge on startup.
@@ -221,4 +219,4 @@ private: // data members
};
-#endif // BRIDGE_GUI_QMLBACKEND_H
+#endif // BRIDGE_GUI_QML_BACKEND_H
diff --git a/internal/frontend/bridge-gui/User/User.cpp b/internal/frontend/bridge-gui/User/User.cpp
deleted file mode 100644
index 627429e7..00000000
--- a/internal/frontend/bridge-gui/User/User.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-// 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 "Pch.h"
-#include "User.h"
-#include "GRPC/GRPCUtils.h"
-#include "GRPC/GRPCClient.h"
-
-
-//****************************************************************************************************************************************************
-/// \param[in] parent The parent object.
-//****************************************************************************************************************************************************
-User::User(QObject *parent)
- : QObject(parent)
-{
-
-}
-
-
-//****************************************************************************************************************************************************
-/// \param[in] user The user to copy from
-//****************************************************************************************************************************************************
-void User::update(User const &user)
-{
- this->setProperty("username", user.username_);
- this->setProperty("avatarText", user.avatarText_);
- this->setProperty("loggedIn", user.loggedIn_);
- this->setProperty("splitMode", user.splitMode_);
- this->setProperty("setupGuideSeen", user.setupGuideSeen_);
- this->setProperty("usedBytes", user.usedBytes_);
- this->setProperty("totalBytes", user.totalBytes_);
- this->setProperty("password", user.password_);
- this->setProperty("addresses", user.addresses_);
- this->setProperty("id", user.id_);
-}
-
-//****************************************************************************************************************************************************
-/// \param[in] makeItActive Should split mode be made active.
-//****************************************************************************************************************************************************
-void User::toggleSplitMode(bool makeItActive)
-{
- logGRPCCallStatus(app().grpc().setUserSplitMode(id_, makeItActive), "toggleSplitMode");
-}
-
-//****************************************************************************************************************************************************
-//
-//****************************************************************************************************************************************************
-void User::logout()
-{
- logGRPCCallStatus(app().grpc().logoutUser(id_), "logoutUser");
-}
-
-
-//****************************************************************************************************************************************************
-//
-//****************************************************************************************************************************************************
-void User::remove()
-{
- logGRPCCallStatus(app().grpc().removeUser(id_), "removeUser");
-}
-
-
-//****************************************************************************************************************************************************
-/// \param[in] address The email address to configure Apple Mail for.
-//****************************************************************************************************************************************************
-void User::configureAppleMail(QString const &address)
-{
- logGRPCCallStatus(app().grpc().configureAppleMail(id_, address), "configureAppleMail");
-}
-
-
-//****************************************************************************************************************************************************
-// The only purpose of this call is to forward to the QML application the toggleSplitModeFinished(userID) event
-// that was received by the UserList model.
-//****************************************************************************************************************************************************
-void User::emitToggleSplitModeFinished()
-{
- this->setProperty("splitMode", QVariant::fromValue(!this->property("splitMode").toBool()));
- emit toggleSplitModeFinished();
-}
diff --git a/internal/frontend/bridge-gui/User/User.h b/internal/frontend/bridge-gui/User/User.h
deleted file mode 100644
index 45163c49..00000000
--- a/internal/frontend/bridge-gui/User/User.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// 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_USER_H
-#define BRIDGE_GUI_USER_H
-
-
-#include "Log.h"
-
-
-//****************************************************************************************************************************************************
-/// \brief User class.
-//****************************************************************************************************************************************************
-class User : public QObject
-{
-Q_OBJECT
-public: // member functions.
- explicit User(QObject *parent = nullptr); ///< Default constructor.
- User(User const &) = delete; ///< Disabled copy-constructor.
- User(User &&) = delete; ///< Disabled assignment copy-constructor.
- ~User() override = default; ///< Destructor.
- User &operator=(User const &) = delete; ///< Disabled assignment operator.
- User &operator=(User &&) = delete; ///< Disabled move assignment operator.
- void update(User const &user); ///< Update the user
-public slots:
- // slots for QML generated calls
- void toggleSplitMode(bool makeItActive); // _ func(makeItActive bool) `slot:"toggleSplitMode"`
- void logout(); // _ func() `slot:"logout"`
- void remove(); // _ func() `slot:"remove"`
- void configureAppleMail(QString const &address); // _ func(address string) `slot:"configureAppleMail"`
-
- // slots for external signals
- void emitToggleSplitModeFinished();
-
-public:
- Q_PROPERTY(QString username MEMBER username_ NOTIFY usernameChanged) // _ string `property:"username"`
- Q_PROPERTY(QString avatarText MEMBER avatarText_ NOTIFY avatarTextChanged) // _ string `property:"avatarText"`
- Q_PROPERTY(bool loggedIn MEMBER loggedIn_ NOTIFY loggedInChanged) // _ bool `property:"loggedIn"`
- Q_PROPERTY(bool splitMode MEMBER splitMode_ NOTIFY splitModeChanged) // _ bool `property:"splitMode"`
- Q_PROPERTY(bool setupGuideSeen MEMBER setupGuideSeen_ NOTIFY setupGuideSeenChanged) // _ bool `property:"setupGuideSeen"`
- Q_PROPERTY(float usedBytes MEMBER usedBytes_ NOTIFY usedBytesChanged) // _ float32 `property:"usedBytes"`
- Q_PROPERTY(float totalBytes MEMBER totalBytes_ NOTIFY totalBytesChanged) // _ float32 `property:"totalBytes"`
- Q_PROPERTY(QString password MEMBER password_ NOTIFY passwordChanged) // _ string `property:"password"`
- Q_PROPERTY(QStringList addresses MEMBER addresses_ NOTIFY addressesChanged) // _ []string `property:"addresses"`
- Q_PROPERTY(QString id MEMBER id_ NOTIFY idChanged) // _ string ID
-
-signals:
- // signals used for Qt properties
- void usernameChanged(QString const &username);
- void avatarTextChanged(QString const &avatarText);
- void loggedInChanged(bool loggedIn);
- void splitModeChanged(bool splitMode);
- void setupGuideSeenChanged(bool seen);
- void usedBytesChanged(float byteCount);
- void totalBytesChanged(float byteCount);
- void passwordChanged(QString const &);
- void addressesChanged(QStringList const &);
- void idChanged(QStringList const &id);
- void toggleSplitModeFinished();
-
-private:
- QString id_; ///< The userID.
- QString username_; ///< The username
- QString avatarText_; ///< The avatar text (i.e. initials of the user)
- bool loggedIn_{false}; ///< Is the user logged in.
- bool splitMode_{false}; ///< Is split mode active.
- bool setupGuideSeen_{false}; ///< Has the setup guide been seen.
- float usedBytes_{0.0f}; ///< The storage used by the user.
- float totalBytes_{0.0f}; ///< The storage quota of the user.
- QString password_; ///< The IMAP password of the user.
- QStringList addresses_; ///< The email address list of the user.
-};
-
-
-typedef std::shared_ptr SPUser;
-
-
-#endif // BRIDGE_GUI_USER_H
diff --git a/internal/frontend/bridge-gui/User/UserList.cpp b/internal/frontend/bridge-gui/UserList.cpp
similarity index 90%
rename from internal/frontend/bridge-gui/User/UserList.cpp
rename to internal/frontend/bridge-gui/UserList.cpp
index 0d7d085c..ac0df9cd 100644
--- a/internal/frontend/bridge-gui/User/UserList.cpp
+++ b/internal/frontend/bridge-gui/UserList.cpp
@@ -16,9 +16,10 @@
// along with Proton Mail Bridge. If not, see .
-#include "Pch.h"
#include "UserList.h"
-#include "GRPC/GRPCClient.h"
+
+
+using namespace bridgepp;
//****************************************************************************************************************************************************
@@ -36,11 +37,12 @@ UserList::UserList(QObject *parent)
//****************************************************************************************************************************************************
void UserList::connectGRPCEvents() const
{
- GRPCClient* client = &app().grpc();
- connect(client, &GRPCClient::userChanged, this, &UserList::onUserChanged);
- connect(client, &GRPCClient::toggleSplitModeFinished, this, &UserList::onToggleSplitModeFinished);
+ GRPCClient& client = app().grpc();
+ connect(&client, &GRPCClient::userChanged, this, &UserList::onUserChanged);
+ connect(&client, &GRPCClient::toggleSplitModeFinished, this, &UserList::onToggleSplitModeFinished);
}
+
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
@@ -60,7 +62,7 @@ QVariant UserList::data(QModelIndex const &index, int role) const
/// This It does not seem to be used, but the method is required by the base class.
/// From the original QtThe recipe QML backend User model, the User is always returned, regardless of the role.
Q_UNUSED(role)
- int const row = index.row();
+ int const row = index.row();
if ((row < 0) || (row >= users_.size()))
return QVariant();
return QVariant::fromValue(users_[row].get());
@@ -91,6 +93,7 @@ void UserList::reset()
this->endResetModel();
}
+
//****************************************************************************************************************************************************
/// \param[in] users The new user list.
//****************************************************************************************************************************************************
@@ -105,7 +108,7 @@ void UserList::reset(QList const &users)
//****************************************************************************************************************************************************
/// \param[in] user The user.
//****************************************************************************************************************************************************
-void UserList::appendUser(SPUser const& user)
+void UserList::appendUser(SPUser const &user)
{
int const size = users_.size();
this->beginInsertRows(QModelIndex(), size, size);
@@ -135,7 +138,7 @@ void UserList::updateUserAtRow(int row, User const &user)
{
if ((row < 0) || (row >= users_.count()))
{
- app().log().error(QString("invalid user at row %2 (user count = %2)").arg(row).arg(users_.count()));
+ app().log().error(QString("invalid user at row %2 (user userCount = %2)").arg(row).arg(users_.count()));
return;
}
@@ -153,11 +156,11 @@ User *UserList::get(int row) const
{
if ((row < 0) || (row >= users_.count()))
{
- app().log().error(QString("Requesting invalid user at row %1 (user count = %2)").arg(row).arg(users_.count()));
+ app().log().error(QString("Requesting invalid user at row %1 (user userCount = %2)").arg(row).arg(users_.count()));
return nullptr;
}
- app().log().debug(QString("Retrieving user at row %1 (user count = %2)").arg(row).arg(users_.count()));
+ app().log().debug(QString("Retrieving user at row %1 (user userCount = %2)").arg(row).arg(users_.count()));
return users_[row].get();
}
@@ -170,11 +173,13 @@ void UserList::onUserChanged(QString const &userID)
int const index = this->rowOfUserID(userID);
SPUser user;
grpc::Status status = app().grpc().getUser(userID, user);
+ QQmlEngine::setObjectOwnership(user.get(), QQmlEngine::CppOwnership);
+
if ((!user) || (!status.ok()))
{
if (index >= 0) // user exists here but not in the go backend. we delete it.
{
- app().log().debug(QString("Removing user from userlist: %1").arg(userID));
+ app().log().debug(QString("Removing user from user list: %1").arg(userID));
this->removeUserAt(index);
}
return;
@@ -182,12 +187,12 @@ void UserList::onUserChanged(QString const &userID)
if (index < 0)
{
- app().log().debug(QString("Adding user in userlist: %1").arg(userID));
+ app().log().debug(QString("Adding user in user list: %1").arg(userID));
this->appendUser(user);
return;
}
- app().log().debug(QString("Updating user in userlist: %1").arg(userID));
+ app().log().debug(QString("Updating user in user list: %1").arg(userID));
this->updateUserAtRow(index, *user);
}
diff --git a/internal/frontend/bridge-gui/User/UserList.h b/internal/frontend/bridge-gui/UserList.h
similarity index 69%
rename from internal/frontend/bridge-gui/User/UserList.h
rename to internal/frontend/bridge-gui/UserList.h
index 7b7a1d40..0f64b1c6 100644
--- a/internal/frontend/bridge-gui/User/UserList.h
+++ b/internal/frontend/bridge-gui/UserList.h
@@ -19,45 +19,49 @@
#ifndef BRIDGE_GUI_USER_LIST_H
#define BRIDGE_GUI_USER_LIST_H
-#include "User.h"
+
+#include
+#include
+#include
+
//****************************************************************************************************************************************************
/// \brief User list class.
//****************************************************************************************************************************************************
-class UserList: public QAbstractListModel
+class UserList : public QAbstractListModel
{
- Q_OBJECT
+Q_OBJECT
public: // member functions.
- explicit UserList(QObject *parent = nullptr); ///< Default constructor.
- UserList(UserList const &other) = delete ; ///< Disabled copy-constructor.
- UserList& operator=(UserList const& other) = delete; ///< Disabled assignment operator.
+ UserList(QObject *parent); ///< Default constructor.
+ UserList(UserList const &other) = delete; ///< Disabled copy-constructor.
+ UserList &operator=(UserList const &other) = delete; ///< Disabled assignment operator.
~UserList() override = default; ///< Destructor
void connectGRPCEvents() const; ///< Connects gRPC event to the model.
int rowCount(QModelIndex const &parent) const override; ///< Return the number of row in the model
QVariant data(QModelIndex const &index, int role) const override; ///< Retrieve model data.
void reset(); ///< Reset the user list.
- void reset(QList const &users); ///< Replace the user list.
+ void reset(QList const &users); ///< Replace the user list.
int rowOfUserID(QString const &userID) const;
void removeUserAt(int row); ///< Remove the user at a given row
- void appendUser(SPUser const& user); ///< Add a new user.
- void updateUserAtRow(int row, User const& user); ///< Update the user at given row.
+ void appendUser(bridgepp::SPUser const &user); ///< Add a new user.
+ void updateUserAtRow(int row, bridgepp::User const &user); ///< Update the user at given row.
- // the count property.
+ // the userCount property.
Q_PROPERTY(int count READ count NOTIFY countChanged)
- int count() const; ///< The count property getter.
+ int count() const; ///< The userCount property getter.
signals:
- void countChanged(int count); ///< Signal for the count property.
+ void countChanged(int count); ///< Signal for the userCount property.
public:
- Q_INVOKABLE User* get(int row) const;
+ Q_INVOKABLE bridgepp::User *get(int row) const;
public slots: ///< handler for signals coming from the gRPC service
void onUserChanged(QString const &userID);
void onToggleSplitModeFinished(QString const &userID);
private: // data members
- QList users_; ///< The user list.
+ QList users_; ///< The user list.
};
diff --git a/internal/frontend/bridge-gui/main.cpp b/internal/frontend/bridge-gui/main.cpp
index da4e2e0d..23d55a29 100644
--- a/internal/frontend/bridge-gui/main.cpp
+++ b/internal/frontend/bridge-gui/main.cpp
@@ -16,12 +16,14 @@
// along with Proton Mail Bridge. If not, see .
-#include "Pch.h"
-#include "Exception.h"
#include "QMLBackend.h"
-#include "Log.h"
#include "BridgeMonitor.h"
#include "Version.h"
+#include
+#include
+
+
+using namespace bridgepp;
//****************************************************************************************************************************************************
@@ -49,7 +51,7 @@ Log &initLog()
Log &log = app().log();
log.setEchoInConsole(true);
log.setLevel(Log::Level::Debug);
- Log::installQtMessageHandler();
+ log.registerAsQtMessageHandler();
return log;
}
@@ -63,7 +65,7 @@ QQmlComponent *createRootQmlComponent(QQmlApplicationEngine &engine)
qmlRegisterSingletonInstance("Proton", 1, 0, "Backend", &app().backend());
qmlRegisterType("Proton", 1, 0, "UserList");
- qmlRegisterType("Proton", 1, 0, "User");
+ qmlRegisterType("Proton", 1, 0, "User");
auto rootComponent = new QQmlComponent(&engine, &engine);
@@ -138,7 +140,7 @@ void parseArguments(int argc, char **argv, bool &outAttach, QString &outExePath)
void closeBridgeApp()
{
UPOverseer& overseer = app().bridgeOverseer();
- if (!overseer) // The app was ran in 'attach' mode and attached to an existing instance of Bridge. No need to close.
+ if (!overseer) // The app was run in 'attach' mode and attached to an existing instance of Bridge. No need to close.
return;
app().grpc().quit(); // this will cause the grpc service and the bridge app to close.
@@ -186,7 +188,7 @@ int main(int argc, char *argv[])
QMetaObject::Connection connection;
if (bridgeMonitor)
connection = QObject::connect(bridgeMonitor, &BridgeMonitor::processExited, [&](int returnCode) {
- // GODT-1671 We need to find a 'safe' way to check if brige crashed and restart instead of just quitting. Is returnCode enough?
+ // GODT-1671 We need to find a 'safe' way to check if Bridge crashed and restart instead of just quitting. Is returnCode enough?
bridgeExited = true;// clazy:exclude=lambda-in-connect
qGuiApp->exit(returnCode);
});
diff --git a/internal/frontend/bridgepp/CMakeLists.txt b/internal/frontend/bridgepp/CMakeLists.txt
new file mode 100644
index 00000000..a685dbe0
--- /dev/null
+++ b/internal/frontend/bridgepp/CMakeLists.txt
@@ -0,0 +1,124 @@
+# 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 .
+
+
+cmake_minimum_required(VERSION 3.22)
+
+
+include_guard()
+set(VCPKG_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../../extern/vcpkg")
+include(bridge_setup.cmake)
+
+
+#****************************************************************************************************************************************************
+# Base project setup
+#****************************************************************************************************************************************************
+project(bridgepp LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+if (NOT DEFINED BRIDGE_APP_VERSION)
+ message(FATAL_ERROR "BRIDGE_APP_VERSION is not defined.")
+else()
+ message(STATUS "Bridge version is ${BRIDGE_APP_VERSION}")
+endif()
+
+#****************************************************************************************************************************************************
+# Qt
+#****************************************************************************************************************************************************
+if (NOT DEFINED ENV{QT6DIR})
+ message(FATAL_ERROR "QT6DIR needs to be defined and point to the root of your Qt 6 folder (e.g. /Users/MyName/Qt/6.3.1/clang_64).")
+endif ()
+set(CMAKE_PREFIX_PATH $ENV{QT6DIR} ${CMAKE_PREFIX_PATH})
+find_package(Qt6 COMPONENTS Core REQUIRED)
+qt_standard_project_setup()
+
+#****************************************************************************************************************************************************
+# gRPC / Protobuf
+#****************************************************************************************************************************************************
+find_package(Protobuf CONFIG REQUIRED)
+message(STATUS "Using protobuf ${Protobuf_VERSION}")
+
+find_package(gRPC CONFIG REQUIRED)
+message(STATUS "Using gRPC ${gRPC_VERSION}")
+
+find_program(PROTOC_EXE protoc REQUIRED)
+message(STATUS "protoc found ${PROTOC_EXE}")
+
+message(STATUS "grpc_cpp_plugin ${grpc_cpp_plugin}")
+
+find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin)
+if (GRPC_CPP_PLUGIN STREQUAL GRPC_CPP_PLUGIN-NOTFOUND)
+ message(FATAL_ERROR "grpc_cpp_plugin exe could not be found. Please add it to your path. it should be located in \${VCPKG_ROOT}/installed/arm64-osx/tools/grpc")
+else ()
+ message(STATUS "grpc_cpp_plugin found at ${GRPC_CPP_PLUGIN}")
+endif ()
+
+set(PROTO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../grpc")
+set(PROTO_FILE "${PROTO_DIR}/bridge.proto")
+set(GRPC_OUT_DIR "bridgepp/GRPC")
+set(PROTO_CPP_FILE "${GRPC_OUT_DIR}/bridge.pb.cc")
+set(PROTO_H_FILE "${GRPC_OUT_DIR}/bridge.pb.h")
+set(GRPC_CPP_FILE "${GRPC_OUT_DIR}/bridge.grpc.pb.cc")
+set(GRPC_H_FILE "${GRPC_OUT_DIR}/bridge.grpc.pb.h")
+
+
+#*****************************************************************************************************************************************************
+# Source files and output
+#*****************************************************************************************************************************************************
+
+add_custom_command(
+ OUTPUT
+ ${PROTO_CPP_FILE}
+ ${PROTO_H_FILE}
+ ${GRPC_CPP_FILE}
+ ${GRPC_H_FILE}
+ COMMAND
+ ${PROTOC_EXE}
+ ARGS
+ --proto_path=${PROTO_DIR}
+ --plugin=protoc-gen-grpc="${GRPC_CPP_PLUGIN}"
+ --cpp_out=${GRPC_OUT_DIR}
+ --grpc_out=${GRPC_OUT_DIR}
+ ${PROTO_FILE}
+ DEPENDS
+ ${PROTO_FILE}
+ COMMENT "Generating gPRC/Protobuf C++ code"
+ )
+
+
+add_library(bridgepp
+ bridgepp/BridgeUtils.cpp bridgepp/BridgeUtils.h
+ bridgepp/Exception/Exception.h bridgepp/Exception/Exception.cpp
+ bridgepp/GRPC/GRPCClient.cpp bridgepp/GRPC/GRPCClient.h
+ bridgepp/GRPC/GRPCUtils.cpp bridgepp/GRPC/GRPCUtils.h
+ ${PROTO_CPP_FILE} ${PROTO_H_FILE} ${GRPC_CPP_FILE} ${GRPC_H_FILE}
+ bridgepp/Log/Log.h bridgepp/Log/Log.cpp
+ bridgepp/User/User.cpp bridgepp/User/User.h
+ bridgepp/Worker/Worker.h bridgepp/Worker/Overseer.h bridgepp/Worker/Overseer.cpp
+ )
+
+target_include_directories(bridgepp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+
+target_link_libraries(bridgepp
+ Qt6::Core
+ protobuf::libprotobuf
+ gRPC::grpc++
+ )
+
+target_precompile_headers(bridgepp PRIVATE Pch.h)
diff --git a/internal/frontend/bridgepp/Pch.h b/internal/frontend/bridgepp/Pch.h
new file mode 100644
index 00000000..fcfed6a4
--- /dev/null
+++ b/internal/frontend/bridgepp/Pch.h
@@ -0,0 +1,26 @@
+// 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_PP_PCH_H
+#define BRIDGE_PP_PCH_H
+
+
+#include
+
+
+#endif // BRIDGE_PP_PCH_H
\ No newline at end of file
diff --git a/internal/frontend/bridgepp/bridge_setup.cmake b/internal/frontend/bridgepp/bridge_setup.cmake
new file mode 100644
index 00000000..3ebafcef
--- /dev/null
+++ b/internal/frontend/bridgepp/bridge_setup.cmake
@@ -0,0 +1,60 @@
+# 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_guard()
+
+
+#****************************************************************************************************************************************************
+# vcpkg, toolchain, and architecture
+#****************************************************************************************************************************************************
+# We rely on vcpkg for to get gRPC / Protobuf
+# run build.sh / build.ps1 to get gRPC / Protobuf and dependencies installed.
+
+set(VCPKG_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../../extern/vcpkg")
+message(STATUS "VCPKG_ROOT is ${VCPKG_ROOT}")
+if (WIN32)
+ find_program(VCPKG_EXE "${VCPKG_ROOT}/vcpkg.exe")
+else()
+ find_program(VCPKG_EXE "${VCPKG_ROOT}/vcpkg")
+endif()
+
+
+# For now we support only a single architecture for macOS (ARM64 or x86_64). We need to investigate how to build universal binaries with vcpkg.
+if (APPLE)
+ if (NOT DEFINED CMAKE_OSX_ARCHITECTURES)
+ execute_process(COMMAND "uname" "-m" OUTPUT_VARIABLE UNAME_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
+ set(CMAKE_OSX_ARCHITECTURES ${UNAME_RESULT} CACHE STRING "osx_architectures")
+ endif()
+
+ if (CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
+ message(STATUS "Building for Apple Silicon Mac computers")
+ set(VCPKG_TARGET_TRIPLET arm64-osx)
+ elseif (CMAKE_OSX_ARCHITECTURES STREQUAL "x86_64")
+ message(STATUS "Building for Intel based Mac computers")
+ set(VCPKG_TARGET_TRIPLET x64-osx)
+ else ()
+ message(FATAL_ERROR "Unknown value for CMAKE_OSX_ARCHITECTURE. Please use one of \"arm64\" and \"x86_64\". Multiple architectures are not supported.")
+ endif ()
+endif()
+
+if (WIN32)
+ message(STATUS "Building for Intel x64 Windows computers")
+ set(VCPKG_TARGET_TRIPLET x64-windows)
+endif()
+
+set(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "toolchain")
\ No newline at end of file
diff --git a/internal/frontend/bridgepp/bridgepp/BridgeUtils.cpp b/internal/frontend/bridgepp/bridgepp/BridgeUtils.cpp
new file mode 100644
index 00000000..d8928cc3
--- /dev/null
+++ b/internal/frontend/bridgepp/bridgepp/BridgeUtils.cpp
@@ -0,0 +1,56 @@
+// 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 "BridgeUtils.h"
+#include "Exception/Exception.h"
+
+
+namespace bridgepp
+{
+
+//****************************************************************************************************************************************************
+/// \return user configuration directory used by bridge (based on Golang OS/File's UserConfigDir).
+//****************************************************************************************************************************************************
+QString userConfigDir()
+{
+ QString dir;
+#ifdef Q_OS_WIN
+ dir = qgetenv ("AppData");
+ if (dir.isEmpty())
+ throw Exception("%AppData% is not defined.");
+#elif defined(Q_OS_IOS) || defined(Q_OS_DARWIN)
+ dir = qgetenv("HOME");
+ if (dir.isEmpty())
+ throw Exception("$HOME is not defined.");
+ dir += "/Library/Application Support";
+#else
+ dir = qgetenv ("XDG_CONFIG_HOME");
+ if (dir.isEmpty())
+ dir = qgetenv ("HOME");
+ if (dir.isEmpty())
+ throw Exception("neither $XDG_CONFIG_HOME nor $HOME are defined");
+ dir += "/.config";
+#endif
+ QString folder = dir + "/protonmail/bridge";
+ QDir().mkpath(folder);
+
+ return folder;
+}
+
+
+} // namespace bridgepp
diff --git a/internal/frontend/bridge-gui/GRPC/GRPCUtils.h b/internal/frontend/bridgepp/bridgepp/BridgeUtils.h
similarity index 60%
rename from internal/frontend/bridge-gui/GRPC/GRPCUtils.h
rename to internal/frontend/bridgepp/bridgepp/BridgeUtils.h
index 913396ad..cdd607c0 100644
--- a/internal/frontend/bridge-gui/GRPC/GRPCUtils.h
+++ b/internal/frontend/bridgepp/bridgepp/BridgeUtils.h
@@ -16,19 +16,18 @@
// along with Proton Mail Bridge. If not, see .
-#ifndef BRIDGE_GUI_GRPCUTILS_H
-#define BRIDGE_GUI_GRPCUTILS_H
+#ifndef BRIDGE_GUI_TESTER_BRIDGE_UTILS_H
+#define BRIDGE_GUI_TESTER_BRIDGE_UTILS_H
-#include "Log.h"
-#include "GRPC/bridge.grpc.pb.h"
-#include "grpc++/grpc++.h"
-#include "User/User.h"
+namespace bridgepp {
-void logGRPCCallStatus(grpc::Status const& status, QString const &callName); ///< Log the status of a gRPC code.
-SPUser parsegrpcUser(grpc::User const& grpcUser); ///< Parse a gRPC user struct and return a User.
-grpc::LogLevel logLevelToGRPC(Log::Level level); ///< Convert a Log::Level to gRPC enum value.
+QString userConfigDir(); ///< Get the path of the user configuration folder.
-#endif // BRIDGE_GUI_GRPCUTILS_H
+} // namespace
+
+
+
+#endif // BRIDGE_GUI_TESTER_BRIDGE_UTILS_H
diff --git a/internal/frontend/bridge-gui/Exception.cpp b/internal/frontend/bridgepp/bridgepp/Exception/Exception.cpp
similarity index 98%
rename from internal/frontend/bridge-gui/Exception.cpp
rename to internal/frontend/bridgepp/bridgepp/Exception/Exception.cpp
index 517193c4..c1996993 100644
--- a/internal/frontend/bridge-gui/Exception.cpp
+++ b/internal/frontend/bridgepp/bridgepp/Exception/Exception.cpp
@@ -16,10 +16,13 @@
// along with Proton Mail Bridge. If not, see .
-#include "Pch.h"
#include "Exception.h"
+namespace bridgepp
+{
+
+
//****************************************************************************************************************************************************
/// \param[in] what A description of the exception
//****************************************************************************************************************************************************
@@ -66,3 +69,6 @@ const char* Exception::what() const noexcept
{
return what_.toLocal8Bit().constData();
}
+
+
+} // namespace bridgepp
diff --git a/internal/frontend/bridge-gui/Exception.h b/internal/frontend/bridgepp/bridgepp/Exception/Exception.h
similarity index 70%
rename from internal/frontend/bridge-gui/Exception.h
rename to internal/frontend/bridgepp/bridgepp/Exception/Exception.h
index cc1d4984..814e21b8 100644
--- a/internal/frontend/bridge-gui/Exception.h
+++ b/internal/frontend/bridgepp/bridgepp/Exception/Exception.h
@@ -16,31 +16,38 @@
// along with Proton Mail Bridge. If not, see .
-#ifndef BRIDGE_GUI_EXCEPTION_H
-#define BRIDGE_GUI_EXCEPTION_H
+#ifndef BRIDGE_PP_EXCEPTION_H
+#define BRIDGE_PP_EXCEPTION_H
#include
+namespace bridgepp
+{
+
+
//****************************************************************************************************************************************************
/// \brief Exception class.
//****************************************************************************************************************************************************
-class Exception: public std::exception
+class Exception : public std::exception
{
public: // member functions
explicit Exception(QString what = QString()) noexcept; ///< Constructor
- Exception(Exception const& ref) noexcept; ///< copy constructor
- Exception(Exception&& ref) noexcept; ///< copy constructor
- Exception& operator=(Exception const&) = delete; ///< Disabled assignment operator
- Exception& operator=(Exception&&) = delete; ///< Disabled assignment operator
+ Exception(Exception const &ref) noexcept; ///< copy constructor
+ Exception(Exception &&ref) noexcept; ///< copy constructor
+ Exception &operator=(Exception const &) = delete; ///< Disabled assignment operator
+ Exception &operator=(Exception &&) = delete; ///< Disabled assignment operator
~Exception() noexcept override = default; ///< Destructor
- QString const& qwhat() const noexcept; ///< Return the description of the exception as a QString
- const char* what() const noexcept override; ///< Return the description of the exception as C style string
+ QString const &qwhat() const noexcept; ///< Return the description of the exception as a QString
+ const char *what() const noexcept override; ///< Return the description of the exception as C style string
private: // data members
QString const what_; ///< The description of the exception
};
-#endif //BRIDGE_GUI_EXCEPTION_H
+} // namespace bridgepp
+
+
+#endif //BRIDGE_PP_EXCEPTION_H
diff --git a/internal/frontend/bridge-gui/GRPC/GRPCClient.cpp b/internal/frontend/bridgepp/bridgepp/GRPC/GRPCClient.cpp
similarity index 80%
rename from internal/frontend/bridge-gui/GRPC/GRPCClient.cpp
rename to internal/frontend/bridgepp/bridgepp/GRPC/GRPCClient.cpp
index 3a91b084..4759217f 100644
--- a/internal/frontend/bridge-gui/GRPC/GRPCClient.cpp
+++ b/internal/frontend/bridgepp/bridgepp/GRPC/GRPCClient.cpp
@@ -16,56 +16,32 @@
// along with Proton Mail Bridge. If not, see .
-#include "Pch.h"
#include "GRPCClient.h"
#include "GRPCUtils.h"
-#include "QMLBackend.h"
-#include "Exception.h"
-#include "AppController.h"
+#include "../Exception/Exception.h"
using namespace google::protobuf;
using namespace grpc;
+namespace bridgepp
+{
+
+
namespace
{
+
+
Empty empty; // re-used across client calls.
-QString const configFolder = "protonmail/bridge";
-QString const certFile = "cert.pem";
-int const maxConnectionTimeSecs = 60; ///< Amount of time after which we consider connection attemps to the server have failed.
-int const maxCertificateWaitMsecs = 60 * 1000; ///< Ammount of time we wait for he server to generate the certificate.
+int const maxConnectionTimeSecs = 60; ///< Amount of time after which we consider connection attempts to the server have failed.
+int const maxCertificateWaitMsecs = 60 * 1000; ///< Amount of time we wait for he server to generate the certificate.
+
+
}
-//****************************************************************************************************************************************************
-/// \return user configuration directory used by bridge (based on Golang OS/File's UserConfigDir).
-//****************************************************************************************************************************************************
-static const QString _userConfigDir(){
- QString dir;
-#ifdef Q_OS_WIN
- dir = qgetenv ("AppData");
- if (dir.isEmpty())
- throw Exception("%AppData% is not defined.");
-#elif defined(Q_OS_IOS) || defined(Q_OS_DARWIN)
- dir = qgetenv ("HOME");
- if (dir.isEmpty())
- throw Exception("$HOME is not defined.");
- dir += "/Library/Application Support";
-#else
- dir = qgetenv ("XDG_CONFIG_HOME");
- if (dir.isEmpty())
- dir = qgetenv ("HOME");
- if (dir.isEmpty())
- throw Exception("neither $XDG_CONFIG_HOME nor $HOME are defined");
- dir += "/.config";
-#endif
- QString folder = dir + "/" + configFolder;
- QDir().mkpath(folder);
-
- return folder;
-}
//****************************************************************************************************************************************************
/// \brief wait for certificate generation by Bridge
@@ -73,8 +49,9 @@ static const QString _userConfigDir(){
//****************************************************************************************************************************************************
std::string GRPCClient::getServerCertificate()
{
- const QString filename = _userConfigDir() + "/" + certFile;
- QFile file(filename);
+ QString const certPath = serverCertificatePath();
+ QString const certFolder = QFileInfo(certPath).absolutePath();
+ QFile file(certPath);
// TODO : the certificate can exist but still be invalid.
// If the certificate is close to its limit, the bridge will generate a new one.
// If we read the certificate before the bridge rewrites it the certificate will be invalid.
@@ -82,7 +59,7 @@ std::string GRPCClient::getServerCertificate()
{
// wait for file creation
QFileSystemWatcher watcher(this);
- if (!watcher.addPath(_userConfigDir()))
+ if (!watcher.addPath(certFolder))
throw Exception("Failed to watch User Config Directory");
connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &GRPCClient::configFolderChanged);
@@ -96,7 +73,7 @@ std::string GRPCClient::getServerCertificate()
loop.exec();
// timeout case.
- if(!timer.isActive())
+ if (!timer.isActive())
throw Exception("Server failed to generate certificate on time");
//else certIsReadySignal.
}
@@ -109,16 +86,26 @@ std::string GRPCClient::getServerCertificate()
return cert;
}
+
//****************************************************************************************************************************************************
/// \brief Action on UserConfig directory changes, looking for the certificate creation
//****************************************************************************************************************************************************
void GRPCClient::configFolderChanged()
{
- QFile cert(_userConfigDir() + "/" + certFile);
- if (cert.exists())
+ if (QFileInfo::exists(serverCertificatePath()))
emit certIsReady();
}
+
+//****************************************************************************************************************************************************
+/// \param[in] log The log
+//****************************************************************************************************************************************************
+void GRPCClient::setLog(Log *log)
+{
+ log_ = log;
+}
+
+
//****************************************************************************************************************************************************
/// \param[out] outError If the function returns false, this variable contains a description of the error.
/// \return true iff the connection was successful.
@@ -142,7 +129,8 @@ bool GRPCClient::connectToServer(QString &outError)
int i = 0;
while (true)
{
- app().log().debug(QString("Connection to gRPC server. attempt #%1").arg(++i));
+ if (log_)
+ log_->debug(QString("Connection to gRPC server. attempt #%1").arg(++i));
if (channel_->WaitForConnected(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(5, GPR_TIMESPAN))))
break; // connection established.
@@ -154,9 +142,8 @@ bool GRPCClient::connectToServer(QString &outError)
if (channel_->GetState(true) != GRPC_CHANNEL_READY)
throw Exception("connection check failed.");
- QMLBackend *backend = &app().backend();
- QObject::connect(this, &GRPCClient::loginFreeUserError, backend, &QMLBackend::loginFreeUserError);
- app().log().debug("Successfully connected to gRPC server.");
+ if (log_)
+ log_->debug("Successfully connected to gRPC server.");
return true;
}
catch (Exception const &e)
@@ -183,13 +170,14 @@ grpc::Status GRPCClient::addLogEntry(Log::Level level, QString const &package, Q
return stub_->AddLogEntry(&ctx, request, &empty);
}
+
//****************************************************************************************************************************************************
/// \return The status for the gRPC call.
//****************************************************************************************************************************************************
grpc::Status GRPCClient::guiReady()
{
grpc::ClientContext ctx;
- return stub_->GuiReady(&ctx, empty, &empty);
+ return this->logGRPCCallStatus(stub_->GuiReady(&ctx, empty, &empty), __FUNCTION__);
}
@@ -199,7 +187,7 @@ grpc::Status GRPCClient::guiReady()
//****************************************************************************************************************************************************
grpc::Status GRPCClient::isFirstGUIStart(bool &outIsFirst)
{
- return this->getBool(&Bridge::Stub::IsFirstGuiStart, outIsFirst);
+ return this->logGRPCCallStatus(this->getBool(&Bridge::Stub::IsFirstGuiStart, outIsFirst), __FUNCTION__);
}
@@ -209,7 +197,7 @@ grpc::Status GRPCClient::isFirstGUIStart(bool &outIsFirst)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::isAutostartOn(bool &outIsOn)
{
- return this->getBool(&Bridge::Stub::IsAutostartOn, outIsOn);
+ return this->logGRPCCallStatus(this->getBool(&Bridge::Stub::IsAutostartOn, outIsOn), __FUNCTION__);
}
@@ -219,7 +207,7 @@ grpc::Status GRPCClient::isAutostartOn(bool &outIsOn)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::setIsAutostartOn(bool on)
{
- return this->setBool(&Bridge::Stub::SetIsAutostartOn, on);
+ return this->logGRPCCallStatus(this->setBool(&Bridge::Stub::SetIsAutostartOn, on), __FUNCTION__);
}
@@ -229,7 +217,7 @@ grpc::Status GRPCClient::setIsAutostartOn(bool on)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::isBetaEnabled(bool &outEnabled)
{
- return this->getBool(&Bridge::Stub::IsBetaEnabled, outEnabled);
+ return this->logGRPCCallStatus(this->getBool(&Bridge::Stub::IsBetaEnabled, outEnabled), __FUNCTION__);
}
@@ -237,9 +225,9 @@ grpc::Status GRPCClient::isBetaEnabled(bool &outEnabled)
/// \param[in] enabled The new value for the property.
/// \return The status for the gRPC call.
//****************************************************************************************************************************************************
-grpc::Status GRPCClient::setisBetaEnabled(bool enabled)
+grpc::Status GRPCClient::setIsBetaEnabled(bool enabled)
{
- return this->setBool(&Bridge::Stub::SetIsBetaEnabled, enabled);
+ return this->logGRPCCallStatus(this->setBool(&Bridge::Stub::SetIsBetaEnabled, enabled), __FUNCTION__);
}
@@ -249,7 +237,7 @@ grpc::Status GRPCClient::setisBetaEnabled(bool enabled)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::colorSchemeName(QString &outName)
{
- return this->getString(&Bridge::Stub::ColorSchemeName, outName);
+ return this->logGRPCCallStatus(this->getString(&Bridge::Stub::ColorSchemeName, outName), __FUNCTION__);
}
@@ -259,7 +247,7 @@ grpc::Status GRPCClient::colorSchemeName(QString &outName)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::setColorSchemeName(QString const &name)
{
- return this->setString(&Bridge::Stub::SetColorSchemeName, name);
+ return this->logGRPCCallStatus(this->setString(&Bridge::Stub::SetColorSchemeName, name), __FUNCTION__);
}
@@ -269,7 +257,7 @@ grpc::Status GRPCClient::setColorSchemeName(QString const &name)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::currentEmailClient(QString &outName)
{
- return this->getString(&Bridge::Stub::CurrentEmailClient, outName);
+ return this->logGRPCCallStatus(this->getString(&Bridge::Stub::CurrentEmailClient, outName), __FUNCTION__);
}
@@ -278,7 +266,7 @@ grpc::Status GRPCClient::currentEmailClient(QString &outName)
/// \param[in] address The email address.
/// \param[in] emailClient The email client.
/// \param[in] includeLogs Should the report include the logs.
-/// \return The status foer the gRPC call.
+/// \return The status for the gRPC call.
//****************************************************************************************************************************************************
grpc::Status GRPCClient::reportBug(QString const &description, QString const &address, QString const &emailClient, bool includeLogs)
{
@@ -290,7 +278,7 @@ grpc::Status GRPCClient::reportBug(QString const &description, QString const &ad
request.set_address(address.toStdString());
request.set_emailclient(emailClient.toStdString());
request.set_includelogs(includeLogs);
- return stub_->ReportBug(&ctx, request, &empty);
+ return this->logGRPCCallStatus(stub_->ReportBug(&ctx, request, &empty), __FUNCTION__);
}
@@ -300,7 +288,7 @@ grpc::Status GRPCClient::reportBug(QString const &description, QString const &ad
//****************************************************************************************************************************************************
grpc::Status GRPCClient::useSSLForSMTP(bool &outUseSSL)
{
- return this->getBool(&Bridge::Stub::UseSslForSmtp, outUseSSL);
+ return this->logGRPCCallStatus(this->getBool(&Bridge::Stub::UseSslForSmtp, outUseSSL), __FUNCTION__);
}
@@ -310,7 +298,7 @@ grpc::Status GRPCClient::useSSLForSMTP(bool &outUseSSL)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::setUseSSLForSMTP(bool useSSL)
{
- return this->setBool(&Bridge::Stub::SetUseSslForSmtp, useSSL);
+ return this->logGRPCCallStatus(this->setBool(&Bridge::Stub::SetUseSslForSmtp, useSSL), __FUNCTION__);
}
@@ -320,7 +308,7 @@ grpc::Status GRPCClient::setUseSSLForSMTP(bool useSSL)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::portIMAP(int &outPort)
{
- return this->getInt32(&Bridge::Stub::ImapPort, outPort);
+ return this->logGRPCCallStatus(this->getInt32(&Bridge::Stub::ImapPort, outPort), __FUNCTION__);
}
@@ -330,7 +318,7 @@ grpc::Status GRPCClient::portIMAP(int &outPort)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::portSMTP(int &outPort)
{
- return this->getInt32(&Bridge::Stub::SmtpPort, outPort);
+ return this->logGRPCCallStatus(this->getInt32(&Bridge::Stub::SmtpPort, outPort), __FUNCTION__);
}
@@ -345,7 +333,7 @@ grpc::Status GRPCClient::changePorts(int portIMAP, int portSMTP)
ChangePortsRequest request;
request.set_imapport(portIMAP);
request.set_smtpport(portSMTP);
- return stub_->ChangePorts(&ctx, request, &empty);
+ return this->logGRPCCallStatus(stub_->ChangePorts(&ctx, request, &empty), __FUNCTION__);
}
@@ -355,7 +343,7 @@ grpc::Status GRPCClient::changePorts(int portIMAP, int portSMTP)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::isDoHEnabled(bool &outEnabled)
{
- return this->getBool(&Bridge::Stub::IsDoHEnabled, outEnabled);
+ return this->logGRPCCallStatus(this->getBool(&Bridge::Stub::IsDoHEnabled, outEnabled), __FUNCTION__);
}
@@ -365,7 +353,7 @@ grpc::Status GRPCClient::isDoHEnabled(bool &outEnabled)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::setIsDoHEnabled(bool enabled)
{
- return this->setBool(&Bridge::Stub::SetIsDoHEnabled, enabled);
+ return this->logGRPCCallStatus(this->setBool(&Bridge::Stub::SetIsDoHEnabled, enabled), __FUNCTION__);
}
@@ -375,7 +363,7 @@ grpc::Status GRPCClient::setIsDoHEnabled(bool enabled)
grpc::Status GRPCClient::quit()
{
grpc::ClientContext ctx;
- return stub_->Quit(&ctx, empty, &empty);
+ return this->logGRPCCallStatus(stub_->Quit(&ctx, empty, &empty), __FUNCTION__);
}
@@ -385,16 +373,17 @@ grpc::Status GRPCClient::quit()
grpc::Status GRPCClient::restart()
{
grpc::ClientContext ctx;
- return stub_->Restart(&ctx, empty, &empty);
+ return this->logGRPCCallStatus(stub_->Restart(&ctx, empty, &empty), __FUNCTION__);
}
+
//****************************************************************************************************************************************************
/// \return The status for the gRPC call.
//****************************************************************************************************************************************************
grpc::Status GRPCClient::triggerReset()
{
grpc::ClientContext ctx;
- return stub_->TriggerReset(&ctx, empty, &empty);
+ return this->logGRPCCallStatus(stub_->TriggerReset(&ctx, empty, &empty), __FUNCTION__);
}
@@ -412,7 +401,7 @@ grpc::Status GRPCClient::isPortFree(qint32 port, bool &outFree)
Status result = stub_->IsPortFree(&ctx, p, &isFree);
if (result.ok())
outFree = isFree.value();
- return result;
+ return this->logGRPCCallStatus(result, __FUNCTION__);
}
@@ -422,7 +411,7 @@ grpc::Status GRPCClient::isPortFree(qint32 port, bool &outFree)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::showOnStartup(bool &outValue)
{
- return this->getBool(&Bridge::Stub::ShowOnStartup, outValue);
+ return this->logGRPCCallStatus(this->getBool(&Bridge::Stub::ShowOnStartup, outValue), __FUNCTION__);
}
@@ -432,7 +421,7 @@ grpc::Status GRPCClient::showOnStartup(bool &outValue)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::showSplashScreen(bool &outValue)
{
- return this->getBool(&Bridge::Stub::ShowSplashScreen, outValue);
+ return this->logGRPCCallStatus(this->getBool(&Bridge::Stub::ShowSplashScreen, outValue), __FUNCTION__);
}
@@ -442,7 +431,7 @@ grpc::Status GRPCClient::showSplashScreen(bool &outValue)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::goos(QString &outGoos)
{
- return this->getString(&Bridge::Stub::GoOs, outGoos);
+ return this->logGRPCCallStatus(this->getString(&Bridge::Stub::GoOs, outGoos), __FUNCTION__);
}
@@ -452,7 +441,7 @@ grpc::Status GRPCClient::goos(QString &outGoos)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::logsPath(QUrl &outPath)
{
- return this->getURLForLocalFile(&Bridge::Stub::LogsPath, outPath);
+ return this->logGRPCCallStatus(this->getURLForLocalFile(&Bridge::Stub::LogsPath, outPath), __FUNCTION__);
}
@@ -462,7 +451,7 @@ grpc::Status GRPCClient::logsPath(QUrl &outPath)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::licensePath(QUrl &outPath)
{
- return this->getURLForLocalFile(&Bridge::Stub::LicensePath, outPath);
+ return this->logGRPCCallStatus(this->getURLForLocalFile(&Bridge::Stub::LicensePath, outPath), __FUNCTION__);
}
@@ -472,7 +461,7 @@ grpc::Status GRPCClient::licensePath(QUrl &outPath)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::dependencyLicensesLink(QUrl &outUrl)
{
- return this->getURL(&Bridge::Stub::DependencyLicensesLink, outUrl);
+ return this->logGRPCCallStatus(this->getURL(&Bridge::Stub::DependencyLicensesLink, outUrl), __FUNCTION__);
}
@@ -482,34 +471,37 @@ grpc::Status GRPCClient::dependencyLicensesLink(QUrl &outUrl)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::version(QString &outVersion)
{
- return this->getString(&Bridge::Stub::Version, outVersion);
+ return this->logGRPCCallStatus(this->getString(&Bridge::Stub::Version, outVersion), __FUNCTION__);
}
+
//****************************************************************************************************************************************************
/// \param[out] outUrl The value for the property.
/// \return The status for the gRPC call.
//****************************************************************************************************************************************************
grpc::Status GRPCClient::releaseNotesPageLink(QUrl &outUrl)
{
- return this->getURL(&Bridge::Stub::ReleaseNotesPageLink, outUrl);
+ return this->logGRPCCallStatus(this->getURL(&Bridge::Stub::ReleaseNotesPageLink, outUrl), __FUNCTION__);
}
+
//****************************************************************************************************************************************************
/// \param[out] outUrl The value for the property.
/// \return The status for the gRPC call.
//****************************************************************************************************************************************************
grpc::Status GRPCClient::landingPageLink(QUrl &outUrl)
{
- return this->getURL(&Bridge::Stub::LandingPageLink, outUrl);
+ return this->logGRPCCallStatus(this->getURL(&Bridge::Stub::LandingPageLink, outUrl), __FUNCTION__);
}
+
//****************************************************************************************************************************************************
/// \param[out] outHostname The value for the property.
/// \return The status for the gRPC call.
//****************************************************************************************************************************************************
grpc::Status GRPCClient::hostname(QString &outHostname)
{
- return this->getString(&Bridge::Stub::Hostname, outHostname);
+ return this->logGRPCCallStatus(this->getString(&Bridge::Stub::Hostname, outHostname), __FUNCTION__);
}
@@ -519,7 +511,7 @@ grpc::Status GRPCClient::hostname(QString &outHostname)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::isCacheOnDiskEnabled(bool &outEnabled)
{
- return getBool(&Bridge::Stub::IsCacheOnDiskEnabled, outEnabled);
+ return this->logGRPCCallStatus(getBool(&Bridge::Stub::IsCacheOnDiskEnabled, outEnabled), __FUNCTION__);
}
@@ -529,7 +521,7 @@ grpc::Status GRPCClient::isCacheOnDiskEnabled(bool &outEnabled)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::diskCachePath(QUrl &outPath)
{
- return this->getURLForLocalFile(&Bridge::Stub::DiskCachePath, outPath);
+ return this->logGRPCCallStatus(this->getURLForLocalFile(&Bridge::Stub::DiskCachePath, outPath), __FUNCTION__);
}
@@ -544,7 +536,7 @@ grpc::Status GRPCClient::changeLocalCache(bool enabled, QUrl const &path)
ChangeLocalCacheRequest request;
request.set_enablediskcache(enabled);
request.set_diskcachepath(path.path(QUrl::FullyDecoded).toStdString());
- return stub_->ChangeLocalCache(&ctx, request, &empty);
+ return this->logGRPCCallStatus(stub_->ChangeLocalCache(&ctx, request, &empty), __FUNCTION__);
}
@@ -559,7 +551,7 @@ grpc::Status GRPCClient::login(QString const &username, QString const &password)
LoginRequest request;
request.set_username(username.toStdString());
request.set_password(password.toStdString());
- return stub_->Login(&ctx, request, &empty);
+ return this->logGRPCCallStatus(stub_->Login(&ctx, request, &empty), __FUNCTION__);
}
@@ -574,7 +566,7 @@ grpc::Status GRPCClient::login2FA(QString const &username, QString const &code)
LoginRequest request;
request.set_username(username.toStdString());
request.set_password(code.toStdString());
- return stub_->Login2FA(&ctx, request, &empty);
+ return this->logGRPCCallStatus(stub_->Login2FA(&ctx, request, &empty), __FUNCTION__);
}
@@ -589,7 +581,7 @@ grpc::Status GRPCClient::login2Passwords(QString const &username, QString const
LoginRequest request;
request.set_username(username.toStdString());
request.set_password(password.toStdString());
- return stub_->Login2Passwords(&ctx, request, &empty);
+ return this->logGRPCCallStatus(stub_->Login2Passwords(&ctx, request, &empty), __FUNCTION__);
}
@@ -602,7 +594,7 @@ grpc::Status GRPCClient::loginAbort(QString const &username)
grpc::ClientContext ctx;
LoginAbortRequest request;
request.set_username(username.toStdString());
- return stub_->LoginAbort(&ctx, request, &empty);
+ return this->logGRPCCallStatus(stub_->LoginAbort(&ctx, request, &empty), __FUNCTION__);
}
@@ -611,7 +603,7 @@ grpc::Status GRPCClient::loginAbort(QString const &username)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::checkUpdate()
{
- return this->simpleMethod(&Bridge::Stub::CheckUpdate);
+ return this->logGRPCCallStatus(this->simpleMethod(&Bridge::Stub::CheckUpdate), __FUNCTION__);
}
@@ -620,7 +612,7 @@ grpc::Status GRPCClient::checkUpdate()
//****************************************************************************************************************************************************
grpc::Status GRPCClient::installUpdate()
{
- return this->simpleMethod(&Bridge::Stub::InstallUpdate);
+ return this->logGRPCCallStatus(this->simpleMethod(&Bridge::Stub::InstallUpdate), __FUNCTION__);
}
@@ -629,7 +621,7 @@ grpc::Status GRPCClient::installUpdate()
//****************************************************************************************************************************************************
grpc::Status GRPCClient::setIsAutomaticUpdateOn(bool on)
{
- return this->setBool(&Bridge::Stub::SetIsAutomaticUpdateOn, on);
+ return this->logGRPCCallStatus(this->setBool(&Bridge::Stub::SetIsAutomaticUpdateOn, on), __FUNCTION__);
}
@@ -638,7 +630,7 @@ grpc::Status GRPCClient::setIsAutomaticUpdateOn(bool on)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::isAutomaticUpdateOn(bool &isOn)
{
- return this->getBool(&Bridge::Stub::IsAutomaticUpdateOn, isOn);
+ return this->logGRPCCallStatus(this->getBool(&Bridge::Stub::IsAutomaticUpdateOn, isOn), __FUNCTION__);
}
@@ -648,7 +640,7 @@ grpc::Status GRPCClient::isAutomaticUpdateOn(bool &isOn)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::logoutUser(QString const &userID)
{
- return methodWithStringParam(&Bridge::Stub::LogoutUser, userID);
+ return this->logGRPCCallStatus(methodWithStringParam(&Bridge::Stub::LogoutUser, userID), __FUNCTION__);
}
@@ -658,7 +650,7 @@ grpc::Status GRPCClient::logoutUser(QString const &userID)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::removeUser(QString const &userID)
{
- return methodWithStringParam(&Bridge::Stub::RemoveUser, userID);
+ return this->logGRPCCallStatus(methodWithStringParam(&Bridge::Stub::RemoveUser, userID), __FUNCTION__);
}
@@ -673,7 +665,7 @@ grpc::Status GRPCClient::configureAppleMail(QString const &userID, QString const
ConfigureAppleMailRequest request;
request.set_userid(userID.toStdString());
request.set_address(address.toStdString());
- return stub_->ConfigureUserAppleMail(&ctx, request, &empty);
+ return this->logGRPCCallStatus(stub_->ConfigureUserAppleMail(&ctx, request, &empty), __FUNCTION__);
}
@@ -689,7 +681,7 @@ grpc::Status GRPCClient::setUserSplitMode(QString const &userID, bool active)
request.set_userid(userID.toStdString());
request.set_active(active);
- return stub_->SetUserSplitMode(&ctx, request, &empty);
+ return this->logGRPCCallStatus(stub_->SetUserSplitMode(&ctx, request, &empty), __FUNCTION__);
}
@@ -705,12 +697,12 @@ grpc::Status GRPCClient::getUserList(QList &outUsers)
UserListResponse response;
Status status = stub_->GetUserList(&ctx, empty, &response);
if (!status.ok())
- return status;
+ return this->logGRPCCallStatus(status, __FUNCTION__);
for (int i = 0; i < response.users_size(); ++i)
- outUsers.append(parsegrpcUser(response.users(i)));
+ outUsers.append(this->parseGRPCUser(response.users(i)));
- return status;
+ return this->logGRPCCallStatus(status, __FUNCTION__);
}
@@ -719,7 +711,7 @@ grpc::Status GRPCClient::getUserList(QList &outUsers)
/// \param[out] outUser The user.
/// \return The status code for the operation.
//****************************************************************************************************************************************************
-grpc::Status GRPCClient::getUser(QString const &userID, ::SPUser &outUser)
+grpc::Status GRPCClient::getUser(QString const &userID, SPUser &outUser)
{
ClientContext ctx;
StringValue s;
@@ -728,9 +720,9 @@ grpc::Status GRPCClient::getUser(QString const &userID, ::SPUser &outUser)
Status status = stub_->GetUser(&ctx, s, &grpcUser);
if (status.ok())
- outUser = parsegrpcUser(grpcUser);
+ outUser = parseGRPCUser(grpcUser);
- return grpc::Status();
+ return this->logGRPCCallStatus(grpc::Status(), __FUNCTION__);
}
@@ -745,12 +737,12 @@ grpc::Status GRPCClient::availableKeychains(QStringList &outKeychains)
AvailableKeychainsResponse response;
Status status = stub_->AvailableKeychains(&ctx, empty, &response);
if (!status.ok())
- return status;
+ return this->logGRPCCallStatus(status, __FUNCTION__);
for (int i = 0; i < response.keychains_size(); ++i)
outKeychains.append(QString::fromStdString(response.keychains(i)));
- return status;
+ return this->logGRPCCallStatus(status, __FUNCTION__);
}
@@ -760,7 +752,7 @@ grpc::Status GRPCClient::availableKeychains(QStringList &outKeychains)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::currentKeychain(QString &outKeychain)
{
- return this->getString(&Bridge::Stub::CurrentKeychain, outKeychain);
+ return this->logGRPCCallStatus(this->getString(&Bridge::Stub::CurrentKeychain, outKeychain), __FUNCTION__);
}
@@ -770,7 +762,7 @@ grpc::Status GRPCClient::currentKeychain(QString &outKeychain)
//****************************************************************************************************************************************************
grpc::Status GRPCClient::setCurrentKeychain(QString const &keychain)
{
- return this->setString(&Bridge::Stub::SetCurrentKeychain, keychain);
+ return this->logGRPCCallStatus(this->setString(&Bridge::Stub::SetCurrentKeychain, keychain), __FUNCTION__);
}
@@ -814,11 +806,12 @@ grpc::Status GRPCClient::startEventStream()
this->processUserEvent(event.user());
break;
default:
- app().log().debug(QString("Unknown stream event type: %1").arg(event.event_case()));
+ if (log_)
+ log_->debug(QString("Unknown stream event type: %1").arg(event.event_case()));
}
}
- return reader->Finish();
+ return this->logGRPCCallStatus(reader->Finish(), __FUNCTION__);
}
@@ -828,7 +821,44 @@ grpc::Status GRPCClient::startEventStream()
grpc::Status GRPCClient::stopEventStream()
{
grpc::ClientContext ctx;
- return stub_->StopEventStream(&ctx, empty, &empty);
+ return this->logGRPCCallStatus(stub_->StopEventStream(&ctx, empty, &empty), __FUNCTION__);
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] message The event message.
+//****************************************************************************************************************************************************
+void GRPCClient::logDebug(QString const &message)
+{
+ if (log_)
+ log_->debug(message);
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] message The event message.
+//****************************************************************************************************************************************************
+void GRPCClient::logError(QString const &message)
+{
+ if (log_)
+ log_->error(message);
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] status The status
+/// \param[in] callName The call name.
+//****************************************************************************************************************************************************
+grpc::Status GRPCClient::logGRPCCallStatus(Status const &status, QString const &callName)
+{
+ if (log_)
+ {
+ if (status.ok())
+ log_->debug(QString("%1()").arg(callName));
+ else
+ log_->error(QString("%1() FAILED").arg(callName));
+ }
+ return status;
}
@@ -977,6 +1007,24 @@ grpc::Status GRPCClient::methodWithStringParam(StringParamMethod method, QString
}
+//****************************************************************************************************************************************************
+/// \param[in] grpcUser The gRPC user.
+/// \return The user.
+//****************************************************************************************************************************************************
+SPUser GRPCClient::parseGRPCUser(grpc::User const &grpcUser)
+{
+ SPUser user = userFromGRPC(grpcUser);
+ User *u = user.get();
+
+ connect(u, &User::toggleSplitModeForUser, [&](QString const &userID, bool makeItActive) { this->setUserSplitMode(userID, makeItActive); });
+ connect(u, &User::logoutUser, [&](QString const &userID) { this->logoutUser(userID); });
+ connect(u, &User::removeUser, [&](QString const &userID) { this->removeUser(userID); });
+ connect(u, &User::configureAppleMailForUser, [&](QString const &userID, QString const& address) { this->configureAppleMail(userID, address); });
+
+ return user;
+}
+
+
//****************************************************************************************************************************************************
/// \param[in] event The event.
//****************************************************************************************************************************************************
@@ -985,35 +1033,35 @@ void GRPCClient::processAppEvent(AppEvent const &event)
switch (event.event_case())
{
case AppEvent::kInternetStatus:
- app().log().debug("App event received: InternetStatus.");
+ this->logDebug("App event received: InternetStatus.");
emit internetStatus(event.internetstatus().connected());
break;
case AppEvent::kToggleAutostartFinished:
- app().log().debug("App event received: AutostartFinished.");
+ this->logDebug("App event received: AutostartFinished.");
emit toggleAutostartFinished();
break;
case AppEvent::kResetFinished:
- app().log().debug("App event received: ResetFinished.");
+ this->logDebug("App event received: ResetFinished.");
emit resetFinished();
break;
case AppEvent::kReportBugFinished:
- app().log().debug("App event received: ReportBugFinished.");
+ this->logDebug("App event received: ReportBugFinished.");
emit reportBugFinished();
break;
case AppEvent::kReportBugSuccess:
- app().log().debug("App event received: ReportBugSuccess.");
+ this->logDebug("App event received: ReportBugSuccess.");
emit reportBugSuccess();
break;
case AppEvent::kReportBugError:
- app().log().debug("App event received: ReportBugError.");
+ this->logDebug("App event received: ReportBugError.");
emit reportBugError();
break;
case AppEvent::kShowMainWindow:
- app().log().debug("App event received: ShowMainWindow.");
+ this->logDebug("App event received: ShowMainWindow.");
emit showMainWindow();
break;
default:
- app().log().error("Unknown App event received.");
+ this->logError("Unknown App event received.");
}
}
@@ -1027,7 +1075,7 @@ void GRPCClient::processLoginEvent(LoginEvent const &event)
{
case LoginEvent::kError:
{
- app().log().debug("Login event received: Error.");
+ this->logDebug("Login event received: Error.");
LoginErrorEvent const &error = event.error();
switch (error.type())
{
@@ -1053,29 +1101,29 @@ void GRPCClient::processLoginEvent(LoginEvent const &event)
emit login2PasswordErrorAbort(QString::fromStdString(error.message()));
break;
default:
- app().log().debug("Unknown login error event received.");
+ this->logError("Unknown login error event received.");
break;
}
break;
}
case LoginEvent::kTfaRequested:
- app().log().debug("Login event received: TfaRequested.");
+ this->logDebug("Login event received: TfaRequested.");
emit login2FARequested(QString::fromStdString(event.tfarequested().username()));
break;
case LoginEvent::kTwoPasswordRequested:
- app().log().debug("Login event received: TwoPasswordRequested.");
+ this->logDebug("Login event received: TwoPasswordRequested.");
emit login2PasswordRequested();
break;
case LoginEvent::kFinished:
- app().log().debug("Login event received: Finished.");
+ this->logDebug("Login event received: Finished.");
emit loginFinished(QString::fromStdString(event.finished().userid()));
break;
case LoginEvent::kAlreadyLoggedIn:
- app().log().debug("Login event received: AlreadyLoggedIn.");
+ this->logDebug("Login event received: AlreadyLoggedIn.");
emit loginAlreadyLoggedIn(QString::fromStdString(event.finished().userid()));
break;
default:
- app().log().error("Unknown Login event received.");
+ this->logError("Unknown Login event received.");
break;
}
}
@@ -1090,7 +1138,7 @@ void GRPCClient::processUpdateEvent(UpdateEvent const &event)
{
case UpdateEvent::kError:
{
- app().log().debug("Update event received: Error.");
+ this->logDebug("Update event received: Error.");
UpdateErrorEvent const &errorEvent = event.error();
switch (errorEvent.type())
@@ -1105,37 +1153,37 @@ void GRPCClient::processUpdateEvent(UpdateEvent const &event)
emit updateSilentError();
break;
default:
- app().log().error("Unknown update error received.");
+ this->logError("Unknown update error received.");
break;
}
break;
}
case UpdateEvent::kManualReady:
- app().log().debug("Update event received: ManualReady.");
+ this->logDebug("Update event received: ManualReady.");
emit updateManualReady(QString::fromStdString(event.manualready().version()));
break;
case UpdateEvent::kManualRestartNeeded:
- app().log().debug("Update event received: kManualRestartNeeded.");
+ this->logDebug("Update event received: kManualRestartNeeded.");
emit updateManualRestartNeeded();
break;
case UpdateEvent::kForce:
- app().log().debug("Update event received: kForce.");
+ this->logDebug("Update event received: kForce.");
emit updateForce(QString::fromStdString(event.force().version()));
break;
case UpdateEvent::kSilentRestartNeeded:
- app().log().debug("Update event received: kSilentRestartNeeded.");
+ this->logDebug("Update event received: kSilentRestartNeeded.");
emit updateSilentRestartNeeded();
break;
case UpdateEvent::kIsLatestVersion:
- app().log().debug("Update event received: kIsLatestVersion.");
+ this->logDebug("Update event received: kIsLatestVersion.");
emit updateIsLatestVersion();
break;
case UpdateEvent::kCheckFinished:
- app().log().debug("Update event received: kCheckFinished.");
+ this->logDebug("Update event received: kCheckFinished.");
emit checkUpdatesFinished();
break;
default:
- app().log().error("Unknown Update event received.");
+ this->logError("Unknown Update event received.");
break;
}
}
@@ -1162,34 +1210,34 @@ void GRPCClient::processCacheEvent(CacheEvent const &event)
emit diskFull();
break;
default:
- app().log().error("Unknown cache error event received.");
+ this->logError("Unknown cache error event received.");
break;
}
break;
}
case CacheEvent::kLocationChangedSuccess:
- app().log().debug("Cache event received: LocationChangedSuccess.");
+ this->logDebug("Cache event received: LocationChangedSuccess.");
emit cacheLocationChangeSuccess();
break;
case CacheEvent::kChangeLocalCacheFinished:
emit cacheLocationChangeSuccess();
- app().log().debug("Cache event received: ChangeLocalCacheFinished.");
+ this->logDebug("Cache event received: ChangeLocalCacheFinished.");
break;
case CacheEvent::kIsCacheOnDiskEnabledChanged:
- app().log().debug("Cache event received: IsCacheOnDiskEnabledChanged.");
+ this->logDebug("Cache event received: IsCacheOnDiskEnabledChanged.");
emit isCacheOnDiskEnabledChanged(event.iscacheondiskenabledchanged().enabled());
break;
case CacheEvent::kDiskCachePathChanged:
- app().log().debug("Cache event received: DiskCachePathChanged.");
+ this->logDebug("Cache event received: DiskCachePathChanged.");
emit diskCachePathChanged(QUrl::fromLocalFile(QString::fromStdString(event.diskcachepathchanged().path())));
break;
default:
- app().log().error("Unknown Cache event received.");
+ this->logError("Unknown Cache event received.");
}
}
@@ -1202,7 +1250,7 @@ void GRPCClient::processMailSettingsEvent(MailSettingsEvent const &event)
switch (event.event_case())
{
case MailSettingsEvent::kError:
- app().log().debug("MailSettings event received: Error.");
+ this->logDebug("MailSettings event received: Error.");
switch (event.error().type())
{
case IMAP_PORT_ISSUE:
@@ -1212,20 +1260,20 @@ void GRPCClient::processMailSettingsEvent(MailSettingsEvent const &event)
emit portIssueSMTP();
break;
default:
- app().log().error("Unknown mail settings error event received.");
+ this->logError("Unknown mail settings error event received.");
break;
}
case MailSettingsEvent::kUseSslForSmtpFinished:
- app().log().debug("MailSettings event received: UseSslForSmtpFinished.");
+ this->logDebug("MailSettings event received: UseSslForSmtpFinished.");
emit toggleUseSSLFinished();
break;
case MailSettingsEvent::kChangePortsFinished:
- app().log().debug("MailSettings event received: ChangePortsFinished.");
+ this->logDebug("MailSettings event received: ChangePortsFinished.");
emit changePortFinished();
break;
default:
- app().log().error("Unknown MailSettings event received.");
+ this->logError("Unknown MailSettings event received.");
}
}
@@ -1238,19 +1286,19 @@ void GRPCClient::processKeychainEvent(KeychainEvent const &event)
switch (event.event_case())
{
case KeychainEvent::kChangeKeychainFinished:
- app().log().debug("Keychain event received: ChangeKeychainFinished.");
+ this->logDebug("Keychain event received: ChangeKeychainFinished.");
emit changeKeychainFinished();
break;
case KeychainEvent::kHasNoKeychain:
- app().log().debug("Keychain event received: HasNoKeychain.");
+ this->logDebug("Keychain event received: HasNoKeychain.");
emit hasNoKeychain();
break;
case KeychainEvent::kRebuildKeychain:
- app().log().debug("Keychain event received: RebuildKeychain.");
+ this->logDebug("Keychain event received: RebuildKeychain.");
emit rebuildKeychain();
break;
default:
- app().log().error("Unknown Keychain event received.");
+ this->logError("Unknown Keychain event received.");
}
}
@@ -1263,23 +1311,23 @@ void GRPCClient::processMailEvent(MailEvent const &event)
switch (event.event_case())
{
case MailEvent::kNoActiveKeyForRecipientEvent:
- app().log().debug("Mail event received: kNoActiveKeyForRecipientEvent.");
+ this->logDebug("Mail event received: kNoActiveKeyForRecipientEvent.");
emit noActiveKeyForRecipient(QString::fromStdString(event.noactivekeyforrecipientevent().email()));
break;
case MailEvent::kAddressChanged:
- app().log().debug("Mail event received: AddressChanged.");
+ this->logDebug("Mail event received: AddressChanged.");
emit addressChanged(QString::fromStdString(event.addresschanged().address()));
break;
case MailEvent::kAddressChangedLogout:
- app().log().debug("Mail event received: AddressChangedLogout.");
+ this->logDebug("Mail event received: AddressChangedLogout.");
emit addressChangedLogout(QString::fromStdString(event.addresschangedlogout().address()));
break;
case MailEvent::kApiCertIssue:
emit apiCertIssue();
- app().log().debug("Mail event received: ApiCertIssue.");
+ this->logDebug("Mail event received: ApiCertIssue.");
break;
default:
- app().log().error("Unknown Mail event received.");
+ this->logError("Unknown Mail event received.");
}
}
@@ -1294,25 +1342,28 @@ void GRPCClient::processUserEvent(UserEvent const &event)
case UserEvent::kToggleSplitModeFinished:
{
QString const userID = QString::fromStdString(event.togglesplitmodefinished().userid());
- app().log().debug(QString("User event received: ToggleSplitModeFinished (userID = %1).").arg(userID));
+ this->logDebug(QString("User event received: ToggleSplitModeFinished (userID = %1).").arg(userID));
emit toggleSplitModeFinished(userID);
break;
}
case UserEvent::kUserDisconnected:
{
QString const username = QString::fromStdString(event.userdisconnected().username());
- app().log().debug(QString("User event received: UserDisconnected (username = %1).").arg(username));
+ this->logDebug(QString("User event received: UserDisconnected (username = %1).").arg(username));
emit userDisconnected(username);
break;
}
case UserEvent::kUserChanged:
{
QString const userID = QString::fromStdString(event.userchanged().userid());
- app().log().debug(QString("User event received: UserChanged (userID = %1).").arg(userID));
+ this->logDebug(QString("User event received: UserChanged (userID = %1).").arg(userID));
emit userChanged(userID);
break;
}
default:
- app().log().error("Unknown User event received.");
+ this->logError("Unknown User event received.");
}
}
+
+
+} // namespace bridgepp
\ No newline at end of file
diff --git a/internal/frontend/bridge-gui/GRPC/GRPCClient.h b/internal/frontend/bridgepp/bridgepp/GRPC/GRPCClient.h
similarity index 77%
rename from internal/frontend/bridge-gui/GRPC/GRPCClient.h
rename to internal/frontend/bridgepp/bridgepp/GRPC/GRPCClient.h
index 0721f307..6826dd6d 100644
--- a/internal/frontend/bridge-gui/GRPC/GRPCClient.h
+++ b/internal/frontend/bridgepp/bridgepp/GRPC/GRPCClient.h
@@ -20,44 +20,49 @@
#define BRIDGE_GUI_RPC_CLIENT_H
-#include "GRPC/bridge.grpc.pb.h"
+#include "../User/User.h"
+#include "../Log/Log.h"
+#include "bridge.grpc.pb.h"
#include "grpc++/grpc++.h"
-#include "User/User.h"
-#include "Log.h"
-typedef grpc::Status (grpc::Bridge::Stub::*SimpleMethod)(grpc::ClientContext*, const google::protobuf::Empty&, google::protobuf::Empty*);
-typedef grpc::Status (grpc::Bridge::Stub::*BoolSetter)(grpc::ClientContext*, const google::protobuf::BoolValue&, google::protobuf::Empty*);
-typedef grpc::Status (grpc::Bridge::Stub::*BoolGetter)(grpc::ClientContext*, const google::protobuf::Empty&, google::protobuf::BoolValue*);
-typedef grpc::Status (grpc::Bridge::Stub::*Int32Setter)(grpc::ClientContext*, const google::protobuf::Int32Value&, google::protobuf::Empty*);
-typedef grpc::Status (grpc::Bridge::Stub::*Int32Getter)(grpc::ClientContext*, const google::protobuf::Empty&, google::protobuf::Int32Value*);
-typedef grpc::Status (grpc::Bridge::Stub::*StringGetter)(grpc::ClientContext*, const google::protobuf::Empty&, google::protobuf::StringValue*);
-typedef grpc::Status (grpc::Bridge::Stub::*StringSetter)(grpc::ClientContext*, const google::protobuf::StringValue&, google::protobuf::Empty*);
-typedef grpc::Status (grpc::Bridge::Stub::*StringParamMethod)(grpc::ClientContext*, const google::protobuf::StringValue&, google::protobuf::Empty*);
+namespace bridgepp
+{
+
+
+typedef grpc::Status (grpc::Bridge::Stub::*SimpleMethod)(grpc::ClientContext *, const google::protobuf::Empty &, google::protobuf::Empty *);
+typedef grpc::Status (grpc::Bridge::Stub::*BoolSetter)(grpc::ClientContext *, const google::protobuf::BoolValue &, google::protobuf::Empty *);
+typedef grpc::Status (grpc::Bridge::Stub::*BoolGetter)(grpc::ClientContext *, const google::protobuf::Empty &, google::protobuf::BoolValue *);
+typedef grpc::Status (grpc::Bridge::Stub::*Int32Setter)(grpc::ClientContext *, const google::protobuf::Int32Value &, google::protobuf::Empty *);
+typedef grpc::Status (grpc::Bridge::Stub::*Int32Getter)(grpc::ClientContext *, const google::protobuf::Empty &, google::protobuf::Int32Value *);
+typedef grpc::Status (grpc::Bridge::Stub::*StringGetter)(grpc::ClientContext *, const google::protobuf::Empty &, google::protobuf::StringValue *);
+typedef grpc::Status (grpc::Bridge::Stub::*StringSetter)(grpc::ClientContext *, const google::protobuf::StringValue &, google::protobuf::Empty *);
+typedef grpc::Status (grpc::Bridge::Stub::*StringParamMethod)(grpc::ClientContext *, const google::protobuf::StringValue &, google::protobuf::Empty *);
//****************************************************************************************************************************************************
/// \brief gRPC client class. This class encapsulate the gRPC service, abstracting all data type conversions.
//****************************************************************************************************************************************************
-class GRPCClient: public QObject
+class GRPCClient : public QObject
{
- Q_OBJECT
+Q_OBJECT
public: // member functions.
GRPCClient() = default; ///< Default constructor.
- GRPCClient(GRPCClient const&) = delete; ///< Disabled copy-constructor.
- GRPCClient(GRPCClient&&) = delete; ///< Disabled assignment copy-constructor.
+ GRPCClient(GRPCClient const &) = delete; ///< Disabled copy-constructor.
+ GRPCClient(GRPCClient &&) = delete; ///< Disabled assignment copy-constructor.
~GRPCClient() override = default; ///< Destructor.
- GRPCClient& operator=(GRPCClient const&) = delete; ///< Disabled assignment operator.
- GRPCClient& operator=(GRPCClient&&) = delete; ///< Disabled move assignment operator.
+ GRPCClient &operator=(GRPCClient const &) = delete; ///< Disabled assignment operator.
+ GRPCClient &operator=(GRPCClient &&) = delete; ///< Disabled move assignment operator.
+ void setLog(Log *log); ///< Set the log for the client.
bool connectToServer(QString &outError); ///< Establish connection to the gRPC server.
-
- grpc::Status addLogEntry(Log::Level level, QString const& package, QString const &message); ///< Performs the "AddLogEntry" gRPC call.
+
+ grpc::Status addLogEntry(Log::Level level, QString const &package, QString const &message); ///< Performs the "AddLogEntry" gRPC call.
grpc::Status guiReady(); ///< performs the "GuiReady" gRPC call.
grpc::Status isFirstGUIStart(bool &outIsFirst); ///< performs the "IsFirstGUIStart" gRPC call.
grpc::Status isAutostartOn(bool &outIsOn); ///< Performs the "isAutostartOn" gRPC call.
grpc::Status setIsAutostartOn(bool on); ///< Performs the "setIsAutostartOn" gRPC call.
grpc::Status isBetaEnabled(bool &outEnabled); ///< Performs the "isBetaEnabled" gRPC call.
- grpc::Status setisBetaEnabled(bool enabled); ///< Performs the 'setIsBetaEnabled' gRPC call.
+ grpc::Status setIsBetaEnabled(bool enabled); ///< Performs the 'setIsBetaEnabled' gRPC call.
grpc::Status colorSchemeName(QString &outName); ///< Performs the "colorSchemeName' gRPC call.
grpc::Status setColorSchemeName(QString const &name); ///< Performs the "setColorSchemeName' gRPC call.
grpc::Status currentEmailClient(QString &outName); ///< Performs the 'currentEmailClient' gRPC call.
@@ -93,7 +98,7 @@ public:
grpc::Status changeLocalCache(bool enabled, QUrl const &path); ///< Performs the 'ChangeLocalCache' call.
signals:
void isCacheOnDiskEnabledChanged(bool enabled);
- void diskCachePathChanged(QUrl const&outPath);
+ void diskCachePathChanged(QUrl const &outPath);
void cacheUnavailable(); // _ func() `signal:"cacheUnavailable"`
void cacheCantMove(); // _ func() `signal:"cacheCantMove"`
void cacheLocationChangeSuccess(); // _ func() `signal:"cacheLocationChangeSuccess"`
@@ -118,9 +123,9 @@ signals:
void changePortFinished();
public: // login related calls
- grpc::Status login(QString const &username, QString const& password); ///< Performs the 'login' call.
- grpc::Status login2FA(QString const &username, QString const& code); ///< Performs the 'login2FA' call.
- grpc::Status login2Passwords(QString const &username, QString const& password); ///< Performs the 'login2Passwords' call.
+ grpc::Status login(QString const &username, QString const &password); ///< Performs the 'login' call.
+ grpc::Status login2FA(QString const &username, QString const &code); ///< Performs the 'login2FA' call.
+ grpc::Status login2Passwords(QString const &username, QString const &password); ///< Performs the 'login2Passwords' call.
grpc::Status loginAbort(QString const &username); ///< Performs the 'loginAbort' call.
signals:
@@ -128,13 +133,13 @@ signals:
void loginFreeUserError(); // _ func() `signal:"loginFreeUserError"`
void loginConnectionError(QString const &errMsg); // _ func(errorMsg string) `signal:"loginConnectionError"`
void login2FARequested(QString const &userName); // _ func(username string) `signal:"login2FARequested"`
- void login2FAError(QString const& errMsg); // _ func(errorMsg string) `signal:"login2FAError"`
- void login2FAErrorAbort(QString const& errMsg); // _ func(errorMsg string) `signal:"login2FAErrorAbort"`
+ void login2FAError(QString const &errMsg); // _ func(errorMsg string) `signal:"login2FAError"`
+ void login2FAErrorAbort(QString const &errMsg); // _ func(errorMsg string) `signal:"login2FAErrorAbort"`
void login2PasswordRequested(); // _ func() `signal:"login2PasswordRequested"`
- void login2PasswordError(QString const& errMsg); // _ func(errorMsg string) `signal:"login2PasswordError"`
- void login2PasswordErrorAbort(QString const& errMsg); // _ func(errorMsg string) `signal:"login2PasswordErrorAbort"`
- void loginFinished(QString const &userID); // _ func(index int) `signal:"loginFinished"`
- void loginAlreadyLoggedIn(QString const &userID); // _ func(index int) `signal:"loginAlreadyLoggedIn"`
+ void login2PasswordError(QString const &errMsg); // _ func(errorMsg string) `signal:"login2PasswordError"`
+ void login2PasswordErrorAbort(QString const &errMsg); // _ func(errorMsg string) `signal:"login2PasswordErrorAbort"`
+ void loginFinished(QString const &userID); // _ func(index int) `signal:"loginFinished"`
+ void loginAlreadyLoggedIn(QString const &userID); // _ func(index int) `signal:"loginAlreadyLoggedIn"`
public: // Update related calls
grpc::Status checkUpdate();
@@ -154,17 +159,17 @@ signals:
void checkUpdatesFinished();
public: // user related calls
- grpc::Status getUserList(QList& outUsers);
- grpc::Status getUser(QString const &userID, SPUser& outUser);
+ grpc::Status getUserList(QList &outUsers);
+ grpc::Status getUser(QString const &userID, SPUser &outUser);
grpc::Status logoutUser(QString const &userID); ///< Performs the 'logoutUser' call.
grpc::Status removeUser(QString const &userID); ///< Performs the 'removeUser' call.
- grpc::Status configureAppleMail(QString const& userID, QString const &address); ///< Performs the 'configureAppleMail' call.
- grpc::Status setUserSplitMode(QString const& userID, bool active); ///< Performs the 'SetUserSplitMode' call.
+ grpc::Status configureAppleMail(QString const &userID, QString const &address); ///< Performs the 'configureAppleMail' call.
+ grpc::Status setUserSplitMode(QString const &userID, bool active); ///< Performs the 'SetUserSplitMode' call.
signals:
- void toggleSplitModeFinished(QString const& userID);
- void userDisconnected(QString const& username);
- void userChanged(QString const& userID);
+ void toggleSplitModeFinished(QString const &userID);
+ void userDisconnected(QString const &username);
+ void userChanged(QString const &userID);
public: // keychain related calls
@@ -178,7 +183,7 @@ signals:
void rebuildKeychain();
void certIsReady();
-signals: // mail releated events
+signals: // mail related events
void noActiveKeyForRecipient(QString const &email); // _ func(email string) `signal:noActiveKeyForRecipient`
void addressChanged(QString const &address); // _ func(address string) `signal:addressChanged`
void addressChangedLogout(QString const &address); // _ func(address string) `signal:addressChangedLogout`
@@ -192,16 +197,20 @@ private slots:
void configFolderChanged();
private:
+ void logDebug(QString const &message); ///< Log an event.
+ void logError(QString const &message); ///< Log an event.
+ grpc::Status logGRPCCallStatus(grpc::Status const &status, QString const &callName); ///< Log the status of a gRPC code.
grpc::Status simpleMethod(SimpleMethod method); ///< perform a gRPC call to a bool setter.
grpc::Status setBool(BoolSetter setter, bool value); ///< perform a gRPC call to a bool setter.
- grpc::Status getBool(BoolGetter getter, bool& outValue); ///< perform a gRPC call to a bool getter.
+ grpc::Status getBool(BoolGetter getter, bool &outValue); ///< perform a gRPC call to a bool getter.
grpc::Status setInt32(Int32Setter setter, int value); ///< perform a gRPC call to an int setter.
- grpc::Status getInt32(Int32Getter getter, int& outValue); ///< perform a gRPC call to an int getter.
- grpc::Status setString(StringSetter getter, QString const& value); ///< Perform a gRPC call to a string setter.
- grpc::Status getString(StringGetter getter, QString& outValue); ///< Perform a gRPC call to a string getter.
- grpc::Status getURLForLocalFile(StringGetter getter, QUrl& outValue); ///< Perform a gRPC call to a string getter, with resulted converted to QUrl for a local file path.
- grpc::Status getURL(StringGetter getter, QUrl& outValue); ///< Perform a gRPC call to a string getter, with resulted converted to QUrl.
- grpc::Status methodWithStringParam(StringParamMethod method, QString const& str); ///< Perfom a gRPC call that takes a string as a parameter and returns an Empty.
+ grpc::Status getInt32(Int32Getter getter, int &outValue); ///< perform a gRPC call to an int getter.
+ grpc::Status setString(StringSetter getter, QString const &value); ///< Perform a gRPC call to a string setter.
+ grpc::Status getString(StringGetter getter, QString &outValue); ///< Perform a gRPC call to a string getter.
+ grpc::Status getURLForLocalFile(StringGetter getter, QUrl &outValue); ///< Perform a gRPC call to a string getter, with resulted converted to QUrl for a local file path.
+ grpc::Status getURL(StringGetter getter, QUrl &outValue); ///< Perform a gRPC call to a string getter, with resulted converted to QUrl.
+ grpc::Status methodWithStringParam(StringParamMethod method, QString const &str); ///< Perform a gRPC call that takes a string as a parameter and returns an Empty.
+ SPUser parseGRPCUser(grpc::User const &grpcUser); ///< Parse a gRPC user struct and return a User.
std::string getServerCertificate(); ///< Wait until server certificates is generated and retrieve it.
void processAppEvent(grpc::AppEvent const &event); ///< Process an 'App' event.
@@ -214,9 +223,13 @@ private:
void processUserEvent(grpc::UserEvent const &event); ///< Process a 'User' event.
private: // data members.
+ Log *log_ { nullptr }; ///< The log for the GRPC client.
std::shared_ptr channel_ { nullptr }; ///< The gRPC channel.
std::shared_ptr stub_ { nullptr }; ///< The gRPC stub (a.k.a. client).
};
+}
+
+
#endif // BRIDGE_GUI_RPC_CLIENT_H
diff --git a/internal/frontend/bridgepp/bridgepp/GRPC/GRPCUtils.cpp b/internal/frontend/bridgepp/bridgepp/GRPC/GRPCUtils.cpp
new file mode 100644
index 00000000..440bdcd3
--- /dev/null
+++ b/internal/frontend/bridgepp/bridgepp/GRPC/GRPCUtils.cpp
@@ -0,0 +1,182 @@
+// 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 "GRPCUtils.h"
+#include "../Exception/Exception.h"
+#include "../BridgeUtils.h"
+
+
+#if defined(Q_OS_WIN32) && defined(ERROR)
+// The folks at Microsoft have decided that it was OK to `#define ERROR 0` in wingdi.h. It is not OK, because
+// any occurrence of ERROR, even scoped, will be substituted. For instance Log::Level::ERROR (case imposed by gRPC).
+#undef ERROR
+#endif
+
+
+namespace bridgepp
+{
+
+
+namespace
+{
+
+
+//****************************************************************************************************************************************************
+/// \return The server certificate file name
+//****************************************************************************************************************************************************
+QString serverCertificateFilename()
+{
+ return "cert.pem";
+}
+
+
+//****************************************************************************************************************************************************
+//
+//****************************************************************************************************************************************************
+QString serverKeyFilename()
+{
+ return "key.pem";
+}
+
+
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The absolute path of the server certificate.
+//****************************************************************************************************************************************************
+QString serverCertificatePath()
+{
+ return QDir(userConfigDir()).absoluteFilePath(serverCertificateFilename());
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The absolute path of the server key.
+//****************************************************************************************************************************************************
+QString serverKeyPath()
+{
+ return QDir(userConfigDir()).absoluteFilePath(serverKeyFilename());
+}
+
+
+
+//****************************************************************************************************************************************************
+/// \param[in] level The Log::Level.
+/// \return The grpc::LogLevel.
+//****************************************************************************************************************************************************
+grpc::LogLevel logLevelToGRPC(Log::Level level)
+{
+ switch (level)
+ {
+ case Log::Level::Panic:
+ return grpc::LogLevel::PANIC;
+ case Log::Level::Fatal:
+ return grpc::LogLevel::FATAL;
+ case Log::Level::Error:
+ return grpc::LogLevel::ERROR;
+ case Log::Level::Warn:
+ return grpc::LogLevel::WARN;
+ case Log::Level::Info:
+ return grpc::LogLevel::INFO;
+ case Log::Level::Debug:
+ return grpc::LogLevel::DEBUG;
+ case Log::Level::Trace:
+ return grpc::LogLevel::TRACE;
+ default:
+ throw Exception(QString("unknown log level %1.").arg(qint32(level)));
+ }
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] level The level::LogLevel.
+/// \return The Log::Level.
+//****************************************************************************************************************************************************
+Log::Level logLevelFromGRPC(grpc::LogLevel level)
+{
+ switch (level)
+ {
+ case grpc::PANIC:
+ return Log::Level::Panic;
+ case grpc::FATAL:
+ return Log::Level::Fatal;
+ case grpc::ERROR:
+ return Log::Level::Error;
+ case grpc::WARN:
+ return Log::Level::Warn;
+ case grpc::INFO:
+ return Log::Level::Info;
+ case grpc::DEBUG:
+ return Log::Level::Debug;
+ case grpc::TRACE:
+ return Log::Level::Trace;
+ default:
+ throw Exception(QString("unknown log level %1.").arg(qint32(level)));
+ }
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] grpcUser The gRPC user.
+/// \param[in] user The user.
+//****************************************************************************************************************************************************
+SPUser userFromGRPC(grpc::User const &grpcUser)
+{
+ SPUser user = User::newUser(nullptr);
+
+ user->setID(QString::fromStdString(grpcUser.id()));
+ user->setUsername(QString::fromStdString(grpcUser.username()));
+ user->setPassword(QString::fromStdString(grpcUser.password()));
+ QStringList addresses;
+ for (int j = 0; j < grpcUser.addresses_size(); ++j)
+ addresses.append(QString::fromStdString(grpcUser.addresses(j)));
+ user->setAddresses(addresses);
+ user->setAvatarText(QString::fromStdString(grpcUser.avatartext()));
+ user->setLoggedIn(grpcUser.loggedin());
+ user->setSplitMode(grpcUser.splitmode());
+ user->setSetupGuideSeen(grpcUser.setupguideseen());
+ user->setUsedBytes(float(grpcUser.usedbytes()));
+ user->setTotalBytes(float(grpcUser.totalbytes()));
+
+ return user;
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] user the user.
+/// \param[out] outGRPCUser The GRPC user.
+//****************************************************************************************************************************************************
+void userToGRPC(User const &user, grpc::User &outGRPCUser)
+{
+ outGRPCUser.set_id(user.id().toStdString());
+ outGRPCUser.set_username(user.username().toStdString());
+ outGRPCUser.set_password(user.password().toStdString());
+ outGRPCUser.clear_addresses();
+ for (QString const& address: user.addresses())
+ outGRPCUser.add_addresses(address.toStdString());
+ outGRPCUser.set_avatartext(user.avatarText().toStdString());
+ outGRPCUser.set_loggedin(user.loggedIn());
+ outGRPCUser.set_splitmode(user.splitMode());
+ outGRPCUser.set_setupguideseen(user.setupGuideSeen());
+ outGRPCUser.set_usedbytes(user.usedBytes());
+ outGRPCUser.set_totalbytes(user.totalBytes());
+}
+
+
+} // namespace bridgepp
\ No newline at end of file
diff --git a/internal/frontend/bridgepp/bridgepp/GRPC/GRPCUtils.h b/internal/frontend/bridgepp/bridgepp/GRPC/GRPCUtils.h
new file mode 100644
index 00000000..9fee503a
--- /dev/null
+++ b/internal/frontend/bridgepp/bridgepp/GRPC/GRPCUtils.h
@@ -0,0 +1,42 @@
+// 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_GRPC_UTILS_H
+#define BRIDGE_GUI_GRPC_UTILS_H
+
+
+#include "../User/User.h"
+#include "../Log/Log.h"
+#include "bridge.grpc.pb.h"
+
+
+namespace bridgepp
+{
+
+
+QString serverCertificatePath(); ///< Return the path of the server certificate.
+QString serverKeyPath(); ///< Return the path of the server key.
+grpc::LogLevel logLevelToGRPC(Log::Level level); ///< Convert a Log::Level to gRPC enum value.
+Log::Level logLevelFromGRPC(grpc::LogLevel level); ///< Convert a grpc::LogLevel to a Log::Level.
+void userToGRPC(User const &user, grpc::User &outGRPCUser); ///< Convert a bridgepp::User to a grpc::User.
+SPUser userFromGRPC(grpc::User const &grpcUser); ///< Create a bridgepp::User from a grpc::User.
+
+}
+
+
+#endif // BRIDGE_GUI_GRPC_UTILS_H
diff --git a/internal/frontend/bridge-gui/GRPC/bridge.grpc.pb.cc b/internal/frontend/bridgepp/bridgepp/GRPC/bridge.grpc.pb.cc
similarity index 100%
rename from internal/frontend/bridge-gui/GRPC/bridge.grpc.pb.cc
rename to internal/frontend/bridgepp/bridgepp/GRPC/bridge.grpc.pb.cc
diff --git a/internal/frontend/bridge-gui/GRPC/bridge.grpc.pb.h b/internal/frontend/bridgepp/bridgepp/GRPC/bridge.grpc.pb.h
similarity index 100%
rename from internal/frontend/bridge-gui/GRPC/bridge.grpc.pb.h
rename to internal/frontend/bridgepp/bridgepp/GRPC/bridge.grpc.pb.h
diff --git a/internal/frontend/bridge-gui/GRPC/bridge.pb.cc b/internal/frontend/bridgepp/bridgepp/GRPC/bridge.pb.cc
similarity index 100%
rename from internal/frontend/bridge-gui/GRPC/bridge.pb.cc
rename to internal/frontend/bridgepp/bridgepp/GRPC/bridge.pb.cc
diff --git a/internal/frontend/bridge-gui/GRPC/bridge.pb.h b/internal/frontend/bridgepp/bridgepp/GRPC/bridge.pb.h
similarity index 100%
rename from internal/frontend/bridge-gui/GRPC/bridge.pb.h
rename to internal/frontend/bridgepp/bridgepp/GRPC/bridge.pb.h
diff --git a/internal/frontend/bridge-gui/Log.cpp b/internal/frontend/bridgepp/bridgepp/Log/Log.cpp
similarity index 81%
rename from internal/frontend/bridge-gui/Log.cpp
rename to internal/frontend/bridgepp/bridgepp/Log/Log.cpp
index 41cacb9c..38c429e8 100644
--- a/internal/frontend/bridge-gui/Log.cpp
+++ b/internal/frontend/bridgepp/bridgepp/Log/Log.cpp
@@ -16,13 +16,38 @@
// along with Proton Mail Bridge. If not, see .
-#include "Pch.h"
#include "Log.h"
+namespace bridgepp
+{
+
+
namespace
{
+Log *qtHandlerLog { nullptr }; ///< The log instance handling qt logs.
+QMutex qtHandlerMutex; ///< A mutex used to access qtHandlerLog.
+
+//****************************************************************************************************************************************************
+/// \param[in] log The log handling qt log entries. Can be null.
+//****************************************************************************************************************************************************
+void setQtMessageHandlerLog(Log *log)
+{
+ QMutexLocker locker(&qtHandlerMutex);
+ qtHandlerLog = log;
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The log handling qt log entries. Can be null.
+//****************************************************************************************************************************************************
+Log *qtMessageHandlerLog()
+{
+ QMutexLocker locker(&qtHandlerMutex);
+ return qtHandlerLog;
+}
+
//****************************************************************************************************************************************************
/// \param[in] type The message type.
@@ -30,25 +55,27 @@ namespace
//****************************************************************************************************************************************************
void qtMessageHandler(QtMsgType type, QMessageLogContext const &, QString const &message)
{
- static Log &log = app().log();
+ Log *log = qtMessageHandlerLog();
+ if (!log)
+ return;
switch (type)
{
case QtDebugMsg:
- log.debug(message);
+ log->debug(message);
break;
case QtWarningMsg:
- log.warn(message);
+ log->warn(message);
break;
case QtCriticalMsg:
case QtFatalMsg:
- log.error(message);
+ log->error(message);
break;
case QtInfoMsg:
default:
- log.info(message);
+ log->info(message);
break;
}
}
@@ -62,18 +89,28 @@ QString logLevelToString(Log::Level level)
{
switch (level)
{
- case Log::Level::Panic: return "PANIC";
- case Log::Level::Fatal: return "FATAL";
- case Log::Level::Error: return "ERROR";
- case Log::Level::Warn: return "WARN";
- case Log::Level::Info: return "INFO";
- case Log::Level::Debug: return "DEBUG";
- case Log::Level::Trace: return "TRACE";
- default: return "UNKNOWN";
+ case Log::Level::Panic:
+ return "PANIC";
+ case Log::Level::Fatal:
+ return "FATAL";
+ case Log::Level::Error:
+ return "ERROR";
+ case Log::Level::Warn:
+ return "WARN";
+ case Log::Level::Info:
+ return "INFO";
+ case Log::Level::Debug:
+ return "DEBUG";
+ case Log::Level::Trace:
+ return "TRACE";
+ default:
+ return "UNKNOWN";
}
}
+} // anonymous namespace
+
//****************************************************************************************************************************************************
/// \brief return a string representing the log entry
@@ -82,20 +119,18 @@ QString logLevelToString(Log::Level level)
/// \param[in] message The log entry message.
/// \return The string for the log entry
//****************************************************************************************************************************************************
-QString logEntryToString(Log::Level level, QString const &message)
+QString Log::logEntryToString(Log::Level level, QString const &message)
{
- return QString("[%1] %2").arg(logLevelToString(level)).arg(message);
-}
-
-
+ return QString("[%1] %2").arg(logLevelToString(level), message);
}
//****************************************************************************************************************************************************
/// the message handle process the message from the Qt logging system.
//****************************************************************************************************************************************************
-void Log::installQtMessageHandler()
+void Log::registerAsQtMessageHandler()
{
+ setQtMessageHandlerLog(this);
qInstallMessageHandler(qtMessageHandler);
}
@@ -227,8 +262,11 @@ void Log::addEntry(Log::Level level, QString const &message)
if (echoInConsole_)
{
- QTextStream& stream = (qint32(level) <= (qint32(Level::Warn))) ? stderr_ : stdout_;
+ QTextStream &stream = (qint32(level) <= (qint32(Level::Warn))) ? stderr_ : stdout_;
stream << logEntryToString(level, message) << "\n";
stream.flush();
}
}
+
+
+} // namespace bridgepp
diff --git a/internal/frontend/bridge-gui/Log.h b/internal/frontend/bridgepp/bridgepp/Log/Log.h
similarity index 87%
rename from internal/frontend/bridge-gui/Log.h
rename to internal/frontend/bridgepp/bridgepp/Log/Log.h
index 2112ef58..95ba2f1c 100644
--- a/internal/frontend/bridge-gui/Log.h
+++ b/internal/frontend/bridgepp/bridgepp/Log/Log.h
@@ -16,8 +16,12 @@
// along with Proton Mail Bridge. If not, see .
-#ifndef BRIDGE_GUI_LOG_H
-#define BRIDGE_GUI_LOG_H
+#ifndef BRIDGE_PP_LOG_H
+#define BRIDGE_PP_LOG_H
+
+
+namespace bridgepp
+{
//****************************************************************************************************************************************************
@@ -25,9 +29,9 @@
//****************************************************************************************************************************************************
class Log : public QObject
{
- Q_OBJECT
+Q_OBJECT
public: // data types.
- /// \brief Log level class. The list matches [logrus log levels](https://pkg.go.dev/github.com/sirupsen/logrus).
+ /// \brief Log level class. The list matches [loggers log levels](https://pkg.go.dev/github.com/sirupsen/logrus).
enum class Level
{
Panic, ///< Panic log level.
@@ -39,8 +43,9 @@ public: // data types.
Trace ///< Trace log level.
};
-public: // static member functions
- static void installQtMessageHandler(); ///< Install the Qt message handler.
+public: // static member functions.
+ static QString logEntryToString(Log::Level level, QString const &message); ///< Return a string describing a log entry.
+
public: // member functions.
Log(); ///< Default constructor.
@@ -54,6 +59,7 @@ public: // member functions.
Level level() const; ///< Get the log level.
void setEchoInConsole(bool value); ///< Set if the log entries should be echoed in STDOUT/STDERR.
bool echoInConsole() const; ///< Check if the log entries should be echoed in STDOUT/STDERR.
+ void registerAsQtMessageHandler(); ///< Install the Qt message handler.
public slots:
void panic(QString const &message); ///< Adds an panic entry to the log.
@@ -79,4 +85,7 @@ private: // data members
};
-#endif //BRIDGE_GUI_LOG_H
+} // namespace bridgepp
+
+
+#endif //BRIDGE_PP_LOG_H
diff --git a/internal/frontend/bridgepp/bridgepp/User/User.cpp b/internal/frontend/bridgepp/bridgepp/User/User.cpp
new file mode 100644
index 00000000..a1fddf44
--- /dev/null
+++ b/internal/frontend/bridgepp/bridgepp/User/User.cpp
@@ -0,0 +1,329 @@
+// 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 "User.h"
+
+
+namespace bridgepp
+{
+
+
+//****************************************************************************************************************************************************
+/// \param[in] parent The parent object of the user.
+//****************************************************************************************************************************************************
+SPUser User::newUser(QObject *parent)
+{
+ return SPUser(new User(parent));
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] parent The parent object.
+//****************************************************************************************************************************************************
+User::User(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] user The user to copy from
+//****************************************************************************************************************************************************
+void User::update(User const &user)
+{
+ this->setID(user.id());
+ this->setUsername(user.username());
+ this->setPassword(user.password());
+ this->setAddresses(user.addresses());
+ this->setAvatarText(user.avatarText());
+ this->setLoggedIn(user.loggedIn());
+ this->setSplitMode(user.splitMode());
+ this->setSetupGuideSeen(user.setupGuideSeen());
+ this->setUsedBytes(user.usedBytes());
+ this->setTotalBytes(user.totalBytes());
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] makeItActive Should split mode be made active.
+//****************************************************************************************************************************************************
+void User::toggleSplitMode(bool makeItActive)
+{
+ emit toggleSplitModeForUser(id_, makeItActive);
+}
+
+
+//****************************************************************************************************************************************************
+//
+//****************************************************************************************************************************************************
+void User::logout()
+{
+ emit logoutUser(id_);
+}
+
+
+//****************************************************************************************************************************************************
+//
+//****************************************************************************************************************************************************
+void User::remove()
+{
+ emit removeUser(id_);
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] address The email address to configure Apple Mail for.
+//****************************************************************************************************************************************************
+void User::configureAppleMail(QString const &address)
+{
+ emit configureAppleMailForUser(id_, address);
+}
+
+
+//****************************************************************************************************************************************************
+// The only purpose of this call is to forward to the QML application the toggleSplitModeFinished(userID) event
+// that was received by the UserList model.
+//****************************************************************************************************************************************************
+void User::emitToggleSplitModeFinished()
+{
+ emit toggleSplitModeFinished();
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The userID.
+//****************************************************************************************************************************************************
+QString User::id() const
+{
+ return id_;
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] id The userID.
+//****************************************************************************************************************************************************
+void User::setID(QString const &id)
+{
+ if (id == id_)
+ return;
+
+ id_ = id;
+ emit idChanged(id_);
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The username.
+//****************************************************************************************************************************************************
+QString User::username() const
+{
+ return username_;
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] username The username.
+//****************************************************************************************************************************************************
+void User::setUsername(QString const &username)
+{
+ if (username == username_)
+ return;
+
+ username_ = username;
+ emit usernameChanged(username_);
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The password.
+//****************************************************************************************************************************************************
+QString User::password() const
+{
+ return password_;
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] password The password.
+//****************************************************************************************************************************************************
+void User::setPassword(QString const &password)
+{
+ if (password == password_)
+ return;
+
+ password_ = password;
+ emit passwordChanged(password_);
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The addresses.
+//****************************************************************************************************************************************************
+QStringList User::addresses() const
+{
+ return addresses_;
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] addresses The addresses.
+//****************************************************************************************************************************************************
+void User::setAddresses(QStringList const &addresses)
+{
+ if (addresses == addresses_)
+ return;
+
+ addresses_ = addresses;
+ emit addressesChanged(addresses_);
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The avatar text.
+//****************************************************************************************************************************************************
+QString User::avatarText() const
+{
+ return avatarText_;
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] avatarText The avatar text.
+//****************************************************************************************************************************************************
+void User::setAvatarText(QString const &avatarText)
+{
+ if (avatarText == avatarText_)
+ return;
+
+ avatarText_ = avatarText;
+ emit usernameChanged(avatarText_);
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The login status.
+//****************************************************************************************************************************************************
+bool User::loggedIn() const
+{
+ return loggedIn_;
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] loggedIn The login status.
+//****************************************************************************************************************************************************
+void User::setLoggedIn(bool loggedIn)
+{
+ if (loggedIn == loggedIn_)
+ return;
+
+ loggedIn_ = loggedIn;
+ emit loggedInChanged(loggedIn_);
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The split mode status.
+//****************************************************************************************************************************************************
+bool User::splitMode() const
+{
+ return splitMode_;
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] splitMode The split mode status.
+//****************************************************************************************************************************************************
+void User::setSplitMode(bool splitMode)
+{
+ if (splitMode == splitMode_)
+ return;
+
+ splitMode_ = splitMode;
+ emit splitModeChanged(splitMode_);
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The 'Setup Guide Seen' status.
+//****************************************************************************************************************************************************
+bool User::setupGuideSeen() const
+{
+ return setupGuideSeen_;
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] setupGuideSeen The 'Setup Guide Seen' status.
+//****************************************************************************************************************************************************
+void User::setSetupGuideSeen(bool setupGuideSeen)
+{
+ if (setupGuideSeen == setupGuideSeen_)
+ return;
+
+ setupGuideSeen_ = setupGuideSeen;
+ emit setupGuideSeenChanged(setupGuideSeen_);
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The used bytes.
+//****************************************************************************************************************************************************
+float User::usedBytes() const
+{
+ return usedBytes_;
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] usedBytes The used bytes.
+//****************************************************************************************************************************************************
+void User::setUsedBytes(float usedBytes)
+{
+ if (usedBytes == usedBytes_)
+ return;
+
+ usedBytes_ = usedBytes;
+ emit usedBytesChanged(usedBytes_);
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The total bytes.
+//****************************************************************************************************************************************************
+float User::totalBytes() const
+{
+ return totalBytes_;
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] totalBytes The total bytes.
+//****************************************************************************************************************************************************
+void User::setTotalBytes(float totalBytes)
+{
+ if (totalBytes == totalBytes_)
+ return;
+
+ totalBytes_ = totalBytes;
+ emit totalBytesChanged(totalBytes_);
+}
+
+
+} // namespace bridgepp
diff --git a/internal/frontend/bridgepp/bridgepp/User/User.h b/internal/frontend/bridgepp/bridgepp/User/User.h
new file mode 100644
index 00000000..472229e1
--- /dev/null
+++ b/internal/frontend/bridgepp/bridgepp/User/User.h
@@ -0,0 +1,130 @@
+// 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_USER_H
+#define BRIDGE_GUI_USER_H
+
+
+namespace bridgepp
+{
+
+
+typedef std::shared_ptr SPUser; ///< Type definition for shared pointer to user.
+
+
+//****************************************************************************************************************************************************
+/// \brief User class.
+//****************************************************************************************************************************************************
+class User : public QObject
+{
+Q_OBJECT
+public: // static member function
+ static SPUser newUser(QObject *parent); ///< Create a new user
+
+public: // member functions.
+ User(User const &) = delete; ///< Disabled copy-constructor.
+ User(User &&) = delete; ///< Disabled assignment copy-constructor.
+ ~User() override = default; ///< Destructor.
+ User &operator=(User const &) = delete; ///< Disabled assignment operator.
+ User &operator=(User &&) = delete; ///< Disabled move assignment operator.
+ void update(User const &user); ///< Update the user.
+
+public slots:
+ // slots for QML generated calls
+ void toggleSplitMode(bool makeItActive); // _ func(makeItActive bool) `slot:"toggleSplitMode"`
+ void logout(); // _ func() `slot:"logout"`
+ void remove(); // _ func() `slot:"remove"`
+ void configureAppleMail(QString const &address); // _ func(address string) `slot:"configureAppleMail"`
+ void emitToggleSplitModeFinished(); // slot for external signals
+
+signals: // signal used to forward QML event received in the above slots
+ void toggleSplitModeForUser(QString const &userID, bool makeItActive);
+ void logoutUser(QString const &userID);
+ void removeUser(QString const &userID);
+ void configureAppleMailForUser(QString const &userID, QString const &address);
+
+
+public:
+ Q_PROPERTY(QString id READ id WRITE setID NOTIFY idChanged) // _ string ID
+ Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged) // _ string `property:"username"`
+ Q_PROPERTY(QString password READ password WRITE setPassword NOTIFY passwordChanged) // _ string `property:"password"`
+ Q_PROPERTY(QStringList addresses READ addresses WRITE setAddresses NOTIFY addressesChanged) // _ []string `property:"addresses"`
+ Q_PROPERTY(QString avatarText READ avatarText WRITE setAvatarText NOTIFY avatarTextChanged) // _ string `property:"avatarText"`
+ Q_PROPERTY(bool loggedIn READ loggedIn WRITE setLoggedIn NOTIFY loggedInChanged) // _ bool `property:"loggedIn"`
+ Q_PROPERTY(bool splitMode READ splitMode WRITE setSplitMode NOTIFY splitModeChanged) // _ bool `property:"splitMode"`
+ Q_PROPERTY(bool setupGuideSeen READ setupGuideSeen WRITE setSetupGuideSeen NOTIFY setupGuideSeenChanged) // _ bool `property:"setupGuideSeen"`
+ Q_PROPERTY(float usedBytes READ usedBytes WRITE setUsedBytes NOTIFY usedBytesChanged) // _ float32 `property:"usedBytes"`
+ Q_PROPERTY(float totalBytes READ totalBytes WRITE setTotalBytes NOTIFY totalBytesChanged) // _ float32 `property:"totalBytes"`
+
+ QString id() const;
+ void setID(QString const &id);
+ QString username() const;
+ void setUsername(QString const &username);
+ QString password() const;
+ void setPassword(QString const &password);
+ QStringList addresses() const;
+ void setAddresses(QStringList const &addresses);
+ QString avatarText() const;
+ void setAvatarText(QString const &avatarText);
+ bool loggedIn() const;
+ void setLoggedIn(bool loggedIn);
+ bool splitMode() const;
+ void setSplitMode(bool splitMode);
+ bool setupGuideSeen() const;
+ void setSetupGuideSeen(bool setupGuideSeen);
+ float usedBytes() const;
+ void setUsedBytes(float usedBytes);
+ float totalBytes() const;
+ void setTotalBytes(float totalBytes);
+
+signals:
+ // signals used for Qt properties
+ void idChanged(QString const &id);
+ void usernameChanged(QString const &username);
+ void passwordChanged(QString const &);
+ void addressesChanged(QStringList const &);
+ void avatarTextChanged(QString const &avatarText);
+ void loggedInChanged(bool loggedIn);
+ void splitModeChanged(bool splitMode);
+ void setupGuideSeenChanged(bool seen);
+ void usedBytesChanged(float byteCount);
+ void totalBytesChanged(float byteCount);
+
+ void toggleSplitModeFinished();
+
+private: // member functions.
+ User(QObject *parent); ///< Default constructor.
+
+private: // data members.
+ QString id_; ///< The userID.
+ QString username_; ///< The username
+ QString password_; ///< The IMAP password of the user.
+ QStringList addresses_; ///< The email address list of the user.
+ QString avatarText_; ///< The avatar text (i.e. initials of the user)
+ bool loggedIn_ { true }; ///< Is the user logged in.
+ bool splitMode_ { false }; ///< Is split mode active.
+ bool setupGuideSeen_ { false }; ///< Has the setup guide been seen.
+ float usedBytes_ { 0.0f }; ///< The storage used by the user.
+ float totalBytes_ { 1.0f }; ///< The storage quota of the user.
+};
+
+
+} // namespace bridgepp
+
+
+#endif // BRIDGE_GUI_USER_H
diff --git a/internal/frontend/bridge-gui/Worker/Overseer.cpp b/internal/frontend/bridgepp/bridgepp/Worker/Overseer.cpp
similarity index 94%
rename from internal/frontend/bridge-gui/Worker/Overseer.cpp
rename to internal/frontend/bridgepp/bridgepp/Worker/Overseer.cpp
index 72aa2c43..37121583 100644
--- a/internal/frontend/bridge-gui/Worker/Overseer.cpp
+++ b/internal/frontend/bridgepp/bridgepp/Worker/Overseer.cpp
@@ -16,9 +16,12 @@
// along with Proton Mail Bridge. If not, see .
-#include "Pch.h"
#include "Overseer.h"
-#include "Exception.h"
+#include "../Exception/Exception.h"
+
+
+namespace bridgepp
+{
//****************************************************************************************************************************************************
@@ -56,7 +59,7 @@ void Overseer::startWorker(bool autorelease) const
worker_->moveToThread(thread_);
connect(thread_, &QThread::started, worker_, &Worker::run);
- connect(worker_, &Worker::finished, [&]() {thread_->quit(); }); // for unkwown reason, connect to the QThread::quit slot does not work...
+ connect(worker_, &Worker::finished, [&]() { thread_->quit(); }); // for unkwown reason, connect to the QThread::quit slot does not work...
connect(worker_, &Worker::error, [&]() { thread_->quit(); });
if (autorelease)
@@ -112,3 +115,6 @@ Worker *Overseer::worker() const
{
return worker_;
}
+
+
+} // namespace bridgepp
diff --git a/internal/frontend/bridge-gui/Worker/Overseer.h b/internal/frontend/bridgepp/bridgepp/Worker/Overseer.h
similarity index 72%
rename from internal/frontend/bridge-gui/Worker/Overseer.h
rename to internal/frontend/bridgepp/bridgepp/Worker/Overseer.h
index a49d6e22..d193289c 100644
--- a/internal/frontend/bridge-gui/Worker/Overseer.h
+++ b/internal/frontend/bridgepp/bridgepp/Worker/Overseer.h
@@ -16,26 +16,30 @@
// along with Proton Mail Bridge. If not, see .
-#ifndef BRIDGE_GUI_OVERSEER_H
-#define BRIDGE_GUI_OVERSEER_H
+#ifndef BRIDGE_PP_OVERSEER_H
+#define BRIDGE_PP_OVERSEER_H
#include "Worker.h"
+namespace bridgepp
+{
+
+
//****************************************************************************************************************************************************
/// \brief Overseer used to manager a worker instance and its associated thread.
//****************************************************************************************************************************************************
-class Overseer: public QObject
+class Overseer : public QObject
{
- Q_OBJECT
+Q_OBJECT
public: // member functions.
- explicit Overseer(Worker* worker, QObject* parent); ///< Default constructor.
- Overseer(Overseer const&) = delete; ///< Disabled copy-constructor.
- Overseer(Overseer&&) = delete; ///< Disabled assignment copy-constructor.
+ explicit Overseer(Worker *worker, QObject *parent); ///< Default constructor.
+ Overseer(Overseer const &) = delete; ///< Disabled copy-constructor.
+ Overseer(Overseer &&) = delete; ///< Disabled assignment copy-constructor.
~Overseer() override; ///< Destructor.
- Overseer& operator=(Overseer const&) = delete; ///< Disabled assignment operator.
- Overseer& operator=(Overseer&&) = delete; ///< Disabled move assignment operator.
+ Overseer &operator=(Overseer const &) = delete; ///< Disabled assignment operator.
+ Overseer &operator=(Overseer &&) = delete; ///< Disabled move assignment operator.
bool isFinished() const; ///< Check if the worker is finished.
Worker *worker() const; ///< Return worker.
@@ -44,8 +48,8 @@ public slots:
void release(); ///< Delete the worker and its thread.
public: // data members.
- QThread *thread_ { nullptr }; ///< The thread.
- Worker *worker_ { nullptr }; ///< The worker.
+ QThread *thread_{nullptr}; ///< The thread.
+ Worker *worker_{nullptr}; ///< The worker.
};
@@ -53,4 +57,7 @@ typedef std::unique_ptr UPOverseer; ///< Type definition for unique po
typedef std::shared_ptr SPOverseer; ///< Type definition for shared pointer to Overseer.
-#endif //BRIDGE_GUI_OVERSEER_H
+} // namespace bridgepp
+
+
+#endif //BRIDGE_PP_OVERSEER_H
diff --git a/internal/frontend/bridge-gui/Worker/Worker.h b/internal/frontend/bridgepp/bridgepp/Worker/Worker.h
similarity index 69%
rename from internal/frontend/bridge-gui/Worker/Worker.h
rename to internal/frontend/bridgepp/bridgepp/Worker/Worker.h
index 6111d943..d893e8bc 100644
--- a/internal/frontend/bridge-gui/Worker/Worker.h
+++ b/internal/frontend/bridgepp/bridgepp/Worker/Worker.h
@@ -16,22 +16,29 @@
// along with Proton Mail Bridge. If not, see .
-#ifndef BRIDGE_GUI_WORKER_H
-#define BRIDGE_GUI_WORKER_H
+#ifndef BRIDGE_PP_WORKER_H
+#define BRIDGE_PP_WORKER_H
+
+
+namespace bridgepp
+{
+
//****************************************************************************************************************************************************
/// \brief Pure virtual class for worker intended to perform a threaded operation.
//****************************************************************************************************************************************************
-class Worker: public QObject
+class Worker : public QObject
{
- Q_OBJECT
+Q_OBJECT
public: // member functions
- explicit Worker(QObject *parent) : QObject(parent) {} ///< Default constructor.
- Worker(Worker const&) = delete; ///< Disabled copy-constructor.
- Worker(Worker&&) = delete; ///< Disabled assignment copy-constructor.
+ explicit Worker(QObject *parent)
+ : QObject(parent)
+ {} ///< Default constructor.
+ Worker(Worker const &) = delete; ///< Disabled copy-constructor.
+ Worker(Worker &&) = delete; ///< Disabled assignment copy-constructor.
~Worker() override = default; ///< Destructor.
- Worker& operator=(Worker const&) = delete; ///< Disabled assignment operator.
- Worker& operator=(Worker&&) = delete; ///< Disabled move assignment operator.
+ Worker &operator=(Worker const &) = delete; ///< Disabled assignment operator.
+ Worker &operator=(Worker &&) = delete; ///< Disabled move assignment operator.
public slots:
virtual void run() = 0; ///< run the worker.
@@ -39,8 +46,11 @@ public slots:
signals:
void started(); ///< Signal for the start of the worker
void finished(); ///< Signal for the end of the worker
- void error(QString const& message); ///< Signal for errors. After an error, worker ends and finished is NOT emitted.
+ void error(QString const &message); ///< Signal for errors. After an error, worker ends and finished is NOT emitted.
};
-#endif //BRIDGE_GUI_WORKER_H
+} // namespace bridgepp
+
+
+#endif //BRIDGE_PP_WORKER_H
diff --git a/utils/missing_license.sh b/utils/missing_license.sh
index 72cd76b7..3ac2b86e 100755
--- a/utils/missing_license.sh
+++ b/utils/missing_license.sh
@@ -19,6 +19,7 @@
YEAR=`date +%Y`
MISSING_FILES=$(find . \
+ -not -path "./extern/*" \
-not -path "./vendor/*" \
-not -path "./vendor-cache/*" \
-not -path "./.cache/*" \