mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-21 02:01:03 +07:00
529 lines
17 KiB
C++
529 lines
17 KiB
C++
#include "serversUiController.h"
|
|
|
|
#include "core/utils/containerEnum.h"
|
|
#include "core/utils/containers/containerUtils.h"
|
|
#include "core/utils/protocolEnum.h"
|
|
#include "core/models/protocolConfig.h"
|
|
#include "core/models/containerConfig.h"
|
|
|
|
using namespace amnezia;
|
|
|
|
namespace {
|
|
int rowForServerId(const QVector<ServerDescription> &list, const QString &serverId)
|
|
{
|
|
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,
|
|
ContainersModel* containersModel,
|
|
ContainersModel* defaultServerContainersModel,
|
|
QObject *parent)
|
|
: QObject(parent),
|
|
m_serversController(serversController),
|
|
m_settingsController(settingsController),
|
|
m_serversModel(serversModel),
|
|
m_containersModel(containersModel),
|
|
m_defaultServerContainersModel(defaultServerContainersModel)
|
|
{
|
|
}
|
|
|
|
void ServersUiController::removeServer(const QString &serverId)
|
|
{
|
|
if (serverId.isEmpty()) {
|
|
return;
|
|
}
|
|
m_serversController->removeServer(serverId);
|
|
updateModel();
|
|
}
|
|
|
|
void ServersUiController::removeServerAtIndex(int index)
|
|
{
|
|
const QString serverId = getServerId(index);
|
|
if (!serverId.isEmpty()) {
|
|
removeServer(serverId);
|
|
}
|
|
}
|
|
|
|
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(serverId, container);
|
|
updateModel();
|
|
}
|
|
|
|
void ServersUiController::toggleAmneziaDns(bool enabled)
|
|
{
|
|
m_settingsController->toggleAmneziaDns(enabled);
|
|
updateModel();
|
|
}
|
|
|
|
void ServersUiController::onDefaultServerChanged(const QString &/*defaultServerId*/)
|
|
{
|
|
updateModel();
|
|
setProcessedServerId(m_serversController->getDefaultServerId());
|
|
updateDefaultServerContainersModel();
|
|
emit defaultServerIdChanged(m_serversController->getDefaultServerId());
|
|
}
|
|
|
|
void ServersUiController::updateModel()
|
|
{
|
|
QVector<ServerDescription> descriptions =
|
|
m_serversController->buildServerDescriptions(m_settingsController->isAmneziaDnsEnabled());
|
|
|
|
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_orderedServerDescriptions, defaultRowInDescriptions);
|
|
|
|
updateContainersModel();
|
|
updateDefaultServerContainersModel();
|
|
|
|
if (hadServersFromGatewayBefore != hasServersFromGatewayNow) {
|
|
emit hasServersFromGatewayApiChanged();
|
|
}
|
|
|
|
emit defaultServerIdChanged(defaultServerId);
|
|
emit defaultServerIndexChanged(defaultServerIndex());
|
|
}
|
|
|
|
QString ServersUiController::getDefaultServerId() const
|
|
{
|
|
return m_serversController->getDefaultServerId();
|
|
}
|
|
|
|
QString ServersUiController::getDefaultServerName() const
|
|
{
|
|
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
|
|
{
|
|
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
|
|
{
|
|
const QString defaultServerId = m_serversController->getDefaultServerId();
|
|
for (const auto &description : m_orderedServerDescriptions) {
|
|
if (description.serverId == defaultServerId) {
|
|
return description.collapsedServerDescription;
|
|
}
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
QString ServersUiController::getDefaultServerImagePathCollapsed() const
|
|
{
|
|
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 ServersUiController::getDefaultServerDescriptionExpanded() const
|
|
{
|
|
const QString defaultServerId = m_serversController->getDefaultServerId();
|
|
for (const auto &description : m_orderedServerDescriptions) {
|
|
if (description.serverId == defaultServerId) {
|
|
return description.expandedServerDescription;
|
|
}
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
bool ServersUiController::isDefaultServerDefaultContainerHasSplitTunneling() const
|
|
{
|
|
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 {
|
|
bool hasSplitTunneling = !allowedIps.isEmpty() && !allowedIps.contains("0.0.0.0/0");
|
|
if (!hasSplitTunneling && !nativeConfig.isEmpty()) {
|
|
hasSplitTunneling = nativeConfig.contains("AllowedIPs")
|
|
&& !nativeConfig.contains("AllowedIPs = 0.0.0.0/0, ::/0");
|
|
}
|
|
return hasSplitTunneling;
|
|
};
|
|
|
|
if (defaultContainer == DockerContainer::Awg) {
|
|
if (const auto* awgConfig = containerConfig.getAwgProtocolConfig()) {
|
|
if (awgConfig->hasClientConfig()) {
|
|
return hasSplitTunnelingFromAllowedIps(
|
|
awgConfig->clientConfig->allowedIps,
|
|
awgConfig->clientConfig->nativeConfig
|
|
);
|
|
}
|
|
}
|
|
} else if (defaultContainer == DockerContainer::WireGuard) {
|
|
if (const auto* wgConfig = containerConfig.getWireGuardProtocolConfig()) {
|
|
if (wgConfig->hasClientConfig()) {
|
|
return hasSplitTunnelingFromAllowedIps(
|
|
wgConfig->clientConfig->allowedIps,
|
|
wgConfig->clientConfig->nativeConfig
|
|
);
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
} else if (defaultContainer == DockerContainer::OpenVpn) {
|
|
if (const auto* ovpnConfig = containerConfig.getOpenVpnProtocolConfig()) {
|
|
if (ovpnConfig->hasClientConfig()) {
|
|
return !ovpnConfig->clientConfig->nativeConfig.isEmpty()
|
|
&& !ovpnConfig->clientConfig->nativeConfig.contains("redirect-gateway");
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool ServersUiController::isDefaultServerFromApi() const
|
|
{
|
|
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
|
|
{
|
|
return m_processedContainerIndex;
|
|
}
|
|
|
|
void ServersUiController::setProcessedContainerIndex(int index)
|
|
{
|
|
if (m_processedContainerIndex != index) {
|
|
m_processedContainerIndex = index;
|
|
m_containersModel->setProcessedContainerIndex(index);
|
|
emit processedContainerIndexChanged(m_processedContainerIndex);
|
|
}
|
|
}
|
|
|
|
QString ServersUiController::getProcessedServerId() const
|
|
{
|
|
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 || m_processedServerId != serverId) {
|
|
m_processedServerIndex = index;
|
|
m_processedServerId = serverId;
|
|
m_serversModel->setProcessedServerIndex(index);
|
|
|
|
if (index >= 0) {
|
|
updateContainersModel();
|
|
for (const auto &description : m_orderedServerDescriptions) {
|
|
if (description.serverId == serverId) {
|
|
setProcessedContainerIndex(static_cast<int>(description.defaultContainer));
|
|
break;
|
|
}
|
|
}
|
|
|
|
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
|
|
{
|
|
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_processedServerId);
|
|
}
|
|
|
|
bool ServersUiController::isDefaultServerCurrentlyProcessed() const
|
|
{
|
|
return m_serversController->getDefaultServerId() == m_processedServerId;
|
|
}
|
|
|
|
bool ServersUiController::isProcessedServerHasWriteAccess() const
|
|
{
|
|
ServerCredentials credentials = m_serversController->getServerCredentials(m_processedServerId);
|
|
return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty());
|
|
}
|
|
|
|
QString ServersUiController::getDefaultServerDescription(const QString &serverId) const
|
|
{
|
|
for (const auto &description : m_orderedServerDescriptions) {
|
|
if (description.serverId == serverId) {
|
|
return description.baseDescription;
|
|
}
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
bool ServersUiController::hasServersFromGatewayApi() const
|
|
{
|
|
return listHasServersFromGatewayApi();
|
|
}
|
|
|
|
bool ServersUiController::isAdVisible() const
|
|
{
|
|
const QString defaultServerId = m_serversController->getDefaultServerId();
|
|
if (defaultServerId.isEmpty()) {
|
|
return false;
|
|
}
|
|
for (const auto &description : m_orderedServerDescriptions) {
|
|
if (description.serverId == defaultServerId) {
|
|
return description.isAdVisible;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
QString ServersUiController::adHeader() const
|
|
{
|
|
const QString defaultServerId = m_serversController->getDefaultServerId();
|
|
if (defaultServerId.isEmpty()) {
|
|
return QString();
|
|
}
|
|
for (const auto &description : m_orderedServerDescriptions) {
|
|
if (description.serverId == defaultServerId) {
|
|
return description.adHeader;
|
|
}
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
QString ServersUiController::adDescription() const
|
|
{
|
|
const QString defaultServerId = m_serversController->getDefaultServerId();
|
|
if (defaultServerId.isEmpty()) {
|
|
return QString();
|
|
}
|
|
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_processedServerId.isEmpty()) {
|
|
return;
|
|
}
|
|
const QMap<DockerContainer, ContainerConfig> containers =
|
|
m_serversController->getServerContainersMap(m_processedServerId);
|
|
m_containersModel->updateModel(containers);
|
|
}
|
|
|
|
void ServersUiController::updateDefaultServerContainersModel()
|
|
{
|
|
const QString defaultServerId = m_serversController->getDefaultServerId();
|
|
if (defaultServerId.isEmpty()) {
|
|
return;
|
|
}
|
|
const QMap<DockerContainer, ContainerConfig> containers =
|
|
m_serversController->getServerContainersMap(defaultServerId);
|
|
m_defaultServerContainersModel->updateModel(containers);
|
|
}
|
|
|
|
QStringList ServersUiController::getAllInstalledServicesName(int serverIndex) const
|
|
{
|
|
QStringList servicesName;
|
|
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) {
|
|
if (container == DockerContainer::Dns) {
|
|
servicesName.append("DNS");
|
|
} else if (container == DockerContainer::Sftp) {
|
|
servicesName.append("SFTP");
|
|
} else if (container == DockerContainer::TorWebSite) {
|
|
servicesName.append("TOR");
|
|
} else if (container == DockerContainer::Socks5Proxy) {
|
|
servicesName.append("SOCKS5");
|
|
} else if (container == DockerContainer::MtProxy) {
|
|
servicesName.append("MTProxy");
|
|
} else if (container == DockerContainer::Telemt) {
|
|
servicesName.append("Telemt");
|
|
}
|
|
}
|
|
}
|
|
servicesName.sort();
|
|
return servicesName;
|
|
}
|
|
|
|
int ServersUiController::serverIndexForId(const QString &serverId) const
|
|
{
|
|
return rowForServerId(m_orderedServerDescriptions, serverId);
|
|
}
|
|
|
|
bool ServersUiController::listHasServersFromGatewayApi() const
|
|
{
|
|
return descriptionsHaveGatewayServers(m_orderedServerDescriptions);
|
|
}
|
|
|