Поддержка протокола Sftp (File Sharing) по ТЗ по гранту от Теплицы

социальных технологий (2021 год)
+ небольшой рефакторинг
This commit is contained in:
pokamest 2021-09-22 14:49:08 +03:00
parent 6ee203a21d
commit 3bcc12869b
45 changed files with 645 additions and 338 deletions

View file

@ -56,6 +56,7 @@ HEADERS += \
ui/pages_logic/WizardLogic.h \ ui/pages_logic/WizardLogic.h \
ui/pages_logic/protocols/CloakLogic.h \ ui/pages_logic/protocols/CloakLogic.h \
ui/pages_logic/protocols/OpenVpnLogic.h \ ui/pages_logic/protocols/OpenVpnLogic.h \
ui/pages_logic/protocols/OtherProtocolsLogic.h \
ui/pages_logic/protocols/PageProtocolLogicBase.h \ ui/pages_logic/protocols/PageProtocolLogicBase.h \
ui/pages_logic/protocols/ShadowSocksLogic.h \ ui/pages_logic/protocols/ShadowSocksLogic.h \
ui/property_helper.h \ ui/property_helper.h \
@ -107,6 +108,7 @@ SOURCES += \
ui/pages_logic/WizardLogic.cpp \ ui/pages_logic/WizardLogic.cpp \
ui/pages_logic/protocols/CloakLogic.cpp \ ui/pages_logic/protocols/CloakLogic.cpp \
ui/pages_logic/protocols/OpenVpnLogic.cpp \ ui/pages_logic/protocols/OpenVpnLogic.cpp \
ui/pages_logic/protocols/OtherProtocolsLogic.cpp \
ui/pages_logic/protocols/PageProtocolLogicBase.cpp \ ui/pages_logic/protocols/PageProtocolLogicBase.cpp \
ui/pages_logic/protocols/ShadowSocksLogic.cpp \ ui/pages_logic/protocols/ShadowSocksLogic.cpp \
ui/models/servers_model.cpp \ ui/models/servers_model.cpp \

View file

@ -38,7 +38,7 @@ QVector<amnezia::Protocol> ContainerProps::protocolsForContainer(amnezia::Docker
return { Protocol::OpenVpn, Protocol::ShadowSocks, Protocol::Cloak }; return { Protocol::OpenVpn, Protocol::ShadowSocks, Protocol::Cloak };
default: default:
return {}; return { defaultProtocol(container) };
} }
} }
@ -62,7 +62,8 @@ QMap<DockerContainer, QString> ContainerProps::containerHumanNames()
{DockerContainer::WireGuard, "WireGuard"}, {DockerContainer::WireGuard, "WireGuard"},
{DockerContainer::TorWebSite, QObject::tr("Web site in TOR network")}, {DockerContainer::TorWebSite, QObject::tr("Web site in TOR network")},
{DockerContainer::Dns, QObject::tr("DNS Service")}, {DockerContainer::Dns, QObject::tr("DNS Service")},
{DockerContainer::FileShare, QObject::tr("File Sharing Service")} {DockerContainer::FileShare, QObject::tr("SMB file sharing service")},
{DockerContainer::Sftp, QObject::tr("Sftp file sharing service")}
}; };
} }
@ -76,7 +77,8 @@ QMap<DockerContainer, QString> ContainerProps::containerDescriptions()
{DockerContainer::WireGuard, QObject::tr("WireGuard container")}, {DockerContainer::WireGuard, QObject::tr("WireGuard container")},
{DockerContainer::TorWebSite, QObject::tr("Web site in TOR network")}, {DockerContainer::TorWebSite, QObject::tr("Web site in TOR network")},
{DockerContainer::Dns, QObject::tr("DNS Service")}, {DockerContainer::Dns, QObject::tr("DNS Service")},
{DockerContainer::FileShare, QObject::tr("File Sharing Service")} {DockerContainer::FileShare, QObject::tr("SMB file sharing service - is Window file sharing protocol")},
{DockerContainer::Sftp, QObject::tr("Sftp file sharing service - is secure FTP service")}
}; };
} }

View file

@ -22,7 +22,8 @@ enum DockerContainer {
//non-vpn //non-vpn
TorWebSite, TorWebSite,
Dns, Dns,
FileShare FileShare,
Sftp
}; };
Q_ENUM_NS(DockerContainer) Q_ENUM_NS(DockerContainer)
} // namespace ContainerEnumNS } // namespace ContainerEnumNS
@ -43,6 +44,7 @@ public:
Q_INVOKABLE static QMap<DockerContainer, QString> containerHumanNames(); Q_INVOKABLE static QMap<DockerContainer, QString> containerHumanNames();
Q_INVOKABLE static QMap<DockerContainer, QString> containerDescriptions(); Q_INVOKABLE static QMap<DockerContainer, QString> containerDescriptions();
// these protocols will be displayed in container settings
Q_INVOKABLE static QVector<Protocol> protocolsForContainer(DockerContainer container); Q_INVOKABLE static QVector<Protocol> protocolsForContainer(DockerContainer container);
Q_INVOKABLE static ServiceType containerService(DockerContainer c); Q_INVOKABLE static ServiceType containerService(DockerContainer c);

View file

@ -12,6 +12,9 @@ QString amnezia::scriptFolder(amnezia::DockerContainer container)
case DockerContainer::ShadowSocks: return QLatin1String("openvpn_shadowsocks"); case DockerContainer::ShadowSocks: return QLatin1String("openvpn_shadowsocks");
case DockerContainer::WireGuard: return QLatin1String("wireguard"); case DockerContainer::WireGuard: return QLatin1String("wireguard");
case DockerContainer::TorWebSite: return QLatin1String("website_tor"); case DockerContainer::TorWebSite: return QLatin1String("website_tor");
case DockerContainer::Dns: return QLatin1String("dns");
case DockerContainer::FileShare: return QLatin1String("file_share");
case DockerContainer::Sftp: return QLatin1String("sftp");
default: return ""; default: return "";
} }
} }
@ -46,12 +49,12 @@ QString amnezia::scriptData(amnezia::SharedScriptType type)
QString fileName = QString(":/server_scripts/%1").arg(amnezia::scriptName(type)); QString fileName = QString(":/server_scripts/%1").arg(amnezia::scriptName(type));
QFile file(fileName); QFile file(fileName);
if (! file.open(QIODevice::ReadOnly)) { if (! file.open(QIODevice::ReadOnly)) {
qDebug() << "Error opening script" << fileName; qDebug() << "Warning: script missing" << fileName;
return ""; return "";
} }
QByteArray ba = file.readAll(); QByteArray ba = file.readAll();
if (ba.isEmpty()) { if (ba.isEmpty()) {
qDebug() << "Error, script is empty" << fileName; qDebug() << "Warning: script is empty" << fileName;
} }
return ba; return ba;
} }
@ -61,7 +64,7 @@ QString amnezia::scriptData(amnezia::ProtocolScriptType type, DockerContainer co
QString fileName = QString(":/server_scripts/%1/%2").arg(amnezia::scriptFolder(container), amnezia::scriptName(type)); QString fileName = QString(":/server_scripts/%1/%2").arg(amnezia::scriptFolder(container), amnezia::scriptName(type));
QFile file(fileName); QFile file(fileName);
if (! file.open(QIODevice::ReadOnly)) { if (! file.open(QIODevice::ReadOnly)) {
qDebug() << "Error opening script" << fileName; qDebug() << "Warning: script missing" << fileName;
return ""; return "";
} }
QByteArray data = file.readAll(); QByteArray data = file.readAll();

View file

@ -413,6 +413,29 @@ ErrorCode ServerController::updateContainer(const ServerCredentials &credentials
} }
} }
QJsonObject ServerController::createContainerInitialConfig(DockerContainer container, int port, TransportProto tp)
{
Protocol mainProto = ContainerProps::defaultProtocol(container);
QJsonObject config {
{ config_key::container, ContainerProps::containerToString(container) }
};
QJsonObject protoConfig;
protoConfig.insert(config_key::port, QString::number(port));
protoConfig.insert(config_key::transport_proto, ProtocolProps::transportProtoToString(tp, mainProto));
if (container == DockerContainer::Sftp) {
protoConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
protoConfig.insert(config_key::password, Utils::getRandomString(10));
}
config.insert(ProtocolProps::protoToString(mainProto), protoConfig);
return config;
}
bool ServerController::isReinstallContainerRequred(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig) bool ServerController::isReinstallContainerRequred(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig)
{ {
const QJsonObject &oldProtoConfig = oldConfig[ContainerProps::containerToString(container)].toObject(); const QJsonObject &oldProtoConfig = oldConfig[ContainerProps::containerToString(container)].toObject();
@ -512,6 +535,7 @@ ErrorCode ServerController::runContainerWorker(const ServerCredentials &credenti
if (stdOut.contains("address already in use")) return ErrorCode::ServerPortAlreadyAllocatedError; if (stdOut.contains("address already in use")) return ErrorCode::ServerPortAlreadyAllocatedError;
if (stdOut.contains("is already in use by container")) return ErrorCode::ServerPortAlreadyAllocatedError; if (stdOut.contains("is already in use by container")) return ErrorCode::ServerPortAlreadyAllocatedError;
if (stdOut.contains("invalid publish")) return ErrorCode::ServerDockerFailedError;
return e; return e;
} }
@ -525,9 +549,14 @@ ErrorCode ServerController::configureContainerWorker(const ServerCredentials &cr
ErrorCode ServerController::startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config) ErrorCode ServerController::startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
{ {
QString script = amnezia::scriptData(ProtocolScriptType::container_startup, container);
if (script.isEmpty()) {
return ErrorCode::NoError;
}
ErrorCode e = uploadTextFileToContainer(container, credentials, ErrorCode e = uploadTextFileToContainer(container, credentials,
replaceVars(amnezia::scriptData(ProtocolScriptType::container_startup, container), replaceVars(script, genVarsForScript(credentials, container, config)),
genVarsForScript(credentials, container, config)),
"/opt/amnezia/start.sh"); "/opt/amnezia/start.sh");
if (e) return e; if (e) return e;
@ -542,6 +571,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Protocol::Cloak)).toObject(); const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Protocol::Cloak)).toObject();
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Protocol::ShadowSocks)).toObject(); const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Protocol::ShadowSocks)).toObject();
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Protocol::WireGuard)).toObject(); const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Protocol::WireGuard)).toObject();
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Protocol::Sftp)).toObject();
// //
Vars vars; Vars vars;
@ -588,6 +618,9 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }}); vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }});
// Sftp vars
vars.append({{"$SFTP_PORT", sftpConfig.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Protocol::Sftp))) }});
QString serverIp = Utils::getIPAddress(credentials.hostName); QString serverIp = Utils::getIPAddress(credentials.hostName);
if (!serverIp.isEmpty()) { if (!serverIp.isEmpty()) {

View file

@ -32,6 +32,9 @@ public:
static ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container, static ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &oldConfig, const QJsonObject &newConfig = QJsonObject()); const QJsonObject &oldConfig, const QJsonObject &newConfig = QJsonObject());
// create initial config - generate passwords, etc
static QJsonObject createContainerInitialConfig(DockerContainer container, int port, TransportProto tp);
static bool isReinstallContainerRequred(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig); static bool isReinstallContainerRequred(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig);
static ErrorCode checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials); static ErrorCode checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials);

View file

@ -70,7 +70,8 @@ QMap<amnezia::Protocol, QString> ProtocolProps::protocolHumanNames()
{Protocol::WireGuard, "WireGuard"}, {Protocol::WireGuard, "WireGuard"},
{Protocol::TorWebSite, "Web site in TOR network"}, {Protocol::TorWebSite, "Web site in TOR network"},
{Protocol::Dns, "DNS Service"}, {Protocol::Dns, "DNS Service"},
{Protocol::FileShare, "File Sharing Service"} {Protocol::FileShare, "File Sharing Service"},
{Protocol::Sftp, QObject::tr("Sftp service")}
}; };
} }
@ -105,6 +106,7 @@ int ProtocolProps::defaultPort(Protocol p)
case Protocol::TorWebSite : return 443; case Protocol::TorWebSite : return 443;
case Protocol::Dns : return 53; case Protocol::Dns : return 53;
case Protocol::FileShare : return 139; case Protocol::FileShare : return 139;
case Protocol::Sftp : return 222;
default: return -1; default: return -1;
} }
} }
@ -132,9 +134,11 @@ TransportProto ProtocolProps::defaultTransportProto(Protocol p)
case Protocol::Cloak : return TransportProto::Tcp; case Protocol::Cloak : return TransportProto::Tcp;
case Protocol::ShadowSocks : return TransportProto::Tcp; case Protocol::ShadowSocks : return TransportProto::Tcp;
case Protocol::WireGuard : return TransportProto::Udp; case Protocol::WireGuard : return TransportProto::Udp;
// non-vpn
case Protocol::TorWebSite : return TransportProto::Tcp; case Protocol::TorWebSite : return TransportProto::Tcp;
case Protocol::Dns : return TransportProto::Udp; case Protocol::Dns : return TransportProto::Udp;
case Protocol::FileShare : return TransportProto::Tcp; case Protocol::FileShare : return TransportProto::Udp;
case Protocol::Sftp : return TransportProto::Tcp;
default: return TransportProto::Udp; default: return TransportProto::Udp;
} }
} }
@ -147,9 +151,11 @@ bool ProtocolProps::defaultTransportProtoChangeable(Protocol p)
case Protocol::Cloak : return false; case Protocol::Cloak : return false;
case Protocol::ShadowSocks : return false; case Protocol::ShadowSocks : return false;
case Protocol::WireGuard : return false; case Protocol::WireGuard : return false;
// non-vpn
case Protocol::TorWebSite : return false; case Protocol::TorWebSite : return false;
case Protocol::Dns : return false; case Protocol::Dns : return false;
case Protocol::FileShare : return false; case Protocol::FileShare : return false;
default: return -1; case Protocol::Sftp : return false;
default: return false;
} }
} }

View file

@ -100,6 +100,10 @@ constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
} }
namespace sftp {
constexpr char defaultUserName[] = "sftp_user";
} // namespace sftp
} // namespace protocols } // namespace protocols
@ -118,9 +122,12 @@ enum Protocol {
ShadowSocks, ShadowSocks,
Cloak, Cloak,
WireGuard, WireGuard,
// non-vpn
TorWebSite, TorWebSite,
Dns, Dns,
FileShare FileShare,
Sftp
}; };
Q_ENUM_NS(Protocol) Q_ENUM_NS(Protocol)
@ -177,6 +184,14 @@ static void declareQmlProtocolEnum() {
"TransportProto", "TransportProto",
"Error: only enums" "Error: only enums"
); );
qmlRegisterUncreatableMetaObject(
ProtocolEnumNS::staticMetaObject,
"ProtocolEnum",
1, 0,
"ServiceType",
"Error: only enums"
);
} }
} // namespace amnezia } // namespace amnezia

View file

@ -114,5 +114,12 @@
<file>images/delete.png</file> <file>images/delete.png</file>
<file>ui/qml/Controls/FadeBehavior.qml</file> <file>ui/qml/Controls/FadeBehavior.qml</file>
<file>ui/qml/Controls/VisibleBehavior.qml</file> <file>ui/qml/Controls/VisibleBehavior.qml</file>
<file>server_scripts/dns/configure_container.sh</file>
<file>server_scripts/dns/Dockerfile</file>
<file>server_scripts/dns/run_container.sh</file>
<file>server_scripts/sftp/configure_container.sh</file>
<file>server_scripts/sftp/Dockerfile</file>
<file>server_scripts/sftp/run_container.sh</file>
<file>ui/qml/Pages/Protocols/PageProtoSftp.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -0,0 +1,3 @@
FROM mvance/unbound:latest
LABEL maintainer="AmneziaVPN"

View file

@ -0,0 +1,2 @@
# Run container
sudo docker run -d --restart always --cap-add=NET_ADMIN -p 53:53/udp -p 53:53/tcp --name $CONTAINER_NAME $CONTAINER_NAME

View file

@ -0,0 +1,3 @@
FROM atmoz/sftp
LABEL maintainer="AmneziaVPN"

View file

@ -0,0 +1 @@
sudo docker run -d --restart always -p $SFTP_PORT:22/tcp --name $CONTAINER_NAME $CONTAINER_NAME $SFTP_USER:$SFTP_PASSWORD:::upload

View file

@ -1,13 +0,0 @@
# Wireguard config
sudo docker exec -i $CONTAINER_NAME bash -c '\
mkdir -p /opt/amnezia/wireguard; \
cd /opt/amnezia/wireguard || exit 1; \
WIREGUARD_SERVER_PRIVATE_KEY=$(wg genkey) && echo $WIREGUARD_SERVER_PRIVATE_KEY > /opt/amnezia/wireguard/wireguard_server_private_key.key; \
WIREGUARD_SERVER_PUBLIC_KEY=$(echo $WIREGUARD_SERVER_PRIVATE_KEY | wg pubkey) && echo $WIREGUARD_SERVER_PUBLIC_KEY > /opt/amnezia/wireguard/wireguard_server_public_key.key; \
WIREGUARD_PSK=$(wg genpsk) && echo $WIREGUARD_PSK > /opt/amnezia/wireguard/wireguard_psk.key; \
echo -e "\
[Interface]\\n\
PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY \\n\
Address = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR \\n\
ListenPort = $WIREGUARD_SERVER_PORT \\n\
" >/opt/amnezia/wireguard/wg0.conf'

View file

@ -16,7 +16,7 @@ AppSettingsLogic::AppSettingsLogic(UiLogic *logic, QObject *parent):
} }
void AppSettingsLogic::updatePage() void AppSettingsLogic::onUpdatePage()
{ {
set_checkBoxAutostartChecked(Autostart::isAutostart()); set_checkBoxAutostartChecked(Autostart::isAutostart());
set_checkBoxAutoConnectChecked(m_settings.isAutoConnect()); set_checkBoxAutoConnectChecked(m_settings.isAutoConnect());

View file

@ -14,7 +14,7 @@ class AppSettingsLogic : public PageLogicBase
AUTO_PROPERTY(QString, labelVersionText) AUTO_PROPERTY(QString, labelVersionText)
public: public:
Q_INVOKABLE void updatePage() override; Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onCheckBoxAutostartToggled(bool checked); Q_INVOKABLE void onCheckBoxAutostartToggled(bool checked);
Q_INVOKABLE void onCheckBoxAutoconnectToggled(bool checked); Q_INVOKABLE void onCheckBoxAutoconnectToggled(bool checked);

View file

@ -9,7 +9,7 @@ GeneralSettingsLogic::GeneralSettingsLogic(UiLogic *logic, QObject *parent):
} }
void GeneralSettingsLogic::updatePage() void GeneralSettingsLogic::onUpdatePage()
{ {
set_pushButtonGeneralSettingsShareConnectionEnable(m_settings.haveAuthData(m_settings.defaultServerIndex())); set_pushButtonGeneralSettingsShareConnectionEnable(m_settings.haveAuthData(m_settings.defaultServerIndex()));
} }

View file

@ -12,7 +12,7 @@ class GeneralSettingsLogic : public PageLogicBase
AUTO_PROPERTY(bool, pushButtonGeneralSettingsShareConnectionEnable) AUTO_PROPERTY(bool, pushButtonGeneralSettingsShareConnectionEnable)
public: public:
Q_INVOKABLE void updatePage() override; Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonGeneralSettingsServerSettingsClicked(); Q_INVOKABLE void onPushButtonGeneralSettingsServerSettingsClicked();
Q_INVOKABLE void onPushButtonGeneralSettingsShareConnectionClicked(); Q_INVOKABLE void onPushButtonGeneralSettingsShareConnectionClicked();

View file

@ -10,7 +10,7 @@ NetworkSettingsLogic::NetworkSettingsLogic(UiLogic *logic, QObject *parent):
} }
void NetworkSettingsLogic::updatePage() void NetworkSettingsLogic::onUpdatePage()
{ {
set_lineEditDns1Text(m_settings.primaryDns()); set_lineEditDns1Text(m_settings.primaryDns());
set_lineEditDns2Text(m_settings.secondaryDns()); set_lineEditDns2Text(m_settings.secondaryDns());
@ -35,13 +35,13 @@ void NetworkSettingsLogic::onLineEditDns2EditFinished(const QString &text)
void NetworkSettingsLogic::onPushButtonResetDns1Clicked() void NetworkSettingsLogic::onPushButtonResetDns1Clicked()
{ {
m_settings.setPrimaryDns(m_settings.cloudFlareNs1); m_settings.setPrimaryDns(m_settings.cloudFlareNs1);
updatePage(); onUpdatePage();
} }
void NetworkSettingsLogic::onPushButtonResetDns2Clicked() void NetworkSettingsLogic::onPushButtonResetDns2Clicked()
{ {
m_settings.setSecondaryDns(m_settings.cloudFlareNs2); m_settings.setSecondaryDns(m_settings.cloudFlareNs2);
updatePage(); onUpdatePage();
} }
QString NetworkSettingsLogic::getIpAddressValidatorRegex() const QString NetworkSettingsLogic::getIpAddressValidatorRegex() const

View file

@ -14,7 +14,7 @@ class NetworkSettingsLogic : public PageLogicBase
READONLY_PROPERTY(QString, ipAddressValidatorRegex) READONLY_PROPERTY(QString, ipAddressValidatorRegex)
public: public:
Q_INVOKABLE void updatePage() override; Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onLineEditDns1EditFinished(const QString& text); Q_INVOKABLE void onLineEditDns1EditFinished(const QString& text);
Q_INVOKABLE void onLineEditDns2EditFinished(const QString& text); Q_INVOKABLE void onLineEditDns2EditFinished(const QString& text);

View file

@ -9,7 +9,7 @@ NewServerProtocolsLogic::NewServerProtocolsLogic(UiLogic *logic, QObject *parent
} }
void NewServerProtocolsLogic::updatePage() void NewServerProtocolsLogic::onUpdatePage()
{ {
set_progressBarConnectionMinimum(0); set_progressBarConnectionMinimum(0);
set_progressBarConnectionMaximum(300); set_progressBarConnectionMaximum(300);

View file

@ -13,7 +13,7 @@ class NewServerProtocolsLogic : public PageLogicBase
AUTO_PROPERTY(double, progressBarConnectionMaximum) AUTO_PROPERTY(double, progressBarConnectionMaximum)
public: public:
Q_INVOKABLE void updatePage() override; Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonConfigureClicked(DockerContainer c, int port, TransportProto tp); Q_INVOKABLE void onPushButtonConfigureClicked(DockerContainer c, int port, TransportProto tp);
public: public:

View file

@ -19,7 +19,7 @@ public:
explicit PageLogicBase(UiLogic *uiLogic, QObject *parent = nullptr); explicit PageLogicBase(UiLogic *uiLogic, QObject *parent = nullptr);
~PageLogicBase() = default; ~PageLogicBase() = default;
Q_INVOKABLE virtual void updatePage() {} Q_INVOKABLE virtual void onUpdatePage() {}
protected: protected:
UiLogic *uiLogic() const { return m_uiLogic; } UiLogic *uiLogic() const { return m_uiLogic; }
@ -27,5 +27,7 @@ protected:
Settings m_settings; Settings m_settings;
UiLogic *m_uiLogic; UiLogic *m_uiLogic;
signals:
void updatePage();
}; };
#endif // PAGE_LOGIC_BASE_H #endif // PAGE_LOGIC_BASE_H

View file

@ -18,13 +18,15 @@ ServerContainersLogic::ServerContainersLogic(UiLogic *logic, QObject *parent):
{ {
} }
void ServerContainersLogic::updateServerContainersPage() void ServerContainersLogic::onUpdatePage()
{ {
ContainersModel *c_model = qobject_cast<ContainersModel *>(uiLogic()->containersModel()); ContainersModel *c_model = qobject_cast<ContainersModel *>(uiLogic()->containersModel());
c_model->setSelectedServerIndex(uiLogic()->selectedServerIndex); c_model->setSelectedServerIndex(uiLogic()->selectedServerIndex);
ProtocolsModel *p_model = qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel()); ProtocolsModel *p_model = qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel());
p_model->setSelectedServerIndex(uiLogic()->selectedServerIndex); p_model->setSelectedServerIndex(uiLogic()->selectedServerIndex);
emit updatePage();
} }
void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, Protocol p) void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, Protocol p)
@ -41,7 +43,7 @@ void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c,
void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c) void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c)
{ {
m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c); m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c);
updateServerContainersPage(); onUpdatePage();
} }
void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c) void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c)
@ -62,23 +64,12 @@ void ServerContainersLogic::onPushButtonRemoveClicked(DockerContainer container)
if (c.isEmpty()) m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None); if (c.isEmpty()) m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None);
else m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c.keys().first()); else m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c.keys().first());
} }
updateServerContainersPage(); onUpdatePage();
} }
void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int port, TransportProto tp) void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int port, TransportProto tp)
{ {
QMap<DockerContainer, QJsonObject> containers; QJsonObject config = ServerController::createContainerInitialConfig(c, port, tp);
Protocol mainProto = ContainerProps::defaultProtocol(c);
QJsonObject config {
{ config_key::container, ContainerProps::containerToString(c) },
{ ProtocolProps::protoToString(mainProto), QJsonObject {
{ config_key::port, QString::number(port) },
{ config_key::transport_proto, ProtocolProps::transportProtoToString(tp, mainProto) }}
}
};
containers.insert(c, config);
emit uiLogic()->goToPage(Page::ServerConfiguringProgress); emit uiLogic()->goToPage(Page::ServerConfiguringProgress);
qApp->processEvents(); qApp->processEvents();
@ -88,10 +79,12 @@ void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int p
}); });
if (!e) { if (!e) {
m_settings.setContainerConfig(uiLogic()->selectedServerIndex, c, QJsonObject()); m_settings.setContainerConfig(uiLogic()->selectedServerIndex, c, config);
if (ContainerProps::containerService(c) == ServiceType::Vpn) {
m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c); m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c);
} }
}
updateServerContainersPage(); onUpdatePage();
emit uiLogic()->closePage(); emit uiLogic()->closePage();
} }

View file

@ -10,7 +10,7 @@ class ServerContainersLogic : public PageLogicBase
Q_OBJECT Q_OBJECT
public: public:
Q_INVOKABLE void updateServerContainersPage(); Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonProtoSettingsClicked(DockerContainer c, Protocol p); Q_INVOKABLE void onPushButtonProtoSettingsClicked(DockerContainer c, Protocol p);
Q_INVOKABLE void onPushButtonDefaultClicked(DockerContainer c); Q_INVOKABLE void onPushButtonDefaultClicked(DockerContainer c);

View file

@ -14,7 +14,7 @@ ServerListLogic::ServerListLogic(UiLogic *logic, QObject *parent):
void ServerListLogic::onServerListPushbuttonDefaultClicked(int index) void ServerListLogic::onServerListPushbuttonDefaultClicked(int index)
{ {
m_settings.setDefaultServer(index); m_settings.setDefaultServer(index);
updatePage(); onUpdatePage();
} }
void ServerListLogic::onServerListPushbuttonSettingsClicked(int index) void ServerListLogic::onServerListPushbuttonSettingsClicked(int index)
@ -23,7 +23,7 @@ void ServerListLogic::onServerListPushbuttonSettingsClicked(int index)
uiLogic()->goToPage(Page::ServerSettings); uiLogic()->goToPage(Page::ServerSettings);
} }
void ServerListLogic::updatePage() void ServerListLogic::onUpdatePage()
{ {
const QJsonArray &servers = m_settings.serversArray(); const QJsonArray &servers = m_settings.serversArray();
int defaultServer = m_settings.defaultServerIndex(); int defaultServer = m_settings.defaultServerIndex();

View file

@ -12,7 +12,7 @@ class ServerListLogic : public PageLogicBase
READONLY_PROPERTY(QObject *, serverListModel) READONLY_PROPERTY(QObject *, serverListModel)
public: public:
Q_INVOKABLE void updatePage() override; Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onServerListPushbuttonDefaultClicked(int index); Q_INVOKABLE void onServerListPushbuttonDefaultClicked(int index);
Q_INVOKABLE void onServerListPushbuttonSettingsClicked(int index); Q_INVOKABLE void onServerListPushbuttonSettingsClicked(int index);

View file

@ -21,7 +21,7 @@ ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent):
} }
void ServerSettingsLogic::updatePage() void ServerSettingsLogic::onUpdatePage()
{ {
set_labelWaitInfoVisible(false); set_labelWaitInfoVisible(false);
set_labelWaitInfoText(""); set_labelWaitInfoText("");
@ -91,7 +91,7 @@ void ServerSettingsLogic::onPushButtonForgetServer()
uiLogic()->selectedServerIndex = -1; uiLogic()->selectedServerIndex = -1;
uiLogic()->serverListLogic()->updatePage(); uiLogic()->serverListLogic()->onUpdatePage();
if (m_settings.serversCount() == 0) { if (m_settings.serversCount() == 0) {
uiLogic()->setStartPage(Page::Start); uiLogic()->setStartPage(Page::Start);
@ -121,7 +121,7 @@ void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
QJsonObject server = m_settings.server(uiLogic()->selectedServerIndex); QJsonObject server = m_settings.server(uiLogic()->selectedServerIndex);
server.insert(config_key::description, newText); server.insert(config_key::description, newText);
m_settings.editServer(uiLogic()->selectedServerIndex, server); m_settings.editServer(uiLogic()->selectedServerIndex, server);
uiLogic()->serverListLogic()->updatePage(); uiLogic()->serverListLogic()->onUpdatePage();
} }
void ServerSettingsLogic::onPushButtonShareFullClicked() void ServerSettingsLogic::onPushButtonShareFullClicked()

View file

@ -21,7 +21,7 @@ class ServerSettingsLogic : public PageLogicBase
AUTO_PROPERTY(QString, labelCurrentVpnProtocolText) AUTO_PROPERTY(QString, labelCurrentVpnProtocolText)
public: public:
Q_INVOKABLE void updatePage() override; Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonClearServer(); Q_INVOKABLE void onPushButtonClearServer();
Q_INVOKABLE void onPushButtonForgetServer(); Q_INVOKABLE void onPushButtonForgetServer();

View file

@ -21,7 +21,7 @@ StartPageLogic::StartPageLogic(UiLogic *logic, QObject *parent):
} }
void StartPageLogic::updatePage() void StartPageLogic::onUpdatePage()
{ {
set_lineEditStartExistingCodeText(""); set_lineEditStartExistingCodeText("");
set_textEditSshKeyText(""); set_textEditSshKeyText("");

View file

@ -23,7 +23,7 @@ class StartPageLogic : public PageLogicBase
AUTO_PROPERTY(bool, pushButtonConnectVisible) AUTO_PROPERTY(bool, pushButtonConnectVisible)
public: public:
Q_INVOKABLE void updatePage() override; Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonConnect(); Q_INVOKABLE void onPushButtonConnect();
Q_INVOKABLE void onPushButtonImport(); Q_INVOKABLE void onPushButtonImport();

View file

@ -12,7 +12,7 @@ WizardLogic::WizardLogic(UiLogic *logic, QObject *parent):
} }
void WizardLogic::updatePage() void WizardLogic::onUpdatePage()
{ {
set_lineEditHighWebsiteMaskingText(protocols::cloak::defaultRedirSite); set_lineEditHighWebsiteMaskingText(protocols::cloak::defaultRedirSite);
} }

View file

@ -16,7 +16,7 @@ class WizardLogic : public PageLogicBase
AUTO_PROPERTY(QString, lineEditHighWebsiteMaskingText) AUTO_PROPERTY(QString, lineEditHighWebsiteMaskingText)
public: public:
Q_INVOKABLE void updatePage() override; Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonVpnModeFinishClicked(); Q_INVOKABLE void onPushButtonVpnModeFinishClicked();
Q_INVOKABLE void onPushButtonLowFinishClicked(); Q_INVOKABLE void onPushButtonLowFinishClicked();

View file

@ -0,0 +1,30 @@
#include "OtherProtocolsLogic.h"
#include "core/servercontroller.h"
#include <functional>
#include "../../uilogic.h"
using namespace amnezia;
using namespace PageEnumNS;
OtherProtocolsLogic::OtherProtocolsLogic(UiLogic *logic, QObject *parent):
PageProtocolLogicBase(logic, parent)
{
}
void OtherProtocolsLogic::updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData)
{
set_labelTftpUserNameText(config.value(config_key::userName).toString());
set_labelTftpPasswordText(config.value(config_key::password).toString(protocols::sftp::defaultUserName));
set_labelTftpPortText(config.value(config_key::port).toString(protocols::sftp::defaultUserName));
}
//QJsonObject OtherProtocolsLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
//{
//}
void OtherProtocolsLogic::onPushButtonProtoShadowSocksSaveClicked()
{
}

View file

@ -0,0 +1,31 @@
#ifndef OTHER_PROTOCOLS_LOGIC_H
#define OTHER_PROTOCOLS_LOGIC_H
#include "PageProtocolLogicBase.h"
class UiLogic;
class OtherProtocolsLogic : public PageProtocolLogicBase
{
Q_OBJECT
AUTO_PROPERTY(QString, labelTftpUserNameText)
AUTO_PROPERTY(QString, labelTftpPasswordText)
AUTO_PROPERTY(QString, labelTftpPortText)
public:
Q_INVOKABLE void onPushButtonProtoShadowSocksSaveClicked();
public:
explicit OtherProtocolsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~OtherProtocolsLogic() = default;
void updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData) override;
//QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
private:
Settings m_settings;
UiLogic *m_uiLogic;
};
#endif // OTHER_PROTOCOLS_LOGIC_H

View file

@ -1,5 +1,6 @@
import QtQuick 2.12 import QtQuick 2.12
import QtQuick.Controls 2.12 import QtQuick.Controls 2.12
import Qt.labs.platform 1.0
TextField { TextField {
id: root id: root
@ -8,6 +9,7 @@ TextField {
width: parent.width - 80 width: parent.width - 80
height: 40 height: 40
anchors.topMargin: 5 anchors.topMargin: 5
selectByMouse: true
selectionColor: "darkgray" selectionColor: "darkgray"
font.pixelSize: 16 font.pixelSize: 16
@ -35,4 +37,36 @@ TextField {
return "#A7A7A7" return "#A7A7A7"
} }
} }
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: contextMenu.open()
}
Menu {
id: contextMenu
onAboutToShow: console.log("aboutToShow")
onAboutToHide: console.log("aboutToHide")
MenuItem {
text: qsTr("C&ut")
shortcut: StandardKey.Cut
enabled: root.selectedText
onTriggered: root.cut()
}
MenuItem {
text: qsTr("&Copy")
shortcut: StandardKey.Copy
enabled: root.selectedText
onTriggered: root.copy()
}
MenuItem {
text: qsTr("&Paste")
shortcut: StandardKey.Paste
enabled: root.canPaste
onTriggered: root.paste()
}
}
} }

View file

@ -5,6 +5,7 @@ import SortFilterProxyModel 0.2
import ContainerProps 1.0 import ContainerProps 1.0
import ProtocolProps 1.0 import ProtocolProps 1.0
import PageEnum 1.0 import PageEnum 1.0
import ProtocolEnum 1.0
import "./" import "./"
import "../Controls" import "../Controls"
import "../Config" import "../Config"
@ -16,6 +17,18 @@ PageBase {
logic: ServerContainersLogic logic: ServerContainersLogic
enabled: ServerContainersLogic.pageEnabled enabled: ServerContainersLogic.pageEnabled
function resetPage() {
container_selector.selectedIndex = -1
}
Connections {
target: logic
function onUpdatePage() {
root.resetPage()
}
}
BackButton { BackButton {
id: back id: back
} }
@ -174,7 +187,7 @@ PageBase {
Caption { Caption {
id: cap1 id: cap1
text: qsTr("Installed VPN containers") text: qsTr("Installed Protocols and Services")
font.pixelSize: 20 font.pixelSize: 20
} }
@ -268,16 +281,13 @@ PageBase {
else tb_c.currentIndex = index else tb_c.currentIndex = index
UiLogic.protocolsModel.setSelectedDockerContainer(proxyContainersModel.mapToSource(index)) UiLogic.protocolsModel.setSelectedDockerContainer(proxyContainersModel.mapToSource(index))
//ServerContainersLogic.setSelectedDockerContainer(proxyContainersModel.mapToSource(index))
//container_selector.containerSelected(index)
//root.close()
} }
} }
} }
ImageButtonType { ImageButtonType {
id: button_default id: button_default
visible: service_type_role == ProtocolEnum.Vpn
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
checkable: true checkable: true

View file

@ -100,7 +100,7 @@ PageBase {
y: 210 y: 210
width: 300 width: 300
height: 40 height: 40
text: qsTr("Protocols and services") text: qsTr("Protocols and Services")
onClicked: { onClicked: {
UiLogic.goToPage(PageEnum.ServerContainers) UiLogic.goToPage(PageEnum.ServerContainers)
} }

View file

@ -1,5 +1,6 @@
import QtQuick 2.12 import QtQuick 2.12
import QtQuick.Controls 2.12 import QtQuick.Controls 2.12
import QtQuick.Layouts 1.15
import ProtocolEnum 1.0 import ProtocolEnum 1.0
import "../" import "../"
import "../../Controls" import "../../Controls"
@ -13,113 +14,52 @@ PageProtocolBase {
BackButton { BackButton {
id: back id: back
} }
Item { Caption {
x: 0 id: caption
y: 40 text: qsTr("OpenVPN Settings")
width: 380
height: 600
enabled: logic.pageEnabled
CheckBoxType {
x: 30
y: 280
width: 321
height: 21
text: qsTr("Auto-negotiate encryption")
checked: logic.checkBoxProtoOpenVpnAutoEncryptionChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnAutoEncryptionChecked = checked
}
onClicked: {
logic.checkBoxProtoOpenVpnAutoEncryptionClicked()
}
}
CheckBoxType {
x: 30
y: 430
width: 321
height: 21
text: qsTr("Block DNS requests outside of VPN")
checked: logic.checkBoxProtoOpenVpnBlockDnsChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnBlockDnsChecked = checked
}
}
CheckBoxType {
x: 30
y: 390
width: 321
height: 21
text: qsTr("Enable TLS auth")
checked: logic.checkBoxProtoOpenVpnTlsAuthChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnTlsAuthChecked = checked
} }
} Item {
ComboBoxType { enabled: logic.pageEnabled
anchors.top: caption.bottom
anchors.bottom: parent.bottom
width: parent.width
LabelType {
id: lb_subnet
x: 30 x: 30
y: 340 anchors.top: parent.top
width: 151 width: parent.width
height: 21
text: qsTr("VPN Addresses Subnet")
}
TextFieldType {
id: tf_subnet
x: 30
anchors.top: lb_subnet.bottom
width: parent.width - 60
height: 31 height: 31
model: [ text: logic.lineEditProtoOpenVpnSubnetText
qsTr("AES-256-GCM"), onEditingFinished: {
qsTr("AES-192-GCM"), logic.lineEditProtoOpenVpnSubnetText = text
qsTr("AES-128-GCM"),
qsTr("AES-256-CBC"),
qsTr("AES-192-CBC"),
qsTr("AES-128-CBC"),
qsTr("ChaCha20-Poly1305"),
qsTr("ARIA-256-CBC"),
qsTr("CAMELLIA-256-CBC"),
qsTr("none")
]
currentIndex: {
for (let i = 0; i < model.length; ++i) {
if (logic.comboBoxProtoOpenVpnCipherText === model[i]) {
return i
} }
} }
return -1
} //
onCurrentTextChanged: { LabelType {
logic.comboBoxProtoOpenVpnCipherText = currentText id: lb_proto
} x: 30
enabled: logic.comboBoxProtoOpenVpnCipherEnabled anchors.top: tf_subnet.bottom
} width: parent.width
ComboBoxType { height: 21
x: 200 text: qsTr("Network protocol")
y: 340
width: 151
height: 31
model: [
qsTr("SHA512"),
qsTr("SHA384"),
qsTr("SHA256"),
qsTr("SHA3-512"),
qsTr("SHA3-384"),
qsTr("SHA3-256"),
qsTr("whirlpool"),
qsTr("BLAKE2b512"),
qsTr("BLAKE2s256"),
qsTr("SHA1")
]
currentIndex: {
for (let i = 0; i < model.length; ++i) {
if (logic.comboBoxProtoOpenVpnHashText === model[i]) {
return i
}
}
return -1
}
onCurrentTextChanged: {
logic.comboBoxProtoOpenVpnHashText = currentText
}
enabled: logic.comboBoxProtoOpenVpnHashEnabled
} }
Rectangle { Rectangle {
id: rect_proto
x: 30 x: 30
y: 140 anchors.top: lb_proto.bottom
width: 321 width: parent.width - 60
height: 71 height: 71
border.width: 1 border.width: 1
border.color: "lightgray" border.color: "lightgray"
@ -149,68 +89,27 @@ PageProtocolBase {
enabled: logic.radioButtonProtoOpenVpnUdpEnabled enabled: logic.radioButtonProtoOpenVpnUdpEnabled
} }
} }
//
LabelType { LabelType {
id: lb_port
anchors.top: rect_proto.bottom
anchors.topMargin: 20
x: 30 x: 30
y: 110 width: root.width / 2 - 10
width: 151
height: 21
text: qsTr("Network protocol")
}
LabelType {
x: 30
y: 230
width: 151
height: 31 height: 31
text: qsTr("Port") text: qsTr("Port")
} }
Text {
font.family: "Lato"
font.styleName: "normal"
font.pixelSize: 24
color: "#100A44"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: qsTr("OpenVPN Settings")
x: 10
y: 0
width: 340
height: 30
}
LabelType {
x: 200
y: 310
width: 151
height: 21
text: qsTr("Hash")
}
LabelType {
x: 30
y: 40
width: 291
height: 21
text: qsTr("VPN Addresses Subnet")
}
LabelType {
x: 30
y: 310
width: 151
height: 21
text: qsTr("Cipher")
}
LabelType {
id: label_proto_openvpn_info
x: 30
y: 550
width: 321
height: 41
visible: logic.labelProtoOpenVpnInfoVisible
text: logic.labelProtoOpenVpnInfoText
}
TextFieldType { TextFieldType {
id: lineEdit_proto_openvpn_port id: tf_port
x: 200 anchors.top: rect_proto.bottom
y: 230 anchors.topMargin: 20
width: 151
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.rightMargin: 30
height: 31 height: 31
text: logic.lineEditProtoOpenVpnPortText text: logic.lineEditProtoOpenVpnPortText
onEditingFinished: { onEditingFinished: {
@ -218,19 +117,157 @@ PageProtocolBase {
} }
enabled: logic.lineEditProtoOpenVpnPortEnabled enabled: logic.lineEditProtoOpenVpnPortEnabled
} }
TextFieldType {
id: lineEdit_proto_openvpn_subnet //
CheckBoxType {
id: check_auto_enc
anchors.top: lb_port.bottom
anchors.topMargin: 20
x: 30 x: 30
y: 65 width: parent.width
width: 321 height: 21
text: qsTr("Auto-negotiate encryption")
checked: logic.checkBoxProtoOpenVpnAutoEncryptionChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnAutoEncryptionChecked = checked
}
onClicked: {
logic.checkBoxProtoOpenVpnAutoEncryptionClicked()
}
}
//
LabelType {
id: lb_cipher
x: 30
anchors.top: check_auto_enc.bottom
anchors.topMargin: 20
width: parent.width
height: 21
text: qsTr("Cipher")
}
ComboBoxType {
id: cb_cipher
x: 30
anchors.top: lb_cipher.bottom
width: parent.width - 60
height: 31 height: 31
text: logic.lineEditProtoOpenVpnSubnetText model: [
onEditingFinished: { qsTr("AES-256-GCM"),
logic.lineEditProtoOpenVpnSubnetText = text qsTr("AES-192-GCM"),
qsTr("AES-128-GCM"),
qsTr("AES-256-CBC"),
qsTr("AES-192-CBC"),
qsTr("AES-128-CBC"),
qsTr("ChaCha20-Poly1305"),
qsTr("ARIA-256-CBC"),
qsTr("CAMELLIA-256-CBC"),
qsTr("none")
]
currentIndex: {
for (let i = 0; i < model.length; ++i) {
if (logic.comboBoxProtoOpenVpnCipherText === model[i]) {
return i
} }
} }
return -1
}
onCurrentTextChanged: {
logic.comboBoxProtoOpenVpnCipherText = currentText
}
enabled: logic.comboBoxProtoOpenVpnCipherEnabled
}
//
LabelType {
id: lb_hash
anchors.top: cb_cipher.bottom
anchors.topMargin: 20
width: parent.width
height: 21
text: qsTr("Hash")
}
ComboBoxType {
id: cb_hash
x: 30
height: 31
anchors.top: lb_hash.bottom
width: parent.width - 60
model: [
qsTr("SHA512"),
qsTr("SHA384"),
qsTr("SHA256"),
qsTr("SHA3-512"),
qsTr("SHA3-384"),
qsTr("SHA3-256"),
qsTr("whirlpool"),
qsTr("BLAKE2b512"),
qsTr("BLAKE2s256"),
qsTr("SHA1")
]
currentIndex: {
for (let i = 0; i < model.length; ++i) {
if (logic.comboBoxProtoOpenVpnHashText === model[i]) {
return i
}
}
return -1
}
onCurrentTextChanged: {
logic.comboBoxProtoOpenVpnHashText = currentText
}
enabled: logic.comboBoxProtoOpenVpnHashEnabled
}
CheckBoxType {
id: check_tls
x: 30
anchors.top: cb_hash.bottom
anchors.topMargin: 20
width: parent.width
height: 21
text: qsTr("Enable TLS auth")
checked: logic.checkBoxProtoOpenVpnTlsAuthChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnTlsAuthChecked = checked
}
}
CheckBoxType {
id: check_block_dns
x: 30
anchors.top: check_tls.bottom
anchors.topMargin: 20
width: parent.width
height: 21
text: qsTr("Block DNS requests outside of VPN")
checked: logic.checkBoxProtoOpenVpnBlockDnsChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnBlockDnsChecked = checked
}
}
// LabelType {
// id: label_proto_openvpn_info
// x: 30
// y: 550
// width: 321
// height: 41
// visible: logic.labelProtoOpenVpnInfoVisible
// text: logic.labelProtoOpenVpnInfoText
// }
ProgressBar { ProgressBar {
id: progressBar_proto_openvpn_reset id: progress_save
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
y: 500 y: 500
width: 321 width: 321
@ -250,7 +287,7 @@ PageProtocolBase {
implicitWidth: parent.width implicitWidth: parent.width
implicitHeight: parent.height implicitHeight: parent.height
Rectangle { Rectangle {
width: progressBar_proto_openvpn_reset.visualPosition * parent.width width: progress_save.visualPosition * parent.width
height: parent.height height: parent.height
radius: 4 radius: 4
color: Qt.rgba(255, 255, 255, 0.15); color: Qt.rgba(255, 255, 255, 0.15);
@ -258,9 +295,12 @@ PageProtocolBase {
} }
} }
BlueButtonType { BlueButtonType {
id: pb_save
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
y: 500 anchors.bottom: parent.bottom
width: 321 anchors.bottomMargin: 20
x: 30
width: parent.width - 60
height: 40 height: 40
text: qsTr("Save and restart VPN") text: qsTr("Save and restart VPN")
visible: logic.pushButtonOpenvpnSaveVisible visible: logic.pushButtonOpenvpnSaveVisible

View file

@ -0,0 +1,79 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import ProtocolEnum 1.0
import "../"
import "../../Controls"
import "../../Config"
PageProtocolBase {
id: root
protocol: ProtocolEnum.Sftp
logic: UiLogic.protocolLogic(protocol)
BackButton {
id: back
}
Caption {
id: caption
text: qsTr("SFTF settings")
}
Rectangle {
id: frame_settings
width: parent.width
anchors.top: caption.bottom
anchors.topMargin: 10
border.width: 1
border.color: "lightgray"
anchors.bottomMargin: 5
anchors.horizontalCenter: parent.horizontalCenter
radius: 2
Grid {
id: grid
anchors.fill: parent
columns: 2
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
topPadding: 5
leftPadding: 10
spacing: 5
LabelType {
width: 130
text: qsTr("Port")
}
TextFieldType {
id: tf_port_num
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
text: logic.labelTftpPortText
readOnly: true
}
LabelType {
width: 130
text: qsTr("User Name")
}
TextFieldType {
id: tf_user_name
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
text: logic.labelTftpUserNameText
readOnly: true
}
LabelType {
width: 130
text: qsTr("Password")
}
TextFieldType {
id: tf_password
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
text: logic.labelTftpPasswordText
readOnly: true
}
}
}
}

View file

@ -31,7 +31,7 @@ Window {
function gotoPage(page, reset, slide) { function gotoPage(page, reset, slide) {
if (reset) { if (reset) {
if (page === PageEnum.ServerSettings) { if (page === PageEnum.ServerSettings) {
ServerSettingsLogic.updatePage(); ServerSettingsLogic.onUpdatePage();
} }
if (page === PageEnum.ShareConnection) { if (page === PageEnum.ShareConnection) {
} }
@ -39,32 +39,32 @@ Window {
WizardLogic.radioButtonMediumChecked = true WizardLogic.radioButtonMediumChecked = true
} }
if (page === PageEnum.WizardHigh) { if (page === PageEnum.WizardHigh) {
WizardLogic.updatePage(); WizardLogic.onUpdatePage();
} }
if (page === PageEnum.ServerConfiguringProgress) { if (page === PageEnum.ServerConfiguringProgress) {
ServerConfiguringProgressLogic.progressBarValue = 0; ServerConfiguringProgressLogic.progressBarValue = 0;
} }
if (page === PageEnum.GeneralSettings) { if (page === PageEnum.GeneralSettings) {
GeneralSettingsLogic.updatePage(); GeneralSettingsLogic.onUpdatePage();
} }
if (page === PageEnum.ServersList) { if (page === PageEnum.ServersList) {
ServerListLogic.updatePage(); ServerListLogic.onUpdatePage();
} }
if (page === PageEnum.Start) { if (page === PageEnum.Start) {
StartPageLogic.pushButtonBackFromStartVisible = !pageLoader.empty StartPageLogic.pushButtonBackFromStartVisible = !pageLoader.empty
StartPageLogic.updatePage(); StartPageLogic.onUpdatePage();
} }
if (page === PageEnum.NewServerProtocols) { if (page === PageEnum.NewServerProtocols) {
NewServerProtocolsLogic.updatePage() NewServerProtocolsLogic.onUpdatePage()
} }
if (page === PageEnum.ServerContainers) { if (page === PageEnum.ServerContainers) {
ServerContainersLogic.updateServerContainersPage() ServerContainersLogic.onUpdatePage()
} }
if (page === PageEnum.AppSettings) { if (page === PageEnum.AppSettings) {
AppSettingsLogic.updatePage() AppSettingsLogic.onUpdatePage()
} }
if (page === PageEnum.NetworkSettings) { if (page === PageEnum.NetworkSettings) {
NetworkSettingsLogic.updatePage() NetworkSettingsLogic.onUpdatePage()
} }
if (page === PageEnum.Sites) { if (page === PageEnum.Sites) {
SitesLogic.updateSitesPage() SitesLogic.updateSitesPage()
@ -84,8 +84,8 @@ Window {
} }
function gotoProtocolPage(protocol, reset, slide) { function gotoProtocolPage(protocol, reset, slide) {
if (reset) { if (reset && protocolPages[protocol] !== "undefined") {
protocolPages[protocol].logic.updatePage(); protocolPages[protocol].logic.onUpdatePage();
} }
if (slide) { if (slide) {
@ -113,7 +113,7 @@ Window {
} }
if (page === PageEnum.Start) { if (page === PageEnum.Start) {
UiLogic.pushButtonBackFromStartVisible = !pageLoader.empty UiLogic.pushButtonBackFromStartVisible = !pageLoader.empty
UiLogic.updatePage(); UiLogic.onUpdatePage();
} }
} }
@ -154,26 +154,31 @@ Window {
// initialItem: page_servers // initialItem: page_servers
onCurrentItemChanged: { onCurrentItemChanged: {
console.debug("QML onCurrentItemChanged " + pageLoader.currentItem)
UiLogic.currentPageValue = currentItem.page UiLogic.currentPageValue = currentItem.page
} }
Keys.onReleased: { // Keys.onReleased: {
if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) { // if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) {
console.debug("Back button captured") // console.debug("Back button captured")
if (UiLogic.currentPageValue !== PageEnum.VPN && // if (UiLogic.currentPageValue !== PageEnum.VPN &&
UiLogic.currentPageValue !== PageEnum.ServerConfiguring && // UiLogic.currentPageValue !== PageEnum.ServerConfiguring &&
!(UiLogic.currentPageValue === PageEnum.Start && pageLoader.depth < 2)) { // !(UiLogic.currentPageValue === PageEnum.Start && pageLoader.depth < 2)) {
close_page(); // close_page();
}
// TODO: fix
//if (ui->stackedWidget_main->currentWidget()->isEnabled()) {
// closePage();
// } // }
event.accepted = true
} // // TODO: fix
// //if (ui->stackedWidget_main->currentWidget()->isEnabled()) {
// // closePage();
// //}
// event.accepted = true
// }
// }
Keys.onPressed: {
UiLogic.keyPressEvent(event.key)
} }
} }
@ -220,13 +225,9 @@ Window {
obj.visible = false obj.visible = false
if (isProtocol) { if (isProtocol) {
protocolPages[obj.protocol] = obj protocolPages[obj.protocol] = obj
console.debug("PPP " + obj.protocol + " " + file)
} }
else { else {
pages[obj.page] = obj pages[obj.page] = obj
console.debug("AAA " + obj.page + " " + file)
} }
@ -246,30 +247,30 @@ Window {
Connections { Connections {
target: UiLogic target: UiLogic
onGoToPage: { function onGoToPage(page, reset, slide) {
console.debug("Connections onGoToPage " + page); console.debug("Connections onGoToPage " + page);
root.gotoPage(page, reset, slide) root.gotoPage(page, reset, slide)
} }
onGoToProtocolPage: { function onGoToProtocolPage(protocol, reset, slide) {
console.debug("Connections onGoToProtocolPage " + protocol); console.debug("Connections onGoToProtocolPage " + protocol);
root.gotoProtocolPage(protocol, reset, slide) root.gotoProtocolPage(protocol, reset, slide)
} }
onClosePage: { function onClosePage() {
root.close_page() root.close_page()
} }
onSetStartPage: { function onSetStartPage(page, slide) {
root.set_start_page(page, slide) root.set_start_page(page, slide)
} }
onShowPublicKeyWarning: { function onShowPublicKeyWarning() {
publicKeyWarning.visible = true publicKeyWarning.visible = true
} }
onShowConnectErrorDialog: { function onShowConnectErrorDialog() {
connectErrorDialog.visible = true connectErrorDialog.visible = true
} }
onShow: { function onShow() {
root.show() root.show()
} }
onHide: { function onHide() {
root.hide() root.hide()
} }
} }

View file

@ -61,6 +61,7 @@
#include "pages_logic/protocols/CloakLogic.h" #include "pages_logic/protocols/CloakLogic.h"
#include "pages_logic/protocols/OpenVpnLogic.h" #include "pages_logic/protocols/OpenVpnLogic.h"
#include "pages_logic/protocols/ShadowSocksLogic.h" #include "pages_logic/protocols/ShadowSocksLogic.h"
#include "pages_logic/protocols/OtherProtocolsLogic.h"
using namespace amnezia; using namespace amnezia;
@ -96,6 +97,10 @@ UiLogic::UiLogic(QObject *parent) :
m_protocolLogicMap.insert(Protocol::ShadowSocks, new ShadowSocksLogic(this)); m_protocolLogicMap.insert(Protocol::ShadowSocks, new ShadowSocksLogic(this));
m_protocolLogicMap.insert(Protocol::Cloak, new CloakLogic(this)); m_protocolLogicMap.insert(Protocol::Cloak, new CloakLogic(this));
//m_protocolLogicMap->insert(Protocol::WireGuard, new WireguardLogic(this)); //m_protocolLogicMap->insert(Protocol::WireGuard, new WireguardLogic(this));
m_protocolLogicMap.insert(Protocol::Dns, new OtherProtocolsLogic(this));
m_protocolLogicMap.insert(Protocol::Sftp, new OtherProtocolsLogic(this));
} }
void UiLogic::initalizeUiLogic() void UiLogic::initalizeUiLogic()
@ -131,8 +136,9 @@ void UiLogic::initalizeUiLogic()
} }
selectedServerIndex = m_settings.defaultServerIndex(); selectedServerIndex = m_settings.defaultServerIndex();
goToPage(Page::ServerContainers, true, false); //goToPage(Page::ServerContainers, true, false);
goToPage(Page::NewServerProtocols, true, false); //goToPage(Page::NewServerProtocols, true, false);
onGotoProtocolPage(Protocol::OpenVpn);
//ui->pushButton_general_settings_exit->hide(); //ui->pushButton_general_settings_exit->hide();
@ -284,52 +290,53 @@ void UiLogic::showOnStartup()
} }
//void UiLogic::keyPressEvent(QKeyEvent *event) void UiLogic::keyPressEvent(Qt::Key key)
//{ {
// switch (event->key()) { switch (key) {
// case Qt::Key_L: case Qt::Key_L:
// if (!Debug::openLogsFolder()) { if (!Debug::openLogsFolder()) {
//QMessageBox::warning(this, APPLICATION_NAME, tr("Cannot open logs folder!")); //QMessageBox::warning(this, APPLICATION_NAME, tr("Cannot open logs folder!"));
// } }
break;
#ifdef QT_DEBUG
case Qt::Key_Q:
qApp->quit();
break;
// case Qt::Key_0:
// *((char*)-1) = 'x';
// break; // break;
//#ifdef QT_DEBUG case Qt::Key_H:
// case Qt::Key_Q: selectedServerIndex = m_settings.defaultServerIndex();
// qApp->quit(); selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
// break;
// // case Qt::Key_0:
// // *((char*)-1) = 'x';
// // break;
// case Qt::Key_H:
// selectedServerIndex = m_settings.defaultServerIndex();
// selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
//updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer); //updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer);
// goToPage(Page::ShareConnection); emit goToPage(Page::ShareConnection);
// break; break;
//#endif #endif
// case Qt::Key_C: case Qt::Key_C:
// qDebug().noquote() << "Def server" << m_settings.defaultServerIndex() << m_settings.defaultContainerName(m_settings.defaultServerIndex()); qDebug().noquote() << "Def server" << m_settings.defaultServerIndex() << m_settings.defaultContainerName(m_settings.defaultServerIndex());
// //qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson(); //qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson();
// qDebug().noquote() << QJsonDocument(m_settings.defaultServer()).toJson(); qDebug().noquote() << QJsonDocument(m_settings.defaultServer()).toJson();
// break; break;
// case Qt::Key_A: case Qt::Key_A:
// goToPage(Page::Start); emit goToPage(Page::Start);
// break; break;
// case Qt::Key_S: case Qt::Key_S:
// selectedServerIndex = m_settings.defaultServerIndex(); selectedServerIndex = m_settings.defaultServerIndex();
// goToPage(Page::ServerSettings); emit goToPage(Page::ServerSettings);
// break; break;
// case Qt::Key_P: case Qt::Key_P:
// selectedServerIndex = m_settings.defaultServerIndex(); selectedServerIndex = m_settings.defaultServerIndex();
// selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex); selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
// goToPage(Page::ServerContainers); emit goToPage(Page::ServerContainers);
// break; break;
// case Qt::Key_T: case Qt::Key_T:
// SshConfigurator::openSshTerminal(m_settings.serverCredentials(m_settings.defaultServerIndex())); SshConfigurator::openSshTerminal(m_settings.serverCredentials(m_settings.defaultServerIndex()));
// break; break;
// case Qt::Key_Escape: case Qt::Key_Escape:
// if (currentPage() == Page::Vpn) break; case Qt::Key_Back:
// if (currentPage() == Page::ServerConfiguring) break; if (currentPage() == Page::Vpn) break;
if (currentPage() == Page::ServerConfiguringProgress) break;
// if (currentPage() == Page::Start && pagesStack.size() < 2) break; // if (currentPage() == Page::Start && pagesStack.size() < 2) break;
// if (currentPage() == Page::Sites && // if (currentPage() == Page::Sites &&
// ui->tableView_sites->selectionModel()->selection().indexes().size() > 0) { // ui->tableView_sites->selectionModel()->selection().indexes().size() > 0) {
@ -338,12 +345,12 @@ void UiLogic::showOnStartup()
// } // }
//if (! ui->stackedWidget_main->isAnimationRunning() && ui->stackedWidget_main->currentWidget()->isEnabled()) { //if (! ui->stackedWidget_main->isAnimationRunning() && ui->stackedWidget_main->currentWidget()->isEnabled()) {
// closePage(); emit closePage();
// }
// default:
// ;
// }
//} //}
default:
;
}
}
void UiLogic::onCloseWindow() void UiLogic::onCloseWindow()
{ {
@ -651,6 +658,15 @@ void UiLogic::setTrayIcon(const QString &iconPath)
setTrayIconUrl(iconPath); setTrayIconUrl(iconPath);
} }
PageProtocolLogicBase *UiLogic::protocolLogic(Protocol p) {
PageProtocolLogicBase *logic = m_protocolLogicMap.value(p);
if (logic) return logic;
else {
qDebug() << "UiLogic::protocolLogic Warning: logic missing for" << p;
return new PageProtocolLogicBase(this);
}
}
PageEnumNS::Page UiLogic::currentPage() PageEnumNS::Page UiLogic::currentPage()
{ {
return static_cast<PageEnumNS::Page>(getCurrentPageValue()); return static_cast<PageEnumNS::Page>(getCurrentPageValue());

View file

@ -4,6 +4,7 @@
#include <QRegExpValidator> #include <QRegExpValidator>
#include <QQmlEngine> #include <QQmlEngine>
#include <functional> #include <functional>
#include <QKeyEvent>
#include "property_helper.h" #include "property_helper.h"
#include "pages.h" #include "pages.h"
@ -86,6 +87,8 @@ public:
Q_INVOKABLE void onGotoPage(PageEnumNS::Page p, bool reset = true, bool slide = true) { emit goToPage(p, reset, slide); } Q_INVOKABLE void onGotoPage(PageEnumNS::Page p, bool reset = true, bool slide = true) { emit goToPage(p, reset, slide); }
Q_INVOKABLE void onGotoProtocolPage(Protocol p, bool reset = true, bool slide = true) { emit goToProtocolPage(p, reset, slide); } Q_INVOKABLE void onGotoProtocolPage(Protocol p, bool reset = true, bool slide = true) { emit goToProtocolPage(p, reset, slide); }
Q_INVOKABLE void keyPressEvent(Qt::Key key);
int getCurrentPageValue() const; int getCurrentPageValue() const;
void setCurrentPageValue(int currentPageValue); void setCurrentPageValue(int currentPageValue);
@ -181,7 +184,7 @@ public:
VpnLogic *vpnLogic() { return m_vpnLogic; } VpnLogic *vpnLogic() { return m_vpnLogic; }
WizardLogic *wizardLogic() { return m_wizardLogic; } WizardLogic *wizardLogic() { return m_wizardLogic; }
Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Protocol p) { return m_protocolLogicMap.value(p); } Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Protocol p);
private: private:
AppSettingsLogic *m_appSettingsLogic; AppSettingsLogic *m_appSettingsLogic;
@ -212,7 +215,6 @@ private:
// QPoint offset; // QPoint offset;
// bool needToHideCustomTitlebar = false; // bool needToHideCustomTitlebar = false;
// void keyPressEvent(QKeyEvent* event) override;
// void showEvent(QShowEvent *event) override; // void showEvent(QShowEvent *event) override;
// void hideEvent(QHideEvent *event) override; // void hideEvent(QHideEvent *event) override;