added separation for read/write and readonly servers for pageSettingsServerProtocols, PageSettingsServerServices, PageSettingsServerData

- added fields validations for pageSetupWizardCredentials
This commit is contained in:
vladimir.kuznetsov 2023-06-23 15:24:40 +09:00
parent 249be451f7
commit 2ef53c6df9
22 changed files with 466 additions and 325 deletions

View file

@ -16,14 +16,14 @@
ExportController::ExportController(const QSharedPointer<ServersModel> &serversModel,
const QSharedPointer<ContainersModel> &containersModel,
const std::shared_ptr<Settings> &settings,
const std::shared_ptr<VpnConfigurator> &configurator,
QObject *parent)
: QObject(parent)
, m_serversModel(serversModel)
, m_containersModel(containersModel)
, m_settings(settings)
, m_configurator(configurator)
{}
const std::shared_ptr<VpnConfigurator> &configurator, QObject *parent)
: QObject(parent),
m_serversModel(serversModel),
m_containersModel(containersModel),
m_settings(settings),
m_configurator(configurator)
{
}
void ExportController::generateFullAccessConfig()
{
@ -33,8 +33,8 @@ void ExportController::generateFullAccessConfig()
QByteArray compressedConfig = QJsonDocument(config).toJson();
compressedConfig = qCompress(compressedConfig, 8);
m_amneziaCode = QString("vpn://%1")
.arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding
| QByteArray::OmitTrailingEquals)));
.arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding
| QByteArray::OmitTrailingEquals)));
m_qrCodes = generateQrCodeImageSeries(compressedConfig);
emit exportConfigChanged();
@ -43,25 +43,21 @@ void ExportController::generateFullAccessConfig()
void ExportController::generateConnectionConfig()
{
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
ServerCredentials credentials = qvariant_cast<ServerCredentials>(
m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
ServerCredentials credentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
DockerContainer container = static_cast<DockerContainer>(
m_containersModel->getCurrentlyProcessedContainerIndex());
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
QModelIndex containerModelIndex = m_containersModel->index(container);
QJsonObject containerConfig = qvariant_cast<QJsonObject>(
m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
QJsonObject containerConfig =
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
ErrorCode errorCode = ErrorCode::NoError;
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
QJsonObject protocolConfig = m_settings->protocolConfig(serverIndex, container, protocol);
QString vpnConfig = m_configurator->genVpnProtocolConfig(credentials,
container,
containerConfig,
protocol,
&errorCode);
QString vpnConfig =
m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, protocol, &errorCode);
if (errorCode) {
emit exportErrorOccurred(errorString(errorCode));
return;
@ -75,7 +71,7 @@ void ExportController::generateConnectionConfig()
config.remove(config_key::userName);
config.remove(config_key::password);
config.remove(config_key::port);
config.insert(config_key::containers, QJsonArray{containerConfig});
config.insert(config_key::containers, QJsonArray { containerConfig });
config.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
auto dns = m_configurator->getDnsForConfig(serverIndex);
@ -86,8 +82,8 @@ void ExportController::generateConnectionConfig()
QByteArray compressedConfig = QJsonDocument(config).toJson();
compressedConfig = qCompress(compressedConfig, 8);
m_amneziaCode = QString("vpn://%1")
.arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding
| QByteArray::OmitTrailingEquals)));
.arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding
| QByteArray::OmitTrailingEquals)));
m_qrCodes = generateQrCodeImageSeries(compressedConfig);
emit exportConfigChanged();
@ -108,10 +104,8 @@ void ExportController::saveFile()
QString fileExtension = ".vpn";
QString docDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
QUrl fileName;
fileName = QFileDialog::getSaveFileUrl(nullptr,
tr("Save AmneziaVPN config"),
QUrl::fromLocalFile(docDir + "/" + "amnezia_config"),
"*" + fileExtension);
fileName = QFileDialog::getSaveFileUrl(nullptr, tr("Save AmneziaVPN config"),
QUrl::fromLocalFile(docDir + "/" + "amnezia_config"), "*" + fileExtension);
if (fileName.isEmpty())
return;
if (!fileName.toString().endsWith(fileExtension)) {
@ -139,10 +133,9 @@ QList<QString> ExportController::generateQrCodeImageSeries(const QByteArray &dat
for (int i = 0; i < data.size(); i = i + k) {
QByteArray chunk;
QDataStream s(&chunk, QIODevice::WriteOnly);
s << amnezia::qrMagicCode << chunksCount << (quint8) std::round(i / k) << data.mid(i, k);
s << amnezia::qrMagicCode << chunksCount << (quint8)std::round(i / k) << data.mid(i, k);
QByteArray ba = chunk.toBase64(QByteArray::Base64UrlEncoding
| QByteArray::OmitTrailingEquals);
QByteArray ba = chunk.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(ba, qrcodegen::QrCode::Ecc::LOW);
QString svg = QString::fromStdString(toSvgString(qr, 0));

View file

@ -5,40 +5,42 @@
#include "core/errorstrings.h"
namespace {
enum class ConfigTypes { Amnezia, OpenVpn, WireGuard };
ConfigTypes checkConfigFormat(const QString &config)
namespace
{
const QString openVpnConfigPatternCli = "client";
const QString openVpnConfigPatternProto1 = "proto tcp";
const QString openVpnConfigPatternProto2 = "proto udp";
const QString openVpnConfigPatternDriver1 = "dev tun";
const QString openVpnConfigPatternDriver2 = "dev tap";
enum class ConfigTypes {
Amnezia,
OpenVpn,
WireGuard
};
const QString wireguardConfigPatternSectionInterface = "[Interface]";
const QString wireguardConfigPatternSectionPeer = "[Peer]";
ConfigTypes checkConfigFormat(const QString &config)
{
const QString openVpnConfigPatternCli = "client";
const QString openVpnConfigPatternProto1 = "proto tcp";
const QString openVpnConfigPatternProto2 = "proto udp";
const QString openVpnConfigPatternDriver1 = "dev tun";
const QString openVpnConfigPatternDriver2 = "dev tap";
if (config.contains(openVpnConfigPatternCli)
&& (config.contains(openVpnConfigPatternProto1)
|| config.contains(openVpnConfigPatternProto2))
&& (config.contains(openVpnConfigPatternDriver1)
|| config.contains(openVpnConfigPatternDriver2))) {
return ConfigTypes::OpenVpn;
} else if (config.contains(wireguardConfigPatternSectionInterface)
&& config.contains(wireguardConfigPatternSectionPeer)) {
return ConfigTypes::WireGuard;
const QString wireguardConfigPatternSectionInterface = "[Interface]";
const QString wireguardConfigPatternSectionPeer = "[Peer]";
if (config.contains(openVpnConfigPatternCli)
&& (config.contains(openVpnConfigPatternProto1) || config.contains(openVpnConfigPatternProto2))
&& (config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) {
return ConfigTypes::OpenVpn;
} else if (config.contains(wireguardConfigPatternSectionInterface)
&& config.contains(wireguardConfigPatternSectionPeer)) {
return ConfigTypes::WireGuard;
}
return ConfigTypes::Amnezia;
}
return ConfigTypes::Amnezia;
}
} // namespace
ImportController::ImportController(const QSharedPointer<ServersModel> &serversModel,
const QSharedPointer<ContainersModel> &containersModel,
const std::shared_ptr<Settings> &settings,
QObject *parent) : QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
const std::shared_ptr<Settings> &settings, QObject *parent)
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
{
}
void ImportController::extractConfigFromFile(const QUrl &fileUrl)
@ -88,8 +90,7 @@ void ImportController::importConfig()
m_serversModel->addServer(m_config);
if (!m_config.value(config_key::containers).toArray().isEmpty()) {
auto newServerIndex = m_serversModel->index(m_serversModel->getServersCount() - 1);
m_serversModel->setData(newServerIndex, true, ServersModel::Roles::IsDefaultRole);
m_serversModel->setDefaultServerIndex(m_serversModel->getServersCount() - 1);
}
emit importFinished();
@ -116,12 +117,12 @@ QJsonObject ImportController::extractAmneziaConfig(QString &data)
return QJsonDocument::fromJson(ba).object();
}
//bool ImportController::importConnectionFromQr(const QByteArray &data)
// bool ImportController::importConnectionFromQr(const QByteArray &data)
//{
// QJsonObject dataObj = QJsonDocument::fromJson(data).object();
// if (!dataObj.isEmpty()) {
// return importConnection(dataObj);
// }
// QJsonObject dataObj = QJsonDocument::fromJson(data).object();
// if (!dataObj.isEmpty()) {
// return importConnection(dataObj);
// }
// QByteArray ba_uncompressed = qUncompress(data);
// if (!ba_uncompressed.isEmpty()) {
@ -159,7 +160,6 @@ QJsonObject ImportController::extractOpenVpnConfig(const QString &data)
config[config_key::defaultContainer] = "amnezia-openvpn";
config[config_key::description] = m_settings->nextAvailableServerName();
const static QRegularExpression dnsRegExp("dhcp-option DNS (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
QRegularExpressionMatchIterator dnsMatch = dnsRegExp.globalMatch(data);
if (dnsMatch.hasNext()) {
@ -206,7 +206,9 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
config[config_key::defaultContainer] = "amnezia-wireguard";
config[config_key::description] = m_settings->nextAvailableServerName();
const static QRegularExpression dnsRegExp("DNS = (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b).*(\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
const static QRegularExpression dnsRegExp(
"DNS = "
"(\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b).*(\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
QRegularExpressionMatch dnsMatch = dnsRegExp.match(data);
if (dnsMatch.hasMatch()) {
config[config_key::dns1] = dnsMatch.captured(1);

View file

@ -67,8 +67,7 @@ void InstallController::installServer(DockerContainer container, QJsonObject &co
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
m_serversModel->addServer(server);
auto newServerIndex = m_serversModel->index(m_serversModel->getServersCount() - 1);
m_serversModel->setData(newServerIndex, true, ServersModel::Roles::IsDefaultRole);
m_serversModel->setDefaultServerIndex(m_serversModel->getServersCount() - 1);
emit installServerFinished(isInstalledContainerFound);
return;