mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-05-17 08:16:06 +03:00
refactor: remove serverConfig struct (#2595)
* refactor: remove serverConfig struct * refactor: add warnings for api v1 configs * refactor: moved the server type definition to a separate namespace * refactor: simplified gateway stacks * fix: fixed server description * fix: fixed postAsync reply usage * fix: fixed validateConfig call * fix: fixed server name in notifications * fix: fixed initPrepareConfigHandler for lagacy configs
This commit is contained in:
@@ -15,7 +15,6 @@ set(HEADERS ${HEADERS}
|
||||
${CLIENT_ROOT_DIR}/core/utils/constants/protocolConstants.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/constants/apiKeys.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/constants/apiConstants.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/api/apiEnums.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/errorStrings.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/selfhosted/scriptsRegistry.h
|
||||
${CLIENT_ROOT_DIR}/core/utils/qrCodeUtils.h
|
||||
@@ -138,6 +137,7 @@ set(SOURCES ${SOURCES}
|
||||
${CLIENT_ROOT_DIR}/../common/logger/logger.cpp
|
||||
${CLIENT_ROOT_DIR}/ui/utils/qmlUtils.cpp
|
||||
${CLIENT_ROOT_DIR}/core/utils/api/apiUtils.cpp
|
||||
${CLIENT_ROOT_DIR}/core/utils/serverConfigUtils.cpp
|
||||
${CLIENT_ROOT_DIR}/core/utils/osSignalHandler.cpp
|
||||
${CLIENT_ROOT_DIR}/core/utils/utilities.cpp
|
||||
${CLIENT_ROOT_DIR}/core/utils/managementServer.cpp
|
||||
|
||||
@@ -1,51 +1,93 @@
|
||||
#include "newsController.h"
|
||||
|
||||
#include "core/controllers/gatewayController.h"
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/repositories/secureServersRepository.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QSet>
|
||||
#include <QSharedPointer>
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
NewsController::NewsController(SecureAppSettingsRepository* appSettingsRepository,
|
||||
ServersController* serversController)
|
||||
: m_appSettingsRepository(appSettingsRepository), m_serversController(serversController)
|
||||
NewsController::NewsController(SecureAppSettingsRepository *appSettingsRepository,
|
||||
SecureServersRepository *serversRepository)
|
||||
: m_appSettingsRepository(appSettingsRepository),
|
||||
m_serversRepository(serversRepository)
|
||||
{
|
||||
}
|
||||
|
||||
QJsonObject NewsController::getServicesList() const
|
||||
{
|
||||
if (!m_serversRepository) {
|
||||
return {};
|
||||
}
|
||||
QSet<QString> userCountryCodes;
|
||||
QSet<QString> serviceTypes;
|
||||
const QVector<QString> ids = m_serversRepository->orderedServerIds();
|
||||
for (const QString &id : ids) {
|
||||
const auto apiV2 = m_serversRepository->apiV2Config(id);
|
||||
if (!apiV2.has_value()) {
|
||||
continue;
|
||||
}
|
||||
if (!apiV2->apiConfig.userCountryCode.isEmpty()) {
|
||||
userCountryCodes.insert(apiV2->apiConfig.userCountryCode);
|
||||
}
|
||||
const QString serviceType = apiV2->serviceType();
|
||||
if (!serviceType.isEmpty()) {
|
||||
serviceTypes.insert(serviceType);
|
||||
}
|
||||
}
|
||||
if (userCountryCodes.isEmpty() && serviceTypes.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
QJsonObject json;
|
||||
|
||||
QJsonArray userCountryCodesArray;
|
||||
for (const QString &code : userCountryCodes) {
|
||||
userCountryCodesArray.append(code);
|
||||
}
|
||||
json[apiDefs::key::userCountryCode] = userCountryCodesArray;
|
||||
|
||||
QJsonArray serviceTypesArray;
|
||||
for (const QString &type : serviceTypes) {
|
||||
serviceTypesArray.append(type);
|
||||
}
|
||||
json[apiDefs::key::serviceType] = serviceTypesArray;
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
QFuture<QPair<ErrorCode, QJsonArray>> NewsController::fetchNews()
|
||||
{
|
||||
if (!m_serversController) {
|
||||
qWarning() << "ServersController is null, skip fetchNews";
|
||||
if (!m_serversRepository) {
|
||||
qWarning() << "SecureServersRepository is null, skip fetchNews";
|
||||
return QtFuture::makeReadyFuture(qMakePair(ErrorCode::InternalError, QJsonArray()));
|
||||
}
|
||||
|
||||
const auto stacks = m_serversController->gatewayStacks();
|
||||
if (stacks.isEmpty()) {
|
||||
|
||||
const QJsonObject services = getServicesList();
|
||||
if (services.isEmpty()) {
|
||||
qDebug() << "No Gateway stacks, skip fetchNews";
|
||||
return QtFuture::makeReadyFuture(qMakePair(ErrorCode::NoError, QJsonArray()));
|
||||
}
|
||||
|
||||
auto gatewayController = QSharedPointer<GatewayController>::create(
|
||||
m_appSettingsRepository->getGatewayEndpoint(),
|
||||
m_appSettingsRepository->isDevGatewayEnv(),
|
||||
apiDefs::requestTimeoutMsecs,
|
||||
m_appSettingsRepository->isStrictKillSwitchEnabled());
|
||||
|
||||
m_appSettingsRepository->getGatewayEndpoint(),
|
||||
m_appSettingsRepository->isDevGatewayEnv(),
|
||||
apiDefs::requestTimeoutMsecs,
|
||||
m_appSettingsRepository->isStrictKillSwitchEnabled());
|
||||
|
||||
QJsonObject payload;
|
||||
payload.insert("locale", m_appSettingsRepository->getAppLanguage().name().split("_").first());
|
||||
|
||||
const QJsonObject stacksJson = stacks.toJson();
|
||||
if (stacksJson.contains(apiDefs::key::userCountryCode)) {
|
||||
payload.insert(apiDefs::key::userCountryCode, stacksJson.value(apiDefs::key::userCountryCode));
|
||||
if (services.contains(apiDefs::key::userCountryCode)) {
|
||||
payload.insert(apiDefs::key::userCountryCode, services.value(apiDefs::key::userCountryCode));
|
||||
}
|
||||
if (stacksJson.contains(apiDefs::key::serviceType)) {
|
||||
payload.insert(apiDefs::key::serviceType, stacksJson.value(apiDefs::key::serviceType));
|
||||
if (services.contains(apiDefs::key::serviceType)) {
|
||||
payload.insert(apiDefs::key::serviceType, services.value(apiDefs::key::serviceType));
|
||||
}
|
||||
|
||||
auto future = gatewayController->postAsync(QString("%1v1/news"), payload);
|
||||
@@ -69,4 +111,3 @@ QFuture<QPair<ErrorCode, QJsonArray>> NewsController::fetchNews()
|
||||
return qMakePair(ErrorCode::NoError, newsArray);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,26 +3,28 @@
|
||||
|
||||
#include <QFuture>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QPair>
|
||||
|
||||
#include "core/utils/errorCodes.h"
|
||||
#include "core/utils/routeModes.h"
|
||||
#include "core/utils/commonStructs.h"
|
||||
#include "core/repositories/secureAppSettingsRepository.h"
|
||||
#include "core/controllers/serversController.h"
|
||||
#include "core/repositories/secureServersRepository.h"
|
||||
|
||||
class NewsController
|
||||
{
|
||||
public:
|
||||
explicit NewsController(SecureAppSettingsRepository* appSettingsRepository,
|
||||
ServersController* serversController);
|
||||
SecureServersRepository* serversRepository);
|
||||
|
||||
QFuture<QPair<ErrorCode, QJsonArray>> fetchNews();
|
||||
|
||||
private:
|
||||
QJsonObject getServicesList() const;
|
||||
|
||||
SecureAppSettingsRepository* m_appSettingsRepository;
|
||||
ServersController* m_serversController;
|
||||
SecureServersRepository* m_serversRepository;
|
||||
};
|
||||
|
||||
#endif // NEWSCONTROLLER_H
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <limits>
|
||||
|
||||
#include "core/controllers/gatewayController.h"
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "version.h"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "version.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/models/api/apiConfig.h"
|
||||
|
||||
@@ -196,7 +195,7 @@ void SubscriptionController::updateApiConfigInJson(QJsonObject &serverConfigJson
|
||||
apiConfig[apiDefs::key::serviceProtocol] = serviceProtocol;
|
||||
apiConfig[apiDefs::key::userCountryCode] = userCountryCode;
|
||||
|
||||
if (serverConfigJson.value(configKey::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) {
|
||||
if (serverConfigJson.value(configKey::configVersion).toInt() == serverConfigUtils::ConfigSource::AmneziaGateway) {
|
||||
QJsonObject responseObj = QJsonDocument::fromJson(apiResponseBody).object();
|
||||
if (responseObj.contains(apiDefs::key::supportedProtocols)) {
|
||||
apiConfig.insert(apiDefs::key::supportedProtocols, responseObj.value(apiDefs::key::supportedProtocols).toArray());
|
||||
@@ -217,8 +216,7 @@ ErrorCode SubscriptionController::executeRequest(const QString &endpoint, const
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::importServiceFromGateway(const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &serviceProtocol, const ProtocolData &protocolData,
|
||||
ServerConfig &serverConfig)
|
||||
const QString &serviceProtocol, const ProtocolData &protocolData)
|
||||
{
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
QString(APP_VERSION),
|
||||
@@ -247,20 +245,18 @@ ErrorCode SubscriptionController::importServiceFromGateway(const QString &userCo
|
||||
|
||||
updateApiConfigInJson(serverConfigJson, serviceType, serviceProtocol, userCountryCode, responseBody);
|
||||
|
||||
ServerConfig serverConfigModel = ServerConfig::fromJson(serverConfigJson);
|
||||
|
||||
if (!serverConfigModel.isApiV2()) {
|
||||
if (serverConfigJson.value(configKey::configVersion).toInt() != serverConfigUtils::ConfigSource::AmneziaGateway) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
m_serversRepository->addServer(serverConfigModel);
|
||||
serverConfig = serverConfigModel;
|
||||
ApiV2ServerConfig apiV2ServerConfig = ApiV2ServerConfig::fromJson(serverConfigJson);
|
||||
m_serversRepository->addServer(QString(), apiV2ServerConfig.toJson(),
|
||||
serverConfigUtils::configTypeFromJson(apiV2ServerConfig.toJson()));
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::importTrialFromGateway(const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &serviceProtocol, const QString &email,
|
||||
ServerConfig &serverConfig)
|
||||
const QString &serviceProtocol, const QString &email)
|
||||
{
|
||||
const QString trimmedEmail = email.trimmed();
|
||||
if (trimmedEmail.isEmpty()) {
|
||||
@@ -306,16 +302,19 @@ ErrorCode SubscriptionController::importTrialFromGateway(const QString &userCoun
|
||||
}
|
||||
|
||||
QJsonObject configObject = QJsonDocument::fromJson(configBytes).object();
|
||||
ServerConfig serverConfigModel = ServerConfig::fromJson(configObject);
|
||||
m_serversRepository->addServer(serverConfigModel);
|
||||
serverConfig = serverConfigModel;
|
||||
if (configObject.value(configKey::configVersion).toInt() != serverConfigUtils::ConfigSource::AmneziaGateway) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
ApiV2ServerConfig apiV2ServerConfig = ApiV2ServerConfig::fromJson(configObject);
|
||||
m_serversRepository->addServer(QString(), apiV2ServerConfig.toJson(),
|
||||
serverConfigUtils::configTypeFromJson(apiV2ServerConfig.toJson()));
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::importServiceFromAppStore(const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &serviceProtocol, const ProtocolData &protocolData,
|
||||
const QString &transactionId, bool isTestPurchase,
|
||||
ServerConfig &serverConfig,
|
||||
int *duplicateServerIndex)
|
||||
{
|
||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||
@@ -351,15 +350,8 @@ ErrorCode SubscriptionController::importServiceFromAppStore(const QString &userC
|
||||
|
||||
// Check if server with this VPN key already exists
|
||||
for (int i = 0; i < m_serversRepository->serversCount(); ++i) {
|
||||
ServerConfig existingServerConfig = m_serversRepository->server(i);
|
||||
QString existingVpnKey;
|
||||
if (existingServerConfig.isApiV1()) {
|
||||
const ApiV1ServerConfig* apiV1 = existingServerConfig.as<ApiV1ServerConfig>();
|
||||
existingVpnKey = apiV1 ? apiV1->vpnKey() : QString();
|
||||
} else if (existingServerConfig.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = existingServerConfig.as<ApiV2ServerConfig>();
|
||||
existingVpnKey = apiV2 ? apiV2->vpnKey() : QString();
|
||||
}
|
||||
const auto apiV2 = m_serversRepository->apiV2Config(m_serversRepository->serverIdAt(i));
|
||||
QString existingVpnKey = apiV2.has_value() ? apiV2->vpnKey() : QString();
|
||||
existingVpnKey.replace(QStringLiteral("vpn://"), QString());
|
||||
if (!existingVpnKey.isEmpty() && existingVpnKey == normalizedKey) {
|
||||
if (duplicateServerIndex) {
|
||||
@@ -385,38 +377,28 @@ ErrorCode SubscriptionController::importServiceFromAppStore(const QString &userC
|
||||
|
||||
quint16 crc = qChecksum(QJsonDocument(configObject).toJson());
|
||||
|
||||
ServerConfig serverConfigModel = ServerConfig::fromJson(configObject);
|
||||
|
||||
if (!serverConfigModel.isApiV2()) {
|
||||
if (configObject.value(configKey::configVersion).toInt() != serverConfigUtils::ConfigSource::AmneziaGateway) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ApiV2ServerConfig apiV2ServerConfig = ApiV2ServerConfig::fromJson(configObject);
|
||||
ApiV2ServerConfig* apiV2 = &apiV2ServerConfig;
|
||||
apiV2->apiConfig.vpnKey = normalizedKey;
|
||||
apiV2->apiConfig.isTestPurchase = isTestPurchase;
|
||||
apiV2->apiConfig.isInAppPurchase = true;
|
||||
apiV2->apiConfig.subscriptionExpiredByServer = false;
|
||||
apiV2->crc = crc;
|
||||
|
||||
m_serversRepository->addServer(serverConfigModel);
|
||||
serverConfig = serverConfigModel;
|
||||
m_serversRepository->addServer(QString(), apiV2ServerConfig.toJson(),
|
||||
serverConfigUtils::configTypeFromJson(apiV2ServerConfig.toJson()));
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::updateServiceFromGateway(int serverIndex, const QString &newCountryCode, bool isConnectEvent)
|
||||
ErrorCode SubscriptionController::updateServiceFromGateway(const QString &serverId, const QString &newCountryCode, bool isConnectEvent)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
|
||||
if (!serverConfigModel.isApiV2()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
const ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) {
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
if (!apiV2.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
const bool isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
@@ -445,12 +427,10 @@ ErrorCode SubscriptionController::updateServiceFromGateway(int serverIndex, cons
|
||||
ErrorCode errorCode = executeRequest(QString("%1v1/config"), apiPayload, responseBody, isTestPurchase);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
if (errorCode == ErrorCode::ApiSubscriptionExpiredError && !apiV2->apiConfig.isInAppPurchase) {
|
||||
ServerConfig expiredServerConfig = serverConfigModel;
|
||||
ApiV2ServerConfig *expiredApiV2 = expiredServerConfig.as<ApiV2ServerConfig>();
|
||||
if (expiredApiV2) {
|
||||
expiredApiV2->apiConfig.subscriptionExpiredByServer = true;
|
||||
m_serversRepository->editServer(serverIndex, expiredServerConfig);
|
||||
}
|
||||
ApiV2ServerConfig expiredApiV2 = *apiV2;
|
||||
expiredApiV2.apiConfig.subscriptionExpiredByServer = true;
|
||||
m_serversRepository->editServer(serverId, expiredApiV2.toJson(),
|
||||
serverConfigUtils::configTypeFromJson(expiredApiV2.toJson()));
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
@@ -463,16 +443,12 @@ ErrorCode SubscriptionController::updateServiceFromGateway(int serverIndex, cons
|
||||
|
||||
updateApiConfigInJson(serverConfigJson, apiV2->apiConfig.serviceType, serviceProtocol, apiV2->apiConfig.userCountryCode, responseBody);
|
||||
|
||||
ServerConfig newServerConfigModel = ServerConfig::fromJson(serverConfigJson);
|
||||
|
||||
if (!newServerConfigModel.isApiV2()) {
|
||||
if (serverConfigJson.value(configKey::configVersion).toInt() != serverConfigUtils::ConfigSource::AmneziaGateway) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
ApiV2ServerConfig* newApiV2 = newServerConfigModel.as<ApiV2ServerConfig>();
|
||||
if (!newApiV2) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ApiV2ServerConfig newApiV2Config = ApiV2ServerConfig::fromJson(serverConfigJson);
|
||||
ApiV2ServerConfig* newApiV2 = &newApiV2Config;
|
||||
|
||||
newApiV2->apiConfig.vpnKey = apiV2->apiConfig.vpnKey;
|
||||
newApiV2->apiConfig.isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
@@ -487,20 +463,15 @@ ErrorCode SubscriptionController::updateServiceFromGateway(int serverIndex, cons
|
||||
newApiV2->nameOverriddenByUser = true;
|
||||
}
|
||||
|
||||
m_serversRepository->editServer(serverIndex, newServerConfigModel);
|
||||
m_serversRepository->editServer(serverId, newApiV2Config.toJson(),
|
||||
serverConfigUtils::configTypeFromJson(newApiV2Config.toJson()));
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::deactivateDevice(int serverIndex)
|
||||
ErrorCode SubscriptionController::deactivateDevice(const QString &serverId)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
|
||||
if (!serverConfigModel.isApiV2()) {
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
const ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) {
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
if (!apiV2.has_value()) {
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
@@ -528,23 +499,16 @@ ErrorCode SubscriptionController::deactivateDevice(int serverIndex)
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
serverConfigModel.visit([](auto& arg) {
|
||||
arg.containers.clear();
|
||||
});
|
||||
m_serversRepository->editServer(serverIndex, serverConfigModel);
|
||||
apiV2->containers.clear();
|
||||
m_serversRepository->editServer(serverId, apiV2->toJson(),
|
||||
serverConfigUtils::configTypeFromJson(apiV2->toJson()));
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::deactivateExternalDevice(int serverIndex, const QString &uuid, const QString &serverCountryCode)
|
||||
ErrorCode SubscriptionController::deactivateExternalDevice(const QString &serverId, const QString &uuid, const QString &serverCountryCode)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
|
||||
if (!serverConfigModel.isApiV2()) {
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
const ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) {
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
if (!apiV2.has_value()) {
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
@@ -573,25 +537,18 @@ ErrorCode SubscriptionController::deactivateExternalDevice(int serverIndex, cons
|
||||
}
|
||||
|
||||
if (uuid == m_appSettingsRepository->getInstallationUuid(true)) {
|
||||
serverConfigModel.visit([](auto& arg) {
|
||||
arg.containers.clear();
|
||||
});
|
||||
m_serversRepository->editServer(serverIndex, serverConfigModel);
|
||||
apiV2->containers.clear();
|
||||
m_serversRepository->editServer(serverId, apiV2->toJson(),
|
||||
serverConfigUtils::configTypeFromJson(apiV2->toJson()));
|
||||
}
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::exportNativeConfig(int serverIndex, const QString &serverCountryCode, QString &nativeConfig)
|
||||
ErrorCode SubscriptionController::exportNativeConfig(const QString &serverId, const QString &serverCountryCode, QString &nativeConfig)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
|
||||
if (!serverConfigModel.isApiV2()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
const ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) {
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
if (!apiV2.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
const bool isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
@@ -624,16 +581,10 @@ ErrorCode SubscriptionController::exportNativeConfig(int serverIndex, const QStr
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::revokeNativeConfig(int serverIndex, const QString &serverCountryCode)
|
||||
ErrorCode SubscriptionController::revokeNativeConfig(const QString &serverId, const QString &serverCountryCode)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
|
||||
if (!serverConfigModel.isApiV2()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
const ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) {
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
if (!apiV2.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
const bool isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
@@ -661,126 +612,54 @@ ErrorCode SubscriptionController::revokeNativeConfig(int serverIndex, const QStr
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::updateServiceFromTelegram(int serverIndex)
|
||||
ErrorCode SubscriptionController::prepareVpnKeyExport(const QString &serverId, QString &vpnKey)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
|
||||
if (!serverConfigModel.isApiV1()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
const ApiV1ServerConfig* apiV1 = serverConfigModel.as<ApiV1ServerConfig>();
|
||||
if (!apiV1) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
QString serviceProtocol = apiV1->protocol;
|
||||
ProtocolData protocolData = generateProtocolData(serviceProtocol);
|
||||
QString installationUuid = m_appSettingsRepository->getInstallationUuid(true);
|
||||
|
||||
GatewayController gatewayController(m_appSettingsRepository->getGatewayEndpoint(), m_appSettingsRepository->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs,
|
||||
m_appSettingsRepository->isStrictKillSwitchEnabled());
|
||||
|
||||
QJsonObject apiPayload;
|
||||
appendProtocolDataToApiPayload(serviceProtocol, protocolData, apiPayload);
|
||||
apiPayload[apiDefs::key::uuid] = installationUuid;
|
||||
apiPayload[apiDefs::key::osVersion] = QSysInfo::productType();
|
||||
apiPayload[apiDefs::key::appVersion] = QString(APP_VERSION);
|
||||
apiPayload[configKey::accessToken] = apiV1->apiKey;
|
||||
apiPayload[apiDefs::key::apiEndpoint] = apiV1->apiEndpoint;
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/proxy_config"), apiPayload, responseBody);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
QJsonObject serverConfigJson;
|
||||
errorCode = extractServerConfigJsonFromResponse(responseBody, serviceProtocol, protocolData, serverConfigJson);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ServerConfig newServerConfigModel = ServerConfig::fromJson(serverConfigJson);
|
||||
|
||||
if (!newServerConfigModel.isApiV1()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
ApiV1ServerConfig* newApiV1 = newServerConfigModel.as<ApiV1ServerConfig>();
|
||||
if (!newApiV1) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
newApiV1->apiKey = apiV1->apiKey;
|
||||
newApiV1->apiEndpoint = apiV1->apiEndpoint;
|
||||
newApiV1->crc = apiV1->crc;
|
||||
|
||||
m_serversRepository->editServer(serverIndex, newServerConfigModel);
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::prepareVpnKeyExport(int serverIndex, QString &vpnKey)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
|
||||
if (serverConfigModel.isApiV1()) {
|
||||
const ApiV1ServerConfig* apiV1 = serverConfigModel.as<ApiV1ServerConfig>();
|
||||
vpnKey = apiV1 ? apiV1->vpnKey() : QString();
|
||||
} else if (serverConfigModel.isApiV2()) {
|
||||
ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
vpnKey = apiV2 ? apiV2->vpnKey() : QString();
|
||||
if (vpnKey.isEmpty()) {
|
||||
QJsonObject serverJson = serverConfigModel.toJson();
|
||||
vpnKey = apiUtils::getPremiumV2VpnKey(serverJson);
|
||||
if (vpnKey.isEmpty()) {
|
||||
return ErrorCode::ApiConfigEmptyError;
|
||||
}
|
||||
apiV2->apiConfig.vpnKey = vpnKey;
|
||||
m_serversRepository->editServer(serverIndex, serverConfigModel);
|
||||
}
|
||||
} else {
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
if (!apiV2.has_value()) {
|
||||
return ErrorCode::ApiConfigEmptyError;
|
||||
}
|
||||
vpnKey = apiV2->vpnKey();
|
||||
if (vpnKey.isEmpty()) {
|
||||
vpnKey = apiUtils::getPremiumV2VpnKey(apiV2->toJson());
|
||||
if (vpnKey.isEmpty()) {
|
||||
return ErrorCode::ApiConfigEmptyError;
|
||||
}
|
||||
apiV2->apiConfig.vpnKey = vpnKey;
|
||||
m_serversRepository->editServer(serverId, apiV2->toJson(),
|
||||
serverConfigUtils::configTypeFromJson(apiV2->toJson()));
|
||||
}
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::validateAndUpdateConfig(int serverIndex, bool hasInstalledContainers)
|
||||
ErrorCode SubscriptionController::validateAndUpdateConfig(const QString &serverId, bool hasInstalledContainers)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
|
||||
apiDefs::ConfigSource configSource;
|
||||
if (serverConfigModel.isApiV1()) {
|
||||
configSource = apiDefs::ConfigSource::Telegram;
|
||||
} else if (serverConfigModel.isApiV2()) {
|
||||
configSource = apiDefs::ConfigSource::AmneziaGateway;
|
||||
} else {
|
||||
if (!m_serversRepository->apiV2Config(serverId).has_value()) {
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
if (configSource == apiDefs::ConfigSource::Telegram && !hasInstalledContainers) {
|
||||
removeApiConfig(serverIndex);
|
||||
return updateServiceFromTelegram(serverIndex);
|
||||
} else if (configSource == apiDefs::ConfigSource::AmneziaGateway && !hasInstalledContainers) {
|
||||
return updateServiceFromGateway(serverIndex, "", true);
|
||||
} else if (configSource && isApiKeyExpired(serverIndex)) {
|
||||
qDebug() << "attempt to update api config by expires_at event";
|
||||
if (configSource == apiDefs::ConfigSource::AmneziaGateway) {
|
||||
return updateServiceFromGateway(serverIndex, "", true);
|
||||
} else {
|
||||
removeApiConfig(serverIndex);
|
||||
return updateServiceFromTelegram(serverIndex);
|
||||
}
|
||||
if (!hasInstalledContainers) {
|
||||
return updateServiceFromGateway(serverId, "", true);
|
||||
}
|
||||
|
||||
if (isApiKeyExpired(serverId)) {
|
||||
qDebug() << "attempt to update api config by expires_at event";
|
||||
return updateServiceFromGateway(serverId, "", true);
|
||||
}
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
void SubscriptionController::removeApiConfig(int serverIndex)
|
||||
void SubscriptionController::removeApiConfig(const QString &serverId)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
if (!apiV2.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
QString description = serverConfigModel.description();
|
||||
QString hostName = serverConfigModel.hostName();
|
||||
QString description = apiV2->description;
|
||||
QString hostName = apiV2->hostName;
|
||||
QString vpncName = QString("%1 (%2) %3")
|
||||
.arg(description)
|
||||
.arg(hostName)
|
||||
@@ -789,34 +668,21 @@ void SubscriptionController::removeApiConfig(int serverIndex)
|
||||
AmneziaVPN::removeVPNC(vpncName.toStdString());
|
||||
#endif
|
||||
|
||||
serverConfigModel.visit([](auto& arg) {
|
||||
arg.dns1.clear();
|
||||
arg.dns2.clear();
|
||||
arg.containers.clear();
|
||||
arg.hostName.clear();
|
||||
arg.defaultContainer = DockerContainer::None;
|
||||
});
|
||||
apiV2->dns1.clear();
|
||||
apiV2->dns2.clear();
|
||||
apiV2->containers.clear();
|
||||
apiV2->hostName.clear();
|
||||
apiV2->defaultContainer = DockerContainer::None;
|
||||
apiV2->apiConfig.publicKey = ApiConfig::PublicKeyInfo{};
|
||||
|
||||
if (serverConfigModel.isApiV2()) {
|
||||
ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
if (apiV2) {
|
||||
apiV2->apiConfig.publicKey = ApiConfig::PublicKeyInfo{};
|
||||
}
|
||||
}
|
||||
|
||||
m_serversRepository->editServer(serverIndex, serverConfigModel);
|
||||
m_serversRepository->editServer(serverId, apiV2->toJson(),
|
||||
serverConfigUtils::configTypeFromJson(apiV2->toJson()));
|
||||
}
|
||||
|
||||
bool SubscriptionController::isApiKeyExpired(int serverIndex) const
|
||||
bool SubscriptionController::isApiKeyExpired(const QString &serverId) const
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
|
||||
if (!serverConfigModel.isApiV2()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) {
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
if (!apiV2.has_value()) {
|
||||
return false;
|
||||
}
|
||||
const QString expiresAt = apiV2->apiConfig.publicKey.expiresAt;
|
||||
@@ -833,31 +699,24 @@ bool SubscriptionController::isApiKeyExpired(int serverIndex) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void SubscriptionController::setCurrentProtocol(int serverIndex, const QString &protocolName)
|
||||
void SubscriptionController::setCurrentProtocol(const QString &serverId, const QString &protocolName)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
if (serverConfigModel.isApiV2()) {
|
||||
ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
if (apiV2) {
|
||||
apiV2->apiConfig.serviceProtocol = protocolName;
|
||||
}
|
||||
m_serversRepository->editServer(serverIndex, serverConfigModel);
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
if (apiV2.has_value()) {
|
||||
apiV2->apiConfig.serviceProtocol = protocolName;
|
||||
m_serversRepository->editServer(serverId, apiV2->toJson(),
|
||||
serverConfigUtils::configTypeFromJson(apiV2->toJson()));
|
||||
}
|
||||
}
|
||||
|
||||
bool SubscriptionController::isVlessProtocol(int serverIndex) const
|
||||
bool SubscriptionController::isVlessProtocol(const QString &serverId) const
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
if (serverConfigModel.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
return apiV2 && apiV2->serviceProtocol() == "vless";
|
||||
}
|
||||
return false;
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
return apiV2.has_value() && apiV2->serviceProtocol() == "vless";
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::processAppStorePurchase(const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &serviceProtocol, const QString &productId,
|
||||
ServerConfig &serverConfig,
|
||||
int *duplicateServerIndex)
|
||||
{
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
@@ -891,13 +750,12 @@ ErrorCode SubscriptionController::processAppStorePurchase(const QString &userCou
|
||||
|
||||
ProtocolData protocolData = generateProtocolData(serviceProtocol);
|
||||
return importServiceFromAppStore(userCountryCode, serviceType, serviceProtocol, protocolData,
|
||||
originalTransactionId, isTestPurchase, serverConfig, duplicateServerIndex);
|
||||
originalTransactionId, isTestPurchase, duplicateServerIndex);
|
||||
#else
|
||||
Q_UNUSED(userCountryCode);
|
||||
Q_UNUSED(serviceType);
|
||||
Q_UNUSED(serviceProtocol);
|
||||
Q_UNUSED(productId);
|
||||
Q_UNUSED(serverConfig);
|
||||
return ErrorCode::ApiPurchaseError;
|
||||
#endif
|
||||
}
|
||||
@@ -956,10 +814,9 @@ SubscriptionController::AppStoreRestoreResult SubscriptionController::processApp
|
||||
<< "originalTransactionId =" << originalTransactionId << "productId =" << transactionProductId;
|
||||
|
||||
ProtocolData protocolData = generateProtocolData(serviceProtocol);
|
||||
ServerConfig serverConfig;
|
||||
int currentDuplicateServerIndex = -1;
|
||||
ErrorCode errorCode = importServiceFromAppStore(userCountryCode, serviceType, serviceProtocol, protocolData,
|
||||
originalTransactionId, isTestPurchase, serverConfig,
|
||||
originalTransactionId, isTestPurchase,
|
||||
¤tDuplicateServerIndex);
|
||||
|
||||
if (errorCode == ErrorCode::ApiConfigAlreadyAdded) {
|
||||
@@ -991,16 +848,10 @@ SubscriptionController::AppStoreRestoreResult SubscriptionController::processApp
|
||||
#endif
|
||||
}
|
||||
|
||||
ErrorCode SubscriptionController::getAccountInfo(int serverIndex, QJsonObject &accountInfo)
|
||||
ErrorCode SubscriptionController::getAccountInfo(const QString &serverId, QJsonObject &accountInfo)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
|
||||
if (!serverConfigModel.isApiV2()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
const ApiV2ServerConfig* apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) {
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
if (!apiV2.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
bool isTestPurchase = apiV2->apiConfig.isTestPurchase;
|
||||
@@ -1030,20 +881,13 @@ ErrorCode SubscriptionController::getAccountInfo(int serverIndex, QJsonObject &a
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
QFuture<QPair<ErrorCode, QString>> SubscriptionController::getRenewalLink(int serverIndex)
|
||||
QFuture<QPair<ErrorCode, QString>> SubscriptionController::getRenewalLink(const QString &serverId)
|
||||
{
|
||||
auto promise = QSharedPointer<QPromise<QPair<ErrorCode, QString>>>::create();
|
||||
promise->start();
|
||||
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
if (!serverConfigModel.isApiV2()) {
|
||||
promise->addResult(qMakePair(ErrorCode::InternalError, QString()));
|
||||
promise->finish();
|
||||
return promise->future();
|
||||
}
|
||||
|
||||
const ApiV2ServerConfig *apiV2 = serverConfigModel.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) {
|
||||
auto apiV2 = m_serversRepository->apiV2Config(serverId);
|
||||
if (!apiV2.has_value()) {
|
||||
promise->addResult(qMakePair(ErrorCode::InternalError, QString()));
|
||||
promise->finish();
|
||||
return promise->future();
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "core/utils/commonStructs.h"
|
||||
#include "core/repositories/secureServersRepository.h"
|
||||
#include "core/repositories/secureAppSettingsRepository.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
|
||||
class ServersController;
|
||||
|
||||
@@ -48,44 +47,38 @@ public:
|
||||
|
||||
ProtocolData generateProtocolData(const QString &protocol);
|
||||
void appendProtocolDataToApiPayload(const QString &protocol, const ProtocolData &protocolData, QJsonObject &apiPayload);
|
||||
ErrorCode fillServerConfig(const QJsonObject &serverConfigJson, ServerConfig &serverConfig);
|
||||
|
||||
ErrorCode importServiceFromGateway(const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &serviceProtocol, const ProtocolData &protocolData,
|
||||
ServerConfig &serverConfig);
|
||||
const QString &serviceProtocol, const ProtocolData &protocolData);
|
||||
ErrorCode importTrialFromGateway(const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &serviceProtocol, const QString &email,
|
||||
ServerConfig &serverConfig);
|
||||
const QString &serviceProtocol, const QString &email);
|
||||
|
||||
ErrorCode importServiceFromAppStore(const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &serviceProtocol, const ProtocolData &protocolData,
|
||||
const QString &transactionId, bool isTestPurchase,
|
||||
ServerConfig &serverConfig,
|
||||
int *duplicateServerIndex = nullptr);
|
||||
|
||||
ErrorCode updateServiceFromGateway(int serverIndex, const QString &newCountryCode, bool isConnectEvent);
|
||||
ErrorCode updateServiceFromGateway(const QString &serverId, const QString &newCountryCode, bool isConnectEvent);
|
||||
|
||||
ErrorCode deactivateDevice(int serverIndex);
|
||||
ErrorCode deactivateDevice(const QString &serverId);
|
||||
|
||||
ErrorCode deactivateExternalDevice(int serverIndex, const QString &uuid, const QString &serverCountryCode);
|
||||
ErrorCode deactivateExternalDevice(const QString &serverId, const QString &uuid, const QString &serverCountryCode);
|
||||
|
||||
ErrorCode exportNativeConfig(int serverIndex, const QString &serverCountryCode, QString &nativeConfig);
|
||||
ErrorCode exportNativeConfig(const QString &serverId, const QString &serverCountryCode, QString &nativeConfig);
|
||||
|
||||
ErrorCode revokeNativeConfig(int serverIndex, const QString &serverCountryCode);
|
||||
ErrorCode revokeNativeConfig(const QString &serverId, const QString &serverCountryCode);
|
||||
|
||||
ErrorCode updateServiceFromTelegram(int serverIndex);
|
||||
ErrorCode prepareVpnKeyExport(const QString &serverId, QString &vpnKey);
|
||||
|
||||
ErrorCode prepareVpnKeyExport(int serverIndex, QString &vpnKey);
|
||||
ErrorCode validateAndUpdateConfig(const QString &serverId, bool hasInstalledContainers);
|
||||
|
||||
ErrorCode validateAndUpdateConfig(int serverIndex, bool hasInstalledContainers);
|
||||
void removeApiConfig(const QString &serverId);
|
||||
|
||||
void removeApiConfig(int serverIndex);
|
||||
void setCurrentProtocol(const QString &serverId, const QString &protocolName);
|
||||
bool isVlessProtocol(const QString &serverId) const;
|
||||
|
||||
void setCurrentProtocol(int serverIndex, const QString &protocolName);
|
||||
bool isVlessProtocol(int serverIndex) const;
|
||||
|
||||
ErrorCode getAccountInfo(int serverIndex, QJsonObject &accountInfo);
|
||||
QFuture<QPair<ErrorCode, QString>> getRenewalLink(int serverIndex);
|
||||
ErrorCode getAccountInfo(const QString &serverId, QJsonObject &accountInfo);
|
||||
QFuture<QPair<ErrorCode, QString>> getRenewalLink(const QString &serverId);
|
||||
|
||||
struct AppStoreRestoreResult
|
||||
{
|
||||
@@ -98,7 +91,6 @@ public:
|
||||
|
||||
ErrorCode processAppStorePurchase(const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &serviceProtocol, const QString &productId,
|
||||
ServerConfig &serverConfig,
|
||||
int *duplicateServerIndex = nullptr);
|
||||
|
||||
AppStoreRestoreResult processAppStoreRestore(const QString &userCountryCode, const QString &serviceType,
|
||||
@@ -106,7 +98,7 @@ public:
|
||||
|
||||
private:
|
||||
ErrorCode executeRequest(const QString &endpoint, const QJsonObject &apiPayload, QByteArray &responseBody, bool isTestPurchase = false);
|
||||
bool isApiKeyExpired(int serverIndex) const;
|
||||
bool isApiKeyExpired(const QString &serverId) const;
|
||||
|
||||
ErrorCode extractServerConfigJsonFromResponse(const QByteArray &apiResponseBody, const QString &protocol,
|
||||
const ProtocolData &protocolData, QJsonObject &serverConfigJson);
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/utils/utilities.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "version.h"
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/models/protocolConfig.h"
|
||||
|
||||
@@ -51,7 +51,7 @@ void ConnectionController::setConnectionState(Vpn::ConnectionState state)
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode ConnectionController::prepareConnection(int serverIndex,
|
||||
ErrorCode ConnectionController::prepareConnection(const QString &serverId,
|
||||
QJsonObject& vpnConfiguration,
|
||||
DockerContainer& container)
|
||||
{
|
||||
@@ -59,35 +59,98 @@ ErrorCode ConnectionController::prepareConnection(int serverIndex,
|
||||
return ErrorCode::AmneziaServiceNotRunning;
|
||||
}
|
||||
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
container = serverConfigModel.defaultContainer();
|
||||
ContainerConfig containerConfigModel;
|
||||
QPair<QString, QString> dns;
|
||||
QString hostName;
|
||||
QString description;
|
||||
int configVersion = 0;
|
||||
bool isApiConfig = false;
|
||||
|
||||
const auto kind = m_serversRepository->serverKind(serverId);
|
||||
switch (kind) {
|
||||
case serverConfigUtils::ConfigType::SelfHostedAdmin: {
|
||||
const auto cfg = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!cfg.has_value()) return ErrorCode::InternalError;
|
||||
container = cfg->defaultContainer;
|
||||
containerConfigModel = cfg->containerConfig(container);
|
||||
dns = { cfg->dns1, cfg->dns2 };
|
||||
hostName = cfg->hostName;
|
||||
description = cfg->description;
|
||||
break;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::SelfHostedUser: {
|
||||
const auto cfg = m_serversRepository->selfHostedUserConfig(serverId);
|
||||
if (!cfg.has_value()) return ErrorCode::InternalError;
|
||||
container = cfg->defaultContainer;
|
||||
containerConfigModel = cfg->containerConfig(container);
|
||||
dns = { cfg->dns1, cfg->dns2 };
|
||||
hostName = cfg->hostName;
|
||||
description = cfg->description;
|
||||
break;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::Native: {
|
||||
const auto cfg = m_serversRepository->nativeConfig(serverId);
|
||||
if (!cfg.has_value()) return ErrorCode::InternalError;
|
||||
container = cfg->defaultContainer;
|
||||
containerConfigModel = cfg->containerConfig(container);
|
||||
dns = { cfg->dns1, cfg->dns2 };
|
||||
hostName = cfg->hostName;
|
||||
description = cfg->description;
|
||||
break;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV2:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV3:
|
||||
case serverConfigUtils::ConfigType::ExternalPremium: {
|
||||
const auto cfg = m_serversRepository->apiV2Config(serverId);
|
||||
if (!cfg.has_value()) return ErrorCode::InternalError;
|
||||
container = cfg->defaultContainer;
|
||||
containerConfigModel = cfg->containerConfig(container);
|
||||
dns = { cfg->dns1, cfg->dns2 };
|
||||
hostName = cfg->hostName;
|
||||
description = cfg->description;
|
||||
configVersion = serverConfigUtils::ConfigSource::AmneziaGateway;
|
||||
isApiConfig = true;
|
||||
break;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV1:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV2:
|
||||
return ErrorCode::InternalError;
|
||||
case serverConfigUtils::ConfigType::Invalid:
|
||||
default:
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
if (!isContainerSupported(container)) {
|
||||
return ErrorCode::NotSupportedOnThisPlatform;
|
||||
}
|
||||
if (dns.first.isEmpty() || !NetworkUtilities::checkIPv4Format(dns.first)) {
|
||||
if (m_appSettingsRepository->useAmneziaDns()) {
|
||||
dns.first = protocols::dns::amneziaDnsIp;
|
||||
} else {
|
||||
dns.first = m_appSettingsRepository->primaryDns();
|
||||
}
|
||||
}
|
||||
if (dns.second.isEmpty() || !NetworkUtilities::checkIPv4Format(dns.second)) {
|
||||
dns.second = m_appSettingsRepository->secondaryDns();
|
||||
}
|
||||
|
||||
ContainerConfig containerConfigModel = m_serversRepository->containerConfig(serverIndex, container);
|
||||
|
||||
auto dns = serverConfigModel.getDnsPair(m_appSettingsRepository->useAmneziaDns(),
|
||||
m_appSettingsRepository->primaryDns(),
|
||||
m_appSettingsRepository->secondaryDns());
|
||||
|
||||
vpnConfiguration = createConnectionConfiguration(dns, serverConfigModel, containerConfigModel, container);
|
||||
vpnConfiguration = createConnectionConfiguration(dns, isApiConfig, hostName, description, configVersion,
|
||||
containerConfigModel, container);
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode ConnectionController::openConnection(int serverIndex)
|
||||
ErrorCode ConnectionController::openConnection(const QString &serverId)
|
||||
{
|
||||
QJsonObject vpnConfiguration;
|
||||
DockerContainer container;
|
||||
|
||||
ErrorCode errorCode = prepareConnection(serverIndex, vpnConfiguration, container);
|
||||
ErrorCode errorCode = prepareConnection(serverId, vpnConfiguration, container);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
emit openConnectionRequested(serverIndex, container, vpnConfiguration);
|
||||
emit openConnectionRequested(serverId, container, vpnConfiguration);
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
@@ -120,7 +183,10 @@ ErrorCode ConnectionController::lastConnectionError() const
|
||||
}
|
||||
|
||||
QJsonObject ConnectionController::createConnectionConfiguration(const QPair<QString, QString> &dns,
|
||||
const ServerConfig &serverConfig,
|
||||
bool isApiConfig,
|
||||
const QString &hostName,
|
||||
const QString &description,
|
||||
int configVersion,
|
||||
const ContainerConfig &containerConfig,
|
||||
DockerContainer container)
|
||||
{
|
||||
@@ -134,7 +200,7 @@ QJsonObject ConnectionController::createConnectionConfiguration(const QPair<QStr
|
||||
|
||||
ConnectionSettings connectionSettings = {
|
||||
{ dns.first, dns.second },
|
||||
serverConfig.isApiConfig(),
|
||||
isApiConfig,
|
||||
{
|
||||
m_appSettingsRepository->isSitesSplitTunnelingEnabled(),
|
||||
m_appSettingsRepository->routeMode()
|
||||
@@ -160,10 +226,9 @@ QJsonObject ConnectionController::createConnectionConfiguration(const QPair<QStr
|
||||
vpnConfiguration[configKey::dns1] = dns.first;
|
||||
vpnConfiguration[configKey::dns2] = dns.second;
|
||||
|
||||
vpnConfiguration[configKey::hostName] = serverConfig.hostName();
|
||||
vpnConfiguration[configKey::description] = serverConfig.description();
|
||||
|
||||
vpnConfiguration[configKey::configVersion] = serverConfig.configVersion();
|
||||
vpnConfiguration[configKey::hostName] = hostName;
|
||||
vpnConfiguration[configKey::description] = description;
|
||||
vpnConfiguration[configKey::configVersion] = configVersion;
|
||||
|
||||
return vpnConfiguration;
|
||||
}
|
||||
|
||||
@@ -30,11 +30,11 @@ public:
|
||||
QObject* parent = nullptr);
|
||||
~ConnectionController() = default;
|
||||
|
||||
ErrorCode prepareConnection(int serverIndex,
|
||||
ErrorCode prepareConnection(const QString &serverId,
|
||||
QJsonObject& vpnConfiguration,
|
||||
DockerContainer& container);
|
||||
|
||||
ErrorCode openConnection(int serverIndex);
|
||||
ErrorCode openConnection(const QString &serverId);
|
||||
|
||||
void closeConnection();
|
||||
|
||||
@@ -50,7 +50,10 @@ public:
|
||||
void setConnectionState(Vpn::ConnectionState state);
|
||||
|
||||
QJsonObject createConnectionConfiguration(const QPair<QString, QString> &dns,
|
||||
const ServerConfig &serverConfig,
|
||||
bool isApiConfig,
|
||||
const QString &hostName,
|
||||
const QString &description,
|
||||
int configVersion,
|
||||
const ContainerConfig &containerConfig,
|
||||
DockerContainer container);
|
||||
|
||||
@@ -60,7 +63,7 @@ public:
|
||||
|
||||
signals:
|
||||
void connectionStateChanged(Vpn::ConnectionState state);
|
||||
void openConnectionRequested(int serverIndex, DockerContainer container, const QJsonObject &vpnConfiguration);
|
||||
void openConnectionRequested(const QString &serverId, DockerContainer container, const QJsonObject &vpnConfiguration);
|
||||
void closeConnectionRequested();
|
||||
void setConnectionStateRequested(Vpn::ConnectionState state);
|
||||
void killSwitchModeChangedRequested(bool enabled);
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "core/controllers/selfhosted/installController.h"
|
||||
#include "core/controllers/selfhosted/importController.h"
|
||||
#include "core/controllers/coreSignalHandlers.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "logger.h"
|
||||
#include "secureQSettings.h"
|
||||
|
||||
@@ -145,7 +144,7 @@ void CoreController::initCoreControllers()
|
||||
m_allowedDnsController = new AllowedDnsController(m_appSettingsRepository);
|
||||
m_servicesCatalogController = new ServicesCatalogController(m_appSettingsRepository);
|
||||
m_subscriptionController = new SubscriptionController(m_serversRepository, m_appSettingsRepository);
|
||||
m_newsController = new NewsController(m_appSettingsRepository, m_serversController);
|
||||
m_newsController = new NewsController(m_appSettingsRepository, m_serversRepository);
|
||||
m_updateController = new UpdateController(m_appSettingsRepository, this);
|
||||
|
||||
m_installController = new InstallController(m_serversRepository, m_appSettingsRepository, this);
|
||||
@@ -165,7 +164,7 @@ void CoreController::initControllers()
|
||||
setQmlContextProperty("FocusController", m_focusController);
|
||||
}
|
||||
|
||||
m_installUiController = new InstallUiController(m_installController, m_serversController, m_settingsController, m_protocolsModel, m_usersController,
|
||||
m_installUiController = new InstallUiController(m_installController, m_serversController, m_settingsController, m_protocolsModel, m_usersController,
|
||||
m_awgConfigModel, m_wireGuardConfigModel, m_openVpnConfigModel, m_xrayConfigModel, m_torConfigModel,
|
||||
#ifdef Q_OS_WINDOWS
|
||||
m_ikev2ConfigModel,
|
||||
@@ -262,9 +261,12 @@ void CoreController::initSignalHandlers()
|
||||
{
|
||||
m_signalHandlers = new CoreSignalHandlers(this, this);
|
||||
m_signalHandlers->initAllHandlers();
|
||||
|
||||
|
||||
// Trigger initial update after handlers are connected
|
||||
m_serversUiController->updateModel();
|
||||
if (m_serversUiController->hasServersFromGatewayApi()) {
|
||||
m_apiNewsUiController->fetchNews(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CoreController::updateTranslator(const QLocale &locale)
|
||||
@@ -322,11 +324,16 @@ PageController* CoreController::pageController() const
|
||||
|
||||
void CoreController::openConnectionByIndex(int serverIndex)
|
||||
{
|
||||
const QString serverId =
|
||||
m_serversUiController ? m_serversUiController->getServerId(serverIndex) : QString();
|
||||
if (serverId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (m_serversModel) {
|
||||
m_serversModel->setProcessedServerIndex(serverIndex);
|
||||
}
|
||||
if (m_serversController) {
|
||||
m_serversController->setDefaultServerIndex(serverIndex);
|
||||
m_serversController->setDefaultServer(serverId);
|
||||
}
|
||||
m_connectionUiController->toggleConnection();
|
||||
}
|
||||
|
||||
@@ -84,7 +84,6 @@ class TestDefaultServerChange;
|
||||
class TestServerEdgeCases;
|
||||
class TestSignalOrder;
|
||||
class TestServersModelSync;
|
||||
class TestGatewayStacks;
|
||||
class TestComplexOperations;
|
||||
class TestSettingsSignals;
|
||||
class TestUiServersModelAndController;
|
||||
@@ -101,7 +100,6 @@ class CoreController : public QObject
|
||||
friend class TestServerEdgeCases;
|
||||
friend class TestSignalOrder;
|
||||
friend class TestServersModelSync;
|
||||
friend class TestGatewayStacks;
|
||||
friend class TestComplexOperations;
|
||||
friend class TestSettingsSignals;
|
||||
friend class TestUiServersModelAndController;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "core/utils/routeModes.h"
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/repositories/secureServersRepository.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/repositories/secureAppSettingsRepository.h"
|
||||
#include "vpnConnection.h"
|
||||
#include "ui/controllers/qml/pageController.h"
|
||||
@@ -65,7 +66,6 @@ void CoreSignalHandlers::initAllHandlers()
|
||||
initImportControllerHandler();
|
||||
initApiCountryModelUpdateHandler();
|
||||
initSubscriptionRefreshHandler();
|
||||
initContainerModelUpdateHandler();
|
||||
initAdminConfigRevokedHandler();
|
||||
initPassphraseRequestHandler();
|
||||
initTranslationsUpdatedHandler();
|
||||
@@ -78,6 +78,7 @@ void CoreSignalHandlers::initAllHandlers()
|
||||
initAllowedDnsModelUpdateHandler();
|
||||
initAppSplitTunnelingModelUpdateHandler();
|
||||
initPrepareConfigHandler();
|
||||
initUnsupportedConnectDrawerHandler();
|
||||
initStrictKillSwitchHandler();
|
||||
initAndroidSettingsHandler();
|
||||
initAndroidConnectionHandler();
|
||||
@@ -124,11 +125,9 @@ void CoreSignalHandlers::initInstallControllerHandler()
|
||||
{
|
||||
connect(m_coreController->m_installController, &InstallController::serverIsBusy, m_coreController->m_installUiController, &InstallUiController::serverIsBusy);
|
||||
connect(m_coreController->m_installUiController, &InstallUiController::cancelInstallation, m_coreController->m_installController, &InstallController::cancelInstallation);
|
||||
connect(m_coreController->m_installUiController, &InstallUiController::currentContainerUpdated, m_coreController->m_connectionUiController,
|
||||
&ConnectionUiController::onCurrentContainerUpdated);
|
||||
connect(m_coreController->m_serversUiController, &ServersUiController::processedServerIndexChanged,
|
||||
m_coreController->m_installUiController, [this](int index) {
|
||||
if (index >= 0) {
|
||||
m_coreController->m_installUiController, [this](int serverIndex) {
|
||||
if (serverIndex >= 0) {
|
||||
m_coreController->m_installUiController->clearProcessedServerCredentials();
|
||||
}
|
||||
});
|
||||
@@ -137,20 +136,20 @@ void CoreSignalHandlers::initInstallControllerHandler()
|
||||
void CoreSignalHandlers::initExportControllerHandler()
|
||||
{
|
||||
connect(m_coreController->m_exportController, &ExportController::appendClientRequested, this,
|
||||
[this](int serverIndex, const QString &clientId, const QString &clientName, DockerContainer container) {
|
||||
m_coreController->m_usersController->appendClient(serverIndex, clientId, clientName, container);
|
||||
[this](const QString &serverId, const QString &clientId, const QString &clientName, DockerContainer container) {
|
||||
m_coreController->m_usersController->appendClient(serverId, clientId, clientName, container);
|
||||
});
|
||||
connect(m_coreController->m_exportController, &ExportController::updateClientsRequested, this,
|
||||
[this](int serverIndex, DockerContainer container) {
|
||||
m_coreController->m_usersController->updateClients(serverIndex, container);
|
||||
[this](const QString &serverId, DockerContainer container) {
|
||||
m_coreController->m_usersController->updateClients(serverId, container);
|
||||
});
|
||||
connect(m_coreController->m_exportController, &ExportController::revokeClientRequested, this,
|
||||
[this](int serverIndex, int row, DockerContainer container) {
|
||||
m_coreController->m_usersController->revokeClient(serverIndex, row, container);
|
||||
[this](const QString &serverId, int row, DockerContainer container) {
|
||||
m_coreController->m_usersController->revokeClient(serverId, row, container);
|
||||
});
|
||||
connect(m_coreController->m_exportController, &ExportController::renameClientRequested, this,
|
||||
[this](int serverIndex, int row, const QString &clientName, DockerContainer container) {
|
||||
m_coreController->m_usersController->renameClient(serverIndex, row, clientName, container);
|
||||
[this](const QString &serverId, int row, const QString &clientName, DockerContainer container) {
|
||||
m_coreController->m_usersController->renameClient(serverId, row, clientName, container);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -159,9 +158,12 @@ void CoreSignalHandlers::initImportControllerHandler()
|
||||
connect(m_coreController->m_importCoreController, &ImportController::importFinished, this, [this]() {
|
||||
if (!m_coreController->m_connectionController->isConnected()) {
|
||||
int newServerIndex = m_coreController->m_serversController->getServersCount() - 1;
|
||||
m_coreController->m_serversController->setDefaultServerIndex(newServerIndex);
|
||||
const QString serverId = m_coreController->m_serversController->getServerId(newServerIndex);
|
||||
if (!serverId.isEmpty()) {
|
||||
m_coreController->m_serversController->setDefaultServer(serverId);
|
||||
}
|
||||
if (m_coreController->m_serversUiController) {
|
||||
m_coreController->m_serversUiController->setProcessedServerIndex(newServerIndex);
|
||||
m_coreController->m_serversUiController->setProcessedServerId(serverId);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -170,21 +172,18 @@ void CoreSignalHandlers::initImportControllerHandler()
|
||||
void CoreSignalHandlers::initApiCountryModelUpdateHandler()
|
||||
{
|
||||
connect(m_coreController->m_serversUiController, &ServersUiController::updateApiCountryModel, this, [this]() {
|
||||
int processedIndex = m_coreController->m_serversUiController->getProcessedServerIndex();
|
||||
if (processedIndex < 0 || processedIndex >= m_coreController->m_serversRepository->serversCount()) {
|
||||
const QString processedServerId = m_coreController->m_serversUiController->getProcessedServerId();
|
||||
if (processedServerId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServerConfig server = m_coreController->m_serversRepository->server(processedIndex);
|
||||
QJsonArray availableCountries;
|
||||
QString serverCountryCode;
|
||||
|
||||
if (server.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = server.as<ApiV2ServerConfig>();
|
||||
if (apiV2) {
|
||||
availableCountries = apiV2->apiConfig.availableCountries;
|
||||
serverCountryCode = apiV2->apiConfig.serverCountryCode;
|
||||
}
|
||||
|
||||
const auto apiV2 = m_coreController->m_serversRepository->apiV2Config(processedServerId);
|
||||
if (apiV2.has_value()) {
|
||||
availableCountries = apiV2->apiConfig.availableCountries;
|
||||
serverCountryCode = apiV2->apiConfig.serverCountryCode;
|
||||
}
|
||||
|
||||
m_coreController->m_apiCountryModel->updateModel(availableCountries, serverCountryCode);
|
||||
@@ -194,18 +193,9 @@ void CoreSignalHandlers::initApiCountryModelUpdateHandler()
|
||||
void CoreSignalHandlers::initSubscriptionRefreshHandler()
|
||||
{
|
||||
connect(m_coreController->m_subscriptionUiController, &SubscriptionUiController::subscriptionRefreshNeeded, this, [this]() {
|
||||
const int defaultServerIndex = m_coreController->m_serversController->getDefaultServerIndex();
|
||||
if (defaultServerIndex >= 0) {
|
||||
m_coreController->m_subscriptionUiController->getAccountInfo(defaultServerIndex, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CoreSignalHandlers::initContainerModelUpdateHandler()
|
||||
{
|
||||
connect(m_coreController->m_serversController, &ServersController::gatewayStacksExpanded, this, [this]() {
|
||||
if (m_coreController->m_serversUiController->hasServersFromGatewayApi()) {
|
||||
m_coreController->m_apiNewsUiController->fetchNews(false);
|
||||
const QString defaultServerId = m_coreController->m_serversController->getDefaultServerId();
|
||||
if (!defaultServerId.isEmpty()) {
|
||||
m_coreController->m_subscriptionUiController->getAccountInfo(defaultServerId, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -213,17 +203,17 @@ void CoreSignalHandlers::initContainerModelUpdateHandler()
|
||||
void CoreSignalHandlers::initAdminConfigRevokedHandler()
|
||||
{
|
||||
connect(m_coreController->m_installController, &InstallController::clientRevocationRequested, this,
|
||||
[this](int serverIndex, const ContainerConfig &containerConfig, DockerContainer container) {
|
||||
m_coreController->m_usersController->revokeClient(serverIndex, containerConfig, container);
|
||||
[this](const QString &serverId, const ContainerConfig &containerConfig, DockerContainer container) {
|
||||
m_coreController->m_usersController->revokeClient(serverId, containerConfig, container);
|
||||
});
|
||||
|
||||
connect(m_coreController->m_installController, &InstallController::clientAppendRequested, this,
|
||||
[this](int serverIndex, const QString &clientId, const QString &clientName, DockerContainer container) {
|
||||
m_coreController->m_usersController->appendClient(serverIndex, clientId, clientName, container);
|
||||
[this](const QString &serverId, const QString &clientId, const QString &clientName, DockerContainer container) {
|
||||
m_coreController->m_usersController->appendClient(serverId, clientId, clientName, container);
|
||||
});
|
||||
|
||||
connect(m_coreController->m_usersController, &UsersController::adminConfigRevoked, m_coreController->m_serversController,
|
||||
&ServersController::clearCachedProfile);
|
||||
connect(m_coreController->m_usersController, &UsersController::adminConfigRevoked, m_coreController->m_installController,
|
||||
&InstallController::clearCachedProfile);
|
||||
}
|
||||
|
||||
void CoreSignalHandlers::initPassphraseRequestHandler()
|
||||
@@ -251,7 +241,8 @@ void CoreSignalHandlers::initLanguageHandler()
|
||||
|
||||
void CoreSignalHandlers::initAutoConnectHandler()
|
||||
{
|
||||
if (m_coreController->m_settingsUiController->isAutoConnectEnabled() && m_coreController->m_serversController->getDefaultServerIndex() >= 0) {
|
||||
if (m_coreController->m_settingsUiController->isAutoConnectEnabled()
|
||||
&& !m_coreController->m_serversController->getDefaultServerId().isEmpty()) {
|
||||
QTimer::singleShot(1000, this, [this]() { m_coreController->m_connectionUiController->openConnection(); });
|
||||
}
|
||||
}
|
||||
@@ -271,16 +262,20 @@ void CoreSignalHandlers::initServersModelUpdateHandler()
|
||||
m_coreController->m_serversUiController, &ServersUiController::updateModel);
|
||||
connect(m_coreController->m_serversRepository, &SecureServersRepository::defaultServerChanged,
|
||||
m_coreController->m_serversUiController, &ServersUiController::onDefaultServerChanged);
|
||||
|
||||
connect(m_coreController->m_serversRepository, &SecureServersRepository::serverAdded,
|
||||
m_coreController->m_serversController, &ServersController::recomputeGatewayStacks);
|
||||
connect(m_coreController->m_serversRepository, &SecureServersRepository::serverEdited,
|
||||
m_coreController->m_serversController, &ServersController::recomputeGatewayStacks);
|
||||
connect(m_coreController->m_serversRepository, &SecureServersRepository::serverRemoved,
|
||||
m_coreController->m_serversController, &ServersController::recomputeGatewayStacks);
|
||||
|
||||
connect(m_coreController->m_settingsUiController, &SettingsUiController::restoreBackupFinished,
|
||||
m_coreController->m_serversUiController, &ServersUiController::updateModel);
|
||||
|
||||
connect(m_coreController->m_serversRepository, &SecureServersRepository::serverAdded, this,
|
||||
[this](const QString &serverId) {
|
||||
if (m_coreController->m_serversRepository->apiV2Config(serverId).has_value()) {
|
||||
m_coreController->m_apiNewsUiController->fetchNews(false);
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_coreController->m_settingsUiController, &SettingsUiController::restoreBackupFinished, this, [this]() {
|
||||
m_coreController->m_serversUiController->updateModel();
|
||||
if (m_coreController->m_serversUiController->hasServersFromGatewayApi()) {
|
||||
m_coreController->m_apiNewsUiController->fetchNews(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CoreSignalHandlers::initClientManagementModelUpdateHandler()
|
||||
@@ -315,7 +310,19 @@ void CoreSignalHandlers::initPrepareConfigHandler()
|
||||
connect(m_coreController->m_connectionUiController, &ConnectionUiController::prepareConfig, this, [this]() {
|
||||
m_coreController->m_connectionController->setConnectionState(Vpn::ConnectionState::Preparing);
|
||||
|
||||
m_coreController->m_subscriptionUiController->validateConfig();
|
||||
const QString serverId = m_coreController->m_serversController->getDefaultServerId();
|
||||
if (serverId.isEmpty()) {
|
||||
m_coreController->m_connectionController->setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
return;
|
||||
}
|
||||
|
||||
const serverConfigUtils::ConfigType kind = m_coreController->m_serversRepository->serverKind(serverId);
|
||||
|
||||
if (serverConfigUtils::isApiV2Subscription(kind) || serverConfigUtils::isLegacyApiSubscription(kind)) {
|
||||
m_coreController->m_subscriptionUiController->validateConfig();
|
||||
} else {
|
||||
m_coreController->m_installUiController->validateConfig();
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_coreController->m_subscriptionUiController, &SubscriptionUiController::configValidated, this, [this](bool isValid) {
|
||||
@@ -324,7 +331,7 @@ void CoreSignalHandlers::initPrepareConfigHandler()
|
||||
return;
|
||||
}
|
||||
|
||||
m_coreController->m_installUiController->validateConfig();
|
||||
m_coreController->m_connectionUiController->openConnection();
|
||||
});
|
||||
|
||||
connect(m_coreController->m_installUiController, &InstallUiController::configValidated, this, [this](bool isValid) {
|
||||
@@ -337,6 +344,12 @@ void CoreSignalHandlers::initPrepareConfigHandler()
|
||||
});
|
||||
}
|
||||
|
||||
void CoreSignalHandlers::initUnsupportedConnectDrawerHandler()
|
||||
{
|
||||
connect(m_coreController->m_subscriptionUiController, &SubscriptionUiController::unsupportedConnectDrawerRequested,
|
||||
m_coreController->m_pageController, &PageController::unsupportedConnectDrawerRequested);
|
||||
}
|
||||
|
||||
void CoreSignalHandlers::initStrictKillSwitchHandler()
|
||||
{
|
||||
connect(m_coreController->m_settingsUiController, &SettingsUiController::strictKillSwitchEnabledChanged, m_coreController->m_connectionController,
|
||||
@@ -348,7 +361,10 @@ void CoreSignalHandlers::initAndroidSettingsHandler()
|
||||
#ifdef Q_OS_ANDROID
|
||||
connect(m_coreController->m_appSettingsRepository, &SecureAppSettingsRepository::saveLogsChanged, AndroidController::instance(), &AndroidController::setSaveLogs);
|
||||
connect(m_coreController->m_appSettingsRepository, &SecureAppSettingsRepository::screenshotsEnabledChanged, AndroidController::instance(), &AndroidController::setScreenshotsEnabled);
|
||||
connect(m_coreController->m_serversRepository, &SecureServersRepository::serverRemoved, AndroidController::instance(), &AndroidController::resetLastServer);
|
||||
connect(m_coreController->m_serversRepository, &SecureServersRepository::serverRemoved, this,
|
||||
[](const QString &/*serverId*/, int removedIndex) {
|
||||
AndroidController::instance()->resetLastServer(removedIndex);
|
||||
});
|
||||
connect(m_coreController->m_appSettingsRepository, &SecureAppSettingsRepository::settingsCleared, []() { AndroidController::instance()->resetLastServer(-1); });
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ private:
|
||||
void initImportControllerHandler();
|
||||
void initApiCountryModelUpdateHandler();
|
||||
void initSubscriptionRefreshHandler();
|
||||
void initContainerModelUpdateHandler();
|
||||
void initAdminConfigRevokedHandler();
|
||||
void initPassphraseRequestHandler();
|
||||
void initTranslationsUpdatedHandler();
|
||||
@@ -34,6 +33,7 @@ private:
|
||||
void initAllowedDnsModelUpdateHandler();
|
||||
void initAppSplitTunnelingModelUpdateHandler();
|
||||
void initPrepareConfigHandler();
|
||||
void initUnsupportedConnectDrawerHandler();
|
||||
void initStrictKillSwitchHandler();
|
||||
void initAndroidSettingsHandler();
|
||||
void initAndroidConnectionHandler();
|
||||
|
||||
@@ -239,7 +239,7 @@ QFuture<QPair<ErrorCode, QByteArray>> GatewayController::postAsync(const QString
|
||||
|
||||
connect(reply, &QNetworkReply::sslErrors, [sslErrors](const QList<QSslError> &errors) { *sslErrors = errors; });
|
||||
|
||||
connect(reply, &QNetworkReply::finished, reply, [promise, sslErrors, encRequestData, endpoint, apiPayload, reply, this]() mutable {
|
||||
connect(reply, &QNetworkReply::finished, this, [promise, sslErrors, encRequestData, endpoint, apiPayload, reply, this]() mutable {
|
||||
QByteArray encryptedResponseBody = reply->readAll();
|
||||
QString replyErrorString = reply->errorString();
|
||||
auto replyError = reply->error();
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
|
||||
#include "core/configurators/configuratorBase.h"
|
||||
#include "core/utils/selfhosted/sshSession.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
#include "core/utils/qrCodeUtils.h"
|
||||
#include "core/utils/serialization/serialization.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/selfhosted/selfHostedAdminServerConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/models/protocolConfig.h"
|
||||
|
||||
@@ -27,18 +26,20 @@ ExportController::ExportController(SecureServersRepository* serversRepository,
|
||||
{
|
||||
}
|
||||
|
||||
ExportController::ExportResult ExportController::generateFullAccessConfig(int serverIndex)
|
||||
ExportController::ExportResult ExportController::generateFullAccessConfig(const QString &serverId)
|
||||
{
|
||||
ExportResult result;
|
||||
|
||||
ServerConfig serverConfig = m_serversRepository->server(serverIndex);
|
||||
serverConfig.visit([](auto& arg) {
|
||||
for (auto it = arg.containers.begin(); it != arg.containers.end(); ++it) {
|
||||
it.value().protocolConfig.clearClientConfig();
|
||||
}
|
||||
});
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
result.errorCode = ErrorCode::InternalError;
|
||||
return result;
|
||||
}
|
||||
for (auto it = adminConfig->containers.begin(); it != adminConfig->containers.end(); ++it) {
|
||||
it.value().protocolConfig.clearClientConfig();
|
||||
}
|
||||
|
||||
QJsonObject serverJson = serverConfig.toJson();
|
||||
QJsonObject serverJson = adminConfig->toJson();
|
||||
QByteArray compressedConfig = QJsonDocument(serverJson).toJson();
|
||||
compressedConfig = qCompress(compressedConfig, 8);
|
||||
result.config = generateVpnUrl(compressedConfig);
|
||||
@@ -47,13 +48,22 @@ ExportController::ExportResult ExportController::generateFullAccessConfig(int se
|
||||
return result;
|
||||
}
|
||||
|
||||
ExportController::ExportResult ExportController::generateConnectionConfig(int serverIndex, int containerIndex, const QString &clientName)
|
||||
ExportController::ExportResult ExportController::generateConnectionConfig(const QString &serverId, int containerIndex, const QString &clientName)
|
||||
{
|
||||
ExportResult result;
|
||||
|
||||
DockerContainer container = static_cast<DockerContainer>(containerIndex);
|
||||
ServerCredentials credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
ContainerConfig containerConfig = m_serversRepository->containerConfig(serverIndex, container);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
result.errorCode = ErrorCode::InternalError;
|
||||
return result;
|
||||
}
|
||||
const ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
result.errorCode = ErrorCode::InternalError;
|
||||
return result;
|
||||
}
|
||||
ContainerConfig containerConfig = adminConfig->containerConfig(container);
|
||||
|
||||
if (ContainerUtils::containerService(container) != ServiceType::Other) {
|
||||
SshSession sshSession;
|
||||
@@ -74,35 +84,25 @@ ExportController::ExportResult ExportController::generateConnectionConfig(int se
|
||||
|
||||
QString clientId = newProtocolConfig.clientId();
|
||||
if (!clientId.isEmpty()) {
|
||||
emit appendClientRequested(serverIndex, clientId, clientName, container);
|
||||
emit appendClientRequested(serverId, clientId, clientName, container);
|
||||
}
|
||||
}
|
||||
|
||||
ServerConfig serverConfig = m_serversRepository->server(serverIndex);
|
||||
serverConfig.visit([container, containerConfig](auto& arg) {
|
||||
arg.containers.clear();
|
||||
arg.containers[container] = containerConfig;
|
||||
arg.defaultContainer = container;
|
||||
});
|
||||
const QPair<QString, QString> dns = adminConfig->getDnsPair(m_appSettingsRepository->useAmneziaDns(),
|
||||
m_appSettingsRepository->primaryDns(),
|
||||
m_appSettingsRepository->secondaryDns());
|
||||
|
||||
if (serverConfig.isSelfHosted()) {
|
||||
SelfHostedServerConfig* selfHosted = serverConfig.as<SelfHostedServerConfig>();
|
||||
if (selfHosted) {
|
||||
selfHosted->userName.reset();
|
||||
selfHosted->password.reset();
|
||||
selfHosted->port.reset();
|
||||
}
|
||||
}
|
||||
adminConfig->containers.clear();
|
||||
adminConfig->containers[container] = containerConfig;
|
||||
adminConfig->defaultContainer = container;
|
||||
adminConfig->userName.clear();
|
||||
adminConfig->password.clear();
|
||||
adminConfig->port = 0;
|
||||
|
||||
auto dns = serverConfig.getDnsPair(m_appSettingsRepository->useAmneziaDns(),
|
||||
m_appSettingsRepository->primaryDns(),
|
||||
m_appSettingsRepository->secondaryDns());
|
||||
serverConfig.visit([&dns](auto& arg) {
|
||||
arg.dns1 = dns.first;
|
||||
arg.dns2 = dns.second;
|
||||
});
|
||||
adminConfig->dns1 = dns.first;
|
||||
adminConfig->dns2 = dns.second;
|
||||
|
||||
QJsonObject serverJson = serverConfig.toJson();
|
||||
QJsonObject serverJson = adminConfig->toJson();
|
||||
QByteArray compressedConfig = QJsonDocument(serverJson).toJson();
|
||||
compressedConfig = qCompress(compressedConfig, 8);
|
||||
result.config = generateVpnUrl(compressedConfig);
|
||||
@@ -111,7 +111,7 @@ ExportController::ExportResult ExportController::generateConnectionConfig(int se
|
||||
return result;
|
||||
}
|
||||
|
||||
ExportController::NativeConfigResult ExportController::generateNativeConfig(int serverIndex, DockerContainer container,
|
||||
ExportController::NativeConfigResult ExportController::generateNativeConfig(const QString &serverId, DockerContainer container,
|
||||
const ContainerConfig &containerConfig,
|
||||
const QString &clientName)
|
||||
{
|
||||
@@ -123,11 +123,19 @@ ExportController::NativeConfigResult ExportController::generateNativeConfig(int
|
||||
|
||||
Proto protocol = ContainerUtils::defaultProtocol(container);
|
||||
|
||||
ServerCredentials credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
ServerConfig serverConfig = m_serversRepository->server(serverIndex);
|
||||
auto dns = serverConfig.getDnsPair(m_appSettingsRepository->useAmneziaDns(),
|
||||
m_appSettingsRepository->primaryDns(),
|
||||
m_appSettingsRepository->secondaryDns());
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
result.errorCode = ErrorCode::InternalError;
|
||||
return result;
|
||||
}
|
||||
const ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
result.errorCode = ErrorCode::InternalError;
|
||||
return result;
|
||||
}
|
||||
const QPair<QString, QString> dns = adminConfig->getDnsPair(m_appSettingsRepository->useAmneziaDns(),
|
||||
m_appSettingsRepository->primaryDns(),
|
||||
m_appSettingsRepository->secondaryDns());
|
||||
|
||||
ContainerConfig modifiedContainerConfig = containerConfig;
|
||||
modifiedContainerConfig.container = container;
|
||||
@@ -157,20 +165,25 @@ ExportController::NativeConfigResult ExportController::generateNativeConfig(int
|
||||
if (protocol == Proto::OpenVpn || protocol == Proto::WireGuard || protocol == Proto::Awg || protocol == Proto::Xray) {
|
||||
QString clientId = newProtocolConfig.clientId();
|
||||
if (!clientId.isEmpty()) {
|
||||
emit appendClientRequested(serverIndex, clientId, clientName, container);
|
||||
emit appendClientRequested(serverId, clientId, clientName, container);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ExportController::ExportResult ExportController::generateOpenVpnConfig(int serverIndex, const QString &clientName)
|
||||
ExportController::ExportResult ExportController::generateOpenVpnConfig(const QString &serverId, const QString &clientName)
|
||||
{
|
||||
ExportResult result;
|
||||
|
||||
DockerContainer container = DockerContainer::OpenVpn;
|
||||
ContainerConfig containerConfig = m_serversRepository->containerConfig(serverIndex, container);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
result.errorCode = ErrorCode::InternalError;
|
||||
return result;
|
||||
}
|
||||
ContainerConfig containerConfig = adminConfig->containerConfig(container);
|
||||
|
||||
auto nativeResult = generateNativeConfig(serverIndex, container, containerConfig, clientName);
|
||||
auto nativeResult = generateNativeConfig(serverId, container, containerConfig, clientName);
|
||||
if (nativeResult.errorCode != ErrorCode::NoError) {
|
||||
result.errorCode = nativeResult.errorCode;
|
||||
return result;
|
||||
@@ -185,13 +198,18 @@ ExportController::ExportResult ExportController::generateOpenVpnConfig(int serve
|
||||
return result;
|
||||
}
|
||||
|
||||
ExportController::ExportResult ExportController::generateWireGuardConfig(int serverIndex, const QString &clientName)
|
||||
ExportController::ExportResult ExportController::generateWireGuardConfig(const QString &serverId, const QString &clientName)
|
||||
{
|
||||
ExportResult result;
|
||||
|
||||
ContainerConfig containerConfig = m_serversRepository->containerConfig(serverIndex, DockerContainer::WireGuard);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
result.errorCode = ErrorCode::InternalError;
|
||||
return result;
|
||||
}
|
||||
ContainerConfig containerConfig = adminConfig->containerConfig(DockerContainer::WireGuard);
|
||||
|
||||
auto nativeResult = generateNativeConfig(serverIndex, DockerContainer::WireGuard, containerConfig, clientName);
|
||||
auto nativeResult = generateNativeConfig(serverId, DockerContainer::WireGuard, containerConfig, clientName);
|
||||
if (nativeResult.errorCode != ErrorCode::NoError) {
|
||||
result.errorCode = nativeResult.errorCode;
|
||||
return result;
|
||||
@@ -206,7 +224,7 @@ ExportController::ExportResult ExportController::generateWireGuardConfig(int ser
|
||||
return result;
|
||||
}
|
||||
|
||||
ExportController::ExportResult ExportController::generateAwgConfig(int serverIndex, int containerIndex, const QString &clientName)
|
||||
ExportController::ExportResult ExportController::generateAwgConfig(const QString &serverId, int containerIndex, const QString &clientName)
|
||||
{
|
||||
ExportResult result;
|
||||
|
||||
@@ -215,9 +233,14 @@ ExportController::ExportResult ExportController::generateAwgConfig(int serverInd
|
||||
result.errorCode = ErrorCode::InternalError;
|
||||
return result;
|
||||
}
|
||||
ContainerConfig containerConfig = m_serversRepository->containerConfig(serverIndex, container);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
result.errorCode = ErrorCode::InternalError;
|
||||
return result;
|
||||
}
|
||||
ContainerConfig containerConfig = adminConfig->containerConfig(container);
|
||||
|
||||
auto nativeResult = generateNativeConfig(serverIndex, container, containerConfig, clientName);
|
||||
auto nativeResult = generateNativeConfig(serverId, container, containerConfig, clientName);
|
||||
if (nativeResult.errorCode != ErrorCode::NoError) {
|
||||
result.errorCode = nativeResult.errorCode;
|
||||
return result;
|
||||
@@ -233,13 +256,18 @@ ExportController::ExportResult ExportController::generateAwgConfig(int serverInd
|
||||
}
|
||||
|
||||
|
||||
ExportController::ExportResult ExportController::generateXrayConfig(int serverIndex, const QString &clientName)
|
||||
ExportController::ExportResult ExportController::generateXrayConfig(const QString &serverId, const QString &clientName)
|
||||
{
|
||||
ExportResult result;
|
||||
|
||||
ContainerConfig containerConfig = m_serversRepository->containerConfig(serverIndex, DockerContainer::Xray);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
result.errorCode = ErrorCode::InternalError;
|
||||
return result;
|
||||
}
|
||||
ContainerConfig containerConfig = adminConfig->containerConfig(DockerContainer::Xray);
|
||||
|
||||
auto nativeResult = generateNativeConfig(serverIndex, DockerContainer::Xray, containerConfig, clientName);
|
||||
auto nativeResult = generateNativeConfig(serverId, DockerContainer::Xray, containerConfig, clientName);
|
||||
if (nativeResult.errorCode != ErrorCode::NoError) {
|
||||
result.errorCode = nativeResult.errorCode;
|
||||
return result;
|
||||
@@ -302,22 +330,22 @@ ExportController::ExportResult ExportController::generateXrayConfig(int serverIn
|
||||
return result;
|
||||
}
|
||||
|
||||
void ExportController::updateClientManagementModel(int serverIndex, int containerIndex)
|
||||
void ExportController::updateClientManagementModel(const QString &serverId, int containerIndex)
|
||||
{
|
||||
DockerContainer container = static_cast<DockerContainer>(containerIndex);
|
||||
emit updateClientsRequested(serverIndex, container);
|
||||
emit updateClientsRequested(serverId, container);
|
||||
}
|
||||
|
||||
void ExportController::revokeConfig(int row, int serverIndex, int containerIndex)
|
||||
void ExportController::revokeConfig(int row, const QString &serverId, int containerIndex)
|
||||
{
|
||||
DockerContainer container = static_cast<DockerContainer>(containerIndex);
|
||||
emit revokeClientRequested(serverIndex, row, container);
|
||||
emit revokeClientRequested(serverId, row, container);
|
||||
}
|
||||
|
||||
void ExportController::renameClient(int row, const QString &clientName, int serverIndex, int containerIndex)
|
||||
void ExportController::renameClient(int row, const QString &clientName, const QString &serverId, int containerIndex)
|
||||
{
|
||||
DockerContainer container = static_cast<DockerContainer>(containerIndex);
|
||||
emit renameClientRequested(serverIndex, row, clientName, container);
|
||||
emit renameClientRequested(serverId, row, clientName, container);
|
||||
}
|
||||
|
||||
QString ExportController::generateVpnUrl(const QByteArray &compressedConfig)
|
||||
|
||||
@@ -37,23 +37,23 @@ public:
|
||||
SecureAppSettingsRepository* appSettingsRepository,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
ExportResult generateFullAccessConfig(int serverIndex);
|
||||
ExportResult generateConnectionConfig(int serverIndex, int containerIndex, const QString &clientName);
|
||||
ExportResult generateOpenVpnConfig(int serverIndex, const QString &clientName);
|
||||
ExportResult generateWireGuardConfig(int serverIndex, const QString &clientName);
|
||||
ExportResult generateAwgConfig(int serverIndex, int containerIndex, const QString &clientName);
|
||||
ExportResult generateXrayConfig(int serverIndex, const QString &clientName);
|
||||
ExportResult generateFullAccessConfig(const QString &serverId);
|
||||
ExportResult generateConnectionConfig(const QString &serverId, int containerIndex, const QString &clientName);
|
||||
ExportResult generateOpenVpnConfig(const QString &serverId, const QString &clientName);
|
||||
ExportResult generateWireGuardConfig(const QString &serverId, const QString &clientName);
|
||||
ExportResult generateAwgConfig(const QString &serverId, int containerIndex, const QString &clientName);
|
||||
ExportResult generateXrayConfig(const QString &serverId, const QString &clientName);
|
||||
|
||||
signals:
|
||||
void appendClientRequested(int serverIndex, const QString &clientId, const QString &clientName, DockerContainer container);
|
||||
void updateClientsRequested(int serverIndex, DockerContainer container);
|
||||
void revokeClientRequested(int serverIndex, int row, DockerContainer container);
|
||||
void renameClientRequested(int serverIndex, int row, const QString &clientName, DockerContainer container);
|
||||
void appendClientRequested(const QString &serverId, const QString &clientId, const QString &clientName, DockerContainer container);
|
||||
void updateClientsRequested(const QString &serverId, DockerContainer container);
|
||||
void revokeClientRequested(const QString &serverId, int row, DockerContainer container);
|
||||
void renameClientRequested(const QString &serverId, int row, const QString &clientName, DockerContainer container);
|
||||
|
||||
public slots:
|
||||
void updateClientManagementModel(int serverIndex, int containerIndex);
|
||||
void revokeConfig(int row, int serverIndex, int containerIndex);
|
||||
void renameClient(int row, const QString &clientName, int serverIndex, int containerIndex);
|
||||
void updateClientManagementModel(const QString &serverId, int containerIndex);
|
||||
void revokeConfig(int row, const QString &serverId, int containerIndex);
|
||||
void renameClient(int row, const QString &clientName, const QString &serverId, int containerIndex);
|
||||
|
||||
private:
|
||||
struct NativeConfigResult
|
||||
@@ -62,7 +62,7 @@ private:
|
||||
QJsonObject jsonNativeConfig;
|
||||
};
|
||||
|
||||
NativeConfigResult generateNativeConfig(int serverIndex, DockerContainer container,
|
||||
NativeConfigResult generateNativeConfig(const QString &serverId, DockerContainer container,
|
||||
const ContainerConfig &containerConfig,
|
||||
const QString &clientName);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/utils/qrCodeUtils.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
|
||||
using namespace amnezia;
|
||||
using namespace ProtocolUtils;
|
||||
@@ -208,12 +207,18 @@ ImportController::ImportResult ImportController::extractConfigFromData(const QSt
|
||||
case ConfigTypes::Amnezia: {
|
||||
result.config = QJsonDocument::fromJson(config.toUtf8()).object();
|
||||
|
||||
if (apiUtils::isServerFromApi(result.config)) {
|
||||
if (serverConfigUtils::isServerFromApi(result.config)) {
|
||||
auto apiConfig = result.config.value(apiDefs::key::apiConfig).toObject();
|
||||
apiConfig[apiDefs::key::vpnKey] = data;
|
||||
result.config[apiDefs::key::apiConfig] = apiConfig;
|
||||
}
|
||||
|
||||
if (serverConfigUtils::isLegacyApiSubscription(serverConfigUtils::configTypeFromJson(result.config))) {
|
||||
result.errorCode = ErrorCode::LegacyApiV1NotSupportedError;
|
||||
result.config = {};
|
||||
return result;
|
||||
}
|
||||
|
||||
processAmneziaConfig(result.config);
|
||||
if (!result.config.empty()) {
|
||||
checkForMaliciousStrings(result.config, result.maliciousWarningText);
|
||||
@@ -381,18 +386,29 @@ void ImportController::importConfig(const QJsonObject &config)
|
||||
credentials.secretData = config.value(configKey::password).toString();
|
||||
|
||||
if (credentials.isValid() || config.contains(configKey::containers)) {
|
||||
ServerConfig serverConfig = ServerConfig::fromJson(config);
|
||||
m_serversRepository->addServer(serverConfig);
|
||||
m_serversRepository->addServer(QString(), config, serverConfigUtils::configTypeFromJson(config));
|
||||
emit importFinished();
|
||||
} else if (config.contains(configKey::configVersion)) {
|
||||
quint16 crc = qChecksum(QJsonDocument(config).toJson());
|
||||
if (m_serversRepository->hasServerWithCrc(crc)) {
|
||||
bool hasServerWithCrc = false;
|
||||
const QVector<QString> ids = m_serversRepository->orderedServerIds();
|
||||
for (const QString &id : ids) {
|
||||
const auto apiV2 = m_serversRepository->apiV2Config(id);
|
||||
if (!apiV2.has_value()) {
|
||||
continue;
|
||||
}
|
||||
if (static_cast<quint16>(apiV2->crc) == crc) {
|
||||
hasServerWithCrc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasServerWithCrc) {
|
||||
emit importErrorOccurred(ErrorCode::ApiConfigAlreadyAdded, true);
|
||||
} else {
|
||||
QJsonObject configWithCrc = config;
|
||||
configWithCrc.insert(configKey::crc, crc);
|
||||
ServerConfig serverConfig = ServerConfig::fromJson(configWithCrc);
|
||||
m_serversRepository->addServer(serverConfig);
|
||||
m_serversRepository->addServer(QString(), configWithCrc, serverConfigUtils::configTypeFromJson(configWithCrc));
|
||||
emit importFinished();
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/models/protocols/awgProtocolConfig.h"
|
||||
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||
@@ -129,15 +128,27 @@ ErrorCode InstallController::setupContainer(const ServerCredentials &credentials
|
||||
return startupContainerWorker(credentials, container, config, sshSession);
|
||||
}
|
||||
|
||||
ErrorCode InstallController::updateContainer(int serverIndex, DockerContainer container, const ContainerConfig &oldConfig,
|
||||
ErrorCode InstallController::updateContainer(const QString &serverId, DockerContainer container, const ContainerConfig &oldConfig,
|
||||
ContainerConfig &newConfig)
|
||||
{
|
||||
if (!isUpdateDockerContainerRequired(container, oldConfig, newConfig)) {
|
||||
m_serversRepository->setContainerConfig(serverIndex, container, newConfig);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
adminConfig->updateContainerConfig(container, newConfig);
|
||||
m_serversRepository->editServer(serverId, adminConfig->toJson(), serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ServerCredentials credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
SshSession sshSession(this);
|
||||
|
||||
bool reinstallRequired = isReinstallContainerRequired(container, oldConfig, newConfig);
|
||||
@@ -154,42 +165,51 @@ ErrorCode InstallController::updateContainer(int serverIndex, DockerContainer co
|
||||
}
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
clearCachedProfile(serverIndex, container);
|
||||
m_serversRepository->setContainerConfig(serverIndex, container, newConfig);
|
||||
clearCachedProfile(serverId, container);
|
||||
adminConfig->updateContainerConfig(container, newConfig);
|
||||
m_serversRepository->editServer(serverId, adminConfig->toJson(), serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
void InstallController::clearCachedProfile(int serverIndex, DockerContainer container)
|
||||
void InstallController::clearCachedProfile(const QString &serverId, DockerContainer container)
|
||||
{
|
||||
if (ContainerUtils::containerService(container) == ServiceType::Other) {
|
||||
return;
|
||||
}
|
||||
|
||||
ContainerConfig containerConfigModel = m_serversRepository->containerConfig(serverIndex, container);
|
||||
|
||||
m_serversRepository->clearLastConnectionConfig(serverIndex, container);
|
||||
|
||||
emit clientRevocationRequested(serverIndex, containerConfigModel, container);
|
||||
}
|
||||
|
||||
ErrorCode InstallController::validateAndPrepareConfig(int serverIndex)
|
||||
{
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
|
||||
if (serverConfigModel.isApiConfig()) {
|
||||
return ErrorCode::NoError;
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DockerContainer container = serverConfigModel.defaultContainer();
|
||||
adminConfig->clearCachedClientProfile(container);
|
||||
const ContainerConfig containerConfigModel = adminConfig->containerConfig(container);
|
||||
|
||||
m_serversRepository->editServer(serverId, adminConfig->toJson(), serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
|
||||
emit clientRevocationRequested(serverId, containerConfigModel, container);
|
||||
}
|
||||
|
||||
ErrorCode InstallController::validateAndPrepareConfig(const QString &serverId)
|
||||
{
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
DockerContainer container = adminConfig->defaultContainer;
|
||||
|
||||
if (container == DockerContainer::None) {
|
||||
return ErrorCode::NoInstalledContainersError;
|
||||
}
|
||||
|
||||
ContainerConfig containerConfig = m_serversRepository->containerConfig(serverIndex, container);
|
||||
ServerCredentials credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
ContainerConfig containerConfig = adminConfig->containerConfig(container);
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
SshSession sshSession;
|
||||
|
||||
auto isProtocolConfigExists = [](const ContainerConfig &cfg) {
|
||||
@@ -198,20 +218,21 @@ ErrorCode InstallController::validateAndPrepareConfig(int serverIndex)
|
||||
|
||||
if (!isProtocolConfigExists(containerConfig)) {
|
||||
QString clientName = QString("Admin [%1]").arg(QSysInfo::prettyProductName());
|
||||
ErrorCode errorCode = processContainerForAdmin(container, containerConfig, credentials, sshSession, serverIndex, clientName);
|
||||
ErrorCode errorCode = processContainerForAdmin(container, containerConfig, credentials, sshSession, serverId, clientName);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
return errorCode;
|
||||
}
|
||||
m_serversRepository->setContainerConfig(serverIndex, container, containerConfig);
|
||||
adminConfig->updateContainerConfig(container, containerConfig);
|
||||
m_serversRepository->editServer(serverId, adminConfig->toJson(), serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
}
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
void InstallController::validateConfig(int serverIndex)
|
||||
void InstallController::validateConfig(const QString &serverId)
|
||||
{
|
||||
QFuture<ErrorCode> future = QtConcurrent::run([this, serverIndex]() {
|
||||
return validateAndPrepareConfig(serverIndex);
|
||||
QFuture<ErrorCode> future = QtConcurrent::run([this, serverId]() {
|
||||
return validateAndPrepareConfig(serverId);
|
||||
});
|
||||
|
||||
auto *watcher = new QFutureWatcher<ErrorCode>(this);
|
||||
@@ -230,6 +251,21 @@ void InstallController::validateConfig(int serverIndex)
|
||||
watcher->setFuture(future);
|
||||
}
|
||||
|
||||
void InstallController::addEmptyServer(const ServerCredentials &credentials)
|
||||
{
|
||||
SelfHostedAdminServerConfig serverConfig;
|
||||
serverConfig.hostName = credentials.hostName;
|
||||
serverConfig.userName = credentials.userName;
|
||||
serverConfig.password = credentials.secretData;
|
||||
serverConfig.port = credentials.port;
|
||||
serverConfig.description = m_appSettingsRepository->nextAvailableServerName();
|
||||
serverConfig.displayName = serverConfig.description.isEmpty() ? serverConfig.hostName : serverConfig.description;
|
||||
serverConfig.defaultContainer = DockerContainer::None;
|
||||
|
||||
m_serversRepository->addServer(QString(), serverConfig.toJson(),
|
||||
serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
}
|
||||
|
||||
ErrorCode InstallController::prepareContainerConfig(DockerContainer container, const ServerCredentials &credentials, ContainerConfig &containerConfig, SshSession &sshSession)
|
||||
{
|
||||
if (!ContainerUtils::isSupportedByCurrentPlatform(container)) {
|
||||
@@ -257,7 +293,7 @@ ErrorCode InstallController::prepareContainerConfig(DockerContainer container, c
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
void InstallController::adminAppendRequested(int serverIndex, DockerContainer container,
|
||||
void InstallController::adminAppendRequested(const QString &serverId, DockerContainer container,
|
||||
const ContainerConfig &containerConfig, const QString &clientName)
|
||||
{
|
||||
if (ContainerUtils::containerService(container) == ServiceType::Other
|
||||
@@ -266,13 +302,13 @@ void InstallController::adminAppendRequested(int serverIndex, DockerContainer co
|
||||
}
|
||||
QString clientId = containerConfig.protocolConfig.clientId();
|
||||
if (!clientId.isEmpty()) {
|
||||
emit clientAppendRequested(serverIndex, clientId, clientName, container);
|
||||
emit clientAppendRequested(serverId, clientId, clientName, container);
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode InstallController::processContainerForAdmin(DockerContainer container, ContainerConfig &containerConfig,
|
||||
const ServerCredentials &credentials, SshSession &sshSession,
|
||||
int serverIndex, const QString &clientName)
|
||||
const QString &serverId, const QString &clientName)
|
||||
{
|
||||
if (ContainerUtils::isSupportedByCurrentPlatform(container)) {
|
||||
ErrorCode errorCode = prepareContainerConfig(container, credentials, containerConfig, sshSession);
|
||||
@@ -280,7 +316,7 @@ ErrorCode InstallController::processContainerForAdmin(DockerContainer container,
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
adminAppendRequested(serverIndex, container, containerConfig, clientName);
|
||||
adminAppendRequested(serverId, container, containerConfig, clientName);
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
@@ -688,9 +724,16 @@ ErrorCode InstallController::setupServerFirewall(const ServerCredentials &creden
|
||||
amnezia::genBaseVars(credentials, DockerContainer::None, QString(), QString())));
|
||||
}
|
||||
|
||||
ErrorCode InstallController::rebootServer(int serverIndex)
|
||||
ErrorCode InstallController::rebootServer(const QString &serverId)
|
||||
{
|
||||
auto credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
const auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
SshSession sshSession(this);
|
||||
|
||||
QString script = QString("sudo reboot");
|
||||
@@ -709,27 +752,38 @@ ErrorCode InstallController::rebootServer(int serverIndex)
|
||||
return sshSession.runScript(credentials, script, cbReadStdOut, cbReadStdErr);
|
||||
}
|
||||
|
||||
ErrorCode InstallController::removeAllContainers(int serverIndex)
|
||||
ErrorCode InstallController::removeAllContainers(const QString &serverId)
|
||||
{
|
||||
auto credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
SshSession sshSession(this);
|
||||
ErrorCode errorCode = sshSession.runScript(credentials, amnezia::scriptData(SharedScriptType::remove_all_containers));
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
serverConfigModel.visit([](auto& arg) {
|
||||
arg.containers.clear();
|
||||
arg.defaultContainer = DockerContainer::None;
|
||||
});
|
||||
m_serversRepository->editServer(serverIndex, serverConfigModel);
|
||||
adminConfig->containers.clear();
|
||||
adminConfig->defaultContainer = DockerContainer::None;
|
||||
m_serversRepository->editServer(serverId, adminConfig->toJson(), serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode InstallController::removeContainer(int serverIndex, DockerContainer container)
|
||||
ErrorCode InstallController::removeContainer(const QString &serverId, DockerContainer container)
|
||||
{
|
||||
auto credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
SshSession sshSession(this);
|
||||
ErrorCode errorCode = sshSession.runScript(
|
||||
credentials,
|
||||
@@ -737,11 +791,10 @@ ErrorCode InstallController::removeContainer(int serverIndex, DockerContainer co
|
||||
amnezia::genBaseVars(credentials, container, QString(), QString())));
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containers = serverConfigModel.containers();
|
||||
QMap<DockerContainer, ContainerConfig> containers = adminConfig->containers;
|
||||
containers.remove(container);
|
||||
|
||||
DockerContainer defaultContainer = serverConfigModel.defaultContainer();
|
||||
|
||||
DockerContainer defaultContainer = adminConfig->defaultContainer;
|
||||
if (defaultContainer == container) {
|
||||
if (containers.isEmpty()) {
|
||||
defaultContainer = DockerContainer::None;
|
||||
@@ -749,12 +802,10 @@ ErrorCode InstallController::removeContainer(int serverIndex, DockerContainer co
|
||||
defaultContainer = containers.begin().key();
|
||||
}
|
||||
}
|
||||
|
||||
serverConfigModel.visit([&containers, defaultContainer](auto& arg) {
|
||||
arg.containers = containers;
|
||||
arg.defaultContainer = defaultContainer;
|
||||
});
|
||||
m_serversRepository->editServer(serverIndex, serverConfigModel);
|
||||
|
||||
adminConfig->containers = containers;
|
||||
adminConfig->defaultContainer = defaultContainer;
|
||||
m_serversRepository->editServer(serverId, adminConfig->toJson(), serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
@@ -815,9 +866,16 @@ bool InstallController::isUpdateDockerContainerRequired(DockerContainer containe
|
||||
return true;
|
||||
}
|
||||
|
||||
ErrorCode InstallController::scanServerForInstalledContainers(int serverIndex)
|
||||
ErrorCode InstallController::scanServerForInstalledContainers(const QString &serverId)
|
||||
{
|
||||
ServerCredentials credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
SshSession sshSession(this);
|
||||
|
||||
QMap<DockerContainer, ContainerConfig> installedContainers;
|
||||
@@ -826,8 +884,7 @@ ErrorCode InstallController::scanServerForInstalledContainers(int serverIndex)
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ServerConfig serverConfigModel = m_serversRepository->server(serverIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containers = serverConfigModel.containers();
|
||||
QMap<DockerContainer, ContainerConfig> containers = adminConfig->containers;
|
||||
bool hasNewContainers = false;
|
||||
|
||||
QString clientName = QString("Admin [%1]").arg(QSysInfo::prettyProductName());
|
||||
@@ -835,29 +892,25 @@ ErrorCode InstallController::scanServerForInstalledContainers(int serverIndex)
|
||||
if (!containers.contains(iterator.key())) {
|
||||
ContainerConfig containerConfig = iterator.value();
|
||||
errorCode = processContainerForAdmin(iterator.key(), containerConfig, credentials, sshSession,
|
||||
serverIndex, clientName);
|
||||
serverId, clientName);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
return errorCode;
|
||||
}
|
||||
containers.insert(iterator.key(), containerConfig);
|
||||
hasNewContainers = true;
|
||||
|
||||
DockerContainer defaultContainer = serverConfigModel.defaultContainer();
|
||||
DockerContainer defaultContainer = adminConfig->defaultContainer;
|
||||
if (defaultContainer == DockerContainer::None
|
||||
&& ContainerUtils::containerService(iterator.key()) != ServiceType::Other
|
||||
&& ContainerUtils::isSupportedByCurrentPlatform(iterator.key())) {
|
||||
serverConfigModel.visit([iterator](auto& arg) {
|
||||
arg.defaultContainer = iterator.key();
|
||||
});
|
||||
adminConfig->defaultContainer = iterator.key();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasNewContainers) {
|
||||
serverConfigModel.visit([&containers](auto& arg) {
|
||||
arg.containers = containers;
|
||||
});
|
||||
m_serversRepository->editServer(serverIndex, serverConfigModel);
|
||||
adminConfig->containers = containers;
|
||||
m_serversRepository->editServer(serverId, adminConfig->toJson(), serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
}
|
||||
|
||||
return ErrorCode::NoError;
|
||||
@@ -899,7 +952,7 @@ ErrorCode InstallController::installServer(const ServerCredentials &credentials,
|
||||
preparedContainers.insert(container, containerConfig);
|
||||
}
|
||||
|
||||
SelfHostedServerConfig serverConfig;
|
||||
SelfHostedAdminServerConfig serverConfig;
|
||||
serverConfig.hostName = credentials.hostName;
|
||||
serverConfig.userName = credentials.userName;
|
||||
serverConfig.password = credentials.secretData;
|
||||
@@ -912,21 +965,29 @@ ErrorCode InstallController::installServer(const ServerCredentials &credentials,
|
||||
|
||||
serverConfig.defaultContainer = container;
|
||||
|
||||
m_serversRepository->addServer(ServerConfig(serverConfig));
|
||||
serverConfig.displayName = serverConfig.description.isEmpty() ? serverConfig.hostName : serverConfig.description;
|
||||
|
||||
int serverIndex = m_serversRepository->serversCount() - 1;
|
||||
const QString newServerId = m_serversRepository->addServer(QString(), serverConfig.toJson(),
|
||||
serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
QString clientName = QString("Admin [%1]").arg(QSysInfo::prettyProductName());
|
||||
for (auto iterator = preparedContainers.begin(); iterator != preparedContainers.end(); iterator++) {
|
||||
adminAppendRequested(serverIndex, iterator.key(), iterator.value(), clientName);
|
||||
adminAppendRequested(newServerId, iterator.key(), iterator.value(), clientName);
|
||||
}
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode InstallController::installContainer(int serverIndex, DockerContainer container, int port,
|
||||
ErrorCode InstallController::installContainer(const QString &serverId, DockerContainer container, int port,
|
||||
TransportProto transportProto, bool &wasContainerInstalled)
|
||||
{
|
||||
ServerCredentials credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
SshSession sshSession(this);
|
||||
|
||||
QMap<DockerContainer, ContainerConfig> installedContainers;
|
||||
@@ -949,15 +1010,17 @@ ErrorCode InstallController::installContainer(int serverIndex, DockerContainer c
|
||||
|
||||
QString clientName = QString("Admin [%1]").arg(QSysInfo::prettyProductName());
|
||||
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
||||
ContainerConfig existingConfigModel = m_serversRepository->containerConfig(serverIndex, iterator.key());
|
||||
ContainerConfig existingConfigModel = adminConfig->containerConfig(iterator.key());
|
||||
if (existingConfigModel.container == DockerContainer::None) {
|
||||
ContainerConfig containerConfig = iterator.value();
|
||||
errorCode = processContainerForAdmin(iterator.key(), containerConfig, credentials, sshSession,
|
||||
serverIndex, clientName);
|
||||
serverId, clientName);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
return errorCode;
|
||||
}
|
||||
m_serversRepository->setContainerConfig(serverIndex, iterator.key(), containerConfig);
|
||||
adminConfig->updateContainerConfig(iterator.key(), containerConfig);
|
||||
m_serversRepository->editServer(serverId, adminConfig->toJson(),
|
||||
serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -993,7 +1056,15 @@ bool InstallController::isServerAlreadyExists(const ServerCredentials &credentia
|
||||
{
|
||||
int serversCount = m_serversRepository->serversCount();
|
||||
for (int i = 0; i < serversCount; i++) {
|
||||
const ServerCredentials existingCredentials = m_serversRepository->serverCredentials(i);
|
||||
const QString existingServerId = m_serversRepository->serverIdAt(i);
|
||||
const auto adminConfig = m_serversRepository->selfHostedAdminConfig(existingServerId);
|
||||
if (!adminConfig.has_value()) {
|
||||
continue;
|
||||
}
|
||||
const ServerCredentials existingCredentials = adminConfig->credentials();
|
||||
if (!existingCredentials.isValid()) {
|
||||
continue;
|
||||
}
|
||||
if (credentials.hostName == existingCredentials.hostName && credentials.port == existingCredentials.port) {
|
||||
existingServerIndex = i;
|
||||
return true;
|
||||
|
||||
@@ -33,22 +33,22 @@ public:
|
||||
~InstallController();
|
||||
|
||||
ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, ContainerConfig &config, bool isUpdate = false);
|
||||
ErrorCode updateContainer(int serverIndex, DockerContainer container, const ContainerConfig &oldConfig, ContainerConfig &newConfig);
|
||||
ErrorCode updateContainer(const QString &serverId, DockerContainer container, const ContainerConfig &oldConfig, ContainerConfig &newConfig);
|
||||
|
||||
ErrorCode rebootServer(int serverIndex);
|
||||
ErrorCode removeAllContainers(int serverIndex);
|
||||
ErrorCode removeContainer(int serverIndex, DockerContainer container);
|
||||
ErrorCode rebootServer(const QString &serverId);
|
||||
ErrorCode removeAllContainers(const QString &serverId);
|
||||
ErrorCode removeContainer(const QString &serverId, DockerContainer container);
|
||||
|
||||
ContainerConfig generateConfig(DockerContainer container, int port, TransportProto transportProto);
|
||||
ErrorCode getAlreadyInstalledContainers(const ServerCredentials &credentials, QMap<DockerContainer, ContainerConfig> &installedContainers, SshSession &sshSession);
|
||||
|
||||
ErrorCode scanServerForInstalledContainers(int serverIndex);
|
||||
ErrorCode scanServerForInstalledContainers(const QString &serverId);
|
||||
|
||||
ErrorCode installContainer(const ServerCredentials &credentials, DockerContainer container, int port, TransportProto transportProto, ContainerConfig &config);
|
||||
|
||||
ErrorCode installServer(const ServerCredentials &credentials, DockerContainer container, int port, TransportProto transportProto,
|
||||
bool &wasContainerInstalled);
|
||||
ErrorCode installContainer(int serverIndex, DockerContainer container, int port, TransportProto transportProto,
|
||||
ErrorCode installContainer(const QString &serverId, DockerContainer container, int port, TransportProto transportProto,
|
||||
bool &wasContainerInstalled);
|
||||
|
||||
bool isUpdateDockerContainerRequired(DockerContainer container, const ContainerConfig &oldConfig, const ContainerConfig &newConfig);
|
||||
@@ -62,11 +62,13 @@ public:
|
||||
|
||||
void cancelInstallation();
|
||||
|
||||
void clearCachedProfile(int serverIndex, DockerContainer container);
|
||||
void clearCachedProfile(const QString &serverId, DockerContainer container);
|
||||
|
||||
ErrorCode validateAndPrepareConfig(int serverIndex);
|
||||
ErrorCode validateAndPrepareConfig(const QString &serverId);
|
||||
|
||||
void validateConfig(int serverIndex);
|
||||
void validateConfig(const QString &serverId);
|
||||
|
||||
void addEmptyServer(const ServerCredentials &credentials);
|
||||
|
||||
signals:
|
||||
void configValidated(bool isValid);
|
||||
@@ -74,8 +76,8 @@ signals:
|
||||
|
||||
void serverIsBusy(const bool isBusy);
|
||||
void cancelInstallationRequested();
|
||||
void clientRevocationRequested(int serverIndex, const ContainerConfig &containerConfig, DockerContainer container);
|
||||
void clientAppendRequested(int serverIndex, const QString &clientId, const QString &clientName, DockerContainer container);
|
||||
void clientRevocationRequested(const QString &serverId, const ContainerConfig &containerConfig, DockerContainer container);
|
||||
void clientAppendRequested(const QString &serverId, const QString &clientId, const QString &clientName, DockerContainer container);
|
||||
|
||||
private:
|
||||
ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container, SshSession &sshSession);
|
||||
@@ -95,9 +97,9 @@ private:
|
||||
|
||||
ErrorCode processContainerForAdmin(DockerContainer container, ContainerConfig &containerConfig,
|
||||
const ServerCredentials &credentials, SshSession &sshSession,
|
||||
int serverIndex, const QString &clientName);
|
||||
const QString &serverId, const QString &clientName);
|
||||
|
||||
void adminAppendRequested(int serverIndex, DockerContainer container,
|
||||
void adminAppendRequested(const QString &serverId, DockerContainer container,
|
||||
const ContainerConfig &containerConfig, const QString &clientName);
|
||||
|
||||
static void updateContainerConfigAfterInstallation(DockerContainer container, ContainerConfig &containerConfig, const QString &stdOut);
|
||||
@@ -114,4 +116,3 @@ private:
|
||||
};
|
||||
|
||||
#endif // INSTALLCONTROLLER_H
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
|
||||
using namespace amnezia;
|
||||
@@ -292,11 +291,18 @@ ErrorCode UsersController::getXrayClients(const DockerContainer container, const
|
||||
return error;
|
||||
}
|
||||
|
||||
ErrorCode UsersController::updateClients(int serverIndex, const DockerContainer container)
|
||||
ErrorCode UsersController::updateClients(const QString &serverId, const DockerContainer container)
|
||||
{
|
||||
ErrorCode error = ErrorCode::NoError;
|
||||
SshSession sshSession;
|
||||
ServerCredentials credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable");
|
||||
if (container == DockerContainer::OpenVpn) {
|
||||
@@ -381,20 +387,27 @@ ErrorCode UsersController::updateClients(int serverIndex, const DockerContainer
|
||||
}
|
||||
|
||||
|
||||
ErrorCode UsersController::appendClient(int serverIndex, const QString &clientId, const QString &clientName, const DockerContainer container)
|
||||
ErrorCode UsersController::appendClient(const QString &serverId, const QString &clientId, const QString &clientName, const DockerContainer container)
|
||||
{
|
||||
ErrorCode error = ErrorCode::NoError;
|
||||
SshSession sshSession;
|
||||
ServerCredentials credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
error = updateClients(serverIndex, container);
|
||||
error = updateClients(serverId, container);
|
||||
if (error != ErrorCode::NoError) {
|
||||
return error;
|
||||
}
|
||||
|
||||
int existingIndex = clientIndexById(clientId, m_clientsTable);
|
||||
if (existingIndex >= 0) {
|
||||
return renameClient(serverIndex, existingIndex, clientName, container, true);
|
||||
return renameClient(serverId, existingIndex, clientName, container, true);
|
||||
}
|
||||
|
||||
QJsonObject client;
|
||||
@@ -426,7 +439,7 @@ ErrorCode UsersController::appendClient(int serverIndex, const QString &clientId
|
||||
return error;
|
||||
}
|
||||
|
||||
ErrorCode UsersController::renameClient(int serverIndex, const int row, const QString &clientName,
|
||||
ErrorCode UsersController::renameClient(const QString &serverId, const int row, const QString &clientName,
|
||||
const DockerContainer container, bool addTimeStamp)
|
||||
{
|
||||
if (row < 0 || row >= m_clientsTable.size()) {
|
||||
@@ -434,7 +447,14 @@ ErrorCode UsersController::renameClient(int serverIndex, const int row, const QS
|
||||
}
|
||||
|
||||
SshSession sshSession;
|
||||
ServerCredentials credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
auto client = m_clientsTable.at(row).toObject();
|
||||
auto userData = client[configKey::userData].toObject();
|
||||
@@ -470,7 +490,7 @@ ErrorCode UsersController::renameClient(int serverIndex, const int row, const QS
|
||||
}
|
||||
|
||||
ErrorCode UsersController::revokeOpenVpn(const int row, const DockerContainer container, const ServerCredentials &credentials,
|
||||
const int serverIndex, SshSession* sshSession, QJsonArray &clientsTable)
|
||||
SshSession* sshSession, QJsonArray &clientsTable)
|
||||
{
|
||||
if (row < 0 || row >= clientsTable.size()) {
|
||||
return ErrorCode::InternalError;
|
||||
@@ -689,14 +709,21 @@ ErrorCode UsersController::revokeXray(const int row,
|
||||
return error;
|
||||
}
|
||||
|
||||
ErrorCode UsersController::revokeClient(int serverIndex, const int index, const DockerContainer container)
|
||||
ErrorCode UsersController::revokeClient(const QString &serverId, const int index, const DockerContainer container)
|
||||
{
|
||||
if (index < 0 || index >= m_clientsTable.size()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
SshSession sshSession;
|
||||
ServerCredentials credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
QString clientId = m_clientsTable.at(index).toObject().value(configKey::clientId).toString();
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
@@ -704,7 +731,7 @@ ErrorCode UsersController::revokeClient(int serverIndex, const int index, const
|
||||
switch(container)
|
||||
{
|
||||
case DockerContainer::OpenVpn: {
|
||||
errorCode = revokeOpenVpn(index, container, credentials, serverIndex, &sshSession, m_clientsTable);
|
||||
errorCode = revokeOpenVpn(index, container, credentials, &sshSession, m_clientsTable);
|
||||
break;
|
||||
}
|
||||
case DockerContainer::WireGuard:
|
||||
@@ -724,12 +751,15 @@ ErrorCode UsersController::revokeClient(int serverIndex, const int index, const
|
||||
}
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
ServerConfig serverConfig = m_serversRepository->server(serverIndex);
|
||||
ContainerConfig containerCfg = m_serversRepository->containerConfig(serverIndex, container);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ContainerConfig containerCfg = adminConfig->containerConfig(container);
|
||||
QString containerClientId = containerCfg.protocolConfig.clientId();
|
||||
|
||||
if (!clientId.isEmpty() && !containerClientId.isEmpty() && containerClientId.contains(clientId)) {
|
||||
emit adminConfigRevoked(serverIndex, container);
|
||||
emit adminConfigRevoked(serverId, container);
|
||||
}
|
||||
|
||||
emit clientRevoked(index);
|
||||
@@ -739,13 +769,20 @@ ErrorCode UsersController::revokeClient(int serverIndex, const int index, const
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode UsersController::revokeClient(int serverIndex, const ContainerConfig &containerConfig, const DockerContainer container)
|
||||
ErrorCode UsersController::revokeClient(const QString &serverId, const ContainerConfig &containerConfig, const DockerContainer container)
|
||||
{
|
||||
SshSession sshSession;
|
||||
ServerCredentials credentials = m_serversRepository->serverCredentials(serverIndex);
|
||||
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!adminConfig.has_value()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
ServerCredentials credentials = adminConfig->credentials();
|
||||
if (!credentials.isValid()) {
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
errorCode = updateClients(serverIndex, container);
|
||||
errorCode = updateClients(serverId, container);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
return errorCode;
|
||||
}
|
||||
@@ -778,7 +815,7 @@ ErrorCode UsersController::revokeClient(int serverIndex, const ContainerConfig &
|
||||
switch (container)
|
||||
{
|
||||
case DockerContainer::OpenVpn: {
|
||||
errorCode = revokeOpenVpn(row, container, credentials, serverIndex, &sshSession, m_clientsTable);
|
||||
errorCode = revokeOpenVpn(row, container, credentials, &sshSession, m_clientsTable);
|
||||
break;
|
||||
}
|
||||
case DockerContainer::WireGuard:
|
||||
@@ -797,7 +834,7 @@ ErrorCode UsersController::revokeClient(int serverIndex, const ContainerConfig &
|
||||
}
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
emit adminConfigRevoked(serverIndex, container);
|
||||
emit adminConfigRevoked(serverId, container);
|
||||
emit clientRevoked(row);
|
||||
emit clientsUpdated(m_clientsTable);
|
||||
}
|
||||
|
||||
@@ -37,21 +37,21 @@ signals:
|
||||
void clientAdded(const QJsonObject &client);
|
||||
void clientRenamed(int row, const QString &newName);
|
||||
void clientRevoked(int row);
|
||||
void adminConfigRevoked(int serverIndex, DockerContainer container);
|
||||
void adminConfigRevoked(const QString &serverId, DockerContainer container);
|
||||
|
||||
public slots:
|
||||
ErrorCode updateClients(int serverIndex, const DockerContainer container);
|
||||
ErrorCode appendClient(int serverIndex, const QString &clientId, const QString &clientName, const DockerContainer container);
|
||||
ErrorCode renameClient(int serverIndex, const int row, const QString &userName, const DockerContainer container, bool addTimeStamp = false);
|
||||
ErrorCode revokeClient(int serverIndex, const int index, const DockerContainer container);
|
||||
ErrorCode revokeClient(int serverIndex, const ContainerConfig &containerConfig, const DockerContainer container);
|
||||
ErrorCode updateClients(const QString &serverId, const DockerContainer container);
|
||||
ErrorCode appendClient(const QString &serverId, const QString &clientId, const QString &clientName, const DockerContainer container);
|
||||
ErrorCode renameClient(const QString &serverId, const int row, const QString &userName, const DockerContainer container, bool addTimeStamp = false);
|
||||
ErrorCode revokeClient(const QString &serverId, const int index, const DockerContainer container);
|
||||
ErrorCode revokeClient(const QString &serverId, const ContainerConfig &containerConfig, const DockerContainer container);
|
||||
|
||||
private:
|
||||
bool isClientExists(const QString &clientId, const QJsonArray &clientsTable);
|
||||
int clientIndexById(const QString &clientId, const QJsonArray &clientsTable);
|
||||
void migration(const QByteArray &clientsTableString, QJsonArray &clientsTable);
|
||||
|
||||
ErrorCode revokeOpenVpn(const int row, const DockerContainer container, const ServerCredentials &credentials, const int serverIndex,
|
||||
ErrorCode revokeOpenVpn(const int row, const DockerContainer container, const ServerCredentials &credentials,
|
||||
SshSession* sshSession, QJsonArray &clientsTable);
|
||||
ErrorCode revokeWireGuard(const int row, const DockerContainer container, const ServerCredentials &credentials,
|
||||
SshSession* sshSession, QJsonArray &clientsTable);
|
||||
@@ -73,4 +73,3 @@ private:
|
||||
};
|
||||
|
||||
#endif // USERSCONTROLLER_H
|
||||
|
||||
|
||||
@@ -1,81 +1,268 @@
|
||||
#include "serversController.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
|
||||
#include "core/models/serverDescription.h"
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#endif
|
||||
|
||||
|
||||
ServersController::ServersController(SecureServersRepository* serversRepository,
|
||||
SecureAppSettingsRepository* appSettingsRepository,
|
||||
QObject *parent)
|
||||
ServersController::ServersController(SecureServersRepository *serversRepository,
|
||||
SecureAppSettingsRepository *appSettingsRepository, QObject *parent)
|
||||
: QObject(parent), m_serversRepository(serversRepository), m_appSettingsRepository(appSettingsRepository)
|
||||
{
|
||||
recomputeGatewayStacks();
|
||||
ensureDefaultServerValid();
|
||||
}
|
||||
|
||||
void ServersController::addServer(const ServerConfig &server)
|
||||
void ServersController::ensureDefaultServerValid()
|
||||
{
|
||||
m_serversRepository->addServer(server);
|
||||
}
|
||||
|
||||
void ServersController::editServer(int index, const ServerConfig &server)
|
||||
{
|
||||
m_serversRepository->editServer(index, server);
|
||||
}
|
||||
|
||||
void ServersController::removeServer(int index)
|
||||
{
|
||||
m_serversRepository->removeServer(index);
|
||||
}
|
||||
|
||||
void ServersController::setDefaultServerIndex(int index)
|
||||
{
|
||||
m_serversRepository->setDefaultServer(index);
|
||||
}
|
||||
|
||||
void ServersController::setDefaultContainer(int serverIndex, DockerContainer container)
|
||||
{
|
||||
m_serversRepository->setDefaultContainer(serverIndex, container);
|
||||
}
|
||||
|
||||
void ServersController::updateContainerConfig(int serverIndex, DockerContainer container, const ContainerConfig &config)
|
||||
{
|
||||
m_serversRepository->setContainerConfig(serverIndex, container, config);
|
||||
}
|
||||
|
||||
void ServersController::clearCachedProfile(int serverIndex, DockerContainer container)
|
||||
{
|
||||
m_serversRepository->clearLastConnectionConfig(serverIndex, container);
|
||||
}
|
||||
|
||||
QJsonArray ServersController::getServersArray() const
|
||||
{
|
||||
QJsonArray result;
|
||||
QVector<ServerConfig> servers = m_serversRepository->servers();
|
||||
for (const ServerConfig& server : servers) {
|
||||
result.append(server.toJson());
|
||||
if (!getServersCount()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString defaultId = getDefaultServerId();
|
||||
if (!defaultId.isEmpty() && indexOfServerId(defaultId) >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString firstId = getServerId(0);
|
||||
if (!firstId.isEmpty()) {
|
||||
setDefaultServer(firstId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QVector<ServerConfig> ServersController::getServers() const
|
||||
bool ServersController::renameServer(const QString &serverId, const QString &name)
|
||||
{
|
||||
return m_serversRepository->servers();
|
||||
const serverConfigUtils::ConfigType kind = m_serversRepository->serverKind(serverId);
|
||||
switch (kind) {
|
||||
case serverConfigUtils::ConfigType::SelfHostedAdmin: {
|
||||
auto cfg = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!cfg.has_value()) return false;
|
||||
cfg->description = name;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return true;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::SelfHostedUser: {
|
||||
auto cfg = m_serversRepository->selfHostedUserConfig(serverId);
|
||||
if (!cfg.has_value()) return false;
|
||||
cfg->description = name;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return true;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::Native: {
|
||||
auto cfg = m_serversRepository->nativeConfig(serverId);
|
||||
if (!cfg.has_value()) return false;
|
||||
cfg->description = name;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return true;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV2:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV3:
|
||||
case serverConfigUtils::ConfigType::ExternalPremium: {
|
||||
auto cfg = m_serversRepository->apiV2Config(serverId);
|
||||
if (!cfg.has_value()) return false;
|
||||
cfg->name = name;
|
||||
cfg->nameOverriddenByUser = true;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return true;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV1:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV2:
|
||||
case serverConfigUtils::ConfigType::Invalid:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ContainerConfig ServersController::getContainerConfig(int serverIndex, DockerContainer container) const
|
||||
void ServersController::removeServer(const QString &serverId)
|
||||
{
|
||||
return m_serversRepository->containerConfig(serverIndex, container);
|
||||
m_serversRepository->removeServer(serverId);
|
||||
}
|
||||
|
||||
void ServersController::setDefaultServer(const QString &serverId)
|
||||
{
|
||||
m_serversRepository->setDefaultServer(serverId);
|
||||
}
|
||||
|
||||
void ServersController::setDefaultContainer(const QString &serverId, DockerContainer container)
|
||||
{
|
||||
const serverConfigUtils::ConfigType kind = m_serversRepository->serverKind(serverId);
|
||||
switch (kind) {
|
||||
case serverConfigUtils::ConfigType::SelfHostedAdmin: {
|
||||
auto cfg = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!cfg.has_value()) return;
|
||||
cfg->defaultContainer = container;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::SelfHostedUser: {
|
||||
auto cfg = m_serversRepository->selfHostedUserConfig(serverId);
|
||||
if (!cfg.has_value()) return;
|
||||
cfg->defaultContainer = container;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::Native: {
|
||||
auto cfg = m_serversRepository->nativeConfig(serverId);
|
||||
if (!cfg.has_value()) return;
|
||||
cfg->defaultContainer = container;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV2:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV3:
|
||||
case serverConfigUtils::ConfigType::ExternalPremium: {
|
||||
auto cfg = m_serversRepository->apiV2Config(serverId);
|
||||
if (!cfg.has_value()) return;
|
||||
cfg->defaultContainer = container;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV1:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV2:
|
||||
case serverConfigUtils::ConfigType::Invalid:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QVector<ServerDescription> ServersController::buildServerDescriptions(bool isAmneziaDnsEnabled) const
|
||||
{
|
||||
QVector<ServerDescription> out;
|
||||
const QVector<QString> ids = m_serversRepository->orderedServerIds();
|
||||
out.reserve(ids.size());
|
||||
|
||||
for (const QString &id : ids) {
|
||||
ServerDescription d;
|
||||
using Kind = serverConfigUtils::ConfigType;
|
||||
const Kind kind = m_serversRepository->serverKind(id);
|
||||
switch (kind) {
|
||||
case Kind::SelfHostedAdmin: {
|
||||
const auto cfg = m_serversRepository->selfHostedAdminConfig(id);
|
||||
if (!cfg) {
|
||||
continue;
|
||||
}
|
||||
d = buildServerDescription(*cfg, isAmneziaDnsEnabled);
|
||||
break;
|
||||
}
|
||||
case Kind::SelfHostedUser: {
|
||||
const auto cfg = m_serversRepository->selfHostedUserConfig(id);
|
||||
if (!cfg) {
|
||||
continue;
|
||||
}
|
||||
d = buildServerDescription(*cfg, isAmneziaDnsEnabled);
|
||||
break;
|
||||
}
|
||||
case Kind::Native: {
|
||||
const auto cfg = m_serversRepository->nativeConfig(id);
|
||||
if (!cfg) {
|
||||
continue;
|
||||
}
|
||||
d = buildServerDescription(*cfg, isAmneziaDnsEnabled);
|
||||
break;
|
||||
}
|
||||
case Kind::AmneziaPremiumV2:
|
||||
case Kind::AmneziaFreeV3:
|
||||
case Kind::ExternalPremium: {
|
||||
const auto cfg = m_serversRepository->apiV2Config(id);
|
||||
if (!cfg) {
|
||||
continue;
|
||||
}
|
||||
d = buildServerDescription(*cfg, isAmneziaDnsEnabled);
|
||||
break;
|
||||
}
|
||||
case Kind::AmneziaPremiumV1:
|
||||
case Kind::AmneziaFreeV2: {
|
||||
const auto cfg = m_serversRepository->legacyApiConfig(id);
|
||||
if (!cfg) {
|
||||
continue;
|
||||
}
|
||||
d = buildServerDescription(*cfg, isAmneziaDnsEnabled);
|
||||
break;
|
||||
}
|
||||
case Kind::Invalid:
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
d.serverId = id;
|
||||
out.append(d);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
QMap<DockerContainer, ContainerConfig> ServersController::getServerContainersMap(const QString &serverId) const
|
||||
{
|
||||
switch (m_serversRepository->serverKind(serverId)) {
|
||||
case serverConfigUtils::ConfigType::SelfHostedAdmin: {
|
||||
const auto cfg = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
return cfg.has_value() ? cfg->containers : QMap<DockerContainer, ContainerConfig>{};
|
||||
}
|
||||
case serverConfigUtils::ConfigType::SelfHostedUser: {
|
||||
const auto cfg = m_serversRepository->selfHostedUserConfig(serverId);
|
||||
return cfg.has_value() ? cfg->containers : QMap<DockerContainer, ContainerConfig>{};
|
||||
}
|
||||
case serverConfigUtils::ConfigType::Native: {
|
||||
const auto cfg = m_serversRepository->nativeConfig(serverId);
|
||||
return cfg.has_value() ? cfg->containers : QMap<DockerContainer, ContainerConfig>{};
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV2:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV3:
|
||||
case serverConfigUtils::ConfigType::ExternalPremium: {
|
||||
const auto cfg = m_serversRepository->apiV2Config(serverId);
|
||||
return cfg.has_value() ? cfg->containers : QMap<DockerContainer, ContainerConfig>{};
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV1:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV2: {
|
||||
const auto cfg = m_serversRepository->legacyApiConfig(serverId);
|
||||
return cfg.has_value() ? cfg->containers : QMap<DockerContainer, ContainerConfig>{};
|
||||
}
|
||||
case serverConfigUtils::ConfigType::Invalid:
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
DockerContainer ServersController::getDefaultContainer(const QString &serverId) const
|
||||
{
|
||||
switch (m_serversRepository->serverKind(serverId)) {
|
||||
case serverConfigUtils::ConfigType::SelfHostedAdmin: {
|
||||
const auto cfg = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
return cfg.has_value() ? cfg->defaultContainer : DockerContainer::None;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::SelfHostedUser: {
|
||||
const auto cfg = m_serversRepository->selfHostedUserConfig(serverId);
|
||||
return cfg.has_value() ? cfg->defaultContainer : DockerContainer::None;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::Native: {
|
||||
const auto cfg = m_serversRepository->nativeConfig(serverId);
|
||||
return cfg.has_value() ? cfg->defaultContainer : DockerContainer::None;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV2:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV3:
|
||||
case serverConfigUtils::ConfigType::ExternalPremium: {
|
||||
const auto cfg = m_serversRepository->apiV2Config(serverId);
|
||||
return cfg.has_value() ? cfg->defaultContainer : DockerContainer::None;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV1:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV2: {
|
||||
const auto cfg = m_serversRepository->legacyApiConfig(serverId);
|
||||
return cfg.has_value() ? cfg->defaultContainer : DockerContainer::None;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::Invalid:
|
||||
default:
|
||||
return DockerContainer::None;
|
||||
}
|
||||
}
|
||||
|
||||
ContainerConfig ServersController::getContainerConfig(const QString &serverId, DockerContainer container) const
|
||||
{
|
||||
return getServerContainersMap(serverId).value(container);
|
||||
}
|
||||
|
||||
int ServersController::getDefaultServerIndex() const
|
||||
@@ -83,114 +270,131 @@ int ServersController::getDefaultServerIndex() const
|
||||
return m_serversRepository->defaultServerIndex();
|
||||
}
|
||||
|
||||
QString ServersController::getDefaultServerId() const
|
||||
{
|
||||
return m_serversRepository->defaultServerId();
|
||||
}
|
||||
|
||||
int ServersController::getServersCount() const
|
||||
{
|
||||
return m_serversRepository->serversCount();
|
||||
}
|
||||
|
||||
ServerConfig ServersController::getServerConfig(int serverIndex) const
|
||||
QString ServersController::getServerId(int serverIndex) const
|
||||
{
|
||||
return m_serversRepository->server(serverIndex);
|
||||
return m_serversRepository->serverIdAt(serverIndex);
|
||||
}
|
||||
|
||||
ServerCredentials ServersController::getServerCredentials(int serverIndex) const
|
||||
int ServersController::indexOfServerId(const QString &serverId) const
|
||||
{
|
||||
return m_serversRepository->serverCredentials(serverIndex);
|
||||
return m_serversRepository->indexOfServerId(serverId);
|
||||
}
|
||||
|
||||
QPair<QString, QString> ServersController::getDnsPair(int serverIndex, bool isAmneziaDnsEnabled) const
|
||||
QString ServersController::notificationDisplayName(const QString &serverId) const
|
||||
{
|
||||
ServerConfig serverConfig = m_serversRepository->server(serverIndex);
|
||||
return serverConfig.getDnsPair(isAmneziaDnsEnabled,
|
||||
m_appSettingsRepository->primaryDns(),
|
||||
m_appSettingsRepository->secondaryDns());
|
||||
}
|
||||
if (serverId.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
ServersController::GatewayStacksData ServersController::gatewayStacks() const
|
||||
{
|
||||
return m_gatewayStacks;
|
||||
}
|
||||
|
||||
void ServersController::recomputeGatewayStacks()
|
||||
{
|
||||
GatewayStacksData computed;
|
||||
bool hasNewTags = false;
|
||||
QVector<ServerConfig> servers = m_serversRepository->servers();
|
||||
|
||||
for (const ServerConfig& serverConfig : servers) {
|
||||
if (serverConfig.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = serverConfig.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) continue;
|
||||
const QString userCountryCode = apiV2->apiConfig.userCountryCode;
|
||||
const QString serviceType = apiV2->serviceType();
|
||||
|
||||
if (!userCountryCode.isEmpty()) {
|
||||
if (!m_gatewayStacks.userCountryCodes.contains(userCountryCode)) {
|
||||
hasNewTags = true;
|
||||
}
|
||||
computed.userCountryCodes.insert(userCountryCode);
|
||||
}
|
||||
|
||||
if (!serviceType.isEmpty()) {
|
||||
if (!m_gatewayStacks.serviceTypes.contains(serviceType)) {
|
||||
hasNewTags = true;
|
||||
}
|
||||
computed.serviceTypes.insert(serviceType);
|
||||
using Kind = serverConfigUtils::ConfigType;
|
||||
switch (m_serversRepository->serverKind(serverId)) {
|
||||
case Kind::SelfHostedAdmin: {
|
||||
if (const auto cfg = m_serversRepository->selfHostedAdminConfig(serverId)) {
|
||||
if (!cfg->displayName.isEmpty()) {
|
||||
return cfg->displayName;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_gatewayStacks = std::move(computed);
|
||||
if (hasNewTags) {
|
||||
emit gatewayStacksExpanded();
|
||||
}
|
||||
}
|
||||
|
||||
bool ServersController::GatewayStacksData::operator==(const GatewayStacksData &other) const
|
||||
{
|
||||
return userCountryCodes == other.userCountryCodes && serviceTypes == other.serviceTypes;
|
||||
}
|
||||
|
||||
QJsonObject ServersController::GatewayStacksData::toJson() const
|
||||
{
|
||||
QJsonObject json;
|
||||
|
||||
QJsonArray userCountryCodesArray;
|
||||
for (const QString &code : userCountryCodes) {
|
||||
userCountryCodesArray.append(code);
|
||||
}
|
||||
json[apiDefs::key::userCountryCode] = userCountryCodesArray;
|
||||
|
||||
QJsonArray serviceTypesArray;
|
||||
for (const QString &type : serviceTypes) {
|
||||
serviceTypesArray.append(type);
|
||||
}
|
||||
json[apiDefs::key::serviceType] = serviceTypesArray;
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
bool ServersController::isServerFromApiAlreadyExists(const QString &userCountryCode, const QString &serviceType, const QString &serviceProtocol) const
|
||||
{
|
||||
QVector<ServerConfig> servers = m_serversRepository->servers();
|
||||
for (const ServerConfig& serverConfig : servers) {
|
||||
if (serverConfig.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = serverConfig.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) return false;
|
||||
if (apiV2->apiConfig.userCountryCode == userCountryCode
|
||||
&& apiV2->serviceType() == serviceType
|
||||
&& apiV2->serviceProtocol() == serviceProtocol) {
|
||||
return true;
|
||||
case Kind::SelfHostedUser: {
|
||||
if (const auto cfg = m_serversRepository->selfHostedUserConfig(serverId)) {
|
||||
if (!cfg->displayName.isEmpty()) {
|
||||
return cfg->displayName;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Kind::Native: {
|
||||
if (const auto cfg = m_serversRepository->nativeConfig(serverId)) {
|
||||
if (!cfg->displayName.isEmpty()) {
|
||||
return cfg->displayName;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Kind::AmneziaPremiumV2:
|
||||
case Kind::AmneziaFreeV3:
|
||||
case Kind::ExternalPremium: {
|
||||
if (const auto cfg = m_serversRepository->apiV2Config(serverId)) {
|
||||
if (!cfg->displayName.isEmpty()) {
|
||||
return cfg->displayName;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Kind::AmneziaPremiumV1:
|
||||
case Kind::AmneziaFreeV2: {
|
||||
if (const auto cfg = m_serversRepository->legacyApiConfig(serverId)) {
|
||||
if (!cfg->displayName.isEmpty()) {
|
||||
return cfg->displayName;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const int idx = indexOfServerId(serverId);
|
||||
if (idx >= 0) {
|
||||
return QString::number(idx + 1);
|
||||
}
|
||||
return serverId;
|
||||
}
|
||||
|
||||
std::optional<ApiV2ServerConfig> ServersController::apiV2Config(const QString &serverId) const
|
||||
{
|
||||
return m_serversRepository->apiV2Config(serverId);
|
||||
}
|
||||
|
||||
std::optional<SelfHostedAdminServerConfig> ServersController::selfHostedAdminConfig(const QString &serverId) const
|
||||
{
|
||||
return m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
}
|
||||
|
||||
ServerCredentials ServersController::getServerCredentials(const QString &serverId) const
|
||||
{
|
||||
const auto cfg = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (cfg.has_value()) {
|
||||
const ServerCredentials creds = cfg->credentials();
|
||||
if (creds.isValid()) {
|
||||
return creds;
|
||||
}
|
||||
}
|
||||
return ServerCredentials {};
|
||||
}
|
||||
|
||||
bool ServersController::isServerFromApiAlreadyExists(const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &serviceProtocol) const
|
||||
{
|
||||
const QVector<QString> ids = m_serversRepository->orderedServerIds();
|
||||
for (const QString &id : ids) {
|
||||
const auto apiV2 = m_serversRepository->apiV2Config(id);
|
||||
if (!apiV2.has_value()) {
|
||||
continue;
|
||||
}
|
||||
if (apiV2->apiConfig.userCountryCode == userCountryCode && apiV2->serviceType() == serviceType
|
||||
&& apiV2->serviceProtocol() == serviceProtocol) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ServersController::hasInstalledContainers(int serverIndex) const
|
||||
bool ServersController::hasInstalledContainers(const QString &serverId) const
|
||||
{
|
||||
ServerConfig serverConfig = m_serversRepository->server(serverIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containers = serverConfig.containers();
|
||||
const QMap<DockerContainer, ContainerConfig> containers = getServerContainersMap(serverId);
|
||||
|
||||
for (auto it = containers.begin(); it != containers.end(); ++it) {
|
||||
DockerContainer container = it.key();
|
||||
if (ContainerUtils::containerService(container) == ServiceType::Vpn) {
|
||||
@@ -203,3 +407,8 @@ bool ServersController::hasInstalledContainers(int serverIndex) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ServersController::isLegacyApiV1Server(const QString &serverId) const
|
||||
{
|
||||
return !serverId.isEmpty()
|
||||
&& serverConfigUtils::isLegacyApiSubscription(m_serversRepository->serverKind(serverId));
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef SERVERSCONTROLLER_H
|
||||
#define SERVERSCONTROLLER_H
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <QObject>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QSet>
|
||||
#include <QVector>
|
||||
#include <QMap>
|
||||
|
||||
#include <QPair>
|
||||
|
||||
@@ -17,34 +17,18 @@
|
||||
#include "core/utils/commonStructs.h"
|
||||
#include "core/repositories/secureServersRepository.h"
|
||||
#include "core/repositories/secureAppSettingsRepository.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
|
||||
class SshSession;
|
||||
class InstallController;
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
/**
|
||||
* @brief Core business logic controller for server operations
|
||||
*
|
||||
* This controller contains pure business logic for managing servers.
|
||||
*/
|
||||
class ServersController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
struct GatewayStacksData
|
||||
{
|
||||
QSet<QString> userCountryCodes;
|
||||
QSet<QString> serviceTypes;
|
||||
|
||||
bool isEmpty() const { return userCountryCodes.isEmpty() && serviceTypes.isEmpty(); }
|
||||
bool operator==(const GatewayStacksData &other) const;
|
||||
QJsonObject toJson() const;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit ServersController(SecureServersRepository* serversRepository,
|
||||
SecureAppSettingsRepository* appSettingsRepository = nullptr,
|
||||
@@ -52,44 +36,38 @@ public:
|
||||
~ServersController() = default;
|
||||
|
||||
// Server management
|
||||
void addServer(const ServerConfig &server);
|
||||
void editServer(int index, const ServerConfig &server);
|
||||
void removeServer(int index);
|
||||
void setDefaultServerIndex(int index);
|
||||
bool renameServer(const QString &serverId, const QString &name);
|
||||
void removeServer(const QString &serverId);
|
||||
void setDefaultServer(const QString &serverId);
|
||||
|
||||
// Container management
|
||||
void setDefaultContainer(int serverIndex, DockerContainer container);
|
||||
void updateContainerConfig(int serverIndex, DockerContainer container, const ContainerConfig &config);
|
||||
|
||||
// Cache management
|
||||
void clearCachedProfile(int serverIndex, DockerContainer container);
|
||||
void setDefaultContainer(const QString &serverId, DockerContainer container);
|
||||
|
||||
// Getters
|
||||
QJsonArray getServersArray() const;
|
||||
QVector<ServerConfig> getServers() const;
|
||||
QVector<ServerDescription> buildServerDescriptions(bool isAmneziaDnsEnabled) const;
|
||||
int getDefaultServerIndex() const;
|
||||
QString getDefaultServerId() const;
|
||||
int getServersCount() const;
|
||||
ServerConfig getServerConfig(int serverIndex) const;
|
||||
ServerCredentials getServerCredentials(int serverIndex) const;
|
||||
ContainerConfig getContainerConfig(int serverIndex, DockerContainer container) const;
|
||||
QPair<QString, QString> getDnsPair(int serverIndex, bool isAmneziaDnsEnabled) const;
|
||||
|
||||
GatewayStacksData gatewayStacks() const;
|
||||
QString getServerId(int serverIndex) const;
|
||||
int indexOfServerId(const QString &serverId) const;
|
||||
QString notificationDisplayName(const QString &serverId) const;
|
||||
std::optional<ApiV2ServerConfig> apiV2Config(const QString &serverId) const;
|
||||
std::optional<SelfHostedAdminServerConfig> selfHostedAdminConfig(const QString &serverId) const;
|
||||
ServerCredentials getServerCredentials(const QString &serverId) const;
|
||||
QMap<DockerContainer, ContainerConfig> getServerContainersMap(const QString &serverId) const;
|
||||
DockerContainer getDefaultContainer(const QString &serverId) const;
|
||||
ContainerConfig getContainerConfig(const QString &serverId, DockerContainer container) const;
|
||||
|
||||
// Validation
|
||||
bool isServerFromApiAlreadyExists(const QString &userCountryCode, const QString &serviceType, const QString &serviceProtocol) const;
|
||||
bool hasInstalledContainers(int serverIndex) const;
|
||||
|
||||
signals:
|
||||
void gatewayStacksExpanded();
|
||||
|
||||
public slots:
|
||||
void recomputeGatewayStacks();
|
||||
bool hasInstalledContainers(const QString &serverId) const;
|
||||
bool isLegacyApiV1Server(const QString &serverId) const;
|
||||
|
||||
private:
|
||||
void ensureDefaultServerValid();
|
||||
|
||||
SecureServersRepository* m_serversRepository;
|
||||
SecureAppSettingsRepository* m_appSettingsRepository;
|
||||
GatewayStacksData m_gatewayStacks;
|
||||
};
|
||||
|
||||
#endif // SERVERSCONTROLLER_H
|
||||
|
||||
@@ -179,12 +179,9 @@ QString SettingsController::getAppVersion() const
|
||||
|
||||
void SettingsController::clearSettings()
|
||||
{
|
||||
int serverCount = m_serversRepository->serversCount();
|
||||
|
||||
m_appSettingsRepository->clearSettings();
|
||||
|
||||
m_serversRepository->setServersArray(QJsonArray());
|
||||
m_serversRepository->setDefaultServer(0);
|
||||
|
||||
m_serversRepository->clearServers();
|
||||
|
||||
emit siteSplitTunnelingRouteModeChanged(RouteMode::VpnOnlyForwardSites);
|
||||
emit siteSplitTunnelingToggled(false);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
#include "apiV1ServerConfig.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
|
||||
using namespace ContainerEnumNS;
|
||||
|
||||
bool ApiV1ServerConfig::isPremium() const
|
||||
{
|
||||
constexpr QLatin1String premiumV1Endpoint(PREM_V1_ENDPOINT);
|
||||
return apiEndpoint.contains(premiumV1Endpoint);
|
||||
}
|
||||
|
||||
bool ApiV1ServerConfig::isFree() const
|
||||
{
|
||||
constexpr QLatin1String freeV2Endpoint(FREE_V2_ENDPOINT);
|
||||
return apiEndpoint.contains(freeV2Endpoint);
|
||||
}
|
||||
|
||||
QString ApiV1ServerConfig::vpnKey() const
|
||||
{
|
||||
QJsonObject json = toJson();
|
||||
return apiUtils::getPremiumV1VpnKey(json);
|
||||
}
|
||||
|
||||
bool ApiV1ServerConfig::hasContainers() const
|
||||
{
|
||||
return !containers.isEmpty();
|
||||
}
|
||||
|
||||
ContainerConfig ApiV1ServerConfig::containerConfig(DockerContainer container) const
|
||||
{
|
||||
if (!containers.contains(container)) {
|
||||
return ContainerConfig{};
|
||||
}
|
||||
return containers.value(container);
|
||||
}
|
||||
|
||||
QJsonObject ApiV1ServerConfig::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
|
||||
if (!name.isEmpty()) {
|
||||
obj[configKey::name] = name;
|
||||
}
|
||||
if (!description.isEmpty()) {
|
||||
obj[configKey::description] = description;
|
||||
}
|
||||
if (!protocol.isEmpty()) {
|
||||
obj[apiDefs::key::protocol] = protocol;
|
||||
}
|
||||
if (!apiEndpoint.isEmpty()) {
|
||||
obj[apiDefs::key::apiEndpoint] = apiEndpoint;
|
||||
}
|
||||
if (!apiKey.isEmpty()) {
|
||||
obj[apiDefs::key::apiKey] = apiKey;
|
||||
}
|
||||
|
||||
obj[configKey::configVersion] = configVersion;
|
||||
|
||||
if (!hostName.isEmpty()) {
|
||||
obj[configKey::hostName] = hostName;
|
||||
}
|
||||
|
||||
QJsonArray containersArray;
|
||||
for (auto it = containers.begin(); it != containers.end(); ++it) {
|
||||
QJsonObject containerObj = it.value().toJson();
|
||||
containersArray.append(containerObj);
|
||||
}
|
||||
if (!containersArray.isEmpty()) {
|
||||
obj[configKey::containers] = containersArray;
|
||||
}
|
||||
|
||||
if (defaultContainer != DockerContainer::None) {
|
||||
obj[configKey::defaultContainer] = ContainerUtils::containerToString(defaultContainer);
|
||||
}
|
||||
|
||||
if (!dns1.isEmpty()) {
|
||||
obj[configKey::dns1] = dns1;
|
||||
}
|
||||
if (!dns2.isEmpty()) {
|
||||
obj[configKey::dns2] = dns2;
|
||||
}
|
||||
|
||||
if (crc > 0) {
|
||||
obj[configKey::crc] = crc;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
ApiV1ServerConfig ApiV1ServerConfig::fromJson(const QJsonObject& json)
|
||||
{
|
||||
ApiV1ServerConfig config;
|
||||
|
||||
config.name = json.value(configKey::name).toString();
|
||||
config.description = json.value(configKey::description).toString();
|
||||
config.protocol = json.value(apiDefs::key::protocol).toString();
|
||||
config.apiEndpoint = json.value(apiDefs::key::apiEndpoint).toString();
|
||||
config.apiKey = json.value(apiDefs::key::apiKey).toString();
|
||||
config.configVersion = json.value(configKey::configVersion).toInt(1);
|
||||
config.hostName = json.value(configKey::hostName).toString();
|
||||
|
||||
QJsonArray containersArray = json.value(configKey::containers).toArray();
|
||||
for (const QJsonValue& val : containersArray) {
|
||||
QJsonObject containerObj = val.toObject();
|
||||
ContainerConfig containerConfig = ContainerConfig::fromJson(containerObj);
|
||||
|
||||
QString containerStr = containerObj.value(configKey::container).toString();
|
||||
DockerContainer container = ContainerUtils::containerFromString(containerStr);
|
||||
|
||||
config.containers.insert(container, containerConfig);
|
||||
}
|
||||
|
||||
QString defaultContainerStr = json.value(configKey::defaultContainer).toString();
|
||||
config.defaultContainer = ContainerUtils::containerFromString(defaultContainerStr);
|
||||
|
||||
config.dns1 = json.value(configKey::dns1).toString();
|
||||
config.dns2 = json.value(configKey::dns2).toString();
|
||||
|
||||
config.crc = json.value(configKey::crc).toInt(0);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
} // namespace amnezia
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
#ifndef APIV1SERVERCONFIG_H
|
||||
#define APIV1SERVERCONFIG_H
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QMap>
|
||||
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
|
||||
using namespace ContainerEnumNS;
|
||||
|
||||
struct ApiV1ServerConfig {
|
||||
QString description;
|
||||
QString hostName;
|
||||
QMap<DockerContainer, ContainerConfig> containers;
|
||||
DockerContainer defaultContainer;
|
||||
QString dns1;
|
||||
QString dns2;
|
||||
|
||||
QString name;
|
||||
QString protocol;
|
||||
QString apiEndpoint;
|
||||
QString apiKey;
|
||||
int crc;
|
||||
int configVersion;
|
||||
|
||||
bool isPremium() const;
|
||||
bool isFree() const;
|
||||
QString vpnKey() const;
|
||||
bool hasContainers() const;
|
||||
ContainerConfig containerConfig(DockerContainer container) const;
|
||||
QJsonObject toJson() const;
|
||||
static ApiV1ServerConfig fromJson(const QJsonObject& json);
|
||||
};
|
||||
|
||||
} // namespace amnezia
|
||||
|
||||
#endif // APIV1SERVERCONFIG_H
|
||||
|
||||
@@ -80,6 +80,9 @@ QJsonObject ApiV2ServerConfig::toJson() const
|
||||
if (!description.isEmpty()) {
|
||||
obj[configKey::description] = description;
|
||||
}
|
||||
if (!displayName.isEmpty()) {
|
||||
obj[configKey::displayName] = displayName;
|
||||
}
|
||||
|
||||
obj[configKey::configVersion] = configVersion;
|
||||
|
||||
@@ -131,6 +134,7 @@ ApiV2ServerConfig ApiV2ServerConfig::fromJson(const QJsonObject& json)
|
||||
config.name = json.value(configKey::name).toString();
|
||||
config.nameOverriddenByUser = json.value(configKey::nameOverriddenByUser).toBool(false);
|
||||
config.description = json.value(configKey::description).toString();
|
||||
config.displayName = json.value(configKey::displayName).toString();
|
||||
config.configVersion = json.value(configKey::configVersion).toInt(2);
|
||||
config.hostName = json.value(configKey::hostName).toString();
|
||||
|
||||
@@ -163,6 +167,10 @@ ApiV2ServerConfig ApiV2ServerConfig::fromJson(const QJsonObject& json)
|
||||
config.authData = AuthData::fromJson(authDataObj);
|
||||
}
|
||||
|
||||
if (config.displayName.isEmpty()) {
|
||||
config.displayName = config.name.isEmpty() ? config.description : config.name;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/models/api/apiConfig.h"
|
||||
#include "core/models/api/authData.h"
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
|
||||
@@ -21,6 +21,7 @@ using namespace ContainerEnumNS;
|
||||
|
||||
struct ApiV2ServerConfig {
|
||||
QString description;
|
||||
QString displayName;
|
||||
QString hostName;
|
||||
QMap<DockerContainer, ContainerConfig> containers;
|
||||
DockerContainer defaultContainer;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
|
||||
|
||||
43
client/core/models/api/legacyApiServerConfig.cpp
Normal file
43
client/core/models/api/legacyApiServerConfig.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "legacyApiServerConfig.h"
|
||||
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
|
||||
bool LegacyApiServerConfig::hasContainers() const
|
||||
{
|
||||
return !containers.isEmpty();
|
||||
}
|
||||
|
||||
ContainerConfig LegacyApiServerConfig::containerConfig(DockerContainer container) const
|
||||
{
|
||||
if (!containers.contains(container)) {
|
||||
return ContainerConfig{};
|
||||
}
|
||||
return containers.value(container);
|
||||
}
|
||||
|
||||
LegacyApiServerConfig LegacyApiServerConfig::fromJson(const QJsonObject &json)
|
||||
{
|
||||
LegacyApiServerConfig config;
|
||||
|
||||
config.name = json.value(configKey::name).toString();
|
||||
config.description = json.value(configKey::description).toString();
|
||||
config.displayName = json.value(configKey::displayName).toString();
|
||||
config.hostName = json.value(configKey::hostName).toString();
|
||||
|
||||
config.crc = json.value(configKey::crc).toInt(0);
|
||||
|
||||
config.configVersion = json.value(configKey::configVersion).toInt(1);
|
||||
config.apiEndpoint = json.value(apiDefs::key::apiEndpoint).toString();
|
||||
|
||||
if (config.displayName.isEmpty()) {
|
||||
config.displayName = config.name.isEmpty() ? config.description : config.name;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
} // namespace amnezia
|
||||
38
client/core/models/api/legacyApiServerConfig.h
Normal file
38
client/core/models/api/legacyApiServerConfig.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef LEGACYAPISERVERCONFIG_H
|
||||
#define LEGACYAPISERVERCONFIG_H
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QMap>
|
||||
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
|
||||
using namespace ContainerEnumNS;
|
||||
|
||||
struct LegacyApiServerConfig {
|
||||
QString description;
|
||||
QString displayName;
|
||||
QString hostName;
|
||||
QMap<DockerContainer, ContainerConfig> containers;
|
||||
DockerContainer defaultContainer = DockerContainer::None;
|
||||
QString dns1;
|
||||
QString dns2;
|
||||
|
||||
QString name;
|
||||
int crc = 0;
|
||||
|
||||
int configVersion = 0;
|
||||
QString apiEndpoint;
|
||||
|
||||
bool hasContainers() const;
|
||||
ContainerConfig containerConfig(DockerContainer container) const;
|
||||
static LegacyApiServerConfig fromJson(const QJsonObject &json);
|
||||
};
|
||||
|
||||
} // namespace amnezia
|
||||
|
||||
#endif // LEGACYAPISERVERCONFIG_H
|
||||
@@ -35,6 +35,9 @@ QJsonObject NativeServerConfig::toJson() const
|
||||
if (!description.isEmpty()) {
|
||||
obj[configKey::description] = this->description;
|
||||
}
|
||||
if (!displayName.isEmpty()) {
|
||||
obj[configKey::displayName] = displayName;
|
||||
}
|
||||
if (!hostName.isEmpty()) {
|
||||
obj[configKey::hostName] = hostName;
|
||||
}
|
||||
@@ -67,6 +70,7 @@ NativeServerConfig NativeServerConfig::fromJson(const QJsonObject& json)
|
||||
NativeServerConfig config;
|
||||
|
||||
config.description = json.value(configKey::description).toString();
|
||||
config.displayName = json.value(configKey::displayName).toString();
|
||||
config.hostName = json.value(configKey::hostName).toString();
|
||||
|
||||
QJsonArray containersArray = json.value(configKey::containers).toArray();
|
||||
@@ -86,6 +90,10 @@ NativeServerConfig NativeServerConfig::fromJson(const QJsonObject& json)
|
||||
config.dns1 = json.value(configKey::dns1).toString();
|
||||
config.dns2 = json.value(configKey::dns2).toString();
|
||||
|
||||
if (config.displayName.isEmpty()) {
|
||||
config.displayName = config.description.isEmpty() ? config.hostName : config.description;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ using namespace ContainerEnumNS;
|
||||
|
||||
struct NativeServerConfig {
|
||||
QString description;
|
||||
QString displayName;
|
||||
QString hostName;
|
||||
QMap<DockerContainer, ContainerConfig> containers;
|
||||
DockerContainer defaultContainer;
|
||||
|
||||
170
client/core/models/selfhosted/selfHostedAdminServerConfig.cpp
Normal file
170
client/core/models/selfhosted/selfHostedAdminServerConfig.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
#include "selfHostedAdminServerConfig.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
|
||||
using namespace ContainerEnumNS;
|
||||
|
||||
bool SelfHostedAdminServerConfig::hasCredentials() const
|
||||
{
|
||||
return !userName.isEmpty() && !password.isEmpty() && port > 0;
|
||||
}
|
||||
|
||||
bool SelfHostedAdminServerConfig::isReadOnly() const
|
||||
{
|
||||
return !hasCredentials();
|
||||
}
|
||||
|
||||
ServerCredentials SelfHostedAdminServerConfig::credentials() const
|
||||
{
|
||||
ServerCredentials creds;
|
||||
creds.hostName = hostName;
|
||||
creds.userName = userName;
|
||||
creds.secretData = password;
|
||||
creds.port = port;
|
||||
return creds;
|
||||
}
|
||||
|
||||
bool SelfHostedAdminServerConfig::hasContainers() const
|
||||
{
|
||||
return !containers.isEmpty();
|
||||
}
|
||||
|
||||
ContainerConfig SelfHostedAdminServerConfig::containerConfig(DockerContainer container) const
|
||||
{
|
||||
if (!containers.contains(container)) {
|
||||
return ContainerConfig{};
|
||||
}
|
||||
return containers.value(container);
|
||||
}
|
||||
|
||||
void SelfHostedAdminServerConfig::updateContainerConfig(DockerContainer container, const ContainerConfig &config)
|
||||
{
|
||||
containers[container] = config;
|
||||
}
|
||||
|
||||
void SelfHostedAdminServerConfig::clearCachedClientProfile(DockerContainer container)
|
||||
{
|
||||
if (ContainerUtils::containerService(container) == ServiceType::Other) {
|
||||
return;
|
||||
}
|
||||
|
||||
ContainerConfig cleared = containerConfig(container);
|
||||
cleared.protocolConfig.clearClientConfig();
|
||||
containers[container] = cleared;
|
||||
}
|
||||
|
||||
QPair<QString, QString> SelfHostedAdminServerConfig::getDnsPair(bool isAmneziaDnsEnabled, const QString &primaryDns,
|
||||
const QString &secondaryDns) const
|
||||
{
|
||||
QString d1 = dns1;
|
||||
QString d2 = dns2;
|
||||
const bool dnsOnServer = containers.contains(DockerContainer::Dns);
|
||||
|
||||
if (d1.isEmpty() || !NetworkUtilities::checkIPv4Format(d1)) {
|
||||
d1 = (isAmneziaDnsEnabled && dnsOnServer) ? protocols::dns::amneziaDnsIp : primaryDns;
|
||||
}
|
||||
if (d2.isEmpty() || !NetworkUtilities::checkIPv4Format(d2)) {
|
||||
d2 = secondaryDns;
|
||||
}
|
||||
return { d1, d2 };
|
||||
}
|
||||
|
||||
QJsonObject SelfHostedAdminServerConfig::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
|
||||
if (!description.isEmpty()) {
|
||||
obj[configKey::description] = this->description;
|
||||
}
|
||||
if (!displayName.isEmpty()) {
|
||||
obj[configKey::displayName] = displayName;
|
||||
}
|
||||
if (!hostName.isEmpty()) {
|
||||
obj[configKey::hostName] = hostName;
|
||||
}
|
||||
|
||||
QJsonArray containersArray;
|
||||
for (auto it = containers.begin(); it != containers.end(); ++it) {
|
||||
QJsonObject containerObj = it.value().toJson();
|
||||
containersArray.append(containerObj);
|
||||
}
|
||||
if (!containersArray.isEmpty()) {
|
||||
obj[configKey::containers] = containersArray;
|
||||
}
|
||||
|
||||
if (defaultContainer != DockerContainer::None) {
|
||||
obj[configKey::defaultContainer] = ContainerUtils::containerToString(defaultContainer);
|
||||
}
|
||||
|
||||
if (!dns1.isEmpty()) {
|
||||
obj[configKey::dns1] = dns1;
|
||||
}
|
||||
if (!dns2.isEmpty()) {
|
||||
obj[configKey::dns2] = dns2;
|
||||
}
|
||||
|
||||
if (!userName.isEmpty()) {
|
||||
obj[configKey::userName] = userName;
|
||||
}
|
||||
if (!password.isEmpty()) {
|
||||
obj[configKey::password] = password;
|
||||
}
|
||||
if (port > 0) {
|
||||
obj[configKey::port] = port;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
SelfHostedAdminServerConfig SelfHostedAdminServerConfig::fromJson(const QJsonObject &json)
|
||||
{
|
||||
SelfHostedAdminServerConfig config;
|
||||
|
||||
config.description = json.value(configKey::description).toString();
|
||||
config.displayName = json.value(configKey::displayName).toString();
|
||||
config.hostName = json.value(configKey::hostName).toString();
|
||||
|
||||
QJsonArray containersArray = json.value(configKey::containers).toArray();
|
||||
for (const QJsonValue &val : containersArray) {
|
||||
QJsonObject containerObj = val.toObject();
|
||||
ContainerConfig cc = ContainerConfig::fromJson(containerObj);
|
||||
|
||||
QString containerStr = containerObj.value(configKey::container).toString();
|
||||
DockerContainer container = ContainerUtils::containerFromString(containerStr);
|
||||
|
||||
config.containers.insert(container, cc);
|
||||
}
|
||||
|
||||
QString defaultContainerStr = json.value(configKey::defaultContainer).toString();
|
||||
config.defaultContainer = ContainerUtils::containerFromString(defaultContainerStr);
|
||||
|
||||
config.dns1 = json.value(configKey::dns1).toString();
|
||||
config.dns2 = json.value(configKey::dns2).toString();
|
||||
|
||||
config.userName = json.value(configKey::userName).toString();
|
||||
config.password = json.value(configKey::password).toString();
|
||||
if (json.contains(configKey::port)) {
|
||||
config.port = json.value(configKey::port).toInt();
|
||||
} else {
|
||||
config.port = 0;
|
||||
}
|
||||
|
||||
if (config.displayName.isEmpty()) {
|
||||
config.displayName = config.description.isEmpty() ? config.hostName : config.description;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
} // namespace amnezia
|
||||
53
client/core/models/selfhosted/selfHostedAdminServerConfig.h
Normal file
53
client/core/models/selfhosted/selfHostedAdminServerConfig.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef SELFHOSTEDADMINSERVERCONFIG_H
|
||||
#define SELFHOSTEDADMINSERVERCONFIG_H
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/utils/errorCodes.h"
|
||||
#include "core/utils/routeModes.h"
|
||||
#include "core/utils/commonStructs.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
|
||||
using namespace ContainerEnumNS;
|
||||
|
||||
struct SelfHostedAdminServerConfig {
|
||||
QString description;
|
||||
QString displayName;
|
||||
QString hostName;
|
||||
QMap<DockerContainer, ContainerConfig> containers;
|
||||
DockerContainer defaultContainer;
|
||||
QString dns1;
|
||||
QString dns2;
|
||||
|
||||
QString userName;
|
||||
QString password;
|
||||
int port = 0;
|
||||
|
||||
bool hasCredentials() const;
|
||||
bool isReadOnly() const;
|
||||
ServerCredentials credentials() const;
|
||||
bool hasContainers() const;
|
||||
ContainerConfig containerConfig(DockerContainer container) const;
|
||||
|
||||
void updateContainerConfig(DockerContainer container, const ContainerConfig &config);
|
||||
|
||||
void clearCachedClientProfile(DockerContainer container);
|
||||
|
||||
QPair<QString, QString> getDnsPair(bool isAmneziaDnsEnabled, const QString &primaryDns,
|
||||
const QString &secondaryDns) const;
|
||||
|
||||
QJsonObject toJson() const;
|
||||
static SelfHostedAdminServerConfig fromJson(const QJsonObject &json);
|
||||
};
|
||||
|
||||
} // namespace amnezia
|
||||
|
||||
#endif // SELFHOSTEDADMINSERVERCONFIG_H
|
||||
@@ -1,53 +1,40 @@
|
||||
#include "selfHostedServerConfig.h"
|
||||
#include "selfHostedUserServerConfig.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
|
||||
using namespace ContainerEnumNS;
|
||||
|
||||
bool SelfHostedServerConfig::hasCredentials() const
|
||||
bool SelfHostedUserServerConfig::hasCredentials() const
|
||||
{
|
||||
return userName.has_value() && password.has_value() && port.has_value();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SelfHostedServerConfig::isReadOnly() const
|
||||
bool SelfHostedUserServerConfig::isReadOnly() const
|
||||
{
|
||||
return !hasCredentials();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<ServerCredentials> SelfHostedServerConfig::credentials() const
|
||||
std::optional<ServerCredentials> SelfHostedUserServerConfig::credentials() const
|
||||
{
|
||||
if (!hasCredentials()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
ServerCredentials creds;
|
||||
creds.hostName = hostName;
|
||||
creds.userName = userName.value();
|
||||
creds.secretData = password.value();
|
||||
creds.port = port.value();
|
||||
|
||||
return creds;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool SelfHostedServerConfig::hasContainers() const
|
||||
bool SelfHostedUserServerConfig::hasContainers() const
|
||||
{
|
||||
return !containers.isEmpty();
|
||||
}
|
||||
|
||||
ContainerConfig SelfHostedServerConfig::containerConfig(DockerContainer container) const
|
||||
ContainerConfig SelfHostedUserServerConfig::containerConfig(DockerContainer container) const
|
||||
{
|
||||
if (!containers.contains(container)) {
|
||||
return ContainerConfig{};
|
||||
@@ -55,17 +42,20 @@ ContainerConfig SelfHostedServerConfig::containerConfig(DockerContainer containe
|
||||
return containers.value(container);
|
||||
}
|
||||
|
||||
QJsonObject SelfHostedServerConfig::toJson() const
|
||||
QJsonObject SelfHostedUserServerConfig::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
|
||||
|
||||
if (!description.isEmpty()) {
|
||||
obj[configKey::description] = this->description;
|
||||
}
|
||||
if (!displayName.isEmpty()) {
|
||||
obj[configKey::displayName] = displayName;
|
||||
}
|
||||
if (!hostName.isEmpty()) {
|
||||
obj[configKey::hostName] = hostName;
|
||||
}
|
||||
|
||||
|
||||
QJsonArray containersArray;
|
||||
for (auto it = containers.begin(); it != containers.end(); ++it) {
|
||||
QJsonObject containerObj = it.value().toJson();
|
||||
@@ -74,67 +64,51 @@ QJsonObject SelfHostedServerConfig::toJson() const
|
||||
if (!containersArray.isEmpty()) {
|
||||
obj[configKey::containers] = containersArray;
|
||||
}
|
||||
|
||||
|
||||
if (defaultContainer != DockerContainer::None) {
|
||||
obj[configKey::defaultContainer] = ContainerUtils::containerToString(defaultContainer);
|
||||
}
|
||||
|
||||
|
||||
if (!dns1.isEmpty()) {
|
||||
obj[configKey::dns1] = dns1;
|
||||
}
|
||||
if (!dns2.isEmpty()) {
|
||||
obj[configKey::dns2] = dns2;
|
||||
}
|
||||
|
||||
if (userName.has_value()) {
|
||||
obj[configKey::userName] = userName.value();
|
||||
}
|
||||
if (password.has_value()) {
|
||||
obj[configKey::password] = password.value();
|
||||
}
|
||||
if (port.has_value()) {
|
||||
obj[configKey::port] = port.value();
|
||||
}
|
||||
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
SelfHostedServerConfig SelfHostedServerConfig::fromJson(const QJsonObject& json)
|
||||
SelfHostedUserServerConfig SelfHostedUserServerConfig::fromJson(const QJsonObject &json)
|
||||
{
|
||||
SelfHostedServerConfig config;
|
||||
|
||||
SelfHostedUserServerConfig config;
|
||||
|
||||
config.description = json.value(configKey::description).toString();
|
||||
config.displayName = json.value(configKey::displayName).toString();
|
||||
config.hostName = json.value(configKey::hostName).toString();
|
||||
|
||||
|
||||
QJsonArray containersArray = json.value(configKey::containers).toArray();
|
||||
for (const QJsonValue& val : containersArray) {
|
||||
for (const QJsonValue &val : containersArray) {
|
||||
QJsonObject containerObj = val.toObject();
|
||||
ContainerConfig containerConfig = ContainerConfig::fromJson(containerObj);
|
||||
|
||||
ContainerConfig cc = ContainerConfig::fromJson(containerObj);
|
||||
|
||||
QString containerStr = containerObj.value(configKey::container).toString();
|
||||
DockerContainer container = ContainerUtils::containerFromString(containerStr);
|
||||
|
||||
config.containers.insert(container, containerConfig);
|
||||
|
||||
config.containers.insert(container, cc);
|
||||
}
|
||||
|
||||
|
||||
QString defaultContainerStr = json.value(configKey::defaultContainer).toString();
|
||||
config.defaultContainer = ContainerUtils::containerFromString(defaultContainerStr);
|
||||
|
||||
|
||||
config.dns1 = json.value(configKey::dns1).toString();
|
||||
config.dns2 = json.value(configKey::dns2).toString();
|
||||
|
||||
if (json.contains(configKey::userName)) {
|
||||
config.userName = json.value(configKey::userName).toString();
|
||||
|
||||
if (config.displayName.isEmpty()) {
|
||||
config.displayName = config.description.isEmpty() ? config.hostName : config.description;
|
||||
}
|
||||
if (json.contains(configKey::password)) {
|
||||
config.password = json.value(configKey::password).toString();
|
||||
}
|
||||
if (json.contains(configKey::port)) {
|
||||
config.port = json.value(configKey::port).toInt();
|
||||
}
|
||||
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
} // namespace amnezia
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef SELFHOSTEDSERVERCONFIG_H
|
||||
#define SELFHOSTEDSERVERCONFIG_H
|
||||
#ifndef SELFHOSTEDUSERSERVERCONFIG_H
|
||||
#define SELFHOSTEDUSERSERVERCONFIG_H
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QMap>
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/utils/errorCodes.h"
|
||||
#include "core/utils/routeModes.h"
|
||||
#include "core/utils/commonStructs.h"
|
||||
|
||||
namespace amnezia
|
||||
@@ -18,28 +16,24 @@ namespace amnezia
|
||||
|
||||
using namespace ContainerEnumNS;
|
||||
|
||||
struct SelfHostedServerConfig {
|
||||
struct SelfHostedUserServerConfig {
|
||||
QString description;
|
||||
QString displayName;
|
||||
QString hostName;
|
||||
QMap<DockerContainer, ContainerConfig> containers;
|
||||
DockerContainer defaultContainer;
|
||||
QString dns1;
|
||||
QString dns2;
|
||||
|
||||
std::optional<QString> userName;
|
||||
std::optional<QString> password;
|
||||
std::optional<int> port;
|
||||
|
||||
|
||||
bool hasCredentials() const;
|
||||
bool isReadOnly() const;
|
||||
std::optional<ServerCredentials> credentials() const;
|
||||
bool hasContainers() const;
|
||||
ContainerConfig containerConfig(DockerContainer container) const;
|
||||
QJsonObject toJson() const;
|
||||
static SelfHostedServerConfig fromJson(const QJsonObject& json);
|
||||
static SelfHostedUserServerConfig fromJson(const QJsonObject &json);
|
||||
};
|
||||
|
||||
} // namespace amnezia
|
||||
|
||||
#endif // SELFHOSTEDSERVERCONFIG_H
|
||||
|
||||
#endif // SELFHOSTEDUSERSERVERCONFIG_H
|
||||
@@ -1,234 +0,0 @@
|
||||
#include "serverConfig.h"
|
||||
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
#include "core/models/selfhosted/selfHostedServerConfig.h"
|
||||
#include "core/models/selfhosted/nativeServerConfig.h"
|
||||
#include "core/models/api/apiV1ServerConfig.h"
|
||||
#include "core/models/api/apiV2ServerConfig.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
|
||||
using namespace ContainerEnumNS;
|
||||
|
||||
QString ServerConfig::description() const
|
||||
{
|
||||
return std::visit([](const auto& v) { return v.description; }, data);
|
||||
}
|
||||
|
||||
QString ServerConfig::hostName() const
|
||||
{
|
||||
return std::visit([](const auto& v) { return v.hostName; }, data);
|
||||
}
|
||||
|
||||
QString ServerConfig::displayName() const
|
||||
{
|
||||
if (isApiV1()) {
|
||||
const auto *apiV1 = as<ApiV1ServerConfig>();
|
||||
return apiV1 ? apiV1->name : description();
|
||||
}
|
||||
if (isApiV2()) {
|
||||
const auto *apiV2 = as<ApiV2ServerConfig>();
|
||||
return apiV2 ? apiV2->name : description();
|
||||
}
|
||||
QString name = description();
|
||||
return name.isEmpty() ? hostName() : name;
|
||||
}
|
||||
|
||||
QMap<DockerContainer, ContainerConfig> ServerConfig::containers() const
|
||||
{
|
||||
return std::visit([](const auto& v) { return v.containers; }, data);
|
||||
}
|
||||
|
||||
DockerContainer ServerConfig::defaultContainer() const
|
||||
{
|
||||
return std::visit([](const auto& v) { return v.defaultContainer; }, data);
|
||||
}
|
||||
|
||||
QString ServerConfig::dns1() const
|
||||
{
|
||||
return std::visit([](const auto& v) { return v.dns1; }, data);
|
||||
}
|
||||
|
||||
QString ServerConfig::dns2() const
|
||||
{
|
||||
return std::visit([](const auto& v) { return v.dns2; }, data);
|
||||
}
|
||||
|
||||
bool ServerConfig::hasContainers() const
|
||||
{
|
||||
return std::visit([](const auto& v) { return v.hasContainers(); }, data);
|
||||
}
|
||||
|
||||
ContainerConfig ServerConfig::containerConfig(DockerContainer container) const
|
||||
{
|
||||
return std::visit([container](const auto& v) { return v.containerConfig(container); }, data);
|
||||
}
|
||||
|
||||
int ServerConfig::crc() const
|
||||
{
|
||||
return std::visit([](const auto& v) -> int {
|
||||
using T = std::decay_t<decltype(v)>;
|
||||
if constexpr (std::is_same_v<T, ApiV1ServerConfig> ||
|
||||
std::is_same_v<T, ApiV2ServerConfig>) {
|
||||
return v.crc;
|
||||
}
|
||||
return 0;
|
||||
}, data);
|
||||
}
|
||||
|
||||
int ServerConfig::configVersion() const
|
||||
{
|
||||
return std::visit([](const auto& v) -> int {
|
||||
using T = std::decay_t<decltype(v)>;
|
||||
if constexpr (std::is_same_v<T, ApiV1ServerConfig>) {
|
||||
return apiDefs::ConfigSource::Telegram;
|
||||
} else if constexpr (std::is_same_v<T, ApiV2ServerConfig>) {
|
||||
return apiDefs::ConfigSource::AmneziaGateway;
|
||||
}
|
||||
return 0; // SelfHostedServerConfig or NativeServerConfig
|
||||
}, data);
|
||||
}
|
||||
|
||||
bool ServerConfig::isSelfHosted() const
|
||||
{
|
||||
return std::holds_alternative<SelfHostedServerConfig>(data);
|
||||
}
|
||||
|
||||
bool ServerConfig::isNative() const
|
||||
{
|
||||
return std::holds_alternative<NativeServerConfig>(data);
|
||||
}
|
||||
|
||||
bool ServerConfig::isApiV1() const
|
||||
{
|
||||
return std::holds_alternative<ApiV1ServerConfig>(data);
|
||||
}
|
||||
|
||||
bool ServerConfig::isApiV2() const
|
||||
{
|
||||
return std::holds_alternative<ApiV2ServerConfig>(data);
|
||||
}
|
||||
|
||||
bool ServerConfig::isApiConfig() const
|
||||
{
|
||||
return isApiV1() || isApiV2();
|
||||
}
|
||||
|
||||
QJsonObject ServerConfig::toJson() const
|
||||
{
|
||||
return std::visit([](const auto& v) { return v.toJson(); }, data);
|
||||
}
|
||||
|
||||
ServerConfig ServerConfig::fromJson(const QJsonObject& json)
|
||||
{
|
||||
apiDefs::ConfigType configType = apiUtils::getConfigType(json);
|
||||
|
||||
switch (configType) {
|
||||
case apiDefs::ConfigType::SelfHosted: {
|
||||
bool hasThirdPartyConfig = false;
|
||||
QJsonArray containersArray = json.value(configKey::containers).toArray();
|
||||
for (const QJsonValue& val : containersArray) {
|
||||
QJsonObject containerObj = val.toObject();
|
||||
for (auto it = containerObj.begin(); it != containerObj.end(); ++it) {
|
||||
QString key = it.key();
|
||||
if (key != configKey::container) {
|
||||
QJsonObject protocolObj = it.value().toObject();
|
||||
if (protocolObj.contains(configKey::isThirdPartyConfig) &&
|
||||
protocolObj.value(configKey::isThirdPartyConfig).toBool()) {
|
||||
hasThirdPartyConfig = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasThirdPartyConfig) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasThirdPartyConfig) {
|
||||
return ServerConfig{NativeServerConfig::fromJson(json)};
|
||||
} else {
|
||||
return ServerConfig{SelfHostedServerConfig::fromJson(json)};
|
||||
}
|
||||
}
|
||||
case apiDefs::ConfigType::AmneziaPremiumV1:
|
||||
case apiDefs::ConfigType::AmneziaFreeV2:
|
||||
return ServerConfig{ApiV1ServerConfig::fromJson(json)};
|
||||
case apiDefs::ConfigType::AmneziaPremiumV2:
|
||||
case apiDefs::ConfigType::AmneziaFreeV3:
|
||||
case apiDefs::ConfigType::ExternalPremium:
|
||||
return ServerConfig{ApiV2ServerConfig::fromJson(json)};
|
||||
default: {
|
||||
// Check if any container has isThirdPartyConfig
|
||||
bool hasThirdPartyConfig = false;
|
||||
QJsonArray containersArray = json.value(configKey::containers).toArray();
|
||||
for (const QJsonValue& val : containersArray) {
|
||||
QJsonObject containerObj = val.toObject();
|
||||
// Check all protocol keys in the container object
|
||||
for (auto it = containerObj.begin(); it != containerObj.end(); ++it) {
|
||||
QString key = it.key();
|
||||
if (key != configKey::container) {
|
||||
QJsonObject protocolObj = it.value().toObject();
|
||||
if (protocolObj.contains(configKey::isThirdPartyConfig) &&
|
||||
protocolObj.value(configKey::isThirdPartyConfig).toBool()) {
|
||||
hasThirdPartyConfig = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasThirdPartyConfig) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasThirdPartyConfig) {
|
||||
return ServerConfig{NativeServerConfig::fromJson(json)};
|
||||
} else {
|
||||
return ServerConfig{SelfHostedServerConfig::fromJson(json)};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPair<QString, QString> ServerConfig::getDnsPair(bool isAmneziaDnsEnabled,
|
||||
const QString &primaryDns,
|
||||
const QString &secondaryDns) const
|
||||
{
|
||||
QPair<QString, QString> dns;
|
||||
|
||||
QMap<DockerContainer, ContainerConfig> serverContainers = containers();
|
||||
|
||||
bool isDnsContainerInstalled = false;
|
||||
for (auto it = serverContainers.begin(); it != serverContainers.end(); ++it) {
|
||||
if (it.key() == DockerContainer::Dns) {
|
||||
isDnsContainerInstalled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dns.first = dns1();
|
||||
dns.second = dns2();
|
||||
|
||||
if (dns.first.isEmpty() || !NetworkUtilities::checkIPv4Format(dns.first)) {
|
||||
if (isAmneziaDnsEnabled && isDnsContainerInstalled) {
|
||||
dns.first = protocols::dns::amneziaDnsIp;
|
||||
} else {
|
||||
dns.first = primaryDns;
|
||||
}
|
||||
}
|
||||
|
||||
if (dns.second.isEmpty() || !NetworkUtilities::checkIPv4Format(dns.second)) {
|
||||
dns.second = secondaryDns;
|
||||
}
|
||||
|
||||
return dns;
|
||||
}
|
||||
|
||||
} // namespace amnezia
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
#ifndef SERVERCONFIG_H
|
||||
#define SERVERCONFIG_H
|
||||
|
||||
#include <variant>
|
||||
#include <QJsonObject>
|
||||
#include <QMap>
|
||||
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/models/selfhosted/selfHostedServerConfig.h"
|
||||
#include "core/models/selfhosted/nativeServerConfig.h"
|
||||
#include "core/models/api/apiV1ServerConfig.h"
|
||||
#include "core/models/api/apiV2ServerConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
|
||||
using namespace ContainerEnumNS;
|
||||
|
||||
struct ServerConfig {
|
||||
using Variant = std::variant<
|
||||
SelfHostedServerConfig,
|
||||
NativeServerConfig,
|
||||
ApiV1ServerConfig,
|
||||
ApiV2ServerConfig
|
||||
>;
|
||||
|
||||
Variant data;
|
||||
|
||||
ServerConfig() = default;
|
||||
ServerConfig(const Variant& v) : data(v) {}
|
||||
ServerConfig(Variant&& v) : data(std::move(v)) {}
|
||||
|
||||
template<typename T, typename = std::enable_if_t<!std::is_same<std::remove_cv_t<std::remove_reference_t<T>>, ServerConfig>::value>>
|
||||
ServerConfig(const T& v) : data(v) {}
|
||||
|
||||
template<typename T, typename = std::enable_if_t<!std::is_same<std::remove_cv_t<std::remove_reference_t<T>>, ServerConfig>::value>>
|
||||
ServerConfig(T&& v) : data(std::forward<T>(v)) {}
|
||||
|
||||
QString description() const;
|
||||
QString hostName() const;
|
||||
QString displayName() const;
|
||||
QMap<DockerContainer, ContainerConfig> containers() const;
|
||||
DockerContainer defaultContainer() const;
|
||||
QString dns1() const;
|
||||
QString dns2() const;
|
||||
bool hasContainers() const;
|
||||
ContainerConfig containerConfig(DockerContainer container) const;
|
||||
|
||||
int crc() const;
|
||||
int configVersion() const;
|
||||
|
||||
bool isSelfHosted() const;
|
||||
bool isNative() const;
|
||||
bool isApiV1() const;
|
||||
bool isApiV2() const;
|
||||
bool isApiConfig() const;
|
||||
|
||||
template<typename T>
|
||||
T* as() {
|
||||
return std::get_if<T>(&data);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T* as() const {
|
||||
return std::get_if<T>(&data);
|
||||
}
|
||||
|
||||
QJsonObject toJson() const;
|
||||
static ServerConfig fromJson(const QJsonObject& json);
|
||||
|
||||
template<typename Visitor>
|
||||
auto visit(Visitor&& visitor) {
|
||||
return std::visit(std::forward<Visitor>(visitor), data);
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
auto visit(Visitor&& visitor) const {
|
||||
return std::visit(std::forward<Visitor>(visitor), data);
|
||||
}
|
||||
|
||||
QPair<QString, QString> getDnsPair(bool isAmneziaDnsEnabled,
|
||||
const QString &primaryDns,
|
||||
const QString &secondaryDns) const;
|
||||
};
|
||||
|
||||
} // namespace amnezia
|
||||
|
||||
#endif // SERVERCONFIG_H
|
||||
|
||||
187
client/core/models/serverDescription.cpp
Normal file
187
client/core/models/serverDescription.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
#include "serverDescription.h"
|
||||
|
||||
#include <QMap>
|
||||
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/models/protocols/awgProtocolConfig.h"
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool computeHasInstalledVpnContainers(const QMap<DockerContainer, ContainerConfig> &containers)
|
||||
{
|
||||
for (auto it = containers.begin(); it != containers.end(); ++it) {
|
||||
const DockerContainer container = it.key();
|
||||
if (ContainerUtils::containerService(container) == ServiceType::Vpn || container == DockerContainer::SSXray) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ServerDescription buildBaseDescription(const T &server)
|
||||
{
|
||||
ServerDescription row;
|
||||
row.hostName = server.hostName;
|
||||
row.defaultContainer = server.defaultContainer;
|
||||
row.primaryDnsIsAmnezia = (server.dns1 == protocols::dns::amneziaDnsIp);
|
||||
row.hasInstalledVpnContainers = computeHasInstalledVpnContainers(server.containers);
|
||||
return row;
|
||||
}
|
||||
|
||||
QString getBaseDescription(const QMap<DockerContainer, ContainerConfig> &containers,
|
||||
bool isAmneziaDnsEnabled,
|
||||
bool hasWriteAccess,
|
||||
bool primaryDnsIsAmnezia)
|
||||
{
|
||||
QString description;
|
||||
if (hasWriteAccess) {
|
||||
const bool isDnsInstalled = containers.contains(DockerContainer::Dns);
|
||||
if (isAmneziaDnsEnabled && isDnsInstalled) {
|
||||
description += QStringLiteral("Amnezia DNS | ");
|
||||
}
|
||||
} else if (primaryDnsIsAmnezia) {
|
||||
description += QStringLiteral("Amnezia DNS | ");
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
QString getProtocolName(DockerContainer defaultContainer, const QMap<DockerContainer, ContainerConfig> &containers)
|
||||
{
|
||||
QString containerName = ContainerUtils::containerHumanNames().value(defaultContainer);
|
||||
QString protocolVersion;
|
||||
|
||||
if (ContainerUtils::isAwgContainer(defaultContainer)) {
|
||||
const auto it = containers.constFind(defaultContainer);
|
||||
if (it != containers.cend()) {
|
||||
if (const AwgProtocolConfig *awg = it->getAwgProtocolConfig()) {
|
||||
protocolVersion = ProtocolUtils::getProtocolVersionString(awg->toJson());
|
||||
if (defaultContainer == DockerContainer::Awg && !awg->serverConfig.isThirdPartyConfig) {
|
||||
containerName = QStringLiteral("AmneziaWG Legacy");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return containerName + protocolVersion + QStringLiteral(" | ");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
|
||||
ServerDescription buildServerDescription(const SelfHostedAdminServerConfig &server, bool isAmneziaDnsEnabled)
|
||||
{
|
||||
ServerDescription row = buildBaseDescription(server);
|
||||
row.selfHostedSshCredentials.hostName = server.hostName;
|
||||
row.selfHostedSshCredentials.userName = server.userName;
|
||||
row.selfHostedSshCredentials.secretData = server.password;
|
||||
row.selfHostedSshCredentials.port = server.port > 0 ? server.port : 22;
|
||||
|
||||
row.hasWriteAccess = !row.selfHostedSshCredentials.userName.isEmpty()
|
||||
&& !row.selfHostedSshCredentials.secretData.isEmpty();
|
||||
|
||||
row.serverName = server.displayName;
|
||||
row.baseDescription = getBaseDescription(server.containers, isAmneziaDnsEnabled, row.hasWriteAccess, row.primaryDnsIsAmnezia);
|
||||
|
||||
const QString protocolName = getProtocolName(server.defaultContainer, server.containers);
|
||||
row.expandedServerDescription = row.baseDescription + row.hostName;
|
||||
row.collapsedServerDescription = row.baseDescription + protocolName + row.hostName;
|
||||
return row;
|
||||
}
|
||||
|
||||
ServerDescription buildServerDescription(const SelfHostedUserServerConfig &server, bool isAmneziaDnsEnabled)
|
||||
{
|
||||
ServerDescription row = buildBaseDescription(server);
|
||||
row.selfHostedSshCredentials.hostName = server.hostName;
|
||||
row.selfHostedSshCredentials.port = 22;
|
||||
row.hasWriteAccess = false;
|
||||
|
||||
row.serverName = server.displayName;
|
||||
row.baseDescription = getBaseDescription(server.containers, isAmneziaDnsEnabled, row.hasWriteAccess, row.primaryDnsIsAmnezia);
|
||||
|
||||
const QString protocolName = getProtocolName(server.defaultContainer, server.containers);
|
||||
row.expandedServerDescription = row.baseDescription + row.hostName;
|
||||
row.collapsedServerDescription = row.baseDescription + protocolName + row.hostName;
|
||||
return row;
|
||||
}
|
||||
|
||||
ServerDescription buildServerDescription(const NativeServerConfig &server, bool isAmneziaDnsEnabled)
|
||||
{
|
||||
ServerDescription row = buildBaseDescription(server);
|
||||
row.hasWriteAccess = false;
|
||||
|
||||
row.serverName = server.displayName;
|
||||
row.baseDescription = getBaseDescription(server.containers, isAmneziaDnsEnabled, row.hasWriteAccess, row.primaryDnsIsAmnezia);
|
||||
|
||||
const QString protocolName = getProtocolName(server.defaultContainer, server.containers);
|
||||
row.expandedServerDescription = row.baseDescription + row.hostName;
|
||||
row.collapsedServerDescription = row.baseDescription + protocolName + row.hostName;
|
||||
return row;
|
||||
}
|
||||
|
||||
ServerDescription buildServerDescription(const LegacyApiServerConfig &server, bool /*isAmneziaDnsEnabled*/)
|
||||
{
|
||||
ServerDescription row = buildBaseDescription(server);
|
||||
row.configVersion = serverConfigUtils::ConfigSource::Telegram;
|
||||
row.isApiV1 = true;
|
||||
row.isServerFromGatewayApi = false;
|
||||
row.hasWriteAccess = false;
|
||||
|
||||
row.serverName = server.displayName;
|
||||
row.baseDescription = server.description;
|
||||
|
||||
const QString fullDescriptionForCollapsed = row.baseDescription;
|
||||
row.collapsedServerDescription = fullDescriptionForCollapsed;
|
||||
row.expandedServerDescription = fullDescriptionForCollapsed;
|
||||
return row;
|
||||
}
|
||||
|
||||
ServerDescription buildServerDescription(const ApiV2ServerConfig &server, bool /*isAmneziaDnsEnabled*/)
|
||||
{
|
||||
ServerDescription row = buildBaseDescription(server);
|
||||
row.configVersion = serverConfigUtils::ConfigSource::AmneziaGateway;
|
||||
row.isApiV2 = true;
|
||||
row.isServerFromGatewayApi = true;
|
||||
row.isPremium = server.isPremium() || server.isExternalPremium();
|
||||
row.hasWriteAccess = false;
|
||||
|
||||
row.serverName = server.displayName;
|
||||
row.baseDescription = server.apiConfig.serverCountryCode.isEmpty() ? server.description : server.apiConfig.serverCountryName;
|
||||
|
||||
row.isCountrySelectionAvailable = !server.apiConfig.availableCountries.isEmpty();
|
||||
row.apiAvailableCountries = server.apiConfig.availableCountries;
|
||||
row.apiServerCountryCode = server.apiConfig.serverCountryCode;
|
||||
|
||||
row.isAdVisible = server.apiConfig.serviceInfo.isAdVisible;
|
||||
row.adHeader = server.apiConfig.serviceInfo.adHeader;
|
||||
row.adDescription = server.apiConfig.serviceInfo.adDescription;
|
||||
row.adEndpoint = server.apiConfig.serviceInfo.adEndpoint;
|
||||
row.isRenewalAvailable = server.apiConfig.serviceInfo.isRenewalAvailable;
|
||||
|
||||
if (!server.apiConfig.isInAppPurchase) {
|
||||
if (server.apiConfig.subscriptionExpiredByServer) {
|
||||
row.isSubscriptionExpired = true;
|
||||
} else if (!server.apiConfig.subscription.endDate.isEmpty()) {
|
||||
row.isSubscriptionExpired = apiUtils::isSubscriptionExpired(server.apiConfig.subscription.endDate);
|
||||
row.isSubscriptionExpiringSoon = apiUtils::isSubscriptionExpiringSoon(server.apiConfig.subscription.endDate);
|
||||
}
|
||||
}
|
||||
|
||||
const QString fullDescriptionForCollapsed = row.baseDescription;
|
||||
row.collapsedServerDescription = fullDescriptionForCollapsed;
|
||||
row.expandedServerDescription = fullDescriptionForCollapsed;
|
||||
return row;
|
||||
}
|
||||
|
||||
} // namespace amnezia
|
||||
64
client/core/models/serverDescription.h
Normal file
64
client/core/models/serverDescription.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef SERVERDESCRIPTION_H
|
||||
#define SERVERDESCRIPTION_H
|
||||
|
||||
#include <QString>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/selfhosted/sshSession.h"
|
||||
#include "core/models/selfhosted/selfHostedAdminServerConfig.h"
|
||||
#include "core/models/selfhosted/selfHostedUserServerConfig.h"
|
||||
#include "core/models/selfhosted/nativeServerConfig.h"
|
||||
#include "core/models/api/legacyApiServerConfig.h"
|
||||
#include "core/models/api/apiV2ServerConfig.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
|
||||
struct ServerDescription
|
||||
{
|
||||
QString serverId;
|
||||
|
||||
QString serverName;
|
||||
QString baseDescription;
|
||||
QString hostName;
|
||||
|
||||
int configVersion = 0;
|
||||
|
||||
ServerCredentials selfHostedSshCredentials;
|
||||
bool hasWriteAccess = false;
|
||||
|
||||
bool primaryDnsIsAmnezia = false;
|
||||
DockerContainer defaultContainer = DockerContainer::None;
|
||||
bool hasInstalledVpnContainers = false;
|
||||
|
||||
bool isApiV1 = false;
|
||||
bool isApiV2 = false;
|
||||
bool isServerFromGatewayApi = false;
|
||||
bool isPremium = false;
|
||||
|
||||
bool isCountrySelectionAvailable = false;
|
||||
QJsonArray apiAvailableCountries;
|
||||
QString apiServerCountryCode;
|
||||
|
||||
bool isAdVisible = false;
|
||||
QString adHeader;
|
||||
QString adDescription;
|
||||
QString adEndpoint;
|
||||
bool isRenewalAvailable = false;
|
||||
bool isSubscriptionExpired = false;
|
||||
bool isSubscriptionExpiringSoon = false;
|
||||
|
||||
QString collapsedServerDescription;
|
||||
QString expandedServerDescription;
|
||||
};
|
||||
|
||||
ServerDescription buildServerDescription(const SelfHostedAdminServerConfig &server, bool isAmneziaDnsEnabled);
|
||||
ServerDescription buildServerDescription(const SelfHostedUserServerConfig &server, bool isAmneziaDnsEnabled);
|
||||
ServerDescription buildServerDescription(const NativeServerConfig &server, bool isAmneziaDnsEnabled);
|
||||
ServerDescription buildServerDescription(const LegacyApiServerConfig &server, bool isAmneziaDnsEnabled);
|
||||
ServerDescription buildServerDescription(const ApiV2ServerConfig &server, bool isAmneziaDnsEnabled);
|
||||
|
||||
} // namespace amnezia
|
||||
|
||||
#endif
|
||||
@@ -2,15 +2,16 @@
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QUuid>
|
||||
|
||||
#include "core/utils/errorCodes.h"
|
||||
#include "core/utils/routeModes.h"
|
||||
#include "core/utils/commonStructs.h"
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
@@ -1,26 +1,44 @@
|
||||
#include "secureServersRepository.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonValue>
|
||||
#include <QUuid>
|
||||
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
|
||||
SecureServersRepository::SecureServersRepository(SecureQSettings* settings, QObject *parent)
|
||||
using namespace amnezia;
|
||||
|
||||
namespace {
|
||||
|
||||
QString readStorageServerId(const QJsonObject &json)
|
||||
{
|
||||
return json.value(QString(configKey::storageServerId)).toString().trimmed();
|
||||
}
|
||||
|
||||
QJsonObject withoutStorageServerId(const QJsonObject &json)
|
||||
{
|
||||
QJsonObject o = json;
|
||||
o.remove(QString(configKey::storageServerId));
|
||||
return o;
|
||||
}
|
||||
|
||||
QJsonObject embedStorageServerId(const QString &serverId, const QJsonObject &payloadSansId)
|
||||
{
|
||||
QJsonObject o = payloadSansId;
|
||||
o.insert(QString(configKey::storageServerId), serverId);
|
||||
return o;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
SecureServersRepository::SecureServersRepository(SecureQSettings *settings, QObject *parent)
|
||||
: QObject(parent), m_settings(settings)
|
||||
{
|
||||
QJsonArray arr = QJsonDocument::fromJson(value("Servers/serversList").toByteArray()).array();
|
||||
for (const QJsonValue &val : arr) {
|
||||
m_servers.append(ServerConfig::fromJson(val.toObject()));
|
||||
}
|
||||
m_defaultServerIndex = value("Servers/defaultServerIndex", 0).toInt();
|
||||
loadFromStorage();
|
||||
persistDefaultServerFields();
|
||||
}
|
||||
|
||||
QVariant SecureServersRepository::value(const QString &key, const QVariant &defaultValue) const
|
||||
@@ -33,216 +51,322 @@ void SecureServersRepository::setValue(const QString &key, const QVariant &value
|
||||
m_settings->setValue(key, value);
|
||||
}
|
||||
|
||||
void SecureServersRepository::clearServerStateMaps()
|
||||
{
|
||||
m_serverJsonById.clear();
|
||||
m_orderedServerIds.clear();
|
||||
}
|
||||
|
||||
QString SecureServersRepository::normalizedOrGeneratedServerId(const QString &candidateId) const
|
||||
{
|
||||
const QString trimmed = candidateId.trimmed();
|
||||
if (!trimmed.isEmpty() && !m_serverJsonById.contains(trimmed)) {
|
||||
return trimmed;
|
||||
}
|
||||
return QUuid::createUuid().toString(QUuid::WithoutBraces);
|
||||
}
|
||||
|
||||
void SecureServersRepository::updateDefaultServerFromStorage()
|
||||
{
|
||||
const QString storedDefaultId = value(QStringLiteral("Servers/defaultServerId"), QString()).toString();
|
||||
if (!storedDefaultId.isEmpty() && m_serverJsonById.contains(storedDefaultId)) {
|
||||
m_defaultServerId = storedDefaultId;
|
||||
return;
|
||||
}
|
||||
|
||||
const int storedDefaultIndex = value("Servers/defaultServerIndex", 0).toInt();
|
||||
if (storedDefaultIndex >= 0 && storedDefaultIndex < m_orderedServerIds.size()) {
|
||||
m_defaultServerId = m_orderedServerIds.at(storedDefaultIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_orderedServerIds.isEmpty()) {
|
||||
m_defaultServerId = m_orderedServerIds.first();
|
||||
return;
|
||||
}
|
||||
|
||||
m_defaultServerId.clear();
|
||||
}
|
||||
|
||||
void SecureServersRepository::persistDefaultServerFields()
|
||||
{
|
||||
if (m_orderedServerIds.isEmpty()) {
|
||||
m_defaultServerId.clear();
|
||||
} else if (!m_orderedServerIds.contains(m_defaultServerId)) {
|
||||
m_defaultServerId = m_orderedServerIds.first();
|
||||
}
|
||||
|
||||
setValue("Servers/defaultServerId", m_defaultServerId);
|
||||
}
|
||||
|
||||
void SecureServersRepository::loadFromStorage()
|
||||
{
|
||||
clearServerStateMaps();
|
||||
|
||||
const QJsonArray serversArray =
|
||||
QJsonDocument::fromJson(value(QStringLiteral("Servers/serversList"), QByteArray()).toByteArray())
|
||||
.array();
|
||||
|
||||
for (int i = 0; i < serversArray.size(); ++i) {
|
||||
const QJsonObject json = serversArray.at(i).toObject();
|
||||
const QString candidateId = readStorageServerId(json);
|
||||
const QString serverId = normalizedOrGeneratedServerId(candidateId);
|
||||
const QJsonObject strippedJson = withoutStorageServerId(json);
|
||||
const serverConfigUtils::ConfigType kind = serverConfigUtils::configTypeFromJson(strippedJson);
|
||||
|
||||
if (m_serverJsonById.contains(serverId) || kind == serverConfigUtils::ConfigType::Invalid) {
|
||||
continue;
|
||||
}
|
||||
m_serverJsonById.insert(serverId, embedStorageServerId(serverId, strippedJson));
|
||||
m_orderedServerIds.append(serverId);
|
||||
}
|
||||
|
||||
updateDefaultServerFromStorage();
|
||||
}
|
||||
|
||||
void SecureServersRepository::syncToStorage()
|
||||
{
|
||||
QJsonArray arr;
|
||||
for (const ServerConfig &cfg : m_servers) {
|
||||
arr.append(cfg.toJson());
|
||||
QJsonArray serversArray;
|
||||
|
||||
for (const QString &serverId : m_orderedServerIds) {
|
||||
if (!m_serverJsonById.contains(serverId)) {
|
||||
continue;
|
||||
}
|
||||
serversArray.append(m_serverJsonById.value(serverId));
|
||||
}
|
||||
setValue("Servers/serversList", QJsonDocument(arr).toJson());
|
||||
|
||||
setValue("Servers/serversList", QJsonDocument(serversArray).toJson());
|
||||
persistDefaultServerFields();
|
||||
}
|
||||
|
||||
void SecureServersRepository::invalidateCache()
|
||||
{
|
||||
m_servers.clear();
|
||||
QJsonArray arr = QJsonDocument::fromJson(value("Servers/serversList").toByteArray()).array();
|
||||
for (const QJsonValue &val : arr) {
|
||||
m_servers.append(ServerConfig::fromJson(val.toObject()));
|
||||
}
|
||||
m_defaultServerIndex = value("Servers/defaultServerIndex", 0).toInt();
|
||||
loadFromStorage();
|
||||
}
|
||||
|
||||
void SecureServersRepository::setServersArray(const QJsonArray &servers)
|
||||
void SecureServersRepository::clearServers()
|
||||
{
|
||||
m_servers.clear();
|
||||
for (const QJsonValue &val : servers) {
|
||||
m_servers.append(ServerConfig::fromJson(val.toObject()));
|
||||
}
|
||||
clearServerStateMaps();
|
||||
|
||||
m_defaultServerId.clear();
|
||||
|
||||
syncToStorage();
|
||||
}
|
||||
|
||||
void SecureServersRepository::addServer(const ServerConfig &server)
|
||||
QString SecureServersRepository::addServer(const QString &serverId, const QJsonObject &serverJson, serverConfigUtils::ConfigType kind)
|
||||
{
|
||||
m_servers.append(server);
|
||||
const QString id = normalizedOrGeneratedServerId(serverId);
|
||||
if (m_serverJsonById.contains(id) || kind == serverConfigUtils::ConfigType::Invalid) {
|
||||
return id;
|
||||
}
|
||||
const QJsonObject strippedJson = withoutStorageServerId(serverJson);
|
||||
if (serverConfigUtils::configTypeFromJson(strippedJson) != kind) {
|
||||
return id;
|
||||
}
|
||||
m_serverJsonById.insert(id, embedStorageServerId(id, strippedJson));
|
||||
|
||||
m_orderedServerIds.append(id);
|
||||
|
||||
if (m_defaultServerId.isEmpty()) {
|
||||
m_defaultServerId = id;
|
||||
}
|
||||
|
||||
syncToStorage();
|
||||
emit serverAdded(server);
|
||||
emit serverAdded(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void SecureServersRepository::editServer(int index, const ServerConfig &server)
|
||||
void SecureServersRepository::editServer(const QString &serverId, const QJsonObject &serverJson, serverConfigUtils::ConfigType kind)
|
||||
{
|
||||
if (index < 0 || index >= m_servers.size()) {
|
||||
if (indexOfServerId(serverId) < 0 || kind == serverConfigUtils::ConfigType::Invalid) {
|
||||
return;
|
||||
}
|
||||
m_servers.replace(index, server);
|
||||
syncToStorage();
|
||||
emit serverEdited(index, server);
|
||||
}
|
||||
|
||||
void SecureServersRepository::removeServer(int index)
|
||||
{
|
||||
if (index < 0 || index >= m_servers.size()) {
|
||||
if (!m_serverJsonById.contains(serverId)) {
|
||||
return;
|
||||
}
|
||||
int defaultIndex = m_defaultServerIndex;
|
||||
m_servers.removeAt(index);
|
||||
|
||||
if (defaultIndex == index) {
|
||||
setDefaultServer(0);
|
||||
} else if (defaultIndex > index) {
|
||||
setDefaultServer(defaultIndex - 1);
|
||||
const QJsonObject oldJson = m_serverJsonById.value(serverId);
|
||||
const serverConfigUtils::ConfigType oldKind = serverConfigUtils::configTypeFromJson(withoutStorageServerId(oldJson));
|
||||
|
||||
m_serverJsonById.remove(serverId);
|
||||
|
||||
const QJsonObject strippedNew = withoutStorageServerId(serverJson);
|
||||
if (serverConfigUtils::configTypeFromJson(strippedNew) != kind) {
|
||||
const QJsonObject strippedOld = withoutStorageServerId(oldJson);
|
||||
if (oldKind != serverConfigUtils::ConfigType::Invalid && serverConfigUtils::configTypeFromJson(strippedOld) == oldKind) {
|
||||
m_serverJsonById.insert(serverId, embedStorageServerId(serverId, strippedOld));
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_serverJsonById.insert(serverId, embedStorageServerId(serverId, strippedNew));
|
||||
|
||||
syncToStorage();
|
||||
emit serverEdited(serverId);
|
||||
}
|
||||
|
||||
void SecureServersRepository::removeServer(const QString &serverId)
|
||||
{
|
||||
const int removedIndex = indexOfServerId(serverId);
|
||||
if (removedIndex < 0) {
|
||||
return;
|
||||
}
|
||||
if (!m_serverJsonById.contains(serverId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_servers.isEmpty()) {
|
||||
setDefaultServer(0);
|
||||
const QString previousDefaultId = m_defaultServerId;
|
||||
const int previousDefaultIndex = defaultServerIndex();
|
||||
|
||||
m_serverJsonById.remove(serverId);
|
||||
m_orderedServerIds.removeAt(removedIndex);
|
||||
|
||||
if (m_orderedServerIds.isEmpty()) {
|
||||
m_defaultServerId.clear();
|
||||
} else if (m_defaultServerId == serverId) {
|
||||
const int fallbackIndex = qMin(removedIndex, m_orderedServerIds.size() - 1);
|
||||
m_defaultServerId = m_orderedServerIds.at(fallbackIndex);
|
||||
} else if (!m_orderedServerIds.contains(m_defaultServerId)) {
|
||||
m_defaultServerId = m_orderedServerIds.first();
|
||||
}
|
||||
|
||||
const int newDefaultIndex = defaultServerIndex();
|
||||
if (previousDefaultId != m_defaultServerId || previousDefaultIndex != newDefaultIndex) {
|
||||
emit defaultServerChanged(m_defaultServerId);
|
||||
}
|
||||
|
||||
syncToStorage();
|
||||
emit serverRemoved(index);
|
||||
emit serverRemoved(serverId, removedIndex);
|
||||
}
|
||||
|
||||
ServerConfig SecureServersRepository::server(int index) const
|
||||
serverConfigUtils::ConfigType SecureServersRepository::serverKind(const QString &serverId) const
|
||||
{
|
||||
if (index < 0 || index >= m_servers.size()) {
|
||||
return SelfHostedServerConfig{};
|
||||
const auto it = m_serverJsonById.constFind(serverId);
|
||||
if (it == m_serverJsonById.constEnd()) {
|
||||
return serverConfigUtils::ConfigType::Invalid;
|
||||
}
|
||||
return m_servers.at(index);
|
||||
return serverConfigUtils::configTypeFromJson(withoutStorageServerId(it.value()));
|
||||
}
|
||||
|
||||
QVector<ServerConfig> SecureServersRepository::servers() const
|
||||
std::optional<SelfHostedAdminServerConfig> SecureServersRepository::selfHostedAdminConfig(const QString &serverId) const
|
||||
{
|
||||
return m_servers;
|
||||
const auto it = m_serverJsonById.constFind(serverId);
|
||||
if (it == m_serverJsonById.constEnd()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const QJsonObject strippedJson = withoutStorageServerId(it.value());
|
||||
if (serverConfigUtils::configTypeFromJson(strippedJson) != serverConfigUtils::ConfigType::SelfHostedAdmin) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return SelfHostedAdminServerConfig::fromJson(strippedJson);
|
||||
}
|
||||
|
||||
std::optional<SelfHostedUserServerConfig> SecureServersRepository::selfHostedUserConfig(const QString &serverId) const
|
||||
{
|
||||
const auto it = m_serverJsonById.constFind(serverId);
|
||||
if (it == m_serverJsonById.constEnd()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const QJsonObject strippedJson = withoutStorageServerId(it.value());
|
||||
if (serverConfigUtils::configTypeFromJson(strippedJson) != serverConfigUtils::ConfigType::SelfHostedUser) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return SelfHostedUserServerConfig::fromJson(strippedJson);
|
||||
}
|
||||
|
||||
std::optional<NativeServerConfig> SecureServersRepository::nativeConfig(const QString &serverId) const
|
||||
{
|
||||
const auto it = m_serverJsonById.constFind(serverId);
|
||||
if (it == m_serverJsonById.constEnd()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const QJsonObject strippedJson = withoutStorageServerId(it.value());
|
||||
if (serverConfigUtils::configTypeFromJson(strippedJson) != serverConfigUtils::ConfigType::Native) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return NativeServerConfig::fromJson(strippedJson);
|
||||
}
|
||||
|
||||
std::optional<ApiV2ServerConfig> SecureServersRepository::apiV2Config(const QString &serverId) const
|
||||
{
|
||||
const auto it = m_serverJsonById.constFind(serverId);
|
||||
if (it == m_serverJsonById.constEnd()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const QJsonObject strippedJson = withoutStorageServerId(it.value());
|
||||
if (!serverConfigUtils::isApiV2Subscription(serverConfigUtils::configTypeFromJson(strippedJson))) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return ApiV2ServerConfig::fromJson(strippedJson);
|
||||
}
|
||||
|
||||
std::optional<LegacyApiServerConfig> SecureServersRepository::legacyApiConfig(const QString &serverId) const
|
||||
{
|
||||
const auto it = m_serverJsonById.constFind(serverId);
|
||||
if (it == m_serverJsonById.constEnd()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const QJsonObject strippedJson = withoutStorageServerId(it.value());
|
||||
if (!serverConfigUtils::isLegacyApiSubscription(serverConfigUtils::configTypeFromJson(strippedJson))) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return LegacyApiServerConfig::fromJson(strippedJson);
|
||||
}
|
||||
|
||||
int SecureServersRepository::serversCount() const
|
||||
{
|
||||
return m_servers.size();
|
||||
return m_orderedServerIds.size();
|
||||
}
|
||||
|
||||
QString SecureServersRepository::serverIdAt(int index) const
|
||||
{
|
||||
if (index < 0 || index >= m_orderedServerIds.size()) {
|
||||
return QString();
|
||||
}
|
||||
return m_orderedServerIds.at(index);
|
||||
}
|
||||
|
||||
QVector<QString> SecureServersRepository::orderedServerIds() const
|
||||
{
|
||||
return m_orderedServerIds;
|
||||
}
|
||||
|
||||
int SecureServersRepository::indexOfServerId(const QString &serverId) const
|
||||
{
|
||||
return m_orderedServerIds.indexOf(serverId);
|
||||
}
|
||||
|
||||
int SecureServersRepository::defaultServerIndex() const
|
||||
{
|
||||
return m_defaultServerIndex;
|
||||
if (m_orderedServerIds.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
const int idx = m_orderedServerIds.indexOf(m_defaultServerId);
|
||||
return idx >= 0 ? idx : 0;
|
||||
}
|
||||
|
||||
void SecureServersRepository::setDefaultServer(int index)
|
||||
QString SecureServersRepository::defaultServerId() const
|
||||
{
|
||||
if (index < 0) {
|
||||
return m_defaultServerId;
|
||||
}
|
||||
|
||||
void SecureServersRepository::setDefaultServer(const QString &serverId)
|
||||
{
|
||||
if (m_orderedServerIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (m_servers.size() > 0 && index >= m_servers.size()) {
|
||||
if (!m_serverJsonById.contains(serverId)) {
|
||||
return;
|
||||
}
|
||||
if (m_servers.isEmpty() && index != 0) {
|
||||
|
||||
if (indexOfServerId(serverId) < 0) {
|
||||
return;
|
||||
}
|
||||
if (m_defaultServerIndex == index) {
|
||||
|
||||
if (m_defaultServerId == serverId) {
|
||||
return;
|
||||
}
|
||||
m_defaultServerIndex = index;
|
||||
setValue("Servers/defaultServerIndex", index);
|
||||
emit defaultServerChanged(index);
|
||||
}
|
||||
|
||||
void SecureServersRepository::setDefaultContainer(int serverIndex, DockerContainer container)
|
||||
{
|
||||
ServerConfig config = server(serverIndex);
|
||||
config.visit([container](auto& arg) {
|
||||
arg.defaultContainer = container;
|
||||
});
|
||||
editServer(serverIndex, config);
|
||||
}
|
||||
|
||||
ContainerConfig SecureServersRepository::containerConfig(int serverIndex, DockerContainer container) const
|
||||
{
|
||||
ServerConfig config = server(serverIndex);
|
||||
return config.containerConfig(container);
|
||||
}
|
||||
|
||||
void SecureServersRepository::setContainerConfig(int serverIndex, DockerContainer container, const ContainerConfig &config)
|
||||
{
|
||||
ServerConfig serverConfig = server(serverIndex);
|
||||
serverConfig.visit([container, &config](auto& arg) {
|
||||
arg.containers[container] = config;
|
||||
});
|
||||
editServer(serverIndex, serverConfig);
|
||||
}
|
||||
|
||||
void SecureServersRepository::clearLastConnectionConfig(int serverIndex, DockerContainer container)
|
||||
{
|
||||
ServerConfig serverConfig = server(serverIndex);
|
||||
ContainerConfig containerCfg = serverConfig.containerConfig(container);
|
||||
|
||||
containerCfg.protocolConfig.clearClientConfig();
|
||||
|
||||
setContainerConfig(serverIndex, container, containerCfg);
|
||||
}
|
||||
|
||||
ServerCredentials SecureServersRepository::serverCredentials(int index) const
|
||||
{
|
||||
ServerConfig config = server(index);
|
||||
|
||||
if (config.isSelfHosted()) {
|
||||
const SelfHostedServerConfig* selfHosted = config.as<SelfHostedServerConfig>();
|
||||
if (!selfHosted) return ServerCredentials();
|
||||
auto creds = selfHosted->credentials();
|
||||
if (creds.has_value()) {
|
||||
return creds.value();
|
||||
}
|
||||
}
|
||||
|
||||
return ServerCredentials{};
|
||||
}
|
||||
|
||||
bool SecureServersRepository::hasServerWithVpnKey(const QString &vpnKey) const
|
||||
{
|
||||
QString normalizedInput = vpnKey.trimmed();
|
||||
if (normalizedInput.startsWith(QStringLiteral("vpn://"), Qt::CaseInsensitive)) {
|
||||
normalizedInput = normalizedInput.mid(QStringLiteral("vpn://").size());
|
||||
}
|
||||
if (normalizedInput.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QVector<ServerConfig> serversList = servers();
|
||||
for (const ServerConfig& serverConfig : serversList) {
|
||||
if (serverConfig.isApiV1()) {
|
||||
const ApiV1ServerConfig* apiV1 = serverConfig.as<ApiV1ServerConfig>();
|
||||
if (!apiV1) continue;
|
||||
QString storedKey = apiV1->vpnKey();
|
||||
if (storedKey.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
QString normalizedStored = storedKey.trimmed();
|
||||
if (normalizedStored.startsWith(QStringLiteral("vpn://"), Qt::CaseInsensitive)) {
|
||||
normalizedStored = normalizedStored.mid(QStringLiteral("vpn://").size());
|
||||
}
|
||||
if (normalizedInput == normalizedStored) {
|
||||
return true;
|
||||
}
|
||||
} else if (serverConfig.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = serverConfig.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) continue;
|
||||
QString storedKey = apiV2->vpnKey();
|
||||
if (storedKey.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
QString normalizedStored = storedKey.trimmed();
|
||||
if (normalizedStored.startsWith(QStringLiteral("vpn://"), Qt::CaseInsensitive)) {
|
||||
normalizedStored = normalizedStored.mid(QStringLiteral("vpn://").size());
|
||||
}
|
||||
if (normalizedInput == normalizedStored) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SecureServersRepository::hasServerWithCrc(quint16 crc) const
|
||||
{
|
||||
for (const ServerConfig& serverConfig : m_servers) {
|
||||
if (static_cast<quint16>(serverConfig.crc()) == crc) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
m_defaultServerId = serverId;
|
||||
persistDefaultServerFields();
|
||||
emit defaultServerChanged(m_defaultServerId);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
#ifndef SECURESERVERSREPOSITORY_H
|
||||
#define SECURESERVERSREPOSITORY_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QJsonObject>
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QtGlobal>
|
||||
#include <optional>
|
||||
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/selfhosted/selfHostedAdminServerConfig.h"
|
||||
#include "core/models/selfhosted/selfHostedUserServerConfig.h"
|
||||
#include "core/models/selfhosted/nativeServerConfig.h"
|
||||
#include "core/models/api/apiV2ServerConfig.h"
|
||||
#include "core/models/api/legacyApiServerConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "secureQSettings.h"
|
||||
|
||||
using namespace amnezia;
|
||||
@@ -18,47 +24,57 @@ class SecureServersRepository : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SecureServersRepository(SecureQSettings* settings, QObject *parent = nullptr);
|
||||
explicit SecureServersRepository(SecureQSettings *settings, QObject *parent = nullptr);
|
||||
|
||||
QString addServer(const QString &serverId, const QJsonObject &serverJson, serverConfigUtils::ConfigType kind);
|
||||
void editServer(const QString &serverId, const QJsonObject &serverJson, serverConfigUtils::ConfigType kind);
|
||||
void removeServer(const QString &serverId);
|
||||
serverConfigUtils::ConfigType serverKind(const QString &serverId) const;
|
||||
|
||||
std::optional<SelfHostedAdminServerConfig> selfHostedAdminConfig(const QString &serverId) const;
|
||||
std::optional<SelfHostedUserServerConfig> selfHostedUserConfig(const QString &serverId) const;
|
||||
std::optional<NativeServerConfig> nativeConfig(const QString &serverId) const;
|
||||
std::optional<ApiV2ServerConfig> apiV2Config(const QString &serverId) const;
|
||||
std::optional<LegacyApiServerConfig> legacyApiConfig(const QString &serverId) const;
|
||||
|
||||
void addServer(const ServerConfig &server);
|
||||
void editServer(int index, const ServerConfig &server);
|
||||
void removeServer(int index);
|
||||
ServerConfig server(int index) const;
|
||||
QVector<ServerConfig> servers() const;
|
||||
int serversCount() const;
|
||||
int indexOfServerId(const QString &serverId) const;
|
||||
QString serverIdAt(int index) const;
|
||||
QVector<QString> orderedServerIds() const;
|
||||
|
||||
int defaultServerIndex() const;
|
||||
void setDefaultServer(int index);
|
||||
QString defaultServerId() const;
|
||||
void setDefaultServer(const QString &serverId);
|
||||
|
||||
void setDefaultContainer(int serverIndex, DockerContainer container);
|
||||
ContainerConfig containerConfig(int serverIndex, DockerContainer container) const;
|
||||
void setContainerConfig(int serverIndex, DockerContainer container, const ContainerConfig &config);
|
||||
void clearLastConnectionConfig(int serverIndex, DockerContainer container);
|
||||
|
||||
ServerCredentials serverCredentials(int index) const;
|
||||
bool hasServerWithVpnKey(const QString &vpnKey) const;
|
||||
bool hasServerWithCrc(quint16 crc) const;
|
||||
|
||||
void setServersArray(const QJsonArray &servers);
|
||||
void clearServers();
|
||||
|
||||
void invalidateCache();
|
||||
|
||||
signals:
|
||||
void serverAdded(ServerConfig config);
|
||||
void serverEdited(int index, ServerConfig config);
|
||||
void serverRemoved(int index);
|
||||
void defaultServerChanged(int index);
|
||||
void serverAdded(const QString &serverId);
|
||||
void serverEdited(const QString &serverId);
|
||||
void serverRemoved(const QString &serverId, int removedIndex);
|
||||
void defaultServerChanged(const QString &defaultServerId);
|
||||
|
||||
private:
|
||||
void loadFromStorage();
|
||||
void updateDefaultServerFromStorage();
|
||||
void persistDefaultServerFields();
|
||||
|
||||
QString normalizedOrGeneratedServerId(const QString &candidateId) const;
|
||||
|
||||
void syncToStorage();
|
||||
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
|
||||
QVariant value(const QString &key, const QVariant &defaultValue) const;
|
||||
void setValue(const QString &key, const QVariant &value);
|
||||
|
||||
SecureQSettings* m_settings;
|
||||
|
||||
QVector<ServerConfig> m_servers;
|
||||
int m_defaultServerIndex = 0;
|
||||
|
||||
void clearServerStateMaps();
|
||||
|
||||
SecureQSettings *m_settings;
|
||||
|
||||
QHash<QString, QJsonObject> m_serverJsonById;
|
||||
QVector<QString> m_orderedServerIds;
|
||||
|
||||
QString m_defaultServerId;
|
||||
};
|
||||
|
||||
#endif // SECURESERVERSREPOSITORY_H
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef APIENUMS_H
|
||||
#define APIENUMS_H
|
||||
|
||||
namespace apiDefs
|
||||
{
|
||||
enum ConfigType {
|
||||
AmneziaFreeV2 = 0,
|
||||
AmneziaFreeV3,
|
||||
AmneziaPremiumV1,
|
||||
AmneziaPremiumV2,
|
||||
AmneziaTrialV2,
|
||||
SelfHosted,
|
||||
ExternalPremium,
|
||||
ExternalTrial
|
||||
};
|
||||
|
||||
enum ConfigSource {
|
||||
Telegram = 1,
|
||||
AmneziaGateway
|
||||
};
|
||||
}
|
||||
|
||||
#endif // APIENUMS_H
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "apiUtils.h"
|
||||
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include <QDateTime>
|
||||
#include <QJsonDocument>
|
||||
@@ -75,63 +76,6 @@ bool apiUtils::isSubscriptionExpiringSoon(const QString &subscriptionEndDate, in
|
||||
return endDate <= nowUtc.addDays(withinDays);
|
||||
}
|
||||
|
||||
bool apiUtils::isServerFromApi(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
auto configVersion = serverConfigObject.value(configKey::configVersion).toInt();
|
||||
switch (configVersion) {
|
||||
case apiDefs::ConfigSource::Telegram: return true;
|
||||
case apiDefs::ConfigSource::AmneziaGateway: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
auto configVersion = serverConfigObject.value(configKey::configVersion).toInt();
|
||||
|
||||
switch (configVersion) {
|
||||
case apiDefs::ConfigSource::Telegram: {
|
||||
constexpr QLatin1String freeV2Endpoint(FREE_V2_ENDPOINT);
|
||||
constexpr QLatin1String premiumV1Endpoint(PREM_V1_ENDPOINT);
|
||||
|
||||
auto apiEndpoint = serverConfigObject.value(apiDefs::key::apiEndpoint).toString();
|
||||
|
||||
if (apiEndpoint.contains(premiumV1Endpoint)) {
|
||||
return apiDefs::ConfigType::AmneziaPremiumV1;
|
||||
} else if (apiEndpoint.contains(freeV2Endpoint)) {
|
||||
return apiDefs::ConfigType::AmneziaFreeV2;
|
||||
}
|
||||
};
|
||||
case apiDefs::ConfigSource::AmneziaGateway: {
|
||||
constexpr QLatin1String servicePremium("amnezia-premium");
|
||||
constexpr QLatin1String serviceFree("amnezia-free");
|
||||
constexpr QLatin1String serviceExternalPremium("external-premium");
|
||||
constexpr QLatin1String serviceExternalTrial("external-trial");
|
||||
|
||||
auto apiConfigObject = serverConfigObject.value(apiDefs::key::apiConfig).toObject();
|
||||
auto serviceType = apiConfigObject.value(apiDefs::key::serviceType).toString();
|
||||
|
||||
if (serviceType == servicePremium) {
|
||||
return apiDefs::ConfigType::AmneziaPremiumV2;
|
||||
} else if (serviceType == serviceFree) {
|
||||
return apiDefs::ConfigType::AmneziaFreeV3;
|
||||
} else if (serviceType == serviceExternalPremium) {
|
||||
return apiDefs::ConfigType::ExternalPremium;
|
||||
} else if (serviceType == serviceExternalTrial) {
|
||||
return apiDefs::ConfigType::ExternalTrial;
|
||||
}
|
||||
}
|
||||
default: {
|
||||
return apiDefs::ConfigType::SelfHosted;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
apiDefs::ConfigSource apiUtils::getConfigSource(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
return static_cast<apiDefs::ConfigSource>(serverConfigObject.value(configKey::configVersion).toInt());
|
||||
}
|
||||
|
||||
amnezia::ErrorCode apiUtils::checkNetworkReplyErrors(const QList<QSslError> &sslErrors, const QString &replyErrorString,
|
||||
const QNetworkReply::NetworkError &replyError, const int httpStatusCode,
|
||||
const QByteArray &responseBody)
|
||||
@@ -197,14 +141,14 @@ amnezia::ErrorCode apiUtils::checkNetworkReplyErrors(const QList<QSslError> &ssl
|
||||
|
||||
bool apiUtils::isPremiumServer(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
static const QSet<apiDefs::ConfigType> premiumTypes = { apiDefs::ConfigType::AmneziaPremiumV1, apiDefs::ConfigType::AmneziaPremiumV2,
|
||||
apiDefs::ConfigType::ExternalPremium, apiDefs::ConfigType::ExternalTrial };
|
||||
return premiumTypes.contains(getConfigType(serverConfigObject));
|
||||
static const QSet<serverConfigUtils::ConfigType> premiumTypes = { serverConfigUtils::ConfigType::AmneziaPremiumV1, serverConfigUtils::ConfigType::AmneziaPremiumV2,
|
||||
serverConfigUtils::ConfigType::ExternalPremium };
|
||||
return premiumTypes.contains(serverConfigUtils::configTypeFromJson(serverConfigObject));
|
||||
}
|
||||
|
||||
QString apiUtils::getPremiumV1VpnKey(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
if (apiUtils::getConfigType(serverConfigObject) != apiDefs::ConfigType::AmneziaPremiumV1) {
|
||||
if (serverConfigUtils::configTypeFromJson(serverConfigObject) != serverConfigUtils::ConfigType::AmneziaPremiumV1) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -242,9 +186,8 @@ QString apiUtils::getPremiumV1VpnKey(const QJsonObject &serverConfigObject)
|
||||
|
||||
QString apiUtils::getPremiumV2VpnKey(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
auto configType = apiUtils::getConfigType(serverConfigObject);
|
||||
if (configType != apiDefs::ConfigType::AmneziaPremiumV2 && configType != apiDefs::ConfigType::ExternalPremium
|
||||
&& configType != apiDefs::ConfigType::ExternalTrial) {
|
||||
auto configType = serverConfigUtils::configTypeFromJson(serverConfigObject);
|
||||
if (configType != serverConfigUtils::ConfigType::AmneziaPremiumV2 && configType != serverConfigUtils::ConfigType::ExternalPremium) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <QNetworkReply>
|
||||
#include <QObject>
|
||||
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/utils/errorCodes.h"
|
||||
@@ -13,17 +13,12 @@
|
||||
|
||||
namespace apiUtils
|
||||
{
|
||||
bool isServerFromApi(const QJsonObject &serverConfigObject);
|
||||
|
||||
bool isSubscriptionExpired(const QString &subscriptionEndDate);
|
||||
|
||||
bool isSubscriptionExpiringSoon(const QString &subscriptionEndDate, int withinDays = 30);
|
||||
|
||||
bool isPremiumServer(const QJsonObject &serverConfigObject);
|
||||
|
||||
apiDefs::ConfigType getConfigType(const QJsonObject &serverConfigObject);
|
||||
apiDefs::ConfigSource getConfigSource(const QJsonObject &serverConfigObject);
|
||||
|
||||
amnezia::ErrorCode checkNetworkReplyErrors(const QList<QSslError> &sslErrors, const QString &replyErrorString,
|
||||
const QNetworkReply::NetworkError &replyError, const int httpStatusCode,
|
||||
const QByteArray &responseBody);
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
namespace apiDefs
|
||||
{
|
||||
const int requestTimeoutMsecs = 12 * 1000; // 12 secs
|
||||
}
|
||||
|
||||
constexpr int requestTimeoutMsecs = 12 * 1000; // 12 secs
|
||||
|
||||
} // namespace apiDefs
|
||||
|
||||
#endif // APICONSTANTS_H
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define APIKEYS_H
|
||||
|
||||
#include <QLatin1String>
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
|
||||
namespace apiDefs
|
||||
{
|
||||
@@ -82,7 +81,7 @@ namespace apiDefs
|
||||
constexpr QLatin1String expiresAt("expires_at");
|
||||
constexpr QLatin1String isConnectEvent("is_connect_event");
|
||||
constexpr QLatin1String certificate("certificate");
|
||||
}
|
||||
}
|
||||
} // namespace key
|
||||
} // namespace apiDefs
|
||||
|
||||
#endif // APIKEYS_H
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace amnezia
|
||||
|
||||
constexpr QLatin1String serverIndex("serverIndex");
|
||||
constexpr QLatin1String description("description");
|
||||
constexpr QLatin1String displayName("displayName");
|
||||
constexpr QLatin1String name("name");
|
||||
constexpr QLatin1String cert("cert");
|
||||
constexpr QLatin1String accessToken("api_key");
|
||||
@@ -121,6 +122,8 @@ namespace amnezia
|
||||
constexpr QLatin1String latestHandshake("latestHandshake");
|
||||
constexpr QLatin1String dataReceived("dataReceived");
|
||||
constexpr QLatin1String dataSent("dataSent");
|
||||
|
||||
constexpr QLatin1String storageServerId("storageServerId");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,10 +71,11 @@ namespace amnezia
|
||||
|
||||
// import and install errors
|
||||
ImportInvalidConfigError = 900,
|
||||
ImportBackupFileUseRestoreInstead = 903,
|
||||
RestoreBackupInvalidError = 904,
|
||||
ImportOpenConfigError = 901,
|
||||
NoInstalledContainersError = 902,
|
||||
ImportBackupFileUseRestoreInstead = 903,
|
||||
RestoreBackupInvalidError = 904,
|
||||
LegacyApiV1NotSupportedError = 905,
|
||||
|
||||
// Android errors
|
||||
AndroidError = 1000,
|
||||
|
||||
@@ -59,6 +59,7 @@ QString errorString(ErrorCode code) {
|
||||
case (ErrorCode::ImportInvalidConfigError): errorMessage = QObject::tr("The config does not contain any containers and credentials for connecting to the server"); break;
|
||||
case (ErrorCode::ImportBackupFileUseRestoreInstead): errorMessage = QObject::tr("Backup files cannot be imported here. Use 'Restore from backup' instead."); break;
|
||||
case (ErrorCode::RestoreBackupInvalidError): errorMessage = QObject::tr("Backup file is corrupted or has invalid format"); break;
|
||||
case (ErrorCode::LegacyApiV1NotSupportedError): errorMessage = QObject::tr("This legacy Amnezia subscription format is no longer supported"); break;
|
||||
case (ErrorCode::ImportOpenConfigError): errorMessage = QObject::tr("Unable to open config file"); break;
|
||||
case (ErrorCode::NoInstalledContainersError): errorMessage = QObject::tr("VPN Protocols is not installed.\n Please install VPN container at first"); break;
|
||||
|
||||
|
||||
122
client/core/utils/serverConfigUtils.cpp
Normal file
122
client/core/utils/serverConfigUtils.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "serverConfigUtils.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonValue>
|
||||
|
||||
#include "core/models/selfhosted/selfHostedAdminServerConfig.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool hasThirdPartyConfig(const QJsonObject &json)
|
||||
{
|
||||
const QJsonArray containersArray = json.value(amnezia::configKey::containers).toArray();
|
||||
for (const QJsonValue &val : containersArray) {
|
||||
const QJsonObject containerObj = val.toObject();
|
||||
for (auto it = containerObj.begin(); it != containerObj.end(); ++it) {
|
||||
if (it.key() == amnezia::configKey::container) {
|
||||
continue;
|
||||
}
|
||||
const QJsonObject protocolObj = it.value().toObject();
|
||||
if (protocolObj.contains(amnezia::configKey::isThirdPartyConfig)
|
||||
&& protocolObj.value(amnezia::configKey::isThirdPartyConfig).toBool()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace serverConfigUtils
|
||||
{
|
||||
|
||||
bool isServerFromApi(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
const int configVersion = serverConfigObject.value(amnezia::configKey::configVersion).toInt();
|
||||
switch (configVersion) {
|
||||
case ConfigSource::Telegram:
|
||||
case ConfigSource::AmneziaGateway:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSource getConfigSource(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
return static_cast<ConfigSource>(serverConfigObject.value(amnezia::configKey::configVersion).toInt());
|
||||
}
|
||||
|
||||
ConfigType configTypeFromJson(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
const int configVersion = serverConfigObject.value(amnezia::configKey::configVersion).toInt();
|
||||
|
||||
switch (configVersion) {
|
||||
case ConfigSource::Telegram: {
|
||||
constexpr QLatin1String freeV2Endpoint(FREE_V2_ENDPOINT);
|
||||
constexpr QLatin1String premiumV1Endpoint(PREM_V1_ENDPOINT);
|
||||
|
||||
const QString apiEndpointValue = serverConfigObject.value(apiDefs::key::apiEndpoint).toString();
|
||||
|
||||
if (apiEndpointValue.contains(premiumV1Endpoint)) {
|
||||
return ConfigType::AmneziaPremiumV1;
|
||||
}
|
||||
if (apiEndpointValue.contains(freeV2Endpoint)) {
|
||||
return ConfigType::AmneziaFreeV2;
|
||||
}
|
||||
}
|
||||
[[fallthrough]];
|
||||
case ConfigSource::AmneziaGateway: {
|
||||
constexpr QLatin1String servicePremium("amnezia-premium");
|
||||
constexpr QLatin1String serviceFree("amnezia-free");
|
||||
constexpr QLatin1String serviceExternalPremium("external-premium");
|
||||
|
||||
const QJsonObject apiConfigObject = serverConfigObject.value(apiDefs::key::apiConfig).toObject();
|
||||
const QString serviceTypeStr = apiConfigObject.value(apiDefs::key::serviceType).toString();
|
||||
|
||||
if (serviceTypeStr == servicePremium) {
|
||||
return ConfigType::AmneziaPremiumV2;
|
||||
}
|
||||
if (serviceTypeStr == serviceFree) {
|
||||
return ConfigType::AmneziaFreeV3;
|
||||
}
|
||||
if (serviceTypeStr == serviceExternalPremium) {
|
||||
return ConfigType::ExternalPremium;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasThirdPartyConfig(serverConfigObject)) {
|
||||
return ConfigType::Native;
|
||||
}
|
||||
|
||||
const amnezia::SelfHostedAdminServerConfig adminProbe =
|
||||
amnezia::SelfHostedAdminServerConfig::fromJson(serverConfigObject);
|
||||
return adminProbe.hasCredentials() ? ConfigType::SelfHostedAdmin : ConfigType::SelfHostedUser;
|
||||
}
|
||||
|
||||
bool isLegacyApiSubscription(ConfigType configType)
|
||||
{
|
||||
return configType == ConfigType::AmneziaPremiumV1 || configType == ConfigType::AmneziaFreeV2;
|
||||
}
|
||||
|
||||
bool isApiV2Subscription(ConfigType configType)
|
||||
{
|
||||
switch (configType) {
|
||||
case ConfigType::AmneziaPremiumV2:
|
||||
case ConfigType::AmneziaFreeV3:
|
||||
case ConfigType::ExternalPremium:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace serverConfigUtils
|
||||
40
client/core/utils/serverConfigUtils.h
Normal file
40
client/core/utils/serverConfigUtils.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef SERVERCONFIGUTILS_H
|
||||
#define SERVERCONFIGUTILS_H
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
namespace serverConfigUtils
|
||||
{
|
||||
|
||||
enum ConfigType {
|
||||
AmneziaFreeV2 = 0,
|
||||
AmneziaFreeV3,
|
||||
AmneziaPremiumV1,
|
||||
AmneziaPremiumV2,
|
||||
SelfHosted,
|
||||
ExternalPremium,
|
||||
|
||||
SelfHostedAdmin = 8,
|
||||
SelfHostedUser,
|
||||
Native,
|
||||
Invalid
|
||||
};
|
||||
|
||||
enum ConfigSource {
|
||||
Telegram = 1,
|
||||
AmneziaGateway
|
||||
};
|
||||
|
||||
bool isServerFromApi(const QJsonObject &serverConfigObject);
|
||||
|
||||
ConfigSource getConfigSource(const QJsonObject &serverConfigObject);
|
||||
|
||||
ConfigType configTypeFromJson(const QJsonObject &serverConfigObject);
|
||||
|
||||
bool isLegacyApiSubscription(ConfigType configType);
|
||||
|
||||
bool isApiV2Subscription(ConfigType configType);
|
||||
|
||||
} // namespace serverConfigUtils
|
||||
|
||||
#endif // SERVERCONFIGUTILS_H
|
||||
@@ -95,15 +95,6 @@ target_link_libraries(test_servers_model_sync PRIVATE
|
||||
test_common
|
||||
)
|
||||
|
||||
add_executable(test_gateway_stacks
|
||||
testGatewayStacks.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(test_gateway_stacks PRIVATE
|
||||
Qt6::Test
|
||||
test_common
|
||||
)
|
||||
|
||||
add_executable(test_complex_operations
|
||||
testComplexOperations.cpp
|
||||
)
|
||||
@@ -148,7 +139,6 @@ add_test(NAME DefaultServerChangeTest COMMAND test_default_server_change)
|
||||
add_test(NAME ServerEdgeCasesTest COMMAND test_server_edge_cases)
|
||||
add_test(NAME SignalOrderTest COMMAND test_signal_order)
|
||||
add_test(NAME ServersModelSyncTest COMMAND test_servers_model_sync)
|
||||
add_test(NAME GatewayStacksTest COMMAND test_gateway_stacks)
|
||||
add_test(NAME ComplexOperationsTest COMMAND test_complex_operations)
|
||||
add_test(NAME SettingsSignalsTest COMMAND test_settings_signals)
|
||||
add_test(NAME UiServersModelAndControllerTest COMMAND test_ui_servers_model_and_controller)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "vpnConnection.h"
|
||||
#include "secureQSettings.h"
|
||||
|
||||
@@ -117,8 +117,8 @@ private slots:
|
||||
QVERIFY2(defaultServerChangedSpy.count() == 0, "defaultServerChanged signal should NOT be emitted (default is already 0)");
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() > 0, "Server should be added");
|
||||
|
||||
int serverIndex = m_coreController->m_serversRepository->defaultServerIndex();
|
||||
auto exportResult = m_coreController->m_exportController->generateFullAccessConfig(serverIndex);
|
||||
const QString serverId = m_coreController->m_serversRepository->defaultServerId();
|
||||
auto exportResult = m_coreController->m_exportController->generateFullAccessConfig(serverId);
|
||||
|
||||
QVERIFY2(exportResult.errorCode == ErrorCode::NoError, "Export should succeed");
|
||||
QVERIFY2(!exportResult.config.isEmpty(), "Exported config should not be empty");
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
#include "tests/testServerRepositoryHelpers.h"
|
||||
#include "vpnConnection.h"
|
||||
#include "secureQSettings.h"
|
||||
|
||||
@@ -37,7 +38,7 @@ private slots:
|
||||
void init() {
|
||||
m_settings->clearSettings();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerConfig>(), -1, false);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,35 +66,33 @@ private slots:
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() == 3, "Should have 3 servers");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 2, "Default should be index 2");
|
||||
|
||||
ServerConfig server0 = m_coreController->m_serversController->getServerConfig(0);
|
||||
server0.visit([](auto& arg) {
|
||||
arg.description = "Edited First Server";
|
||||
});
|
||||
m_coreController->m_serversController->editServer(0, server0);
|
||||
amnezia::test::setServerDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversController->getServerId(0),
|
||||
QStringLiteral("Edited First Server"));
|
||||
|
||||
QVERIFY2(serverEditedSpy.count() == 1, "serverEdited should be emitted");
|
||||
QString editedDesc0 = m_coreController->m_serversRepository->server(0).description();
|
||||
QString editedDesc0 = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(0));
|
||||
QVERIFY2(editedDesc0 == "Edited First Server", "First server should be edited");
|
||||
|
||||
m_coreController->m_serversController->removeServer(1);
|
||||
m_coreController->m_serversController->removeServer(m_coreController->m_serversController->getServerId(1));
|
||||
|
||||
QVERIFY2(serverRemovedSpy.count() == 1, "serverRemoved should be emitted");
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() == 2, "Should have 2 servers");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 1, "Default should be index 1 (was 2, removed 1)");
|
||||
|
||||
m_coreController->m_serversController->setDefaultServerIndex(0);
|
||||
m_coreController->m_serversController->setDefaultServer(m_coreController->m_serversController->getServerId(0));
|
||||
|
||||
QVERIFY2(defaultServerChangedSpy.count() == 4, "defaultServerChanged should be emitted again");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 0, "Default should be index 0");
|
||||
|
||||
ServerConfig server0After = m_coreController->m_serversController->getServerConfig(0);
|
||||
server0After.visit([](auto& arg) {
|
||||
arg.description = "Final Edited Server";
|
||||
});
|
||||
m_coreController->m_serversController->editServer(0, server0After);
|
||||
amnezia::test::setServerDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversController->getServerId(0),
|
||||
QStringLiteral("Final Edited Server"));
|
||||
|
||||
QVERIFY2(serverEditedSpy.count() == 2, "serverEdited should be emitted again");
|
||||
QString finalDesc0 = m_coreController->m_serversRepository->server(0).description();
|
||||
QString finalDesc0 = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(0));
|
||||
QVERIFY2(finalDesc0 == "Final Edited Server", "First server should be edited again");
|
||||
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() == 2, "Final servers count should be 2");
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
#include "tests/testServerRepositoryHelpers.h"
|
||||
#include "ui/models/serversModel.h"
|
||||
#include "vpnConnection.h"
|
||||
#include "secureQSettings.h"
|
||||
@@ -39,7 +40,7 @@ private slots:
|
||||
m_settings->clearSettings();
|
||||
m_coreController->m_serversRepository->invalidateCache();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerConfig>(), -1, false);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,9 +61,10 @@ private slots:
|
||||
|
||||
QSignalSpy defaultServerChangedSpy(m_coreController->m_serversRepository, &SecureServersRepository::defaultServerChanged);
|
||||
|
||||
m_coreController->m_serversController->setDefaultServerIndex(0);
|
||||
m_coreController->m_serversController->setDefaultServer(m_coreController->m_serversController->getServerId(0));
|
||||
QVERIFY2(defaultServerChangedSpy.count() == 1, "defaultServerChanged signal should be emitted");
|
||||
QVERIFY2(defaultServerChangedSpy.at(0).at(0).toInt() == 0, "defaultServerChanged should emit index 0");
|
||||
QVERIFY2(defaultServerChangedSpy.at(0).at(0).toString() == m_coreController->m_serversController->getServerId(0),
|
||||
"defaultServerChanged should emit new default server id");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 0, "Default server index should be 0");
|
||||
|
||||
if (m_coreController->m_serversModel) {
|
||||
@@ -70,9 +72,10 @@ private slots:
|
||||
QVERIFY2(modelDefaultIndex == 0, "Model should reflect default server");
|
||||
}
|
||||
|
||||
m_coreController->m_serversController->setDefaultServerIndex(2);
|
||||
m_coreController->m_serversController->setDefaultServer(m_coreController->m_serversController->getServerId(2));
|
||||
QVERIFY2(defaultServerChangedSpy.count() == 2, "defaultServerChanged signal should be emitted again");
|
||||
QVERIFY2(defaultServerChangedSpy.at(1).at(0).toInt() == 2, "defaultServerChanged should emit index 2");
|
||||
QVERIFY2(defaultServerChangedSpy.at(1).at(0).toString() == m_coreController->m_serversController->getServerId(2),
|
||||
"defaultServerChanged should emit new default server id");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 2, "Default server index should be 2");
|
||||
}
|
||||
|
||||
@@ -94,28 +97,28 @@ private slots:
|
||||
QSignalSpy defaultServerChangedSpy(m_coreController->m_serversRepository, &SecureServersRepository::defaultServerChanged);
|
||||
QSignalSpy serverRemovedSpy(m_coreController->m_serversRepository, &SecureServersRepository::serverRemoved);
|
||||
|
||||
m_coreController->m_serversController->removeServer(0);
|
||||
m_coreController->m_serversController->removeServer(m_coreController->m_serversController->getServerId(0));
|
||||
QVERIFY2(serverRemovedSpy.count() == 1, "serverRemoved signal should be emitted");
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() == 2, "Should have 2 servers");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 1, "Default should be index 1 (was 2, removed 0)");
|
||||
|
||||
ServerConfig remainingServer1 = m_coreController->m_serversRepository->server(0);
|
||||
ServerConfig remainingServer2 = m_coreController->m_serversRepository->server(1);
|
||||
QString desc1 = remainingServer1.description();
|
||||
QString desc2 = remainingServer2.description();
|
||||
QString desc1 = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(0));
|
||||
QString desc2 = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(1));
|
||||
QVERIFY2(desc1 == "Xray Server", "First remaining server should be Xray");
|
||||
QVERIFY2(desc2 == "WireGuard Server", "Second remaining server should be WireGuard");
|
||||
|
||||
defaultServerChangedSpy.clear();
|
||||
serverRemovedSpy.clear();
|
||||
|
||||
m_coreController->m_serversController->removeServer(0);
|
||||
m_coreController->m_serversController->removeServer(m_coreController->m_serversController->getServerId(0));
|
||||
QVERIFY2(serverRemovedSpy.count() == 1, "serverRemoved signal should be emitted");
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() == 1, "Should have 1 server");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 0, "Default should be index 0 (was 1, removed 0)");
|
||||
|
||||
ServerConfig lastServer = m_coreController->m_serversRepository->server(0);
|
||||
QString lastDesc = lastServer.description();
|
||||
QString lastDesc = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(0));
|
||||
QVERIFY2(lastDesc == "WireGuard Server", "Last server should be WireGuard");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#include <QTest>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QUuid>
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "vpnConnection.h"
|
||||
#include "secureQSettings.h"
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
class TestGatewayStacks : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
CoreController* m_coreController;
|
||||
SecureQSettings* m_settings;
|
||||
|
||||
private slots:
|
||||
void initTestCase() {
|
||||
QString testOrg = "AmneziaVPN-Test-" + QUuid::createUuid().toString();
|
||||
m_settings = new SecureQSettings(testOrg, "amnezia-client", nullptr, false);
|
||||
|
||||
auto vpnConnection = QSharedPointer<VpnConnection>::create(nullptr, nullptr);
|
||||
m_coreController = new CoreController(vpnConnection, m_settings, nullptr, this);
|
||||
}
|
||||
|
||||
void cleanupTestCase() {
|
||||
m_settings->clearSettings();
|
||||
delete m_coreController;
|
||||
delete m_settings;
|
||||
}
|
||||
|
||||
void init() {
|
||||
m_settings->clearSettings();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerConfig>(), -1, false);
|
||||
}
|
||||
}
|
||||
|
||||
void testGatewayStacksRecomputeOnServerOperations() {
|
||||
QString awgKey = "vpn://AAABFHjadZBBT4QwEIX_ipkzS2wBJdyMB1cPXvbgwRgyQnclgZa0RTYS_rszXRa52Mt77TfzOu0EldEeG62sg-J9AhxPUEywF1CAuF3WTl4dRLCXhJIVpVuUEMpWdLdFKaH7FeUb9Mx3scpFk0XTRbOLvlSkKZsOz-Gi4BsdRiV_EGEydhwlg0tWynEZmd5Yz1bkoaK3xpvKtOU3_UFjOE3SsRs-tfIl1rVVzoWQOI9FzC3eonYcU4ZmgkPdwxz9fSYdYafVT4M7-lEJ80cEtTri0PrH_2q4wlW26f1lioe3p5uDsjQWoS_j_Ct2ipvGU6zO2PWtiivT8RPQudHYmqBXzl-3Yn2slBEMTtklgYt4C_Mv3ROMwA";
|
||||
|
||||
QSignalSpy gatewayStacksExpandedSpy(m_coreController->m_serversController, &ServersController::gatewayStacksExpanded);
|
||||
QSignalSpy serverAddedSpy(m_coreController->m_serversRepository, &SecureServersRepository::serverAdded);
|
||||
QSignalSpy serverEditedSpy(m_coreController->m_serversRepository, &SecureServersRepository::serverEdited);
|
||||
QSignalSpy serverRemovedSpy(m_coreController->m_serversRepository, &SecureServersRepository::serverRemoved);
|
||||
|
||||
auto importResult = m_coreController->m_importCoreController->extractConfigFromData(awgKey);
|
||||
m_coreController->m_importCoreController->importConfig(importResult.config);
|
||||
|
||||
QVERIFY2(serverAddedSpy.count() == 1, "serverAdded signal should be emitted");
|
||||
QVERIFY2(m_coreController->m_serversController->gatewayStacks().isEmpty(), "Gateway stacks should be empty for self-hosted servers");
|
||||
|
||||
ServerConfig serverConfig = m_coreController->m_serversController->getServerConfig(0);
|
||||
serverConfig.visit([](auto& arg) {
|
||||
arg.description = "Edited Server";
|
||||
});
|
||||
m_coreController->m_serversController->editServer(0, serverConfig);
|
||||
|
||||
QVERIFY2(serverEditedSpy.count() == 1, "serverEdited signal should be emitted");
|
||||
|
||||
m_coreController->m_serversController->removeServer(0);
|
||||
|
||||
QVERIFY2(serverRemovedSpy.count() == 1, "serverRemoved signal should be emitted");
|
||||
QVERIFY2(m_coreController->m_serversController->gatewayStacks().isEmpty(), "Gateway stacks should remain empty");
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(TestGatewayStacks)
|
||||
#include "testGatewayStacks.moc"
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
#include "tests/testServerRepositoryHelpers.h"
|
||||
#include "vpnConnection.h"
|
||||
#include "secureQSettings.h"
|
||||
|
||||
@@ -40,7 +41,7 @@ private slots:
|
||||
m_settings->clearSettings();
|
||||
m_coreController->m_serversRepository->invalidateCache();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerConfig>(), -1, false);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,8 +71,8 @@ private slots:
|
||||
}
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 0, "First server should be default");
|
||||
|
||||
ServerConfig server1 = m_coreController->m_serversRepository->server(0);
|
||||
QString desc1 = server1.description();
|
||||
QString desc1 = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(0));
|
||||
QVERIFY2(desc1 == "AWG Server", "First server description should match");
|
||||
|
||||
if (m_coreController->m_serversModel) {
|
||||
@@ -92,8 +93,8 @@ private slots:
|
||||
}
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 1, "Second server should be default");
|
||||
|
||||
ServerConfig server2 = m_coreController->m_serversRepository->server(1);
|
||||
QString desc2 = server2.description();
|
||||
QString desc2 = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(1));
|
||||
QVERIFY2(desc2 == "Xray Server", "Second server description should match");
|
||||
|
||||
if (m_coreController->m_serversModel) {
|
||||
@@ -114,8 +115,8 @@ private slots:
|
||||
}
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 2, "Third server should be default");
|
||||
|
||||
ServerConfig server3 = m_coreController->m_serversRepository->server(2);
|
||||
QString desc3 = server3.description();
|
||||
QString desc3 = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(2));
|
||||
QVERIFY2(desc3 == "WireGuard Server", "Third server description should match");
|
||||
|
||||
if (m_coreController->m_serversModel) {
|
||||
@@ -147,25 +148,25 @@ private slots:
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() == 2, "After two imports servers count should be 2");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 1, "Second server should be default");
|
||||
|
||||
ServerConfig server0 = m_coreController->m_serversRepository->server(0);
|
||||
ServerConfig server1 = m_coreController->m_serversRepository->server(1);
|
||||
QString desc0 = server0.description();
|
||||
QString desc1 = server1.description();
|
||||
QString desc0 = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(0));
|
||||
QString desc1 = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(1));
|
||||
QVERIFY2(desc0 == "AWG Server", "First server description should match");
|
||||
QVERIFY2(desc1 == "Xray Server", "Second server description should match");
|
||||
|
||||
defaultServerChangedSpy.clear();
|
||||
serverRemovedSpy.clear();
|
||||
|
||||
m_coreController->m_serversController->removeServer(0);
|
||||
m_coreController->m_serversController->removeServer(m_coreController->m_serversController->getServerId(0));
|
||||
|
||||
QVERIFY2(serverRemovedSpy.count() == 1, "serverRemoved signal should be emitted");
|
||||
QVERIFY2(serverRemovedSpy.at(0).at(0).toInt() == 0, "serverRemoved should emit index 0");
|
||||
QVERIFY2(serverRemovedSpy.at(0).at(1).toInt() == 0, "serverRemoved should emit removed index 0");
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() == 1, "After removing first server, servers count should be 1");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 0, "After removing first server, default index should be 0");
|
||||
|
||||
ServerConfig remainingServer = m_coreController->m_serversRepository->server(0);
|
||||
QString remainingDesc = remainingServer.description();
|
||||
QString remainingDesc = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(0));
|
||||
QVERIFY2(remainingDesc == "Xray Server", "Remaining server should be Xray Server");
|
||||
|
||||
if (m_coreController->m_serversModel) {
|
||||
@@ -177,10 +178,10 @@ private slots:
|
||||
defaultServerChangedSpy.clear();
|
||||
serverRemovedSpy.clear();
|
||||
|
||||
m_coreController->m_serversController->removeServer(0);
|
||||
m_coreController->m_serversController->removeServer(m_coreController->m_serversController->getServerId(0));
|
||||
|
||||
QVERIFY2(serverRemovedSpy.count() == 1, "serverRemoved signal should be emitted");
|
||||
QVERIFY2(serverRemovedSpy.at(0).at(0).toInt() == 0, "serverRemoved should emit index 0");
|
||||
QVERIFY2(serverRemovedSpy.at(0).at(1).toInt() == 0, "serverRemoved should emit removed index 0");
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() == 0, "After removing last server, servers count should be 0");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 0, "After removing last server, default index should be 0");
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/selfhosted/selfHostedServerConfig.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
#include "core/models/selfhosted/selfHostedAdminServerConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/models/protocols/awgProtocolConfig.h"
|
||||
#include "core/models/protocols/dnsProtocolConfig.h"
|
||||
@@ -60,21 +60,24 @@ private:
|
||||
qDebug() << "SSH connection successful. Output:" << sshOutput;
|
||||
}
|
||||
|
||||
void verifyAdminAccess(int serverIndex) {
|
||||
ServerConfig server = m_coreController->m_serversRepository->server(serverIndex);
|
||||
const SelfHostedServerConfig* selfHosted = server.as<SelfHostedServerConfig>();
|
||||
QVERIFY2(selfHosted != nullptr, "Server config should be SelfHostedServerConfig");
|
||||
void verifyAdminAccess(int serverIndex)
|
||||
{
|
||||
const QString serverId = m_coreController->m_serversRepository->serverIdAt(serverIndex);
|
||||
const auto adminCfg = m_coreController->m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
QVERIFY2(adminCfg.has_value(), "Server config should be SelfHostedAdminServerConfig");
|
||||
|
||||
const SelfHostedAdminServerConfig &selfHosted = *adminCfg;
|
||||
|
||||
QVERIFY2(selfHosted->hasCredentials(),
|
||||
QVERIFY2(selfHosted.hasCredentials(),
|
||||
"Server should have credentials (admin access)");
|
||||
|
||||
QVERIFY2(selfHosted->userName.has_value() && !selfHosted->userName.value().isEmpty(),
|
||||
QVERIFY2(!selfHosted.userName.isEmpty(),
|
||||
"Server should have userName for admin access");
|
||||
|
||||
QVERIFY2(selfHosted->password.has_value() && !selfHosted->password.value().isEmpty(),
|
||||
QVERIFY2(!selfHosted.password.isEmpty(),
|
||||
"Server should have password for admin access");
|
||||
|
||||
QVERIFY2(!selfHosted->isReadOnly(),
|
||||
QVERIFY2(!selfHosted.isReadOnly(),
|
||||
"Server should not be read-only (should have admin access)");
|
||||
|
||||
if (m_coreController->m_serversModel) {
|
||||
@@ -143,7 +146,7 @@ private slots:
|
||||
void init() {
|
||||
m_settings->clearSettings();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerConfig>(), -1, false);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,10 +180,10 @@ private slots:
|
||||
int serverIndex = m_coreController->m_serversRepository->serversCount() - 1;
|
||||
qDebug() << "Server with Awg container added at index:" << serverIndex;
|
||||
|
||||
ServerConfig serverAfterAwg = m_coreController->m_serversRepository->server(serverIndex);
|
||||
QVERIFY2(serverAfterAwg.isSelfHosted(), "Server should be self-hosted");
|
||||
const SelfHostedServerConfig* selfHostedAfterAwg = serverAfterAwg.as<SelfHostedServerConfig>();
|
||||
QVERIFY2(selfHostedAfterAwg != nullptr, "Server config should be SelfHostedServerConfig");
|
||||
const auto adminAfterAwg = m_coreController->m_serversRepository->selfHostedAdminConfig(
|
||||
m_coreController->m_serversRepository->serverIdAt(serverIndex));
|
||||
QVERIFY2(adminAfterAwg.has_value(), "Server should be self-hosted (admin)");
|
||||
const SelfHostedAdminServerConfig *selfHostedAfterAwg = &(*adminAfterAwg);
|
||||
QVERIFY2(selfHostedAfterAwg->defaultContainer == DockerContainer::Awg, "Default container should be Awg");
|
||||
QVERIFY2(selfHostedAfterAwg->containers.contains(DockerContainer::Awg), "Server should have Awg container");
|
||||
|
||||
@@ -198,8 +201,9 @@ private slots:
|
||||
TransportProto dnsTransportProto = TransportProto::Udp;
|
||||
bool wasDnsInstalled = false;
|
||||
|
||||
const QString serverIdForOps = m_coreController->m_serversRepository->serverIdAt(serverIndex);
|
||||
ErrorCode installContainerError = m_coreController->m_installController->installContainer(
|
||||
serverIndex, DockerContainer::Dns, dnsPort, dnsTransportProto, wasDnsInstalled);
|
||||
serverIdForOps, DockerContainer::Dns, dnsPort, dnsTransportProto, wasDnsInstalled);
|
||||
|
||||
QVERIFY2(installContainerError == ErrorCode::NoError,
|
||||
QString("installContainer for Dns should succeed. Error: %1")
|
||||
@@ -207,9 +211,10 @@ private slots:
|
||||
.toUtf8().constData());
|
||||
qDebug() << "Dns container installed:" << wasDnsInstalled;
|
||||
|
||||
ServerConfig serverAfterDns = m_coreController->m_serversRepository->server(serverIndex);
|
||||
const SelfHostedServerConfig* selfHostedAfterDns = serverAfterDns.as<SelfHostedServerConfig>();
|
||||
QVERIFY2(selfHostedAfterDns != nullptr, "Server config should be SelfHostedServerConfig");
|
||||
const auto adminAfterDns = m_coreController->m_serversRepository->selfHostedAdminConfig(
|
||||
m_coreController->m_serversRepository->serverIdAt(serverIndex));
|
||||
QVERIFY2(adminAfterDns.has_value(), "Server config should be SelfHostedAdminServerConfig");
|
||||
const SelfHostedAdminServerConfig *selfHostedAfterDns = &(*adminAfterDns);
|
||||
QVERIFY2(selfHostedAfterDns->containers.contains(DockerContainer::Awg), "Server should still have Awg container");
|
||||
QVERIFY2(selfHostedAfterDns->containers.contains(DockerContainer::Dns), "Server should have Dns container");
|
||||
QVERIFY2(selfHostedAfterDns->containers.size() == 2,
|
||||
@@ -242,16 +247,18 @@ private slots:
|
||||
|
||||
verifySshConnection(credentials);
|
||||
|
||||
SelfHostedServerConfig serverConfig;
|
||||
SelfHostedAdminServerConfig serverConfig;
|
||||
serverConfig.hostName = credentials.hostName;
|
||||
serverConfig.userName = credentials.userName;
|
||||
serverConfig.password = credentials.secretData;
|
||||
serverConfig.port = credentials.port;
|
||||
serverConfig.description = m_coreController->m_appSettingsRepository->nextAvailableServerName();
|
||||
serverConfig.displayName = serverConfig.description.isEmpty() ? serverConfig.hostName : serverConfig.description;
|
||||
serverConfig.defaultContainer = DockerContainer::None;
|
||||
|
||||
QSignalSpy serverAddedSpy(m_coreController->m_serversRepository, &SecureServersRepository::serverAdded);
|
||||
m_coreController->m_serversController->addServer(ServerConfig(serverConfig));
|
||||
m_coreController->m_serversRepository->addServer(QString(), serverConfig.toJson(),
|
||||
serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
|
||||
QVERIFY2(serverAddedSpy.count() == 1, "serverAdded signal should be emitted");
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() > 0, "Server should be added");
|
||||
@@ -259,23 +266,25 @@ private slots:
|
||||
int serverIndex = m_coreController->m_serversRepository->serversCount() - 1;
|
||||
qDebug() << "Empty server added at index:" << serverIndex;
|
||||
|
||||
ServerConfig addedServer = m_coreController->m_serversRepository->server(serverIndex);
|
||||
QVERIFY2(addedServer.isSelfHosted(), "Added server should be self-hosted");
|
||||
const SelfHostedServerConfig* selfHosted = addedServer.as<SelfHostedServerConfig>();
|
||||
QVERIFY2(selfHosted != nullptr, "Server config should be SelfHostedServerConfig");
|
||||
const auto addedAdmin = m_coreController->m_serversRepository->selfHostedAdminConfig(
|
||||
m_coreController->m_serversRepository->serverIdAt(serverIndex));
|
||||
QVERIFY2(addedAdmin.has_value(), "Added server should be self-hosted admin");
|
||||
const SelfHostedAdminServerConfig *selfHosted = &(*addedAdmin);
|
||||
QVERIFY2(selfHosted->containers.isEmpty(), "Server should have no containers initially");
|
||||
QVERIFY2(selfHosted->defaultContainer == DockerContainer::None, "Default container should be None");
|
||||
|
||||
ErrorCode scanError = m_coreController->m_installController->scanServerForInstalledContainers(serverIndex);
|
||||
const QString scanServerId = m_coreController->m_serversRepository->serverIdAt(serverIndex);
|
||||
ErrorCode scanError = m_coreController->m_installController->scanServerForInstalledContainers(scanServerId);
|
||||
QVERIFY2(scanError == ErrorCode::NoError,
|
||||
QString("Server scan should succeed. Error: %1")
|
||||
.arg(static_cast<int>(scanError))
|
||||
.toUtf8().constData());
|
||||
qDebug() << "Server scan completed successfully";
|
||||
|
||||
ServerConfig scannedServer = m_coreController->m_serversRepository->server(serverIndex);
|
||||
const SelfHostedServerConfig* scannedSelfHosted = scannedServer.as<SelfHostedServerConfig>();
|
||||
QVERIFY2(scannedSelfHosted != nullptr, "Scanned server config should be SelfHostedServerConfig");
|
||||
const auto scannedAdmin = m_coreController->m_serversRepository->selfHostedAdminConfig(
|
||||
m_coreController->m_serversRepository->serverIdAt(serverIndex));
|
||||
QVERIFY2(scannedAdmin.has_value(), "Scanned server config should be SelfHostedAdminServerConfig");
|
||||
const SelfHostedAdminServerConfig *scannedSelfHosted = &(*scannedAdmin);
|
||||
|
||||
QMap<DockerContainer, ContainerConfig> containers = scannedSelfHosted->containers;
|
||||
int containersCount = containers.size();
|
||||
@@ -336,24 +345,27 @@ private slots:
|
||||
int serverIndex = m_coreController->m_serversRepository->serversCount() - 1;
|
||||
qDebug() << "Server with Awg container added at index:" << serverIndex;
|
||||
|
||||
ServerConfig serverBeforeRemoval = m_coreController->m_serversRepository->server(serverIndex);
|
||||
const SelfHostedServerConfig* selfHostedBeforeRemoval = serverBeforeRemoval.as<SelfHostedServerConfig>();
|
||||
QVERIFY2(selfHostedBeforeRemoval != nullptr, "Server config should be SelfHostedServerConfig");
|
||||
const auto adminBeforeRemoval = m_coreController->m_serversRepository->selfHostedAdminConfig(
|
||||
m_coreController->m_serversRepository->serverIdAt(serverIndex));
|
||||
QVERIFY2(adminBeforeRemoval.has_value(), "Server config should be SelfHostedAdminServerConfig");
|
||||
const SelfHostedAdminServerConfig *selfHostedBeforeRemoval = &(*adminBeforeRemoval);
|
||||
QVERIFY2(!selfHostedBeforeRemoval->containers.isEmpty(), "Server should have containers before removal");
|
||||
QVERIFY2(selfHostedBeforeRemoval->defaultContainer != DockerContainer::None, "Server should have default container before removal");
|
||||
|
||||
qDebug() << "Containers before removal:" << selfHostedBeforeRemoval->containers.size();
|
||||
|
||||
ErrorCode removeError = m_coreController->m_installController->removeAllContainers(serverIndex);
|
||||
const QString removeServerId = m_coreController->m_serversRepository->serverIdAt(serverIndex);
|
||||
ErrorCode removeError = m_coreController->m_installController->removeAllContainers(removeServerId);
|
||||
QVERIFY2(removeError == ErrorCode::NoError,
|
||||
QString("removeAllContainers should succeed. Error: %1")
|
||||
.arg(static_cast<int>(removeError))
|
||||
.toUtf8().constData());
|
||||
qDebug() << "All containers removed successfully";
|
||||
|
||||
ServerConfig serverAfterRemoval = m_coreController->m_serversRepository->server(serverIndex);
|
||||
const SelfHostedServerConfig* selfHostedAfterRemoval = serverAfterRemoval.as<SelfHostedServerConfig>();
|
||||
QVERIFY2(selfHostedAfterRemoval != nullptr, "Server config should be SelfHostedServerConfig");
|
||||
const auto adminAfterRemoval = m_coreController->m_serversRepository->selfHostedAdminConfig(
|
||||
m_coreController->m_serversRepository->serverIdAt(serverIndex));
|
||||
QVERIFY2(adminAfterRemoval.has_value(), "Server config should be SelfHostedAdminServerConfig");
|
||||
const SelfHostedAdminServerConfig *selfHostedAfterRemoval = &(*adminAfterRemoval);
|
||||
|
||||
QVERIFY2(selfHostedAfterRemoval->containers.isEmpty(),
|
||||
"Server should have no containers after removal");
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#include <QTest>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QUuid>
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/repositories/secureServersRepository.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
#include "core/models/selfhosted/selfHostedAdminServerConfig.h"
|
||||
#include "vpnConnection.h"
|
||||
#include "secureQSettings.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
@@ -38,7 +40,7 @@ private slots:
|
||||
m_settings->clearSettings();
|
||||
m_coreController->m_serversRepository->invalidateCache();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerConfig>(), -1, false);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,27 +56,32 @@ private slots:
|
||||
QSignalSpy serverEditedSpy(m_coreController->m_serversRepository, &SecureServersRepository::serverEdited);
|
||||
QSignalSpy defaultServerChangedSpy(m_coreController->m_serversRepository, &SecureServersRepository::defaultServerChanged);
|
||||
|
||||
m_coreController->m_serversController->removeServer(-1);
|
||||
m_coreController->m_serversController->removeServer(m_coreController->m_serversController->getServerId(-1));
|
||||
QVERIFY2(serverRemovedSpy.count() == 0, "serverRemoved should NOT be emitted for invalid index");
|
||||
|
||||
m_coreController->m_serversController->removeServer(10);
|
||||
m_coreController->m_serversController->removeServer(m_coreController->m_serversController->getServerId(10));
|
||||
QVERIFY2(serverRemovedSpy.count() == 0, "serverRemoved should NOT be emitted for invalid index");
|
||||
|
||||
m_coreController->m_serversController->removeServer(100);
|
||||
m_coreController->m_serversController->removeServer(m_coreController->m_serversController->getServerId(100));
|
||||
QVERIFY2(serverRemovedSpy.count() == 0, "serverRemoved should NOT be emitted for invalid index");
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() == 1, "Server count should remain 1");
|
||||
|
||||
ServerConfig serverConfig = m_coreController->m_serversController->getServerConfig(0);
|
||||
m_coreController->m_serversController->editServer(-1, serverConfig);
|
||||
const QString validServerId = m_coreController->m_serversController->getServerId(0);
|
||||
const serverConfigUtils::ConfigType editKind =
|
||||
m_coreController->m_serversRepository->serverKind(validServerId);
|
||||
|
||||
m_coreController->m_serversRepository->editServer(m_coreController->m_serversController->getServerId(-1),
|
||||
QJsonObject(), editKind);
|
||||
QVERIFY2(serverEditedSpy.count() == 0, "serverEdited should NOT be emitted for invalid index");
|
||||
|
||||
m_coreController->m_serversController->editServer(10, serverConfig);
|
||||
m_coreController->m_serversRepository->editServer(m_coreController->m_serversController->getServerId(10),
|
||||
QJsonObject(), editKind);
|
||||
QVERIFY2(serverEditedSpy.count() == 0, "serverEdited should NOT be emitted for invalid index");
|
||||
|
||||
m_coreController->m_serversController->setDefaultServerIndex(-1);
|
||||
m_coreController->m_serversController->setDefaultServer(m_coreController->m_serversController->getServerId(-1));
|
||||
QVERIFY2(defaultServerChangedSpy.count() == 0, "defaultServerChanged should NOT be emitted for invalid index");
|
||||
|
||||
m_coreController->m_serversController->setDefaultServerIndex(10);
|
||||
m_coreController->m_serversController->setDefaultServer(m_coreController->m_serversController->getServerId(10));
|
||||
QVERIFY2(defaultServerChangedSpy.count() == 0, "defaultServerChanged should NOT be emitted for invalid index");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 0, "Default server index should remain 0");
|
||||
}
|
||||
@@ -86,14 +93,15 @@ private slots:
|
||||
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() == 0, "Should start with 0 servers");
|
||||
|
||||
ServerConfig emptyConfig = SelfHostedServerConfig{};
|
||||
m_coreController->m_serversController->removeServer(0);
|
||||
m_coreController->m_serversController->removeServer(m_coreController->m_serversController->getServerId(0));
|
||||
QVERIFY2(serverRemovedSpy.count() == 0, "serverRemoved should NOT be emitted for empty repository");
|
||||
|
||||
m_coreController->m_serversController->editServer(0, emptyConfig);
|
||||
m_coreController->m_serversRepository->editServer(m_coreController->m_serversController->getServerId(0),
|
||||
SelfHostedAdminServerConfig {}.toJson(),
|
||||
serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
QVERIFY2(serverEditedSpy.count() == 0, "serverEdited should NOT be emitted for empty repository");
|
||||
|
||||
m_coreController->m_serversController->setDefaultServerIndex(0);
|
||||
m_coreController->m_serversController->setDefaultServer(m_coreController->m_serversController->getServerId(0));
|
||||
QVERIFY2(defaultServerChangedSpy.count() == 0, "defaultServerChanged should NOT be emitted for empty repository");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 0, "Default server index should be 0 for empty repository");
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
#include "tests/testServerRepositoryHelpers.h"
|
||||
#include "ui/models/serversModel.h"
|
||||
#include "vpnConnection.h"
|
||||
#include "secureQSettings.h"
|
||||
@@ -39,7 +40,7 @@ private slots:
|
||||
m_settings->clearSettings();
|
||||
m_coreController->m_serversRepository->invalidateCache();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerConfig>(), -1, false);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,20 +53,17 @@ private slots:
|
||||
QVERIFY2(importFinishedSpy.count() == 1, "Import should succeed");
|
||||
|
||||
QSignalSpy serverEditedSpy(m_coreController->m_serversRepository, &SecureServersRepository::serverEdited);
|
||||
QSignalSpy gatewayStacksExpandedSpy(m_coreController->m_serversController, &ServersController::gatewayStacksExpanded);
|
||||
|
||||
ServerConfig serverConfig = m_coreController->m_serversController->getServerConfig(0);
|
||||
serverConfig.visit([](auto& arg) {
|
||||
arg.description = "Edited AWG Server";
|
||||
});
|
||||
|
||||
m_coreController->m_serversController->editServer(0, serverConfig);
|
||||
amnezia::test::setServerDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversController->getServerId(0),
|
||||
QStringLiteral("Edited AWG Server"));
|
||||
|
||||
QVERIFY2(serverEditedSpy.count() == 1, "serverEdited signal should be emitted");
|
||||
QVERIFY2(serverEditedSpy.at(0).at(0).toInt() == 0, "serverEdited should emit index 0");
|
||||
QVERIFY2(serverEditedSpy.at(0).at(0).toString() == m_coreController->m_serversRepository->serverIdAt(0),
|
||||
"serverEdited should emit edited server id");
|
||||
|
||||
ServerConfig editedServer = m_coreController->m_serversRepository->server(0);
|
||||
QString editedDesc = editedServer.description();
|
||||
const QString editedDesc = amnezia::test::serverDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversRepository->serverIdAt(0));
|
||||
QVERIFY2(editedDesc == "Edited AWG Server", "Server description should be updated");
|
||||
|
||||
if (m_coreController->m_serversModel) {
|
||||
@@ -87,20 +85,16 @@ private slots:
|
||||
|
||||
QSignalSpy defaultServerChangedSpy(m_coreController->m_serversRepository, &SecureServersRepository::defaultServerChanged);
|
||||
|
||||
ServerConfig defaultServerConfig = m_coreController->m_serversController->getServerConfig(1);
|
||||
defaultServerConfig.visit([](auto& arg) {
|
||||
arg.description = "Edited Default Server";
|
||||
});
|
||||
m_coreController->m_serversController->editServer(1, defaultServerConfig);
|
||||
amnezia::test::setServerDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversController->getServerId(1),
|
||||
QStringLiteral("Edited Default Server"));
|
||||
|
||||
QVERIFY2(defaultServerChangedSpy.count() == 0, "defaultServerChanged should NOT be emitted when editing default server");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 1, "Default server index should remain 1");
|
||||
|
||||
ServerConfig nonDefaultServerConfig = m_coreController->m_serversController->getServerConfig(0);
|
||||
nonDefaultServerConfig.visit([](auto& arg) {
|
||||
arg.description = "Edited Non-Default Server";
|
||||
});
|
||||
m_coreController->m_serversController->editServer(0, nonDefaultServerConfig);
|
||||
amnezia::test::setServerDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversController->getServerId(0),
|
||||
QStringLiteral("Edited Non-Default Server"));
|
||||
|
||||
QVERIFY2(defaultServerChangedSpy.count() == 0, "defaultServerChanged should NOT be emitted when editing non-default server");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 1, "Default server index should remain 1");
|
||||
|
||||
93
client/tests/testServerRepositoryHelpers.h
Normal file
93
client/tests/testServerRepositoryHelpers.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#ifndef TESTSERVERREPOSITORYHELPERS_H
|
||||
#define TESTSERVERREPOSITORYHELPERS_H
|
||||
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "core/repositories/secureServersRepository.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
|
||||
namespace amnezia::test
|
||||
{
|
||||
|
||||
inline QString serverDescription(SecureServersRepository *repo, const QString &serverId)
|
||||
{
|
||||
switch (repo->serverKind(serverId)) {
|
||||
case serverConfigUtils::ConfigType::SelfHostedAdmin: {
|
||||
const auto cfg = repo->selfHostedAdminConfig(serverId);
|
||||
return cfg.has_value() ? cfg->description : QString();
|
||||
}
|
||||
case serverConfigUtils::ConfigType::SelfHostedUser: {
|
||||
const auto cfg = repo->selfHostedUserConfig(serverId);
|
||||
return cfg.has_value() ? cfg->description : QString();
|
||||
}
|
||||
case serverConfigUtils::ConfigType::Native: {
|
||||
const auto cfg = repo->nativeConfig(serverId);
|
||||
return cfg.has_value() ? cfg->description : QString();
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV2:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV3:
|
||||
case serverConfigUtils::ConfigType::ExternalPremium: {
|
||||
const auto cfg = repo->apiV2Config(serverId);
|
||||
return cfg.has_value() ? cfg->description : QString();
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV1:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV2: {
|
||||
const auto cfg = repo->legacyApiConfig(serverId);
|
||||
return cfg.has_value() ? cfg->description : QString();
|
||||
}
|
||||
case serverConfigUtils::ConfigType::Invalid:
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
inline void setServerDescription(SecureServersRepository *repo, const QString &serverId, const QString &description)
|
||||
{
|
||||
const serverConfigUtils::ConfigType kind = repo->serverKind(serverId);
|
||||
switch (kind) {
|
||||
case serverConfigUtils::ConfigType::SelfHostedAdmin: {
|
||||
auto cfg = repo->selfHostedAdminConfig(serverId);
|
||||
if (!cfg.has_value()) return;
|
||||
cfg->description = description;
|
||||
cfg->displayName = description;
|
||||
repo->editServer(serverId, cfg->toJson(), kind);
|
||||
return;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::SelfHostedUser: {
|
||||
auto cfg = repo->selfHostedUserConfig(serverId);
|
||||
if (!cfg.has_value()) return;
|
||||
cfg->description = description;
|
||||
cfg->displayName = description;
|
||||
repo->editServer(serverId, cfg->toJson(), kind);
|
||||
return;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::Native: {
|
||||
auto cfg = repo->nativeConfig(serverId);
|
||||
if (!cfg.has_value()) return;
|
||||
cfg->description = description;
|
||||
cfg->displayName = description;
|
||||
repo->editServer(serverId, cfg->toJson(), kind);
|
||||
return;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV2:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV3:
|
||||
case serverConfigUtils::ConfigType::ExternalPremium: {
|
||||
auto cfg = repo->apiV2Config(serverId);
|
||||
if (!cfg.has_value()) return;
|
||||
cfg->description = description;
|
||||
cfg->displayName = description;
|
||||
repo->editServer(serverId, cfg->toJson(), kind);
|
||||
return;
|
||||
}
|
||||
case serverConfigUtils::ConfigType::AmneziaPremiumV1:
|
||||
case serverConfigUtils::ConfigType::AmneziaFreeV2:
|
||||
case serverConfigUtils::ConfigType::Invalid:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace amnezia::test
|
||||
|
||||
#endif
|
||||
@@ -5,7 +5,8 @@
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
#include "tests/testServerRepositoryHelpers.h"
|
||||
#include "ui/models/serversModel.h"
|
||||
#include "vpnConnection.h"
|
||||
#include "secureQSettings.h"
|
||||
@@ -38,7 +39,7 @@ private slots:
|
||||
void init() {
|
||||
m_settings->clearSettings();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerConfig>(), -1, false);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,16 +59,14 @@ private slots:
|
||||
QString modelDesc1 = m_coreController->m_serversModel->data(m_coreController->m_serversModel->index(0, 0), ServersModel::NameRole).toString();
|
||||
QVERIFY2(modelDesc1 == "AWG Server", "Model should have correct server name");
|
||||
|
||||
ServerConfig serverConfig = m_coreController->m_serversController->getServerConfig(0);
|
||||
serverConfig.visit([](auto& arg) {
|
||||
arg.description = "Edited AWG Server";
|
||||
});
|
||||
m_coreController->m_serversController->editServer(0, serverConfig);
|
||||
amnezia::test::setServerDescription(m_coreController->m_serversRepository,
|
||||
m_coreController->m_serversController->getServerId(0),
|
||||
QStringLiteral("Edited AWG Server"));
|
||||
|
||||
QString modelDesc2 = m_coreController->m_serversModel->data(m_coreController->m_serversModel->index(0, 0), ServersModel::NameRole).toString();
|
||||
QVERIFY2(modelDesc2 == "Edited AWG Server", "Model should be updated after edit");
|
||||
|
||||
m_coreController->m_serversController->removeServer(0);
|
||||
m_coreController->m_serversController->removeServer(m_coreController->m_serversController->getServerId(0));
|
||||
QVERIFY2(m_coreController->m_serversModel->rowCount() == 0, "Model should have 0 rows after removal");
|
||||
}
|
||||
|
||||
@@ -98,7 +97,7 @@ private slots:
|
||||
QVERIFY2(!isDefault1, "Server 1 should not be default");
|
||||
QVERIFY2(isDefault2, "Server 2 should be default");
|
||||
|
||||
m_coreController->m_serversController->setDefaultServerIndex(0);
|
||||
m_coreController->m_serversController->setDefaultServer(m_coreController->m_serversController->getServerId(0));
|
||||
|
||||
isDefault0 = m_coreController->m_serversModel->data(m_coreController->m_serversModel->index(0, 0), ServersModel::IsDefaultRole).toBool();
|
||||
isDefault2 = m_coreController->m_serversModel->data(m_coreController->m_serversModel->index(2, 0), ServersModel::IsDefaultRole).toBool();
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <QLocale>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "ui/controllers/settingsUiController.h"
|
||||
#include "ui/controllers/languageUiController.h"
|
||||
#include "ui/models/allowedDnsModel.h"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
#include "vpnConnection.h"
|
||||
#include "secureQSettings.h"
|
||||
|
||||
@@ -38,7 +38,7 @@ private slots:
|
||||
m_settings->clearSettings();
|
||||
m_coreController->m_serversRepository->invalidateCache();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerConfig>(), -1, false);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,11 +73,12 @@ private slots:
|
||||
QSignalSpy serverRemovedSpy(m_coreController->m_serversRepository, &SecureServersRepository::serverRemoved);
|
||||
QSignalSpy defaultServerChangedSpy(m_coreController->m_serversRepository, &SecureServersRepository::defaultServerChanged);
|
||||
|
||||
m_coreController->m_serversController->removeServer(1);
|
||||
m_coreController->m_serversController->removeServer(m_coreController->m_serversController->getServerId(1));
|
||||
|
||||
QVERIFY2(serverRemovedSpy.count() == 1, "serverRemoved signal should be emitted");
|
||||
QVERIFY2(defaultServerChangedSpy.count() == 1, "defaultServerChanged signal should be emitted when removing default server");
|
||||
QVERIFY2(defaultServerChangedSpy.at(0).at(0).toInt() == 0, "defaultServerChanged should emit new default index 0");
|
||||
QVERIFY2(defaultServerChangedSpy.at(0).at(0).toString() == m_coreController->m_serversRepository->defaultServerId(),
|
||||
"defaultServerChanged should emit new default server id");
|
||||
QVERIFY2(m_coreController->m_serversRepository->defaultServerIndex() == 0, "Default server index should be 0");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <QModelIndex>
|
||||
|
||||
#include "core/controllers/coreController.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
#include "core/controllers/selfhosted/importController.h"
|
||||
#include "ui/models/serversModel.h"
|
||||
#include "ui/models/containersModel.h"
|
||||
@@ -23,6 +23,18 @@ using namespace amnezia;
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
namespace {
|
||||
int defaultServerRow(const QVector<ServerDescription> &descriptions, const QString &defaultServerId)
|
||||
{
|
||||
for (int i = 0; i < descriptions.size(); ++i) {
|
||||
if (descriptions.at(i).serverId == defaultServerId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class TestUiServersModelAndController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -119,7 +131,7 @@ private slots:
|
||||
void init() {
|
||||
m_settings->clearSettings();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerConfig>(), -1, false);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,11 +178,9 @@ private slots:
|
||||
}
|
||||
|
||||
if (m_coreController->m_serversUiController) {
|
||||
m_coreController->m_serversUiController->setProcessedServerIndex(serverIndex);
|
||||
|
||||
ServerConfig serverConfig = m_coreController->m_serversRepository->server(serverIndex);
|
||||
QString actualServerName = serverConfig.description();
|
||||
QString containerName = ContainerUtils::containerHumanNames().value(DockerContainer::Awg);
|
||||
m_coreController->m_serversUiController->setProcessedServerId(
|
||||
m_coreController->m_serversUiController->getServerId(0));
|
||||
|
||||
QString hostName = "test.example.com";
|
||||
|
||||
QString collapsedDescription = m_coreController->m_serversUiController->getDefaultServerDescriptionCollapsed();
|
||||
@@ -261,27 +271,29 @@ private slots:
|
||||
m_coreController->m_importCoreController->importConfig(configNoDns);
|
||||
QVERIFY2(importFinishedSpy.count() == 1, "importFinished should be emitted");
|
||||
m_coreController->m_appSettingsRepository->setUseAmneziaDns(false);
|
||||
m_coreController->m_serversModel->updateModel(
|
||||
m_coreController->m_serversRepository->servers(),
|
||||
m_coreController->m_serversRepository->defaultServerIndex(),
|
||||
QVector<ServerDescription> descriptionsNoDns = m_coreController->m_serversController->buildServerDescriptions(
|
||||
m_coreController->m_appSettingsRepository->useAmneziaDns());
|
||||
const QString defIdNoDns = m_coreController->m_serversRepository->defaultServerId();
|
||||
m_coreController->m_serversModel->updateModel(descriptionsNoDns, defaultServerRow(descriptionsNoDns, defIdNoDns));
|
||||
|
||||
QString descNoDns = m_coreController->m_serversModel->data(
|
||||
m_coreController->m_serversModel->index(0, 0), ServersModel::ServerDescriptionRole).toString();
|
||||
QVERIFY2(descNoDns == "test.example.com",
|
||||
QString("Without Amnezia DNS expected 'test.example.com', got '%1'").arg(descNoDns).toUtf8().constData());
|
||||
|
||||
m_coreController->m_serversRepository->setServersArray(QJsonArray());
|
||||
m_coreController->m_serversRepository->setDefaultServer(0);
|
||||
m_coreController->m_serversRepository->clearServers();
|
||||
if (m_coreController->m_serversRepository->serversCount() > 0) {
|
||||
m_coreController->m_serversRepository->setDefaultServer(m_coreController->m_serversRepository->serverIdAt(0));
|
||||
}
|
||||
|
||||
QJsonObject configWithDns = createServerDescriptionTestConfig(true);
|
||||
m_coreController->m_importCoreController->importConfig(configWithDns);
|
||||
QVERIFY2(m_coreController->m_serversRepository->serversCount() == 1, "Server should be imported");
|
||||
m_coreController->m_appSettingsRepository->setUseAmneziaDns(true);
|
||||
m_coreController->m_serversModel->updateModel(
|
||||
m_coreController->m_serversRepository->servers(),
|
||||
m_coreController->m_serversRepository->defaultServerIndex(),
|
||||
QVector<ServerDescription> descriptionsWithDns = m_coreController->m_serversController->buildServerDescriptions(
|
||||
m_coreController->m_appSettingsRepository->useAmneziaDns());
|
||||
const QString defIdWithDns = m_coreController->m_serversRepository->defaultServerId();
|
||||
m_coreController->m_serversModel->updateModel(descriptionsWithDns, defaultServerRow(descriptionsWithDns, defIdWithDns));
|
||||
|
||||
QString descWithDns = m_coreController->m_serversModel->data(
|
||||
m_coreController->m_serversModel->index(0, 0), ServersModel::ServerDescriptionRole).toString();
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
|
||||
#include "amneziaApplication.h"
|
||||
#include "core/configurators/wireguardConfigurator.h"
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
#include "core/utils/qrCodeUtils.h"
|
||||
#include "ui/controllers/systemController.h"
|
||||
#include "version.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include <QClipboard>
|
||||
#include <QDebug>
|
||||
#include <QSet>
|
||||
@@ -67,7 +66,17 @@ SubscriptionUiController::SubscriptionUiController(ServersController* serversCon
|
||||
ApiDevicesModel* apiDevicesModel,
|
||||
SettingsController* settingsController,
|
||||
QObject *parent)
|
||||
: QObject(parent), m_serversController(serversController), m_apiServicesModel(apiServicesModel), m_servicesCatalogController(servicesCatalogController), m_subscriptionController(subscriptionController), m_apiSubscriptionPlansModel(apiSubscriptionPlansModel), m_apiBenefitsModel(apiBenefitsModel), m_apiAccountInfoModel(apiAccountInfoModel), m_apiCountryModel(apiCountryModel), m_apiDevicesModel(apiDevicesModel), m_settingsController(settingsController)
|
||||
: QObject(parent),
|
||||
m_serversController(serversController),
|
||||
m_apiServicesModel(apiServicesModel),
|
||||
m_servicesCatalogController(servicesCatalogController),
|
||||
m_subscriptionController(subscriptionController),
|
||||
m_apiSubscriptionPlansModel(apiSubscriptionPlansModel),
|
||||
m_apiBenefitsModel(apiBenefitsModel),
|
||||
m_apiAccountInfoModel(apiAccountInfoModel),
|
||||
m_apiCountryModel(apiCountryModel),
|
||||
m_apiDevicesModel(apiDevicesModel),
|
||||
m_settingsController(settingsController)
|
||||
{
|
||||
connect(m_apiServicesModel, &ApiServicesModel::serviceSelectionChanged, this, [this]() {
|
||||
ApiServicesModel::ApiServicesData selectedServiceData = m_apiServicesModel->selectedServiceData();
|
||||
@@ -76,14 +85,14 @@ SubscriptionUiController::SubscriptionUiController(ServersController* serversCon
|
||||
});
|
||||
}
|
||||
|
||||
bool SubscriptionUiController::exportVpnKey(int serverIndex, const QString &fileName)
|
||||
bool SubscriptionUiController::exportVpnKey(const QString &serverId, const QString &fileName)
|
||||
{
|
||||
if (fileName.isEmpty()) {
|
||||
emit errorOccurred(ErrorCode::PermissionsError);
|
||||
return false;
|
||||
}
|
||||
|
||||
prepareVpnKeyExport(serverIndex);
|
||||
prepareVpnKeyExport(serverId);
|
||||
if (m_vpnKey.isEmpty()) {
|
||||
emit errorOccurred(ErrorCode::ApiConfigEmptyError);
|
||||
return false;
|
||||
@@ -93,7 +102,8 @@ bool SubscriptionUiController::exportVpnKey(int serverIndex, const QString &file
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SubscriptionUiController::exportNativeConfig(int serverIndex, const QString &serverCountryCode, const QString &fileName)
|
||||
|
||||
bool SubscriptionUiController::exportNativeConfig(const QString &serverId, const QString &serverCountryCode, const QString &fileName)
|
||||
{
|
||||
if (fileName.isEmpty()) {
|
||||
emit errorOccurred(ErrorCode::PermissionsError);
|
||||
@@ -101,7 +111,7 @@ bool SubscriptionUiController::exportNativeConfig(int serverIndex, const QString
|
||||
}
|
||||
|
||||
QString nativeConfig;
|
||||
ErrorCode errorCode = m_subscriptionController->exportNativeConfig(serverIndex, serverCountryCode, nativeConfig);
|
||||
ErrorCode errorCode = m_subscriptionController->exportNativeConfig(serverId, serverCountryCode, nativeConfig);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit errorOccurred(errorCode);
|
||||
return false;
|
||||
@@ -111,9 +121,10 @@ bool SubscriptionUiController::exportNativeConfig(int serverIndex, const QString
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SubscriptionUiController::revokeNativeConfig(int serverIndex, const QString &serverCountryCode)
|
||||
|
||||
bool SubscriptionUiController::revokeNativeConfig(const QString &serverId, const QString &serverCountryCode)
|
||||
{
|
||||
ErrorCode errorCode = m_subscriptionController->revokeNativeConfig(serverIndex, serverCountryCode);
|
||||
ErrorCode errorCode = m_subscriptionController->revokeNativeConfig(serverId, serverCountryCode);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit errorOccurred(errorCode);
|
||||
return false;
|
||||
@@ -121,10 +132,11 @@ bool SubscriptionUiController::revokeNativeConfig(int serverIndex, const QString
|
||||
return true;
|
||||
}
|
||||
|
||||
void SubscriptionUiController::prepareVpnKeyExport(int serverIndex)
|
||||
|
||||
void SubscriptionUiController::prepareVpnKeyExport(const QString &serverId)
|
||||
{
|
||||
QString vpnKey;
|
||||
ErrorCode errorCode = m_subscriptionController->prepareVpnKeyExport(serverIndex, vpnKey);
|
||||
ErrorCode errorCode = m_subscriptionController->prepareVpnKeyExport(serverId, vpnKey);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit errorOccurred(errorCode);
|
||||
return;
|
||||
@@ -140,6 +152,7 @@ void SubscriptionUiController::prepareVpnKeyExport(int serverIndex)
|
||||
emit vpnKeyExportReady();
|
||||
}
|
||||
|
||||
|
||||
void SubscriptionUiController::copyVpnKeyToClipboard()
|
||||
{
|
||||
auto clipboard = amnApp->getClipboard();
|
||||
@@ -170,14 +183,12 @@ bool SubscriptionUiController::importPremiumFromAppStore(const QString &storePro
|
||||
productId = QStringLiteral("amnezia_premium_6_month");
|
||||
}
|
||||
|
||||
ServerConfig serverConfig;
|
||||
int duplicateServerIndex = -1;
|
||||
ErrorCode errorCode = m_subscriptionController->processAppStorePurchase(
|
||||
m_apiServicesModel->getCountryCode(),
|
||||
m_apiServicesModel->getSelectedServiceType(),
|
||||
m_apiServicesModel->getSelectedServiceProtocol(),
|
||||
productId,
|
||||
serverConfig,
|
||||
&duplicateServerIndex);
|
||||
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
@@ -260,11 +271,8 @@ bool SubscriptionUiController::importFreeFromGateway()
|
||||
}
|
||||
|
||||
SubscriptionController::ProtocolData protocolData = m_subscriptionController->generateProtocolData(serviceProtocol);
|
||||
|
||||
ServerConfig serverConfig;
|
||||
ErrorCode errorCode = m_subscriptionController->importServiceFromGateway(userCountryCode, serviceType,
|
||||
serviceProtocol, protocolData,
|
||||
serverConfig);
|
||||
serviceProtocol, protocolData);
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
emit installServerFromApiFinished(tr("%1 installed successfully.").arg(m_apiServicesModel->getSelectedServiceName()));
|
||||
@@ -278,12 +286,10 @@ bool SubscriptionUiController::importFreeFromGateway()
|
||||
bool SubscriptionUiController::importTrialFromGateway(const QString &email)
|
||||
{
|
||||
emit trialEmailError(QString());
|
||||
ServerConfig serverConfig;
|
||||
ErrorCode errorCode = m_subscriptionController->importTrialFromGateway(m_apiServicesModel->getCountryCode(),
|
||||
m_apiServicesModel->getSelectedServiceType(),
|
||||
m_apiServicesModel->getSelectedServiceProtocol(),
|
||||
email,
|
||||
serverConfig);
|
||||
email);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
if (errorCode == ErrorCode::ApiTrialAlreadyUsedError) {
|
||||
emit trialEmailError(
|
||||
@@ -298,21 +304,17 @@ bool SubscriptionUiController::importTrialFromGateway(const QString &email)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SubscriptionUiController::updateServiceFromGateway(const int serverIndex, const QString &newCountryCode, const QString &newCountryName,
|
||||
bool SubscriptionUiController::updateServiceFromGateway(const QString &serverId, const QString &newCountryCode, const QString &newCountryName,
|
||||
bool reloadServiceConfig)
|
||||
{
|
||||
bool isConnectEvent = newCountryCode.isEmpty() && newCountryName.isEmpty() && !reloadServiceConfig;
|
||||
bool wasSubscriptionExpired = false;
|
||||
ServerConfig oldServerConfig = m_serversController->getServerConfig(serverIndex);
|
||||
if (oldServerConfig.isApiV2()) {
|
||||
const ApiV2ServerConfig *oldApiV2 = oldServerConfig.as<ApiV2ServerConfig>();
|
||||
if (oldApiV2) {
|
||||
wasSubscriptionExpired = oldApiV2->apiConfig.subscriptionExpiredByServer
|
||||
|| oldApiV2->apiConfig.isSubscriptionExpired();
|
||||
}
|
||||
if (const auto oldApiV2 = m_serversController->apiV2Config(serverId)) {
|
||||
wasSubscriptionExpired = oldApiV2->apiConfig.subscriptionExpiredByServer
|
||||
|| oldApiV2->apiConfig.isSubscriptionExpired();
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_subscriptionController->updateServiceFromGateway(serverIndex, newCountryCode, isConnectEvent);
|
||||
ErrorCode errorCode = m_subscriptionController->updateServiceFromGateway(serverId, newCountryCode, isConnectEvent);
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
if (wasSubscriptionExpired) {
|
||||
@@ -336,27 +338,10 @@ bool SubscriptionUiController::updateServiceFromGateway(const int serverIndex, c
|
||||
}
|
||||
}
|
||||
|
||||
bool SubscriptionUiController::updateServiceFromTelegram(const int serverIndex)
|
||||
|
||||
bool SubscriptionUiController::deactivateDevice(const QString &serverId)
|
||||
{
|
||||
#ifdef Q_OS_IOS
|
||||
IosController::Instance()->requestInetAccess();
|
||||
QThread::msleep(10);
|
||||
#endif
|
||||
|
||||
ErrorCode errorCode = m_subscriptionController->updateServiceFromTelegram(serverIndex);
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
emit updateServerFromApiFinished();
|
||||
return true;
|
||||
} else {
|
||||
emit errorOccurred(errorCode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SubscriptionUiController::deactivateDevice(int serverIndex)
|
||||
{
|
||||
ErrorCode errorCode = m_subscriptionController->deactivateDevice(serverIndex);
|
||||
ErrorCode errorCode = m_subscriptionController->deactivateDevice(serverId);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit errorOccurred(errorCode);
|
||||
return false;
|
||||
@@ -365,9 +350,10 @@ bool SubscriptionUiController::deactivateDevice(int serverIndex)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SubscriptionUiController::deactivateExternalDevice(int serverIndex, const QString &uuid, const QString &serverCountryCode)
|
||||
|
||||
bool SubscriptionUiController::deactivateExternalDevice(const QString &serverId, const QString &uuid, const QString &serverCountryCode)
|
||||
{
|
||||
ErrorCode errorCode = m_subscriptionController->deactivateExternalDevice(serverIndex, uuid, serverCountryCode);
|
||||
ErrorCode errorCode = m_subscriptionController->deactivateExternalDevice(serverId, uuid, serverCountryCode);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit errorOccurred(errorCode);
|
||||
return false;
|
||||
@@ -376,12 +362,19 @@ bool SubscriptionUiController::deactivateExternalDevice(int serverIndex, const Q
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SubscriptionUiController::validateConfig()
|
||||
{
|
||||
int serverIndex = m_serversController->getDefaultServerIndex();
|
||||
bool hasInstalledContainers = m_serversController->hasInstalledContainers(serverIndex);
|
||||
const QString serverId = m_serversController->getDefaultServerId();
|
||||
if (!serverId.isEmpty() && m_serversController->isLegacyApiV1Server(serverId)) {
|
||||
emit unsupportedConnectDrawerRequested();
|
||||
emit configValidated(false);
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_subscriptionController->validateAndUpdateConfig(serverIndex, hasInstalledContainers);
|
||||
bool hasInstalledContainers = m_serversController->hasInstalledContainers(serverId);
|
||||
|
||||
ErrorCode errorCode = m_subscriptionController->validateAndUpdateConfig(serverId, hasInstalledContainers);
|
||||
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
if (errorCode == ErrorCode::ApiSubscriptionExpiredError) {
|
||||
@@ -395,22 +388,25 @@ void SubscriptionUiController::validateConfig()
|
||||
emit configValidated(true);
|
||||
}
|
||||
|
||||
void SubscriptionUiController::setCurrentProtocol(int serverIndex, const QString &protocolName)
|
||||
void SubscriptionUiController::setCurrentProtocol(const QString &serverId, const QString &protocolName)
|
||||
{
|
||||
m_subscriptionController->setCurrentProtocol(serverIndex, protocolName);
|
||||
m_subscriptionController->setCurrentProtocol(serverId, protocolName);
|
||||
}
|
||||
|
||||
bool SubscriptionUiController::isVlessProtocol(int serverIndex)
|
||||
|
||||
bool SubscriptionUiController::isVlessProtocol(const QString &serverId)
|
||||
{
|
||||
return m_subscriptionController->isVlessProtocol(serverIndex);
|
||||
return m_subscriptionController->isVlessProtocol(serverId);
|
||||
}
|
||||
|
||||
void SubscriptionUiController::removeApiConfig(int serverIndex)
|
||||
|
||||
void SubscriptionUiController::removeApiConfig(const QString &serverId)
|
||||
{
|
||||
m_subscriptionController->removeApiConfig(serverIndex);
|
||||
m_subscriptionController->removeApiConfig(serverId);
|
||||
emit apiConfigRemoved(tr("Api config removed"));
|
||||
}
|
||||
|
||||
|
||||
QList<QString> SubscriptionUiController::getQrCodes()
|
||||
{
|
||||
return m_qrCodes;
|
||||
@@ -426,7 +422,7 @@ QString SubscriptionUiController::getVpnKey()
|
||||
return m_vpnKey;
|
||||
}
|
||||
|
||||
bool SubscriptionUiController::getAccountInfo(int serverIndex, bool reload)
|
||||
bool SubscriptionUiController::getAccountInfo(const QString &serverId, bool reload)
|
||||
{
|
||||
if (reload) {
|
||||
QEventLoop wait;
|
||||
@@ -434,15 +430,18 @@ bool SubscriptionUiController::getAccountInfo(int serverIndex, bool reload)
|
||||
wait.exec(QEventLoop::ExcludeUserInputEvents);
|
||||
}
|
||||
QJsonObject accountInfo;
|
||||
ErrorCode errorCode = m_subscriptionController->getAccountInfo(serverIndex, accountInfo);
|
||||
ErrorCode errorCode = m_subscriptionController->getAccountInfo(serverId, accountInfo);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit errorOccurred(errorCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
ServerConfig serverConfig = m_serversController->getServerConfig(serverIndex);
|
||||
QJsonObject serverConfigJson = serverConfig.toJson();
|
||||
m_apiAccountInfoModel->updateModel(accountInfo, serverConfigJson);
|
||||
const auto apiV2 = m_serversController->apiV2Config(serverId);
|
||||
if (!apiV2.has_value()) {
|
||||
emit errorOccurred(ErrorCode::InternalError);
|
||||
return false;
|
||||
}
|
||||
m_apiAccountInfoModel->updateModel(accountInfo, apiV2->toJson());
|
||||
|
||||
if (reload) {
|
||||
updateApiCountryModel();
|
||||
@@ -463,9 +462,9 @@ void SubscriptionUiController::updateApiDevicesModel()
|
||||
m_apiDevicesModel->updateModel(m_apiAccountInfoModel->getIssuedConfigsInfo(), m_settingsController->getInstallationUuid(false));
|
||||
}
|
||||
|
||||
void SubscriptionUiController::getRenewalLink(int serverIndex)
|
||||
void SubscriptionUiController::getRenewalLink(const QString &serverId)
|
||||
{
|
||||
if (serverIndex < 0) {
|
||||
if (serverId.isEmpty()) {
|
||||
emit errorOccurred(ErrorCode::InternalError);
|
||||
return;
|
||||
}
|
||||
@@ -483,6 +482,6 @@ void SubscriptionUiController::getRenewalLink(int serverIndex)
|
||||
}
|
||||
emit renewalLinkReceived(url);
|
||||
});
|
||||
watcher->setFuture(m_subscriptionController->getRenewalLink(serverIndex));
|
||||
watcher->setFuture(m_subscriptionController->getRenewalLink(serverId));
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "ui/models/api/apiAccountInfoModel.h"
|
||||
#include "ui/models/api/apiCountryModel.h"
|
||||
#include "ui/models/api/apiDevicesModel.h"
|
||||
|
||||
class SubscriptionUiController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -34,10 +35,10 @@ public:
|
||||
Q_PROPERTY(QString vpnKey READ getVpnKey NOTIFY vpnKeyExportReady)
|
||||
|
||||
public slots:
|
||||
bool exportNativeConfig(int serverIndex, const QString &serverCountryCode, const QString &fileName);
|
||||
bool revokeNativeConfig(int serverIndex, const QString &serverCountryCode);
|
||||
bool exportVpnKey(int serverIndex, const QString &fileName);
|
||||
void prepareVpnKeyExport(int serverIndex);
|
||||
bool exportNativeConfig(const QString &serverId, const QString &serverCountryCode, const QString &fileName);
|
||||
bool revokeNativeConfig(const QString &serverId, const QString &serverCountryCode);
|
||||
bool exportVpnKey(const QString &serverId, const QString &fileName);
|
||||
void prepareVpnKeyExport(const QString &serverId);
|
||||
void copyVpnKeyToClipboard();
|
||||
|
||||
bool fillAvailableServices();
|
||||
@@ -45,21 +46,21 @@ public slots:
|
||||
bool importFreeFromGateway();
|
||||
bool restoreServiceFromAppStore();
|
||||
bool importTrialFromGateway(const QString &email);
|
||||
bool updateServiceFromGateway(const int serverIndex, const QString &newCountryCode, const QString &newCountryName,
|
||||
bool updateServiceFromGateway(const QString &serverId, const QString &newCountryCode, const QString &newCountryName,
|
||||
bool reloadServiceConfig = false);
|
||||
bool updateServiceFromTelegram(const int serverIndex);
|
||||
bool deactivateDevice(int serverIndex);
|
||||
bool deactivateExternalDevice(int serverIndex, const QString &uuid, const QString &serverCountryCode);
|
||||
bool deactivateDevice(const QString &serverId);
|
||||
bool deactivateExternalDevice(const QString &serverId, const QString &uuid, const QString &serverCountryCode);
|
||||
|
||||
void validateConfig();
|
||||
|
||||
void setCurrentProtocol(int serverIndex, const QString &protocolName);
|
||||
bool isVlessProtocol(int serverIndex);
|
||||
void setCurrentProtocol(const QString &serverId, const QString &protocolName);
|
||||
bool isVlessProtocol(const QString &serverId);
|
||||
|
||||
void removeApiConfig(int serverIndex);
|
||||
void removeApiConfig(const QString &serverId);
|
||||
|
||||
bool getAccountInfo(const QString &serverId, bool reload);
|
||||
void getRenewalLink(const QString &serverId);
|
||||
|
||||
bool getAccountInfo(int serverIndex, bool reload);
|
||||
void getRenewalLink(int serverIndex);
|
||||
void updateApiCountryModel();
|
||||
void updateApiDevicesModel();
|
||||
|
||||
@@ -80,6 +81,8 @@ signals:
|
||||
|
||||
void vpnKeyExportReady();
|
||||
|
||||
void unsupportedConnectDrawerRequested();
|
||||
|
||||
private:
|
||||
QList<QString> getQrCodes();
|
||||
int getQrCodesCount();
|
||||
|
||||
@@ -25,9 +25,12 @@ ConnectionUiController::ConnectionUiController(ConnectionController* connectionC
|
||||
|
||||
void ConnectionUiController::openConnection()
|
||||
{
|
||||
int serverIndex = m_serversController->getDefaultServerIndex();
|
||||
const QString serverId = m_serversController->getDefaultServerId();
|
||||
if (serverId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_connectionController->openConnection(serverIndex);
|
||||
ErrorCode errorCode = m_connectionController->openConnection(serverId);
|
||||
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit connectionErrorOccurred(errorCode);
|
||||
@@ -100,16 +103,6 @@ void ConnectionUiController::onConnectionStateChanged(Vpn::ConnectionState state
|
||||
emit connectionStateChanged();
|
||||
}
|
||||
|
||||
void ConnectionUiController::onCurrentContainerUpdated()
|
||||
{
|
||||
if (m_isConnected || m_isConnectionInProgress) {
|
||||
emit reconnectWithUpdatedContainer(tr("Settings updated successfully, reconnection..."));
|
||||
openConnection();
|
||||
} else {
|
||||
emit reconnectWithUpdatedContainer(tr("Settings updated successfully"));
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionUiController::onTranslationsUpdated()
|
||||
{
|
||||
onConnectionStateChanged(getCurrentConnectionState());
|
||||
|
||||
@@ -38,8 +38,6 @@ public slots:
|
||||
ErrorCode getLastConnectionError();
|
||||
void onConnectionStateChanged(Vpn::ConnectionState state);
|
||||
|
||||
void onCurrentContainerUpdated();
|
||||
|
||||
void onTranslationsUpdated();
|
||||
|
||||
signals:
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
#include "ui/utils/macosUtil.h"
|
||||
#endif
|
||||
|
||||
PageController::PageController(ServersController* serversController,
|
||||
SettingsController* settingsController,
|
||||
PageController::PageController(ServersController* serversController, SettingsController* settingsController,
|
||||
QObject *parent)
|
||||
: QObject(parent), m_serversController(serversController), m_settingsController(settingsController)
|
||||
{
|
||||
@@ -57,14 +56,7 @@ PageController::PageController(ServersController* serversController,
|
||||
|
||||
bool PageController::isStartPageVisible()
|
||||
{
|
||||
if (m_serversController->getServersCount()) {
|
||||
if (m_serversController->getDefaultServerIndex() < 0) {
|
||||
m_serversController->setDefaultServerIndex(0);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return m_serversController->getServersCount() == 0;
|
||||
}
|
||||
|
||||
QString PageController::getPagePath(PageLoader::PageEnum page)
|
||||
|
||||
@@ -94,8 +94,7 @@ class PageController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PageController(ServersController* serversController,
|
||||
SettingsController* settingsController,
|
||||
explicit PageController(ServersController* serversController, SettingsController* settingsController,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
Q_PROPERTY(int safeAreaTopMargin READ getSafeAreaTopMargin NOTIFY safeAreaTopMarginChanged)
|
||||
@@ -164,6 +163,8 @@ signals:
|
||||
void showPassphraseRequestDrawer();
|
||||
void passphraseRequestDrawerClosed(QString passphrase);
|
||||
|
||||
void unsupportedConnectDrawerRequested();
|
||||
|
||||
void escapePressed();
|
||||
void closeTopDrawer();
|
||||
|
||||
|
||||
@@ -8,46 +8,46 @@ ExportUiController::ExportUiController(ExportController* exportController, QObje
|
||||
{
|
||||
}
|
||||
|
||||
void ExportUiController::generateFullAccessConfig(int serverIndex)
|
||||
void ExportUiController::generateFullAccessConfig(const QString &serverId)
|
||||
{
|
||||
clearPreviousConfig();
|
||||
auto result = m_exportController->generateFullAccessConfig(serverIndex);
|
||||
auto result = m_exportController->generateFullAccessConfig(serverId);
|
||||
applyExportResult(result);
|
||||
}
|
||||
|
||||
void ExportUiController::generateConnectionConfig(int serverIndex, int containerIndex, const QString &clientName)
|
||||
void ExportUiController::generateConnectionConfig(const QString &serverId, int containerIndex, const QString &clientName)
|
||||
{
|
||||
clearPreviousConfig();
|
||||
auto result = m_exportController->generateConnectionConfig(serverIndex, containerIndex, clientName);
|
||||
auto result = m_exportController->generateConnectionConfig(serverId, containerIndex, clientName);
|
||||
applyExportResult(result);
|
||||
}
|
||||
|
||||
void ExportUiController::generateOpenVpnConfig(int serverIndex, const QString &clientName)
|
||||
void ExportUiController::generateOpenVpnConfig(const QString &serverId, const QString &clientName)
|
||||
{
|
||||
clearPreviousConfig();
|
||||
auto result = m_exportController->generateOpenVpnConfig(serverIndex, clientName);
|
||||
auto result = m_exportController->generateOpenVpnConfig(serverId, clientName);
|
||||
applyExportResult(result);
|
||||
}
|
||||
|
||||
void ExportUiController::generateWireGuardConfig(int serverIndex, const QString &clientName)
|
||||
void ExportUiController::generateWireGuardConfig(const QString &serverId, const QString &clientName)
|
||||
{
|
||||
clearPreviousConfig();
|
||||
auto result = m_exportController->generateWireGuardConfig(serverIndex, clientName);
|
||||
auto result = m_exportController->generateWireGuardConfig(serverId, clientName);
|
||||
applyExportResult(result);
|
||||
}
|
||||
|
||||
void ExportUiController::generateAwgConfig(int serverIndex, int containerIndex, const QString &clientName)
|
||||
void ExportUiController::generateAwgConfig(const QString &serverId, int containerIndex, const QString &clientName)
|
||||
{
|
||||
clearPreviousConfig();
|
||||
auto result = m_exportController->generateAwgConfig(serverIndex, containerIndex, clientName);
|
||||
auto result = m_exportController->generateAwgConfig(serverId, containerIndex, clientName);
|
||||
applyExportResult(result);
|
||||
}
|
||||
|
||||
|
||||
void ExportUiController::generateXrayConfig(int serverIndex, const QString &clientName)
|
||||
void ExportUiController::generateXrayConfig(const QString &serverId, const QString &clientName)
|
||||
{
|
||||
clearPreviousConfig();
|
||||
auto result = m_exportController->generateXrayConfig(serverIndex, clientName);
|
||||
auto result = m_exportController->generateXrayConfig(serverId, clientName);
|
||||
applyExportResult(result);
|
||||
}
|
||||
|
||||
@@ -71,20 +71,20 @@ void ExportUiController::exportConfig(const QString &fileName)
|
||||
SystemController::saveFile(fileName, m_config);
|
||||
}
|
||||
|
||||
void ExportUiController::updateClientManagementModel(int serverIndex, int containerIndex)
|
||||
void ExportUiController::updateClientManagementModel(const QString &serverId, int containerIndex)
|
||||
{
|
||||
m_exportController->updateClientManagementModel(serverIndex, containerIndex);
|
||||
m_exportController->updateClientManagementModel(serverId, containerIndex);
|
||||
}
|
||||
|
||||
void ExportUiController::revokeConfig(int row, int serverIndex, int containerIndex)
|
||||
void ExportUiController::revokeConfig(int row, const QString &serverId, int containerIndex)
|
||||
{
|
||||
m_exportController->revokeConfig(row, serverIndex, containerIndex);
|
||||
m_exportController->revokeConfig(row, serverId, containerIndex);
|
||||
emit revokeConfigFinished();
|
||||
}
|
||||
|
||||
void ExportUiController::renameClient(int row, const QString &clientName, int serverIndex, int containerIndex)
|
||||
void ExportUiController::renameClient(int row, const QString &clientName, const QString &serverId, int containerIndex)
|
||||
{
|
||||
m_exportController->renameClient(row, clientName, serverIndex, containerIndex);
|
||||
m_exportController->renameClient(row, clientName, serverId, containerIndex);
|
||||
}
|
||||
|
||||
int ExportUiController::getQrCodesCount()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <QObject>
|
||||
|
||||
#include "core/controllers/selfhosted/exportController.h"
|
||||
#include "core/utils/errorCodes.h"
|
||||
|
||||
class ExportUiController : public QObject
|
||||
{
|
||||
@@ -17,12 +18,13 @@ public:
|
||||
Q_PROPERTY(QString nativeConfigString READ getNativeConfigString NOTIFY exportConfigChanged)
|
||||
|
||||
public slots:
|
||||
void generateFullAccessConfig(int serverIndex);
|
||||
void generateConnectionConfig(int serverIndex, int containerIndex, const QString &clientName);
|
||||
void generateOpenVpnConfig(int serverIndex, const QString &clientName);
|
||||
void generateWireGuardConfig(int serverIndex, const QString &clientName);
|
||||
void generateAwgConfig(int serverIndex, int containerIndex, const QString &clientName);
|
||||
void generateXrayConfig(int serverIndex, const QString &clientName);
|
||||
void generateFullAccessConfig(const QString &serverId);
|
||||
|
||||
void generateConnectionConfig(const QString &serverId, int containerIndex, const QString &clientName);
|
||||
void generateOpenVpnConfig(const QString &serverId, const QString &clientName);
|
||||
void generateWireGuardConfig(const QString &serverId, const QString &clientName);
|
||||
void generateAwgConfig(const QString &serverId, int containerIndex, const QString &clientName);
|
||||
void generateXrayConfig(const QString &serverId, const QString &clientName);
|
||||
|
||||
QString getConfig();
|
||||
QString getNativeConfigString();
|
||||
@@ -30,9 +32,11 @@ public slots:
|
||||
|
||||
void exportConfig(const QString &fileName);
|
||||
|
||||
void updateClientManagementModel(int serverIndex, int containerIndex);
|
||||
void revokeConfig(int row, int serverIndex, int containerIndex);
|
||||
void renameClient(int row, const QString &clientName, int serverIndex, int containerIndex);
|
||||
void updateClientManagementModel(const QString &serverId, int containerIndex);
|
||||
|
||||
void revokeConfig(int row, const QString &serverId, int containerIndex);
|
||||
|
||||
void renameClient(int row, const QString &clientName, const QString &serverId, int containerIndex);
|
||||
|
||||
signals:
|
||||
void generateConfig(int type);
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "core/controllers/selfhosted/installController.h"
|
||||
#include "core/utils/selfhosted/sshSession.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
#include "logger.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
@@ -27,33 +26,12 @@
|
||||
#include "ui/models/services/socks5ProxyConfigModel.h"
|
||||
#include "ui/models/services/torConfigModel.h"
|
||||
#include "core/utils/utilities.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/models/protocols/awgProtocolConfig.h"
|
||||
#include "core/models/protocols/wireGuardProtocolConfig.h"
|
||||
#include "core/models/protocols/openVpnProtocolConfig.h"
|
||||
#include "core/models/protocols/xrayProtocolConfig.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
Logger logger("InstallUiController");
|
||||
|
||||
namespace configKey
|
||||
{
|
||||
constexpr char serviceInfo[] = "service_info";
|
||||
constexpr char serviceType[] = "service_type";
|
||||
constexpr char serviceProtocol[] = "service_protocol";
|
||||
constexpr char userCountryCode[] = "user_country_code";
|
||||
|
||||
constexpr char serverCountryCode[] = "server_country_code";
|
||||
constexpr char serverCountryName[] = "server_country_name";
|
||||
constexpr char availableCountries[] = "available_countries";
|
||||
|
||||
constexpr char apiConfig[] = "api_config";
|
||||
constexpr char authData[] = "auth_data";
|
||||
}
|
||||
}
|
||||
|
||||
InstallUiController::InstallUiController(InstallController *installController,
|
||||
ServersController *serversController,
|
||||
SettingsController *settingsController,
|
||||
@@ -101,19 +79,18 @@ InstallUiController::~InstallUiController()
|
||||
{
|
||||
}
|
||||
|
||||
void InstallUiController::install(DockerContainer container, int port, TransportProto transportProto, int serverIndex)
|
||||
void InstallUiController::install(DockerContainer container, int port, TransportProto transportProto, const QString &serverId)
|
||||
{
|
||||
const bool isNewServer = serverIndex < 0;
|
||||
const bool isNewServer = serverId.isEmpty();
|
||||
|
||||
ServerCredentials serverCredentials;
|
||||
if (isNewServer) {
|
||||
serverCredentials = m_processedServerCredentials;
|
||||
} else {
|
||||
serverCredentials = m_serversController->getServerCredentials(serverIndex);
|
||||
serverCredentials = m_serversController->getServerCredentials(serverId);
|
||||
m_processedServerCredentials = ServerCredentials();
|
||||
}
|
||||
|
||||
QMap<DockerContainer, QJsonObject> preparedContainers;
|
||||
QString finishMessage;
|
||||
ErrorCode errorCode;
|
||||
|
||||
@@ -131,9 +108,13 @@ void InstallUiController::install(DockerContainer container, int port, Transport
|
||||
return;
|
||||
}
|
||||
|
||||
int serverIndex = m_serversController->getServersCount() - 1;
|
||||
ServerConfig serverConfig = m_serversController->getServerConfig(serverIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containers = serverConfig.containers();
|
||||
const QString newServerId = m_serversController->getServerId(m_serversController->getServersCount() - 1);
|
||||
const auto admin = m_serversController->selfHostedAdminConfig(newServerId);
|
||||
if (!admin.has_value()) {
|
||||
emit installationErrorOccurred(ErrorCode::InternalError);
|
||||
return;
|
||||
}
|
||||
QMap<DockerContainer, ContainerConfig> containers = admin->containers;
|
||||
int containersCount = containers.size();
|
||||
|
||||
if (wasContainerInstalled) {
|
||||
@@ -148,20 +129,28 @@ void InstallUiController::install(DockerContainer container, int port, Transport
|
||||
|
||||
emit installServerFinished(finishMessage);
|
||||
} else {
|
||||
ServerConfig serverConfig = m_serversController->getServerConfig(serverIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containers = serverConfig.containers();
|
||||
const auto adminBefore = m_serversController->selfHostedAdminConfig(serverId);
|
||||
if (!adminBefore.has_value()) {
|
||||
emit installationErrorOccurred(ErrorCode::InternalError);
|
||||
return;
|
||||
}
|
||||
QMap<DockerContainer, ContainerConfig> containers = adminBefore->containers;
|
||||
int containersCount = containers.size();
|
||||
|
||||
bool wasContainerInstalled = false;
|
||||
errorCode = m_installController->installContainer(serverIndex, container, port, transportProto,
|
||||
errorCode = m_installController->installContainer(serverId, container, port, transportProto,
|
||||
wasContainerInstalled);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
ServerConfig newServerConfig = m_serversController->getServerConfig(serverIndex);
|
||||
QMap<DockerContainer, ContainerConfig> newContainers = newServerConfig.containers();
|
||||
const auto adminAfter = m_serversController->selfHostedAdminConfig(serverId);
|
||||
if (!adminAfter.has_value()) {
|
||||
emit installationErrorOccurred(ErrorCode::InternalError);
|
||||
return;
|
||||
}
|
||||
QMap<DockerContainer, ContainerConfig> newContainers = adminAfter->containers;
|
||||
int newContainersCount = newContainers.size();
|
||||
|
||||
bool hasNewContainers = (newContainersCount - containersCount) > (wasContainerInstalled ? 1 : 0);
|
||||
@@ -181,17 +170,25 @@ void InstallUiController::install(DockerContainer container, int port, Transport
|
||||
}
|
||||
}
|
||||
|
||||
void InstallUiController::scanServerForInstalledContainers(int serverIndex)
|
||||
void InstallUiController::scanServerForInstalledContainers(const QString &serverId)
|
||||
{
|
||||
ServerConfig serverBefore = m_serversController->getServerConfig(serverIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containersBefore = serverBefore.containers();
|
||||
const auto serverBefore = m_serversController->selfHostedAdminConfig(serverId);
|
||||
if (!serverBefore.has_value()) {
|
||||
emit installationErrorOccurred(ErrorCode::InternalError);
|
||||
return;
|
||||
}
|
||||
QMap<DockerContainer, ContainerConfig> containersBefore = serverBefore->containers;
|
||||
int containersCountBefore = containersBefore.size();
|
||||
|
||||
ErrorCode errorCode = m_installController->scanServerForInstalledContainers(serverIndex);
|
||||
ErrorCode errorCode = m_installController->scanServerForInstalledContainers(serverId);
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
ServerConfig serverAfter = m_serversController->getServerConfig(serverIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containersAfter = serverAfter.containers();
|
||||
const auto serverAfter = m_serversController->selfHostedAdminConfig(serverId);
|
||||
if (!serverAfter.has_value()) {
|
||||
emit installationErrorOccurred(ErrorCode::InternalError);
|
||||
return;
|
||||
}
|
||||
QMap<DockerContainer, ContainerConfig> containersAfter = serverAfter->containers;
|
||||
int containersCountAfter = containersAfter.size();
|
||||
|
||||
bool isInstalledContainerAdded = containersCountAfter > containersCountBefore;
|
||||
@@ -202,7 +199,7 @@ void InstallUiController::scanServerForInstalledContainers(int serverIndex)
|
||||
emit installationErrorOccurred(errorCode);
|
||||
}
|
||||
|
||||
void InstallUiController::updateContainer(int serverIndex, int containerIndex, int protocolIndex)
|
||||
void InstallUiController::updateContainer(const QString &serverId, int containerIndex, int protocolIndex)
|
||||
{
|
||||
DockerContainer container = static_cast<DockerContainer>(containerIndex);
|
||||
|
||||
@@ -250,32 +247,26 @@ void InstallUiController::updateContainer(int serverIndex, int containerIndex, i
|
||||
default:
|
||||
return;
|
||||
}
|
||||
ContainerConfig oldContainerConfig = m_serversController->getContainerConfig(serverIndex, container);
|
||||
ContainerConfig oldContainerConfig = m_serversController->getContainerConfig(serverId, container);
|
||||
|
||||
ErrorCode errorCode = m_installController->updateContainer(serverIndex, container, oldContainerConfig, containerConfig);
|
||||
ErrorCode errorCode = m_installController->updateContainer(serverId, container, oldContainerConfig, containerConfig);
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
ContainerConfig updatedConfig = m_serversController->getContainerConfig(serverIndex, container);
|
||||
ContainerConfig updatedConfig = m_serversController->getContainerConfig(serverId, container);
|
||||
m_protocolModel->updateModel(updatedConfig);
|
||||
|
||||
auto defaultContainer = m_serversController->getServerConfig(serverIndex).defaultContainer();
|
||||
if ((serverIndex == m_serversController->getDefaultServerIndex()) && (container == defaultContainer)) {
|
||||
emit currentContainerUpdated();
|
||||
} else {
|
||||
emit updateContainerFinished(tr("Settings updated successfully"));
|
||||
}
|
||||
|
||||
emit updateContainerFinished(tr("Settings updated successfully"));
|
||||
return;
|
||||
}
|
||||
|
||||
emit installationErrorOccurred(errorCode);
|
||||
}
|
||||
|
||||
void InstallUiController::rebootServer(int serverIndex)
|
||||
void InstallUiController::rebootServer(const QString &serverId)
|
||||
{
|
||||
QString serverName = m_serversController->getServerConfig(serverIndex).displayName();
|
||||
const QString serverName = m_serversController->notificationDisplayName(serverId);
|
||||
|
||||
const auto errorCode = m_installController->rebootServer(serverIndex);
|
||||
const auto errorCode = m_installController->rebootServer(serverId);
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
emit rebootServerFinished(tr("Server '%1' was rebooted").arg(serverName));
|
||||
} else {
|
||||
@@ -283,19 +274,22 @@ void InstallUiController::rebootServer(int serverIndex)
|
||||
}
|
||||
}
|
||||
|
||||
void InstallUiController::removeServer(int serverIndex)
|
||||
void InstallUiController::removeServer(const QString &serverId)
|
||||
{
|
||||
QString serverName = m_serversController->getServerConfig(serverIndex).displayName();
|
||||
if (serverId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
const QString serverName = m_serversController->notificationDisplayName(serverId);
|
||||
|
||||
m_serversController->removeServer(serverIndex);
|
||||
m_serversController->removeServer(serverId);
|
||||
emit removeServerFinished(tr("Server '%1' was removed").arg(serverName));
|
||||
}
|
||||
|
||||
void InstallUiController::removeAllContainers(int serverIndex)
|
||||
void InstallUiController::removeAllContainers(const QString &serverId)
|
||||
{
|
||||
QString serverName = m_serversController->getServerConfig(serverIndex).displayName();
|
||||
const QString serverName = m_serversController->notificationDisplayName(serverId);
|
||||
|
||||
ErrorCode errorCode = m_installController->removeAllContainers(serverIndex);
|
||||
ErrorCode errorCode = m_installController->removeAllContainers(serverId);
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
emit removeAllContainersFinished(tr("All containers from server '%1' have been removed").arg(serverName));
|
||||
return;
|
||||
@@ -303,14 +297,14 @@ void InstallUiController::removeAllContainers(int serverIndex)
|
||||
emit installationErrorOccurred(errorCode);
|
||||
}
|
||||
|
||||
void InstallUiController::removeContainer(int serverIndex, int containerIndex)
|
||||
void InstallUiController::removeContainer(const QString &serverId, int containerIndex)
|
||||
{
|
||||
QString serverName = m_serversController->getServerConfig(serverIndex).displayName();
|
||||
const QString serverName = m_serversController->notificationDisplayName(serverId);
|
||||
|
||||
DockerContainer container = static_cast<DockerContainer>(containerIndex);
|
||||
QString containerName = ContainerUtils::containerHumanNames().value(container);
|
||||
|
||||
ErrorCode errorCode = m_installController->removeContainer(serverIndex, container);
|
||||
ErrorCode errorCode = m_installController->removeContainer(serverId, container);
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
|
||||
emit removeContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName, serverName));
|
||||
@@ -319,17 +313,17 @@ void InstallUiController::removeContainer(int serverIndex, int containerIndex)
|
||||
emit installationErrorOccurred(errorCode);
|
||||
}
|
||||
|
||||
void InstallUiController::clearCachedProfile(int serverIndex, int containerIndex)
|
||||
void InstallUiController::clearCachedProfile(const QString &serverId, int containerIndex)
|
||||
{
|
||||
DockerContainer container = static_cast<DockerContainer>(containerIndex);
|
||||
if (ContainerUtils::containerService(container) == ServiceType::Other) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_installController->clearCachedProfile(serverIndex, container);
|
||||
m_installController->clearCachedProfile(serverId, container);
|
||||
|
||||
emit cachedProfileCleared(tr("%1 cached profile cleared").arg(ContainerUtils::containerHumanNames().value(container)));
|
||||
ContainerConfig updatedConfig = m_serversController->getContainerConfig(serverIndex, container);
|
||||
ContainerConfig updatedConfig = m_serversController->getContainerConfig(serverId, container);
|
||||
m_protocolModel->updateModel(updatedConfig);
|
||||
}
|
||||
|
||||
@@ -354,9 +348,9 @@ void InstallUiController::setProcessedServerCredentials(const QString &hostName,
|
||||
m_processedServerCredentials.secretData = secretData;
|
||||
}
|
||||
|
||||
void InstallUiController::mountSftpDrive(int serverIndex, const QString &port, const QString &password, const QString &username)
|
||||
void InstallUiController::mountSftpDrive(const QString &serverId, const QString &port, const QString &password, const QString &username)
|
||||
{
|
||||
ServerCredentials serverCredentials = m_serversController->getServerCredentials(serverIndex);
|
||||
ServerCredentials serverCredentials = m_serversController->getServerCredentials(serverId);
|
||||
ErrorCode errorCode = m_installController->mountSftpDrive(serverCredentials, port, password, username);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
@@ -399,40 +393,35 @@ void InstallUiController::setEncryptedPassphrase(QString passphrase)
|
||||
|
||||
void InstallUiController::addEmptyServer()
|
||||
{
|
||||
SelfHostedServerConfig serverConfig;
|
||||
serverConfig.hostName = m_processedServerCredentials.hostName;
|
||||
serverConfig.userName = m_processedServerCredentials.userName;
|
||||
serverConfig.password = m_processedServerCredentials.secretData;
|
||||
serverConfig.port = m_processedServerCredentials.port;
|
||||
serverConfig.description = m_settingsController->nextAvailableServerName();
|
||||
serverConfig.defaultContainer = DockerContainer::None;
|
||||
|
||||
m_serversController->addServer(ServerConfig(serverConfig));
|
||||
m_installController->addEmptyServer(m_processedServerCredentials);
|
||||
emit installServerFinished(tr("Server added successfully"));
|
||||
}
|
||||
|
||||
void InstallUiController::validateConfig()
|
||||
{
|
||||
int serverIndex = m_serversController->getDefaultServerIndex();
|
||||
m_installController->validateConfig(serverIndex);
|
||||
const QString serverId = m_serversController->getDefaultServerId();
|
||||
if (serverId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_installController->validateConfig(serverId);
|
||||
}
|
||||
|
||||
void InstallUiController::updateProtocols(int serverIndex, int containerIndex)
|
||||
void InstallUiController::updateProtocols(const QString &serverId, int containerIndex)
|
||||
{
|
||||
DockerContainer container = static_cast<DockerContainer>(containerIndex);
|
||||
ContainerConfig containerConfig = m_serversController->getContainerConfig(serverIndex, container);
|
||||
ContainerConfig containerConfig = m_serversController->getContainerConfig(serverId, container);
|
||||
containerConfig.container = container;
|
||||
m_protocolModel->updateModel(containerConfig);
|
||||
}
|
||||
|
||||
void InstallUiController::openServerSettings(int serverIndex, int containerIndex, int protocolIndex)
|
||||
void InstallUiController::openServerSettings(const QString &serverId, int containerIndex, int protocolIndex)
|
||||
{
|
||||
updateProtocolConfigModel(serverIndex, containerIndex, protocolIndex);
|
||||
updateProtocolConfigModel(serverId, containerIndex, protocolIndex);
|
||||
}
|
||||
|
||||
void InstallUiController::openClientSettings(int serverIndex, int containerIndex, int protocolIndex)
|
||||
void InstallUiController::openClientSettings(const QString &serverId, int containerIndex, int protocolIndex)
|
||||
{
|
||||
updateProtocolConfigModel(serverIndex, containerIndex, protocolIndex);
|
||||
updateProtocolConfigModel(serverId, containerIndex, protocolIndex);
|
||||
}
|
||||
|
||||
int InstallUiController::defaultPort(int protocolIndex)
|
||||
@@ -465,10 +454,10 @@ bool InstallUiController::defaultTransportProtoChangeable(int protocolIndex)
|
||||
return ProtocolUtils::defaultTransportProtoChangeable(proto);
|
||||
}
|
||||
|
||||
void InstallUiController::updateProtocolConfigModel(int serverIndex, int containerIndex, int protocolIndex)
|
||||
void InstallUiController::updateProtocolConfigModel(const QString &serverId, int containerIndex, int protocolIndex)
|
||||
{
|
||||
DockerContainer container = static_cast<DockerContainer>(containerIndex);
|
||||
ContainerConfig containerConfig = m_serversController->getContainerConfig(serverIndex, container);
|
||||
ContainerConfig containerConfig = m_serversController->getContainerConfig(serverId, container);
|
||||
containerConfig.container = container;
|
||||
Proto protocolType = static_cast<Proto>(protocolIndex);
|
||||
|
||||
@@ -490,4 +479,3 @@ void InstallUiController::updateProtocolConfigModel(int serverIndex, int contain
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,24 +52,24 @@ public:
|
||||
~InstallUiController();
|
||||
|
||||
public slots:
|
||||
void install(DockerContainer container, int port, TransportProto transportProto, int serverIndex);
|
||||
void install(DockerContainer container, int port, TransportProto transportProto, const QString &serverId);
|
||||
void setProcessedServerCredentials(const QString &hostName, const QString &userName, const QString &secretData);
|
||||
void clearProcessedServerCredentials();
|
||||
|
||||
void scanServerForInstalledContainers(int serverIndex);
|
||||
void scanServerForInstalledContainers(const QString &serverId);
|
||||
|
||||
void updateContainer(int serverIndex, int containerIndex, int protocolIndex);
|
||||
void updateContainer(const QString &serverId, int containerIndex, int protocolIndex);
|
||||
|
||||
void removeServer(int serverIndex);
|
||||
void rebootServer(int serverIndex);
|
||||
void removeAllContainers(int serverIndex);
|
||||
void removeContainer(int serverIndex, int containerIndex);
|
||||
void removeServer(const QString &serverId);
|
||||
void rebootServer(const QString &serverId);
|
||||
void removeAllContainers(const QString &serverId);
|
||||
void removeContainer(const QString &serverId, int containerIndex);
|
||||
|
||||
void clearCachedProfile(int serverIndex, int containerIndex);
|
||||
void clearCachedProfile(const QString &serverId, int containerIndex);
|
||||
|
||||
QRegularExpression ipAddressRegExp();
|
||||
|
||||
void mountSftpDrive(int serverIndex, const QString &port, const QString &password, const QString &username);
|
||||
void mountSftpDrive(const QString &serverId, const QString &port, const QString &password, const QString &username);
|
||||
|
||||
bool checkSshConnection();
|
||||
|
||||
@@ -78,12 +78,12 @@ public slots:
|
||||
void addEmptyServer();
|
||||
|
||||
void validateConfig();
|
||||
|
||||
Q_INVOKABLE void updateProtocols(int serverIndex, int containerIndex);
|
||||
|
||||
void openServerSettings(int serverIndex, int containerIndex, int protocolIndex);
|
||||
void openClientSettings(int serverIndex, int containerIndex, int protocolIndex);
|
||||
|
||||
|
||||
Q_INVOKABLE void updateProtocols(const QString &serverId, int containerIndex);
|
||||
|
||||
void openServerSettings(const QString &serverId, int containerIndex, int protocolIndex);
|
||||
void openClientSettings(const QString &serverId, int containerIndex, int protocolIndex);
|
||||
|
||||
int defaultPort(int protocolIndex);
|
||||
int getPortForInstall(int protocolIndex);
|
||||
int defaultTransportProto(int protocolIndex);
|
||||
@@ -114,8 +114,6 @@ signals:
|
||||
void serverIsBusy(const bool isBusy);
|
||||
void cancelInstallation();
|
||||
|
||||
void currentContainerUpdated();
|
||||
|
||||
void cachedProfileCleared(const QString &message);
|
||||
void apiConfigRemoved(const QString &message);
|
||||
|
||||
@@ -145,7 +143,7 @@ private:
|
||||
|
||||
QString m_privateKeyPassphrase;
|
||||
|
||||
void updateProtocolConfigModel(int serverIndex, int containerIndex, int protocolIndex);
|
||||
void updateProtocolConfigModel(const QString &serverId, int containerIndex, int protocolIndex);
|
||||
};
|
||||
|
||||
#endif // INSTALLUICONTROLLER_H
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
#include "serversUiController.h"
|
||||
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/protocolConfig.h"
|
||||
#include "core/models/containerConfig.h"
|
||||
#include "core/models/protocols/awgProtocolConfig.h"
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
namespace
|
||||
namespace {
|
||||
int rowForServerId(const QVector<ServerDescription> &list, const QString &serverId)
|
||||
{
|
||||
namespace configKey
|
||||
{
|
||||
constexpr char apiConfig[] = "api_config";
|
||||
constexpr char serverCountryCode[] = "server_country_code";
|
||||
constexpr char serverCountryName[] = "server_country_name";
|
||||
constexpr char userCountryCode[] = "user_country_code";
|
||||
constexpr char serviceType[] = "service_type";
|
||||
if (serverId.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
if (list.at(i).serverId == serverId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool descriptionsHaveGatewayServers(const QVector<ServerDescription> &list)
|
||||
{
|
||||
for (const auto &d : list) {
|
||||
if (d.isServerFromGatewayApi) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
ServersUiController::ServersUiController(ServersController* serversController,
|
||||
SettingsController* settingsController,
|
||||
ServersModel* serversModel,
|
||||
@@ -47,48 +47,70 @@ ServersUiController::ServersUiController(ServersController* serversController,
|
||||
{
|
||||
}
|
||||
|
||||
void ServersUiController::removeServer(int index)
|
||||
void ServersUiController::removeServer(const QString &serverId)
|
||||
{
|
||||
m_serversController->removeServer(index);
|
||||
updateModel();
|
||||
}
|
||||
|
||||
void ServersUiController::editServerName(int index, const QString &name)
|
||||
{
|
||||
ServerConfig serverConfig = m_serversController->getServerConfig(index);
|
||||
|
||||
if (serverConfig.isApiV1()) {
|
||||
ApiV1ServerConfig* apiV1 = serverConfig.as<ApiV1ServerConfig>();
|
||||
if (apiV1) {
|
||||
apiV1->name = name;
|
||||
}
|
||||
} else if (serverConfig.isApiV2()) {
|
||||
ApiV2ServerConfig* apiV2 = serverConfig.as<ApiV2ServerConfig>();
|
||||
if (apiV2) {
|
||||
apiV2->name = name;
|
||||
apiV2->nameOverriddenByUser = true;
|
||||
}
|
||||
} else {
|
||||
serverConfig.visit([&name](auto& arg) {
|
||||
arg.description = name;
|
||||
});
|
||||
if (serverId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_serversController->editServer(index, serverConfig);
|
||||
m_serversController->removeServer(serverId);
|
||||
updateModel();
|
||||
}
|
||||
|
||||
void ServersUiController::setDefaultServerIndex(int index)
|
||||
void ServersUiController::removeServerAtIndex(int index)
|
||||
{
|
||||
m_serversController->setDefaultServerIndex(index);
|
||||
updateModel();
|
||||
emit defaultServerIndexChanged(index);
|
||||
const QString serverId = getServerId(index);
|
||||
if (!serverId.isEmpty()) {
|
||||
removeServer(serverId);
|
||||
}
|
||||
}
|
||||
|
||||
void ServersUiController::setDefaultContainer(int serverIndex, int containerIndex)
|
||||
void ServersUiController::setDefaultServerAtIndex(int index)
|
||||
{
|
||||
const QString serverId = getServerId(index);
|
||||
if (!serverId.isEmpty()) {
|
||||
setDefaultServer(serverId);
|
||||
}
|
||||
}
|
||||
|
||||
void ServersUiController::setDefaultContainerAtIndex(int index, int containerIndex)
|
||||
{
|
||||
const QString serverId = getServerId(index);
|
||||
if (!serverId.isEmpty()) {
|
||||
setDefaultContainer(serverId, containerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void ServersUiController::editServerName(const QString &serverId, const QString &name)
|
||||
{
|
||||
if (serverId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_serversController->renameServer(serverId, name)) {
|
||||
emit errorOccurred(tr("Legacy API v1 configs are no longer supported. Remove this server to continue."));
|
||||
emit finished(tr("Use the remove action to delete this legacy config."));
|
||||
return;
|
||||
}
|
||||
updateModel();
|
||||
}
|
||||
|
||||
void ServersUiController::setDefaultServer(const QString &serverId)
|
||||
{
|
||||
if (serverId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_serversController->setDefaultServer(serverId);
|
||||
updateModel();
|
||||
emit defaultServerIdChanged(serverId);
|
||||
}
|
||||
|
||||
void ServersUiController::setDefaultContainer(const QString &serverId, int containerIndex)
|
||||
{
|
||||
if (serverId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
auto container = static_cast<DockerContainer>(containerIndex);
|
||||
m_serversController->setDefaultContainer(serverIndex, container);
|
||||
m_serversController->setDefaultContainer(serverId, container);
|
||||
updateModel();
|
||||
}
|
||||
|
||||
@@ -98,129 +120,123 @@ void ServersUiController::toggleAmneziaDns(bool enabled)
|
||||
updateModel();
|
||||
}
|
||||
|
||||
void ServersUiController::onDefaultServerChanged(int index)
|
||||
void ServersUiController::onDefaultServerChanged(const QString &/*defaultServerId*/)
|
||||
{
|
||||
setProcessedServerIndex(index);
|
||||
updateModel();
|
||||
setProcessedServerId(m_serversController->getDefaultServerId());
|
||||
updateDefaultServerContainersModel();
|
||||
emit defaultServerIndexChanged(index);
|
||||
emit defaultServerIdChanged(m_serversController->getDefaultServerId());
|
||||
}
|
||||
|
||||
void ServersUiController::updateModel()
|
||||
{
|
||||
int defaultIndex = m_serversController->getDefaultServerIndex();
|
||||
bool wasEmpty = !hasServersFromGatewayApi();
|
||||
int serversCount = m_serversController->getServersCount();
|
||||
QVector<ServerDescription> descriptions =
|
||||
m_serversController->buildServerDescriptions(m_settingsController->isAmneziaDnsEnabled());
|
||||
|
||||
if (m_processedServerIndex >= serversCount) {
|
||||
setProcessedServerIndex(defaultIndex);
|
||||
} else if (m_processedServerIndex >= 0) {
|
||||
setProcessedServerIndex(m_processedServerIndex);
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
const bool hadServersFromGatewayBefore = descriptionsHaveGatewayServers(m_orderedServerDescriptions);
|
||||
const bool hasServersFromGatewayNow = descriptionsHaveGatewayServers(descriptions);
|
||||
const int listCount = descriptions.size();
|
||||
const int defaultRowInDescriptions = rowForServerId(descriptions, defaultServerId);
|
||||
|
||||
m_orderedServerDescriptions = descriptions;
|
||||
|
||||
if (listCount == 0) {
|
||||
setProcessedServerId(QString());
|
||||
} else if (m_processedServerIndex >= listCount) {
|
||||
setProcessedServerId(defaultServerId);
|
||||
} else if (!m_processedServerId.isEmpty()) {
|
||||
const int row = rowForServerId(m_orderedServerDescriptions, m_processedServerId);
|
||||
if (row < 0) {
|
||||
setProcessedServerId(defaultServerId);
|
||||
} else {
|
||||
setProcessedServerId(m_processedServerId);
|
||||
}
|
||||
} else if (defaultRowInDescriptions >= 0) {
|
||||
setProcessedServerId(defaultServerId);
|
||||
}
|
||||
|
||||
m_serversModel->updateModel(m_serversController->getServers(), defaultIndex, m_settingsController->isAmneziaDnsEnabled());
|
||||
|
||||
|
||||
|
||||
m_serversModel->updateModel(m_orderedServerDescriptions, defaultRowInDescriptions);
|
||||
|
||||
updateContainersModel();
|
||||
updateDefaultServerContainersModel();
|
||||
|
||||
bool isEmpty = !hasServersFromGatewayApi();
|
||||
if (wasEmpty != isEmpty) {
|
||||
|
||||
if (hadServersFromGatewayBefore != hasServersFromGatewayNow) {
|
||||
emit hasServersFromGatewayApiChanged();
|
||||
}
|
||||
|
||||
emit defaultServerIndexChanged(defaultIndex);
|
||||
|
||||
emit defaultServerIdChanged(defaultServerId);
|
||||
emit defaultServerIndexChanged(defaultServerIndex());
|
||||
}
|
||||
|
||||
int ServersUiController::getDefaultServerIndex() const
|
||||
QString ServersUiController::getDefaultServerId() const
|
||||
{
|
||||
return m_serversController->getDefaultServerIndex();
|
||||
return m_serversController->getDefaultServerId();
|
||||
}
|
||||
|
||||
QString ServersUiController::getDefaultServerName() const
|
||||
{
|
||||
int defaultIndex = getDefaultServerIndex();
|
||||
return m_serversController->getServerConfig(defaultIndex).displayName();
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return description.serverName;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString ServersUiController::getDefaultServerDefaultContainerName() const
|
||||
{
|
||||
int defaultIndex = getDefaultServerIndex();
|
||||
const ServerConfig server = m_serversController->getServerConfig(defaultIndex);
|
||||
return ContainerUtils::containerHumanNames().value(server.defaultContainer());
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return ContainerUtils::containerHumanNames().value(description.defaultContainer);
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString ServersUiController::getDefaultServerDescriptionCollapsed() const
|
||||
{
|
||||
int defaultIndex = getDefaultServerIndex();
|
||||
const ServerConfig server = m_serversController->getServerConfig(defaultIndex);
|
||||
QString description = getDefaultServerDescription(server, defaultIndex);
|
||||
|
||||
if (server.isApiConfig()) {
|
||||
return description;
|
||||
}
|
||||
|
||||
DockerContainer container = server.defaultContainer();
|
||||
QString containerName = ContainerUtils::containerHumanNames().value(container);
|
||||
QString protocolVersion;
|
||||
QString hostName = server.hostName();
|
||||
|
||||
if (ContainerUtils::isAwgContainer(container)) {
|
||||
ContainerConfig containerConfig = server.containerConfig(container);
|
||||
if (auto* awgProtocolConfig = containerConfig.getAwgProtocolConfig()) {
|
||||
QString version = awgProtocolConfig->serverConfig.protocolVersion;
|
||||
if (version == protocols::awg::awgV2) {
|
||||
protocolVersion = QObject::tr(" (version 2)");
|
||||
} else if (version == protocols::awg::awgV1_5) {
|
||||
protocolVersion = QObject::tr(" (version 1.5)");
|
||||
}
|
||||
|
||||
if (container == DockerContainer::Awg && !awgProtocolConfig->serverConfig.isThirdPartyConfig) {
|
||||
containerName = "AmneziaWG Legacy";
|
||||
}
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return description.collapsedServerDescription;
|
||||
}
|
||||
}
|
||||
|
||||
return description + containerName + protocolVersion + " | " + hostName;
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString ServersUiController::getDefaultServerImagePathCollapsed() const
|
||||
{
|
||||
int defaultIndex = getDefaultServerIndex();
|
||||
const ServerConfig server = m_serversController->getServerConfig(defaultIndex);
|
||||
|
||||
if (server.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = server.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) return QString();
|
||||
const QString countryCode = apiV2->apiConfig.serverCountryCode;
|
||||
if (countryCode.isEmpty()) {
|
||||
return "";
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
if (!description.isApiV2 || description.apiServerCountryCode.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(description.apiServerCountryCode.toUpper());
|
||||
}
|
||||
return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(countryCode.toUpper());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
QString ServersUiController::getDefaultServerDescriptionExpanded() const
|
||||
{
|
||||
int defaultIndex = getDefaultServerIndex();
|
||||
const ServerConfig server = m_serversController->getServerConfig(defaultIndex);
|
||||
QString description = getDefaultServerDescription(server, defaultIndex);
|
||||
|
||||
if (server.isApiConfig()) {
|
||||
return description;
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return description.expandedServerDescription;
|
||||
}
|
||||
}
|
||||
|
||||
return description + server.hostName();
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool ServersUiController::isDefaultServerDefaultContainerHasSplitTunneling() const
|
||||
{
|
||||
int defaultIndex = getDefaultServerIndex();
|
||||
const ServerConfig server = m_serversController->getServerConfig(defaultIndex);
|
||||
DockerContainer defaultContainer = server.defaultContainer();
|
||||
|
||||
ContainerConfig containerConfig = server.containerConfig(defaultContainer);
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
const DockerContainer defaultContainer = m_serversController->getDefaultContainer(defaultServerId);
|
||||
const ContainerConfig containerConfig = m_serversController->getContainerConfig(defaultServerId, defaultContainer);
|
||||
|
||||
if (defaultContainer == DockerContainer::Awg || defaultContainer == DockerContainer::WireGuard) {
|
||||
auto hasSplitTunnelingFromAllowedIps = [](const QStringList& allowedIps, const QString& nativeConfig) -> bool {
|
||||
@@ -265,16 +281,13 @@ bool ServersUiController::isDefaultServerDefaultContainerHasSplitTunneling() con
|
||||
|
||||
bool ServersUiController::isDefaultServerFromApi() const
|
||||
{
|
||||
int defaultIndex = getDefaultServerIndex();
|
||||
const ServerConfig server = m_serversController->getServerConfig(defaultIndex);
|
||||
const int configVersion = server.configVersion();
|
||||
return configVersion == apiDefs::ConfigSource::Telegram
|
||||
|| configVersion == apiDefs::ConfigSource::AmneziaGateway;
|
||||
}
|
||||
|
||||
int ServersUiController::getProcessedServerIndex() const
|
||||
{
|
||||
return m_processedServerIndex;
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return description.isApiV2;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ServersUiController::getProcessedContainerIndex() const
|
||||
@@ -291,186 +304,196 @@ void ServersUiController::setProcessedContainerIndex(int index)
|
||||
}
|
||||
}
|
||||
|
||||
void ServersUiController::setProcessedServerIndex(int index)
|
||||
QString ServersUiController::getProcessedServerId() const
|
||||
{
|
||||
if (index >= m_serversController->getServersCount()) {
|
||||
return m_processedServerId;
|
||||
}
|
||||
|
||||
void ServersUiController::setProcessedServerId(const QString &serverId)
|
||||
{
|
||||
const int index = serverId.isEmpty() ? -1 : serverIndexForId(serverId);
|
||||
if (!serverId.isEmpty() && index < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_processedServerIndex != index) {
|
||||
if (m_processedServerIndex != index || m_processedServerId != serverId) {
|
||||
m_processedServerIndex = index;
|
||||
m_processedServerId = serverId;
|
||||
m_serversModel->setProcessedServerIndex(index);
|
||||
|
||||
if (index >= 0) {
|
||||
updateContainersModel();
|
||||
|
||||
ServerConfig server = m_serversController->getServerConfig(index);
|
||||
setProcessedContainerIndex(static_cast<int>(server.defaultContainer()));
|
||||
|
||||
if (server.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = server.as<ApiV2ServerConfig>();
|
||||
if (apiV2 && !apiV2->apiConfig.availableCountries.isEmpty()) {
|
||||
emit updateApiCountryModel();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == serverId) {
|
||||
setProcessedContainerIndex(static_cast<int>(description.defaultContainer));
|
||||
break;
|
||||
}
|
||||
emit updateApiServicesModel();
|
||||
}
|
||||
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId != serverId) {
|
||||
continue;
|
||||
}
|
||||
if (description.isApiV2) {
|
||||
if (description.isCountrySelectionAvailable && !description.apiAvailableCountries.isEmpty()) {
|
||||
emit updateApiCountryModel();
|
||||
}
|
||||
emit updateApiServicesModel();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
emit processedServerIdChanged(m_processedServerId);
|
||||
emit processedServerIndexChanged(m_processedServerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
int ServersUiController::getProcessedServerIndex() const
|
||||
{
|
||||
return m_processedServerIndex;
|
||||
}
|
||||
|
||||
void ServersUiController::setProcessedServerIndex(int index)
|
||||
{
|
||||
if (index < 0) {
|
||||
setProcessedServerId(QString());
|
||||
return;
|
||||
}
|
||||
const QString id = getServerId(index);
|
||||
if (!id.isEmpty()) {
|
||||
setProcessedServerId(id);
|
||||
}
|
||||
}
|
||||
|
||||
int ServersUiController::defaultServerIndex() const
|
||||
{
|
||||
return rowForServerId(m_orderedServerDescriptions, getDefaultServerId());
|
||||
}
|
||||
|
||||
bool ServersUiController::processedServerIsPremium() const
|
||||
{
|
||||
ServerConfig server = m_serversController->getServerConfig(m_processedServerIndex);
|
||||
if (server.isApiV1()) {
|
||||
const ApiV1ServerConfig* apiV1 = server.as<ApiV1ServerConfig>();
|
||||
return apiV1 ? apiV1->isPremium() : false;
|
||||
} else if (server.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = server.as<ApiV2ServerConfig>();
|
||||
return apiV2 ? (apiV2->isPremium() || apiV2->isExternalPremium()) : false;
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == m_processedServerId) {
|
||||
return description.isPremium;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const ServerCredentials ServersUiController::getProcessedServerCredentials() const
|
||||
{
|
||||
return m_serversController->getServerCredentials(m_processedServerIndex);
|
||||
return m_serversController->getServerCredentials(m_processedServerId);
|
||||
}
|
||||
|
||||
bool ServersUiController::isDefaultServerCurrentlyProcessed() const
|
||||
{
|
||||
return m_serversController->getDefaultServerIndex() == m_processedServerIndex;
|
||||
return m_serversController->getDefaultServerId() == m_processedServerId;
|
||||
}
|
||||
|
||||
bool ServersUiController::isProcessedServerHasWriteAccess() const
|
||||
{
|
||||
ServerCredentials credentials = m_serversController->getServerCredentials(m_processedServerIndex);
|
||||
ServerCredentials credentials = m_serversController->getServerCredentials(m_processedServerId);
|
||||
return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
QString ServersUiController::getDefaultServerDescription(const ServerConfig& server, int index) const
|
||||
QString ServersUiController::getDefaultServerDescription(const QString &serverId) const
|
||||
{
|
||||
QString description;
|
||||
|
||||
if (server.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = server.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) return QString();
|
||||
if (!apiV2->apiConfig.serverCountryCode.isEmpty()) {
|
||||
return apiV2->apiConfig.serverCountryName;
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == serverId) {
|
||||
return description.baseDescription;
|
||||
}
|
||||
return apiV2->description;
|
||||
} else if (server.isApiV1()) {
|
||||
const ApiV1ServerConfig* apiV1 = server.as<ApiV1ServerConfig>();
|
||||
return apiV1 ? apiV1->description : QString();
|
||||
} else {
|
||||
ServerCredentials credentials = m_serversController->getServerCredentials(index);
|
||||
if (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty()) {
|
||||
bool isAmneziaDnsEnabled = m_settingsController->isAmneziaDnsEnabled();
|
||||
if (isAmneziaDnsEnabled && isAmneziaDnsContainerInstalled(index)) {
|
||||
description += "Amnezia DNS | ";
|
||||
}
|
||||
} else {
|
||||
if (server.dns1() == protocols::dns::amneziaDnsIp) {
|
||||
description += "Amnezia DNS | ";
|
||||
}
|
||||
}
|
||||
return description;
|
||||
}
|
||||
}
|
||||
|
||||
bool ServersUiController::isAmneziaDnsContainerInstalled(int serverIndex) const
|
||||
{
|
||||
const ServerConfig server = m_serversController->getServerConfig(serverIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containers = server.containers();
|
||||
|
||||
return containers.contains(DockerContainer::Dns);
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool ServersUiController::hasServersFromGatewayApi() const
|
||||
{
|
||||
QVector<ServerConfig> servers = m_serversController->getServers();
|
||||
for (const ServerConfig &server : servers) {
|
||||
if (server.isApiV2()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return listHasServersFromGatewayApi();
|
||||
}
|
||||
|
||||
bool ServersUiController::isAdVisible() const
|
||||
{
|
||||
int defaultIndex = getDefaultServerIndex();
|
||||
if (defaultIndex < 0) {
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
if (defaultServerId.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
ServerConfig server = m_serversController->getServerConfig(defaultIndex);
|
||||
if (server.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = server.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) return false;
|
||||
return apiV2->apiConfig.serviceInfo.isAdVisible;
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return description.isAdVisible;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ServersUiController::adHeader() const
|
||||
{
|
||||
int defaultIndex = getDefaultServerIndex();
|
||||
if (defaultIndex < 0) {
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
if (defaultServerId.isEmpty()) {
|
||||
return QString();
|
||||
}
|
||||
ServerConfig server = m_serversController->getServerConfig(defaultIndex);
|
||||
if (server.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = server.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) return QString();
|
||||
return apiV2->apiConfig.serviceInfo.adHeader;
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return description.adHeader;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString ServersUiController::adDescription() const
|
||||
{
|
||||
int defaultIndex = getDefaultServerIndex();
|
||||
if (defaultIndex < 0) {
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
if (defaultServerId.isEmpty()) {
|
||||
return QString();
|
||||
}
|
||||
ServerConfig server = m_serversController->getServerConfig(defaultIndex);
|
||||
if (server.isApiV2()) {
|
||||
const ApiV2ServerConfig* apiV2 = server.as<ApiV2ServerConfig>();
|
||||
if (!apiV2) return QString();
|
||||
return apiV2->apiConfig.serviceInfo.adDescription;
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return description.adDescription;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString ServersUiController::getServerId(int index) const
|
||||
{
|
||||
if (index < 0 || index >= m_orderedServerDescriptions.size()) {
|
||||
return QString();
|
||||
}
|
||||
return m_orderedServerDescriptions.at(index).serverId;
|
||||
}
|
||||
|
||||
int ServersUiController::getServerIndexById(const QString &serverId) const
|
||||
{
|
||||
return rowForServerId(m_orderedServerDescriptions, serverId);
|
||||
}
|
||||
|
||||
void ServersUiController::updateContainersModel()
|
||||
{
|
||||
if (m_processedServerIndex < 0 || m_processedServerIndex >= m_serversController->getServersCount()) {
|
||||
if (m_processedServerId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ServerConfig server = m_serversController->getServerConfig(m_processedServerIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containers = server.containers();
|
||||
const QMap<DockerContainer, ContainerConfig> containers =
|
||||
m_serversController->getServerContainersMap(m_processedServerId);
|
||||
m_containersModel->updateModel(containers);
|
||||
}
|
||||
|
||||
void ServersUiController::updateDefaultServerContainersModel()
|
||||
{
|
||||
int defaultIndex = m_serversController->getDefaultServerIndex();
|
||||
if (defaultIndex < 0 || defaultIndex >= m_serversController->getServersCount()) {
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
if (defaultServerId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ServerConfig server = m_serversController->getServerConfig(defaultIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containers = server.containers();
|
||||
const QMap<DockerContainer, ContainerConfig> containers =
|
||||
m_serversController->getServerContainersMap(defaultServerId);
|
||||
m_defaultServerContainersModel->updateModel(containers);
|
||||
}
|
||||
|
||||
QStringList ServersUiController::getAllInstalledServicesName(int serverIndex) const
|
||||
{
|
||||
QStringList servicesName;
|
||||
ServerConfig server = m_serversController->getServerConfig(serverIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containers = server.containers();
|
||||
|
||||
const QString serverId = getServerId(serverIndex);
|
||||
const QMap<DockerContainer, ContainerConfig> containers = m_serversController->getServerContainersMap(serverId);
|
||||
|
||||
for (auto it = containers.begin(); it != containers.end(); ++it) {
|
||||
DockerContainer container = it.key();
|
||||
if (ContainerUtils::containerService(container) == ServiceType::Other) {
|
||||
@@ -489,3 +512,13 @@ QStringList ServersUiController::getAllInstalledServicesName(int serverIndex) co
|
||||
return servicesName;
|
||||
}
|
||||
|
||||
int ServersUiController::serverIndexForId(const QString &serverId) const
|
||||
{
|
||||
return rowForServerId(m_orderedServerDescriptions, serverId);
|
||||
}
|
||||
|
||||
bool ServersUiController::listHasServersFromGatewayApi() const
|
||||
{
|
||||
return descriptionsHaveGatewayServers(m_orderedServerDescriptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,35 +6,39 @@
|
||||
#include <QSet>
|
||||
#include <QJsonObject>
|
||||
#include <QStringList>
|
||||
#include <QVector>
|
||||
|
||||
#include "core/controllers/serversController.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
#include "core/controllers/settingsController.h"
|
||||
#include "ui/models/serversModel.h"
|
||||
#include "ui/models/containersModel.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
|
||||
class ServersUiController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int defaultIndex READ getDefaultServerIndex NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString defaultServerDefaultContainerName READ getDefaultServerDefaultContainerName NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString defaultServerImagePathCollapsed READ getDefaultServerImagePathCollapsed NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(bool isDefaultServerDefaultContainerHasSplitTunneling READ isDefaultServerDefaultContainerHasSplitTunneling NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(bool isDefaultServerFromApi READ isDefaultServerFromApi NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString defaultServerId READ getDefaultServerId NOTIFY defaultServerIdChanged)
|
||||
Q_PROPERTY(int defaultServerIndex READ defaultServerIndex NOTIFY defaultServerIndexChanged)
|
||||
|
||||
Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerIdChanged)
|
||||
Q_PROPERTY(QString defaultServerDefaultContainerName READ getDefaultServerDefaultContainerName NOTIFY defaultServerIdChanged)
|
||||
Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerIdChanged)
|
||||
Q_PROPERTY(QString defaultServerImagePathCollapsed READ getDefaultServerImagePathCollapsed NOTIFY defaultServerIdChanged)
|
||||
Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerIdChanged)
|
||||
Q_PROPERTY(bool isDefaultServerDefaultContainerHasSplitTunneling READ isDefaultServerDefaultContainerHasSplitTunneling NOTIFY defaultServerIdChanged)
|
||||
Q_PROPERTY(bool isDefaultServerFromApi READ isDefaultServerFromApi NOTIFY defaultServerIdChanged)
|
||||
|
||||
Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
|
||||
Q_PROPERTY(QString processedServerId READ getProcessedServerId WRITE setProcessedServerId NOTIFY processedServerIdChanged)
|
||||
Q_PROPERTY(int processedServerIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
|
||||
Q_PROPERTY(int processedContainerIndex READ getProcessedContainerIndex WRITE setProcessedContainerIndex NOTIFY processedContainerIndexChanged)
|
||||
Q_PROPERTY(bool processedServerIsPremium READ processedServerIsPremium NOTIFY processedServerIndexChanged)
|
||||
|
||||
Q_PROPERTY(bool hasServersFromGatewayApi READ hasServersFromGatewayApi NOTIFY hasServersFromGatewayApiChanged)
|
||||
|
||||
Q_PROPERTY(bool isAdVisible READ isAdVisible NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString adHeader READ adHeader NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString adDescription READ adDescription NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(bool isAdVisible READ isAdVisible NOTIFY defaultServerIdChanged)
|
||||
Q_PROPERTY(QString adHeader READ adHeader NOTIFY defaultServerIdChanged)
|
||||
Q_PROPERTY(QString adDescription READ adDescription NOTIFY defaultServerIdChanged)
|
||||
|
||||
public:
|
||||
explicit ServersUiController(ServersController* serversController,
|
||||
@@ -45,15 +49,22 @@ public:
|
||||
QObject *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void removeServer(int index);
|
||||
void editServerName(int index, const QString &name);
|
||||
void setDefaultServerIndex(int index);
|
||||
void setDefaultContainer(int serverIndex, int containerIndex);
|
||||
void removeServer(const QString &serverId);
|
||||
void removeServerAtIndex(int index);
|
||||
|
||||
void editServerName(const QString &serverId, const QString &name);
|
||||
|
||||
void setDefaultServer(const QString &serverId);
|
||||
void setDefaultServerAtIndex(int index);
|
||||
|
||||
void setDefaultContainer(const QString &serverId, int containerIndex);
|
||||
void setDefaultContainerAtIndex(int index, int containerIndex);
|
||||
|
||||
void toggleAmneziaDns(bool enabled);
|
||||
void onDefaultServerChanged(int index);
|
||||
void onDefaultServerChanged(const QString &defaultServerId);
|
||||
|
||||
// Getters for properties
|
||||
int getDefaultServerIndex() const;
|
||||
QString getDefaultServerId() const;
|
||||
QString getDefaultServerName() const;
|
||||
QString getDefaultServerDefaultContainerName() const;
|
||||
QString getDefaultServerDescriptionCollapsed() const;
|
||||
@@ -62,8 +73,14 @@ public slots:
|
||||
bool isDefaultServerDefaultContainerHasSplitTunneling() const;
|
||||
bool isDefaultServerFromApi() const;
|
||||
|
||||
QString getProcessedServerId() const;
|
||||
void setProcessedServerId(const QString &serverId);
|
||||
|
||||
int getProcessedServerIndex() const;
|
||||
void setProcessedServerIndex(int index);
|
||||
|
||||
int defaultServerIndex() const;
|
||||
|
||||
int getProcessedContainerIndex() const;
|
||||
void setProcessedContainerIndex(int index);
|
||||
bool processedServerIsPremium() const;
|
||||
@@ -78,12 +95,16 @@ public slots:
|
||||
QString adHeader() const;
|
||||
QString adDescription() const;
|
||||
|
||||
QString getServerId(int index) const;
|
||||
int getServerIndexById(const QString &serverId) const;
|
||||
QStringList getAllInstalledServicesName(int serverIndex) const;
|
||||
|
||||
signals:
|
||||
void errorOccurred(const QString &errorMessage);
|
||||
void finished(const QString &message);
|
||||
void defaultServerIdChanged(const QString &serverId);
|
||||
void defaultServerIndexChanged(int index);
|
||||
void processedServerIdChanged(const QString &serverId);
|
||||
void processedServerIndexChanged(int index);
|
||||
void processedContainerIndexChanged(int index);
|
||||
void hasServersFromGatewayApiChanged();
|
||||
@@ -94,20 +115,23 @@ public:
|
||||
void updateModel();
|
||||
|
||||
private:
|
||||
QString getDefaultServerDescription(const ServerConfig& server, int index) const;
|
||||
bool isAmneziaDnsContainerInstalled(int serverIndex) const;
|
||||
QString getDefaultServerDescription(const QString &serverId) const;
|
||||
int serverIndexForId(const QString &serverId) const;
|
||||
bool listHasServersFromGatewayApi() const;
|
||||
|
||||
void updateContainersModel();
|
||||
void updateDefaultServerContainersModel();
|
||||
void updateApiModelsForProcessedServer();
|
||||
|
||||
|
||||
ServersController* m_serversController;
|
||||
SettingsController* m_settingsController;
|
||||
ServersModel* m_serversModel;
|
||||
ContainersModel* m_containersModel;
|
||||
ContainersModel* m_defaultServerContainersModel;
|
||||
|
||||
QVector<amnezia::ServerDescription> m_orderedServerDescriptions;
|
||||
|
||||
int m_processedServerIndex = -1;
|
||||
QString m_processedServerId;
|
||||
int m_processedContainerIndex = -1;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "logger.h"
|
||||
|
||||
namespace
|
||||
@@ -28,7 +29,7 @@ QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
switch (role) {
|
||||
case SubscriptionStatusRole: {
|
||||
if (m_accountInfoData.configType == apiDefs::ConfigType::AmneziaFreeV3) {
|
||||
if (m_accountInfoData.configType == serverConfigUtils::ConfigType::AmneziaFreeV3) {
|
||||
return tr("Active");
|
||||
}
|
||||
|
||||
@@ -37,14 +38,14 @@ QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const
|
||||
: QStringLiteral("<p><a style=\"color: #28c840;\">%1</a>").arg(tr("Active"));
|
||||
}
|
||||
case EndDateRole: {
|
||||
if (m_accountInfoData.configType == apiDefs::ConfigType::AmneziaFreeV3) {
|
||||
if (m_accountInfoData.configType == serverConfigUtils::ConfigType::AmneziaFreeV3) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return QDateTime::fromString(m_accountInfoData.subscriptionEndDate, Qt::ISODate).toLocalTime().toString("d MMM yyyy");
|
||||
}
|
||||
case ConnectedDevicesRole: {
|
||||
if (m_accountInfoData.configType == apiDefs::ConfigType::AmneziaFreeV3) {
|
||||
if (m_accountInfoData.configType == serverConfigUtils::ConfigType::AmneziaFreeV3) {
|
||||
return "";
|
||||
}
|
||||
return tr("%1 out of %2").arg(m_accountInfoData.activeDeviceCount).arg(m_accountInfoData.maxDeviceCount);
|
||||
@@ -53,9 +54,8 @@ QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const
|
||||
return m_accountInfoData.subscriptionDescription;
|
||||
}
|
||||
case IsComponentVisibleRole: {
|
||||
return m_accountInfoData.configType == apiDefs::ConfigType::AmneziaPremiumV2
|
||||
|| m_accountInfoData.configType == apiDefs::ConfigType::ExternalPremium
|
||||
|| m_accountInfoData.configType == apiDefs::ConfigType::ExternalTrial;
|
||||
return m_accountInfoData.configType == serverConfigUtils::ConfigType::AmneziaPremiumV2
|
||||
|| m_accountInfoData.configType == serverConfigUtils::ConfigType::ExternalPremium;
|
||||
}
|
||||
case IsSubscriptionRenewalAvailableRole: {
|
||||
return m_accountInfoData.isRenewalAvailable;
|
||||
@@ -80,7 +80,7 @@ QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const
|
||||
return false;
|
||||
}
|
||||
case IsSubscriptionExpiredRole: {
|
||||
if (m_accountInfoData.configType == apiDefs::ConfigType::AmneziaFreeV3) {
|
||||
if (m_accountInfoData.configType == serverConfigUtils::ConfigType::AmneziaFreeV3) {
|
||||
return false;
|
||||
}
|
||||
if (m_accountInfoData.isInAppPurchase) {
|
||||
@@ -92,7 +92,7 @@ QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const
|
||||
return apiUtils::isSubscriptionExpired(m_accountInfoData.subscriptionEndDate);
|
||||
}
|
||||
case IsSubscriptionExpiringSoonRole: {
|
||||
if (m_accountInfoData.configType == apiDefs::ConfigType::AmneziaFreeV3) {
|
||||
if (m_accountInfoData.configType == serverConfigUtils::ConfigType::AmneziaFreeV3) {
|
||||
return false;
|
||||
}
|
||||
if (m_accountInfoData.isInAppPurchase) {
|
||||
@@ -124,7 +124,7 @@ void ApiAccountInfoModel::updateModel(const QJsonObject &accountInfoObject, cons
|
||||
accountInfoData.maxDeviceCount = accountInfoObject.value(apiDefs::key::maxDeviceCount).toInt();
|
||||
accountInfoData.subscriptionEndDate = accountInfoObject.value(apiDefs::key::subscriptionEndDate).toString();
|
||||
|
||||
accountInfoData.configType = apiUtils::getConfigType(serverConfig);
|
||||
accountInfoData.configType = serverConfigUtils::configTypeFromJson(serverConfig);
|
||||
|
||||
const QJsonObject apiConfig = serverConfig.value(apiDefs::key::apiConfig).toObject();
|
||||
accountInfoData.isInAppPurchase = apiConfig.value(apiDefs::key::isInAppPurchase).toBool(false);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
|
||||
@@ -56,7 +56,7 @@ private:
|
||||
int activeDeviceCount;
|
||||
int maxDeviceCount;
|
||||
|
||||
apiDefs::ConfigType configType;
|
||||
serverConfigUtils::ConfigType configType;
|
||||
|
||||
QStringList supportedProtocols;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "logger.h"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "logger.h"
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#include "serversModel.h"
|
||||
|
||||
#include "core/models/serverDescription.h"
|
||||
|
||||
#include <QHash>
|
||||
#include <QSet>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/utils/api/apiEnums.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "core/utils/constants/apiKeys.h"
|
||||
#include "core/utils/constants/apiConstants.h"
|
||||
#include "core/utils/selfhosted/sshSession.h"
|
||||
@@ -19,42 +20,15 @@
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace configKey
|
||||
{
|
||||
constexpr char apiConfig[] = "api_config";
|
||||
constexpr char serviceInfo[] = "service_info";
|
||||
constexpr char availableCountries[] = "available_countries";
|
||||
constexpr char serverCountryCode[] = "server_country_code";
|
||||
constexpr char serverCountryName[] = "server_country_name";
|
||||
constexpr char userCountryCode[] = "user_country_code";
|
||||
constexpr char serviceType[] = "service_type";
|
||||
constexpr char serviceProtocol[] = "service_protocol";
|
||||
|
||||
constexpr char publicKeyInfo[] = "public_key";
|
||||
constexpr char expiresAt[] = "expires_at";
|
||||
}
|
||||
|
||||
QString normalizeVpnKey(const QString &vpnKey)
|
||||
{
|
||||
QString normalized = vpnKey.trimmed();
|
||||
if (normalized.startsWith(QStringLiteral("vpn://"), Qt::CaseInsensitive)) {
|
||||
normalized = normalized.mid(QStringLiteral("vpn://").size());
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
}
|
||||
|
||||
ServersModel::ServersModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged);
|
||||
|
||||
connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) {
|
||||
if (serverIndex < 0 || serverIndex >= m_servers.size()) {
|
||||
if (serverIndex < 0 || serverIndex >= m_descriptions.size()) {
|
||||
return;
|
||||
}
|
||||
auto defaultContainer = m_servers.at(serverIndex).defaultContainer();
|
||||
auto defaultContainer = m_descriptions.at(serverIndex).defaultContainer;
|
||||
emit ServersModel::defaultServerDefaultContainerChanged(defaultContainer);
|
||||
emit ServersModel::defaultServerNameChanged();
|
||||
});
|
||||
@@ -65,148 +39,73 @@ ServersModel::ServersModel(QObject *parent) : QAbstractListModel(parent)
|
||||
int ServersModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return static_cast<int>(m_servers.size());
|
||||
return static_cast<int>(m_descriptions.size());
|
||||
}
|
||||
|
||||
QVariant ServersModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_servers.size())) {
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_descriptions.size())) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
const ServerConfig &server = m_servers.at(index.row());
|
||||
const int configVersion = server.configVersion();
|
||||
|
||||
const ServerDescription &row = m_descriptions.at(index.row());
|
||||
const int configVersion = row.configVersion;
|
||||
|
||||
switch (role) {
|
||||
case NameRole: {
|
||||
if (configVersion) {
|
||||
if (server.isApiV1()) {
|
||||
return server.as<ApiV1ServerConfig>()->name;
|
||||
} else if (server.isApiV2()) {
|
||||
return server.as<ApiV2ServerConfig>()->name;
|
||||
}
|
||||
}
|
||||
QString name = server.description();
|
||||
if (name.isEmpty()) {
|
||||
return server.hostName();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
case ServerDescriptionRole: {
|
||||
auto description = getServerDescription(server, index.row());
|
||||
return configVersion ? description : description + server.hostName();
|
||||
}
|
||||
case HostNameRole: return server.hostName();
|
||||
case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row()));
|
||||
case CredentialsLoginRole: return serverCredentials(index.row()).userName;
|
||||
case IsDefaultRole: return index.row() == m_defaultServerIndex;
|
||||
case IsCurrentlyProcessedRole: return index.row() == m_processedServerIndex;
|
||||
case HasWriteAccessRole: {
|
||||
auto credentials = serverCredentials(index.row());
|
||||
return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty());
|
||||
}
|
||||
case ContainsAmneziaDnsRole: {
|
||||
QString primaryDns = server.dns1();
|
||||
return primaryDns == protocols::dns::amneziaDnsIp;
|
||||
}
|
||||
case DefaultContainerRole: {
|
||||
return server.defaultContainer();
|
||||
}
|
||||
case HasInstalledContainers: {
|
||||
return serverHasInstalledContainers(index.row());
|
||||
}
|
||||
case IsServerFromTelegramApiRole: {
|
||||
return configVersion == apiDefs::ConfigSource::Telegram;
|
||||
}
|
||||
case IsServerFromGatewayApiRole: {
|
||||
return configVersion == apiDefs::ConfigSource::AmneziaGateway;
|
||||
}
|
||||
case ApiConfigRole: {
|
||||
case NameRole:
|
||||
return row.serverName;
|
||||
case ServerDescriptionRole:
|
||||
return configVersion ? row.baseDescription : (row.baseDescription + row.hostName);
|
||||
case CollapsedServerDescriptionRole:
|
||||
return row.collapsedServerDescription;
|
||||
case ExpandedServerDescriptionRole:
|
||||
return row.expandedServerDescription;
|
||||
case HostNameRole:
|
||||
return row.hostName;
|
||||
case CredentialsRole:
|
||||
return QVariant::fromValue(serverCredentials(index.row()));
|
||||
case CredentialsLoginRole:
|
||||
return serverCredentials(index.row()).userName;
|
||||
case IsDefaultRole:
|
||||
return index.row() == m_defaultServerIndex;
|
||||
case IsCurrentlyProcessedRole:
|
||||
return index.row() == m_processedServerIndex;
|
||||
case HasWriteAccessRole:
|
||||
return row.hasWriteAccess;
|
||||
case ContainsAmneziaDnsRole:
|
||||
return row.primaryDnsIsAmnezia;
|
||||
case DefaultContainerRole:
|
||||
return QVariant::fromValue(row.defaultContainer);
|
||||
case HasInstalledContainers:
|
||||
return row.hasInstalledVpnContainers;
|
||||
case IsServerFromTelegramApiRole:
|
||||
return false;
|
||||
case IsServerFromGatewayApiRole:
|
||||
return row.isServerFromGatewayApi;
|
||||
case ApiConfigRole:
|
||||
return QVariant();
|
||||
}
|
||||
case IsCountrySelectionAvailableRole: {
|
||||
if (server.isApiV2()) {
|
||||
return !server.as<ApiV2ServerConfig>()->apiConfig.availableCountries.isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case ApiAvailableCountriesRole: {
|
||||
if (server.isApiV2()) {
|
||||
return server.as<ApiV2ServerConfig>()->apiConfig.availableCountries;
|
||||
}
|
||||
return QJsonArray();
|
||||
}
|
||||
case ApiServerCountryCodeRole: {
|
||||
if (server.isApiV2()) {
|
||||
return server.as<ApiV2ServerConfig>()->apiConfig.serverCountryCode;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
case HasAmneziaDns: {
|
||||
QString primaryDns = server.dns1();
|
||||
return primaryDns == protocols::dns::amneziaDnsIp;
|
||||
}
|
||||
case IsAdVisibleRole: {
|
||||
if (server.isApiV2()) {
|
||||
return server.as<ApiV2ServerConfig>()->apiConfig.serviceInfo.isAdVisible;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case AdHeaderRole: {
|
||||
if (server.isApiV2()) {
|
||||
return server.as<ApiV2ServerConfig>()->apiConfig.serviceInfo.adHeader;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
case AdDescriptionRole: {
|
||||
if (server.isApiV2()) {
|
||||
return server.as<ApiV2ServerConfig>()->apiConfig.serviceInfo.adDescription;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
case AdEndpointRole: {
|
||||
if (server.isApiV2()) {
|
||||
return server.as<ApiV2ServerConfig>()->apiConfig.serviceInfo.adEndpoint;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
case IsRenewalAvailableRole: {
|
||||
if (server.isApiV2()) {
|
||||
return server.as<ApiV2ServerConfig>()->apiConfig.serviceInfo.isRenewalAvailable;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case IsSubscriptionExpiredRole: {
|
||||
if (!server.isApiV2()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ApiConfig &apiConfig = server.as<ApiV2ServerConfig>()->apiConfig;
|
||||
if (apiConfig.isInAppPurchase) {
|
||||
return false;
|
||||
}
|
||||
if (apiConfig.subscriptionExpiredByServer) {
|
||||
return true;
|
||||
}
|
||||
if (apiConfig.subscription.endDate.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return apiUtils::isSubscriptionExpired(apiConfig.subscription.endDate);
|
||||
}
|
||||
case IsSubscriptionExpiringSoonRole: {
|
||||
if (!server.isApiV2()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ApiConfig &apiConfig = server.as<ApiV2ServerConfig>()->apiConfig;
|
||||
if (apiConfig.isInAppPurchase) {
|
||||
return false;
|
||||
}
|
||||
if (apiConfig.subscription.endDate.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return apiUtils::isSubscriptionExpiringSoon(apiConfig.subscription.endDate);
|
||||
}
|
||||
case IsCountrySelectionAvailableRole:
|
||||
return row.isCountrySelectionAvailable;
|
||||
case ApiAvailableCountriesRole:
|
||||
return row.apiAvailableCountries;
|
||||
case ApiServerCountryCodeRole:
|
||||
return row.apiServerCountryCode;
|
||||
case HasAmneziaDns:
|
||||
return row.primaryDnsIsAmnezia;
|
||||
case IsAdVisibleRole:
|
||||
return row.isAdVisible;
|
||||
case AdHeaderRole:
|
||||
return row.adHeader;
|
||||
case AdDescriptionRole:
|
||||
return row.adDescription;
|
||||
case AdEndpointRole:
|
||||
return row.adEndpoint;
|
||||
case IsRenewalAvailableRole:
|
||||
return row.isRenewalAvailable;
|
||||
case IsSubscriptionExpiredRole:
|
||||
return row.isSubscriptionExpired;
|
||||
case IsSubscriptionExpiringSoonRole:
|
||||
return row.isSubscriptionExpiringSoon;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@@ -218,12 +117,11 @@ QVariant ServersModel::data(const int index, int role) const
|
||||
return data(modelIndex, role);
|
||||
}
|
||||
|
||||
void ServersModel::updateModel(const QVector<ServerConfig> &servers, int defaultServerIndex, bool isAmneziaDnsEnabled)
|
||||
void ServersModel::updateModel(const QVector<ServerDescription> &descriptions, int defaultServerIndex)
|
||||
{
|
||||
beginResetModel();
|
||||
m_servers = servers;
|
||||
m_descriptions = descriptions;
|
||||
m_defaultServerIndex = defaultServerIndex;
|
||||
m_isAmneziaDnsEnabled = isAmneziaDnsEnabled;
|
||||
endResetModel();
|
||||
emit defaultServerIndexChanged(m_defaultServerIndex);
|
||||
emit processedServerChanged();
|
||||
@@ -234,43 +132,15 @@ const int ServersModel::getDefaultServerIndex()
|
||||
return m_defaultServerIndex;
|
||||
}
|
||||
|
||||
QString ServersModel::getServerDescription(const ServerConfig &server, const int index) const
|
||||
{
|
||||
const int configVersion = server.configVersion();
|
||||
QString description;
|
||||
|
||||
if (server.isApiV2()) {
|
||||
const ApiV2ServerConfig *apiV2 = server.as<ApiV2ServerConfig>();
|
||||
if (apiV2 && !apiV2->apiConfig.serverCountryCode.isEmpty()) {
|
||||
return apiV2->apiConfig.serverCountryName;
|
||||
}
|
||||
return apiV2 ? apiV2->description : server.description();
|
||||
} else if (server.isApiV1()) {
|
||||
const ApiV1ServerConfig *apiV1 = server.as<ApiV1ServerConfig>();
|
||||
return apiV1 ? apiV1->description : server.description();
|
||||
} else if (data(index, HasWriteAccessRole).toBool()) {
|
||||
QMap<DockerContainer, ContainerConfig> containers = server.containers();
|
||||
bool isDnsInstalled = containers.contains(DockerContainer::Dns);
|
||||
if (m_isAmneziaDnsEnabled && isDnsInstalled) {
|
||||
description += "Amnezia DNS | ";
|
||||
}
|
||||
} else {
|
||||
if (data(index, HasAmneziaDns).toBool()) {
|
||||
description += "Amnezia DNS | ";
|
||||
}
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
const int ServersModel::getServersCount()
|
||||
{
|
||||
return m_servers.size();
|
||||
return m_descriptions.size();
|
||||
}
|
||||
|
||||
bool ServersModel::hasServerWithWriteAccess()
|
||||
{
|
||||
for (size_t i = 0; i < getServersCount(); i++) {
|
||||
if (qvariant_cast<bool>(data(i, HasWriteAccessRole))) {
|
||||
if (qvariant_cast<bool>(data(static_cast<int>(i), HasWriteAccessRole))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -350,29 +220,17 @@ QHash<int, QByteArray> ServersModel::roleNames() const
|
||||
roles[IsSubscriptionExpiredRole] = "isSubscriptionExpired";
|
||||
roles[IsSubscriptionExpiringSoonRole] = "isSubscriptionExpiringSoon";
|
||||
|
||||
roles[HasAmneziaDns] = "hasAmneziaDns";
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
ServerCredentials ServersModel::serverCredentials(int index) const
|
||||
{
|
||||
if (index < 0 || index >= m_servers.size()) {
|
||||
if (index < 0 || index >= m_descriptions.size()) {
|
||||
return ServerCredentials();
|
||||
}
|
||||
const ServerConfig &server = m_servers.at(index);
|
||||
|
||||
if (server.isSelfHosted()) {
|
||||
const SelfHostedServerConfig *selfHosted = server.as<SelfHostedServerConfig>();
|
||||
if (selfHosted) {
|
||||
ServerCredentials credentials;
|
||||
credentials.hostName = selfHosted->hostName;
|
||||
credentials.userName = selfHosted->userName.value_or("");
|
||||
credentials.secretData = selfHosted->password.value_or("");
|
||||
credentials.port = selfHosted->port.value_or(22);
|
||||
return credentials;
|
||||
}
|
||||
}
|
||||
|
||||
return ServerCredentials();
|
||||
return m_descriptions.at(index).selfHostedSshCredentials;
|
||||
}
|
||||
|
||||
bool ServersModel::isServerFromApi(const int serverIndex)
|
||||
@@ -405,21 +263,10 @@ QVariant ServersModel::getProcessedServerData(const QString &roleString)
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
bool ServersModel::serverHasInstalledContainers(const int serverIndex) const
|
||||
{
|
||||
const ServerConfig &server = m_servers.at(serverIndex);
|
||||
QMap<DockerContainer, ContainerConfig> containers = server.containers();
|
||||
|
||||
for (auto it = containers.begin(); it != containers.end(); ++it) {
|
||||
DockerContainer container = it.key();
|
||||
if (ContainerUtils::containerService(container) == ServiceType::Vpn) {
|
||||
return true;
|
||||
}
|
||||
if (container == DockerContainer::SSXray) {
|
||||
return true;
|
||||
}
|
||||
if (serverIndex < 0 || serverIndex >= m_descriptions.size()) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return m_descriptions.at(serverIndex).hasInstalledVpnContainers;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <QVector>
|
||||
|
||||
#include "core/utils/selfhosted/sshSession.h"
|
||||
#include "core/models/serverConfig.h"
|
||||
#include "core/models/serverDescription.h"
|
||||
|
||||
class ServersModel : public QAbstractListModel
|
||||
{
|
||||
@@ -75,14 +75,13 @@ public slots:
|
||||
|
||||
bool isServerFromApi(const int serverIndex);
|
||||
|
||||
void updateModel(const QVector<ServerConfig> &servers, int defaultServerIndex, bool isAmneziaDnsEnabled = false);
|
||||
|
||||
void updateModel(const QVector<amnezia::ServerDescription> &descriptions, int defaultServerIndex);
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
signals:
|
||||
void processedServerIndexChanged(const int index);
|
||||
// emitted when the processed server index or processed server data is changed
|
||||
void processedServerChanged();
|
||||
|
||||
void defaultServerIndexChanged(const int index);
|
||||
@@ -97,16 +96,12 @@ signals:
|
||||
private:
|
||||
ServerCredentials serverCredentials(int index) const;
|
||||
|
||||
QString getServerDescription(const ServerConfig &server, const int index) const;
|
||||
|
||||
bool serverHasInstalledContainers(const int serverIndex) const;
|
||||
|
||||
QVector<ServerConfig> m_servers;
|
||||
QVector<amnezia::ServerDescription> m_descriptions;
|
||||
|
||||
int m_defaultServerIndex;
|
||||
int m_processedServerIndex;
|
||||
|
||||
bool m_isAmneziaDnsEnabled = false;
|
||||
int m_defaultServerIndex = -1;
|
||||
int m_processedServerIndex = -1;
|
||||
};
|
||||
|
||||
#endif // SERVERSMODEL_H
|
||||
|
||||
@@ -182,7 +182,7 @@ Button {
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultIndex)
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultServerIndex)
|
||||
ConnectionController.connectButtonClicked()
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Item {
|
||||
|
||||
onButtonStartChanged: {
|
||||
if (buttonStart) {
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultIndex)
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultServerIndex)
|
||||
ConnectionController.connectButtonClicked()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ ListViewType {
|
||||
|
||||
if (checked) {
|
||||
containersDropDown.closeTriggered()
|
||||
ServersUiController.setDefaultContainer(ServersUiController.defaultIndex, proxyDefaultServerContainersModel.mapToSource(index))
|
||||
ServersUiController.setDefaultContainer(ServersUiController.getServerId(ServersUiController.defaultServerIndex), proxyDefaultServerContainersModel.mapToSource(index))
|
||||
} else {
|
||||
ServersUiController.processedContainerIndex = proxyDefaultServerContainersModel.mapToSource(index)
|
||||
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
||||
|
||||
@@ -46,7 +46,7 @@ DrawerType2 {
|
||||
}
|
||||
|
||||
if (serverName.textField.text !== root.serverNameText) {
|
||||
ServersUiController.editServerName(ServersUiController.processedIndex, serverName.textField.text);
|
||||
ServersUiController.editServerName(ServersUiController.getServerId(ServersUiController.processedServerIndex), serverName.textField.text);
|
||||
}
|
||||
root.closeTriggered()
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import "../Config"
|
||||
ListViewType {
|
||||
id: root
|
||||
|
||||
property int selectedIndex: ServersUiController.defaultIndex
|
||||
property int selectedIndex: ServersUiController.defaultServerIndex
|
||||
|
||||
anchors.top: serversMenuHeader.bottom
|
||||
anchors.right: parent.right
|
||||
@@ -29,8 +29,8 @@ ListViewType {
|
||||
|
||||
Connections {
|
||||
target: ServersUiController
|
||||
function onDefaultServerIndexChanged(serverIndex) {
|
||||
root.selectedIndex = serverIndex
|
||||
function onDefaultServerIndexChanged() {
|
||||
root.selectedIndex = ServersUiController.defaultServerIndex
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ ListViewType {
|
||||
|
||||
root.selectedIndex = index
|
||||
|
||||
ServersUiController.setDefaultServerIndex(index)
|
||||
ServersUiController.setDefaultServerAtIndex(index)
|
||||
}
|
||||
|
||||
Keys.onEnterPressed: serverRadioButton.clicked()
|
||||
@@ -106,14 +106,14 @@ ListViewType {
|
||||
z: 1
|
||||
|
||||
onClicked: function() {
|
||||
ServersUiController.processedIndex = index
|
||||
ServersUiController.processedServerIndex = index
|
||||
|
||||
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
||||
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.getProcessedServerIndex(), false)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.getServerId(ServersUiController.processedServerIndex), false)
|
||||
PageController.showBusyIndicator(false)
|
||||
if (!result) {
|
||||
return
|
||||
|
||||
@@ -34,19 +34,19 @@ ListViewType {
|
||||
if (isVpnContainer) {
|
||||
// var isThirdPartyConfig = root.model.data(index, ContainersModel.IsThirdPartyConfigRole)
|
||||
if (isThirdPartyConfig) {
|
||||
InstallController.updateProtocols(ServersUiController.processedIndex, containerIndex)
|
||||
InstallController.updateProtocols(ServersUiController.getServerId(ServersUiController.processedServerIndex), containerIndex)
|
||||
PageController.goToPage(PageEnum.PageProtocolRaw)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (isIpsec) {
|
||||
InstallController.updateProtocols(ServersUiController.processedIndex, containerIndex)
|
||||
InstallController.updateProtocols(ServersUiController.getServerId(ServersUiController.processedServerIndex), containerIndex)
|
||||
PageController.goToPage(PageEnum.PageProtocolRaw)
|
||||
} else if (isDns) {
|
||||
PageController.goToPage(PageEnum.PageServiceDnsSettings)
|
||||
} else {
|
||||
InstallController.updateProtocols(ServersUiController.processedIndex, containerIndex)
|
||||
InstallController.updateProtocols(ServersUiController.getServerId(ServersUiController.processedServerIndex), containerIndex)
|
||||
PageController.goToPage(PageEnum.PageSettingsServerProtocol)
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ DrawerType2 {
|
||||
textColor: AmneziaStyle.color.midnightBlack
|
||||
|
||||
clickedFunc: function() {
|
||||
SubscriptionUiController.getRenewalLink(ServersUiController.defaultIndex)
|
||||
SubscriptionUiController.getRenewalLink(ServersUiController.getServerId(ServersUiController.defaultServerIndex))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ DrawerType2 {
|
||||
|
||||
clickedFunc: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.defaultIndex, false)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.getServerId(ServersUiController.defaultServerIndex), false)
|
||||
PageController.showBusyIndicator(false)
|
||||
if (result) {
|
||||
root.closeTriggered()
|
||||
|
||||
@@ -344,14 +344,14 @@ PageType {
|
||||
Keys.onReturnPressed: this.clicked()
|
||||
|
||||
onClicked: {
|
||||
ServersUiController.processedIndex = ServersUiController.defaultIndex
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultServerIndex)
|
||||
|
||||
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
||||
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.getProcessedServerIndex(), false)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.getServerId(ServersUiController.processedServerIndex), false)
|
||||
PageController.showBusyIndicator(false)
|
||||
if (!result) {
|
||||
return
|
||||
|
||||
@@ -441,7 +441,7 @@ PageType {
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.updateContainer(ServersUiController.processedIndex, ServersUiController.processedContainerIndex, ProtocolEnum.Awg)
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.Awg)
|
||||
}
|
||||
|
||||
var noButtonFunction = function() {}
|
||||
|
||||
@@ -561,7 +561,7 @@ PageType {
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.updateContainer(ServersUiController.processedIndex, ServersUiController.processedContainerIndex, ProtocolEnum.Awg)
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.Awg)
|
||||
}
|
||||
|
||||
var noButtonFunction = function() {}
|
||||
|
||||
@@ -434,7 +434,7 @@ PageType {
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.updateContainer(ServersUiController.processedIndex, ServersUiController.processedContainerIndex, ProtocolEnum.OpenVpn)
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.OpenVpn)
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
|
||||
@@ -184,7 +184,7 @@ PageType {
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeContainer(ServersUiController.processedIndex, ServersUiController.processedContainerIndex)
|
||||
InstallController.removeContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
}
|
||||
var noButtonFunction = function() {}
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ PageType {
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.updateContainer(ServersUiController.processedIndex, ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard)
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard)
|
||||
}
|
||||
var noButtonFunction = function() {}
|
||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||
|
||||
@@ -129,7 +129,7 @@ PageType {
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.updateContainer(ServersUiController.processedIndex, ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard)
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard)
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user