diff --git a/client/3rd/OpenVPNAdapter b/client/3rd/OpenVPNAdapter index 7b4046fa..0e2db0ba 160000 --- a/client/3rd/OpenVPNAdapter +++ b/client/3rd/OpenVPNAdapter @@ -1 +1 @@ -Subproject commit 7b4046faf358206d9640a8cc01cb4ab5fe2e4a6c +Subproject commit 0e2db0baa0d66029cbb18d74b78bc7a5c9013fba diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index fad1b67e..dde3d508 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -92,6 +92,7 @@ set(HEADERS ${HEADERS} ${CMAKE_CURRENT_LIST_DIR}/protocols/vpnprotocol.h ${CMAKE_CURRENT_BINARY_DIR}/version.h ${CMAKE_CURRENT_LIST_DIR}/core/sshclient.h + ${CMAKE_CURRENT_LIST_DIR}/protocols/ ) if(NOT IOS) diff --git a/client/containers/containers_defs.cpp b/client/containers/containers_defs.cpp index 17391988..e33585bb 100644 --- a/client/containers/containers_defs.cpp +++ b/client/containers/containers_defs.cpp @@ -61,6 +61,9 @@ QVector ContainerProps::protocolsForContainer(amnezia::DockerCon case DockerContainer::Sftp: return { Proto::Sftp}; + case DockerContainer::Nextcloud: + return { Proto::Nextcloud }; + default: return { defaultProtocol(container) }; } @@ -90,7 +93,8 @@ QMap ContainerProps::containerHumanNames() {DockerContainer::TorWebSite, QObject::tr("Web site in Tor network")}, {DockerContainer::Dns, QObject::tr("DNS Service")}, //{DockerContainer::FileShare, QObject::tr("SMB file sharing service")}, - {DockerContainer::Sftp, QObject::tr("Sftp file sharing service")} + {DockerContainer::Sftp, QObject::tr("Sftp file sharing service")}, + {DockerContainer::Nextcloud, QObject::tr("Nextcloud")} }; } @@ -107,7 +111,8 @@ QMap ContainerProps::containerDescriptions() {DockerContainer::TorWebSite, QObject::tr("Web site in Tor network")}, {DockerContainer::Dns, QObject::tr("DNS 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")} + {DockerContainer::Sftp, QObject::tr("Sftp file sharing service - is secure FTP service")}, + {DockerContainer::Nextcloud, QObject::tr("Nextcloud private cloud")}, }; } @@ -124,6 +129,7 @@ amnezia::ServiceType ContainerProps::containerService(DockerContainer c) case DockerContainer::Dns : return ServiceType::Other; //case DockerContainer::FileShare : return ServiceType::Other; case DockerContainer::Sftp : return ServiceType::Other; + case DockerContainer::Nextcloud : return ServiceType::Other; default: return ServiceType::Other; } } @@ -142,6 +148,7 @@ Proto ContainerProps::defaultProtocol(DockerContainer c) case DockerContainer::Dns : return Proto::Dns; //case DockerContainer::FileShare : return Protocol::FileShare; case DockerContainer::Sftp : return Proto::Sftp; + case DockerContainer::Nextcloud : return Proto::Nextcloud; default: return Proto::Any; } } diff --git a/client/containers/containers_defs.h b/client/containers/containers_defs.h index ff230c3e..50488d1d 100644 --- a/client/containers/containers_defs.h +++ b/client/containers/containers_defs.h @@ -24,7 +24,9 @@ enum DockerContainer { TorWebSite, Dns, //FileShare, - Sftp + Sftp, + Nextcloud + }; Q_ENUM_NS(DockerContainer) } // namespace ContainerEnumNS diff --git a/client/core/scripts_registry.cpp b/client/core/scripts_registry.cpp index 1b379ea1..6633eaf4 100644 --- a/client/core/scripts_registry.cpp +++ b/client/core/scripts_registry.cpp @@ -17,6 +17,7 @@ QString amnezia::scriptFolder(amnezia::DockerContainer container) case DockerContainer::Dns: return QLatin1String("dns"); //case DockerContainer::FileShare: return QLatin1String("file_share"); case DockerContainer::Sftp: return QLatin1String("sftp"); + case DockerContainer::Nextcloud: return QLatin1String("nextcloud"); default: return ""; } } diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index 7f4690dc..6b424286 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -491,6 +491,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Proto::ShadowSocks)).toObject(); const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject(); const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Proto::Sftp)).toObject(); + const QJsonObject &nextcloudConfig = config.value(ProtocolProps::protoToString(Proto::Nextcloud)).toObject(); // Vars vars; @@ -568,6 +569,11 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential vars.append({{"$SFTP_USER", sftpConfig.value(config_key::userName).toString() }}); vars.append({{"$SFTP_PASSWORD", sftpConfig.value(config_key::password).toString() }}); + // Nextcloud vars + QString port = nextcloudConfig.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Proto::Nextcloud))); + vars.append({{"$NEXTCLOUD_PORT", port }}); + vars.append({{"$NEXTCLOUD_ADMIN_USER", nextcloudConfig.value(config_key::adminUser).toString(protocols::nextcloud::defaultAdminUser) }}); + vars.append({{"$NEXTCLOUD_ADMIN_PASSWORD", nextcloudConfig.value(config_key::adminPassword).toString(protocols::nextcloud::defaultAdminPassword) }}); QString serverIp = Utils::getIPAddress(credentials.hostName); if (!serverIp.isEmpty()) { @@ -661,7 +667,7 @@ ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credential } ErrorCode errorCode = runScript(credentials, - replaceVars(script, genVarsForScript(credentials, container)), cbReadStdOut, cbReadStdErr); + replaceVars(script, genVarsForScript(credentials, container, containerConfig)), cbReadStdOut, cbReadStdErr); if (errorCode != ErrorCode::NoError) { return errorCode; } diff --git a/client/protocols/protocols_defs.cpp b/client/protocols/protocols_defs.cpp index 549c3774..7cd9e7b1 100644 --- a/client/protocols/protocols_defs.cpp +++ b/client/protocols/protocols_defs.cpp @@ -79,7 +79,8 @@ QMap ProtocolProps::protocolHumanNames() {Proto::TorWebSite, "Web site in Tor network"}, {Proto::Dns, "DNS Service"}, {Proto::FileShare, "File Sharing Service"}, - {Proto::Sftp, QObject::tr("Sftp service")} + {Proto::Sftp, QObject::tr("Sftp service")}, + {Proto::Nextcloud, QObject::tr("Nextcloud")} }; } @@ -96,10 +97,11 @@ amnezia::ServiceType ProtocolProps::protocolService(Proto p) case Proto::Cloak : return ServiceType::Vpn; case Proto::ShadowSocks : return ServiceType::Vpn; case Proto::WireGuard : return ServiceType::Vpn; - case Proto::TorWebSite : return ServiceType::Other; + case Proto::TorWebSite : return ServiceType::Other; case Proto::Dns : return ServiceType::Other; case Proto::FileShare : return ServiceType::Other; - default: return ServiceType::Other; + case Proto::Nextcloud : return ServiceType::Other; + default: return ServiceType::Other; } } @@ -118,6 +120,7 @@ int ProtocolProps::defaultPort(Proto p) case Proto::Dns : return 53; case Proto::FileShare : return 139; case Proto::Sftp : return 222; + case Proto::Nextcloud : return 8080; default: return -1; } } @@ -130,6 +133,7 @@ bool ProtocolProps::defaultPortChangeable(Proto p) case Proto::Cloak : return true; case Proto::ShadowSocks : return true; case Proto::WireGuard : return true; + case Proto::Nextcloud : return true; case Proto::Ikev2 : return false; case Proto::L2tp : return false; @@ -156,6 +160,8 @@ TransportProto ProtocolProps::defaultTransportProto(Proto p) case Proto::Dns : return TransportProto::Udp; case Proto::FileShare : return TransportProto::Udp; case Proto::Sftp : return TransportProto::Tcp; + case Proto::Nextcloud : return TransportProto::Tcp; + default: return defaultTransportProto(Proto::Any); } } @@ -174,7 +180,8 @@ bool ProtocolProps::defaultTransportProtoChangeable(Proto p) case Proto::Dns : return false; case Proto::FileShare : return false; case Proto::Sftp : return false; - default: return false; + case Proto::Nextcloud : return false; + default: return false; } } diff --git a/client/protocols/protocols_defs.h b/client/protocols/protocols_defs.h index 1f890f4c..f5be7db9 100644 --- a/client/protocols/protocols_defs.h +++ b/client/protocols/protocols_defs.h @@ -12,6 +12,9 @@ namespace config_key { constexpr char hostName[] = "hostName"; constexpr char userName[] = "userName"; constexpr char password[] = "password"; +constexpr char adminUser[] = "adminUser"; +constexpr char adminPassword[] = "adminPassword"; + constexpr char port[] = "port"; constexpr char local_port[] = "local_port"; @@ -125,6 +128,12 @@ constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key"; } +namespace nextcloud { +constexpr char defaultAdminUser[] = "admin"; +constexpr char defaultAdminPassword[] = "admin"; +} + + namespace sftp { constexpr char defaultUserName[] = "sftp_user"; @@ -154,7 +163,9 @@ enum Proto { TorWebSite, Dns, FileShare, - Sftp + // Fileshare + Sftp, + Nextcloud }; Q_ENUM_NS(Proto) diff --git a/client/resources.qrc b/client/resources.qrc index 91830679..697e35f9 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -34,6 +34,9 @@ server_scripts/openvpn_cloak/configure_container.sh server_scripts/openvpn_cloak/start.sh server_scripts/openvpn_cloak/template.ovpn + server_scripts/nextcloud/Dockerfile + server_scripts/nextcloud/configure_container.sh + server_scripts/nextcloud/run_container.sh server_scripts/install_docker.sh server_scripts/build_container.sh server_scripts/prepare_host.sh @@ -95,6 +98,7 @@ ui/qml/Pages/Protocols/PageProtoTorWebSite.qml ui/qml/Pages/Protocols/PageProtocolBase.qml ui/qml/Pages/Protocols/PageProtoWireGuard.qml + ui/qml/Pages/Protocols/PageProtoNextcloud.qml ui/qml/Pages/InstallSettings/InstallSettingsBase.qml ui/qml/Pages/InstallSettings/SelectContainer.qml ui/qml/Pages/Share/PageShareProtoCloak.qml diff --git a/client/server_scripts/install_docker.sh b/client/server_scripts/install_docker.sh index bb14e4cf..d2a32dfe 100644 --- a/client/server_scripts/install_docker.sh +++ b/client/server_scripts/install_docker.sh @@ -7,4 +7,6 @@ if [[ -z "$docker_service" ]]; then sudo $pm update -y -q; sudo $pm install -y - docker_service=$(systemctl list-units --full -all | grep docker.service | grep -v inactive | grep -v dead | grep -v failed);\ if [[ -z "$docker_service" ]]; then sleep 5 && sudo systemctl start docker && sleep 5; fi;\ if [[ -f "$pm_yum" ]]; then sudo systemctl enable docker && sudo systemctl start docker; fi;\ -docker --version +if [[ ! -f "/usr/bin/docker-compose" ]]; then sudo $pm update -y -q; sudo $pm install -y -q docker-compose; fi;\ +docker --version \ +docker-compose --version \ No newline at end of file diff --git a/client/server_scripts/nextcloud/Dockerfile b/client/server_scripts/nextcloud/Dockerfile new file mode 100644 index 00000000..12cf9763 --- /dev/null +++ b/client/server_scripts/nextcloud/Dockerfile @@ -0,0 +1,3 @@ +FROM nextcloud:latest as amnezia-nextcloud + +LABEL maintainer="AmneziaVPN" \ No newline at end of file diff --git a/client/server_scripts/nextcloud/configure_container.sh b/client/server_scripts/nextcloud/configure_container.sh new file mode 100644 index 00000000..e69de29b diff --git a/client/server_scripts/nextcloud/run_container.sh b/client/server_scripts/nextcloud/run_container.sh new file mode 100644 index 00000000..515cbba0 --- /dev/null +++ b/client/server_scripts/nextcloud/run_container.sh @@ -0,0 +1,4 @@ +# Run container +sudo docker run -d \ +-p $NEXTCLOUD_PORT:80 \ +--name $CONTAINER_NAME $CONTAINER_NAME \ No newline at end of file diff --git a/client/ui/pages_logic/ServerConfiguringProgressLogic.h b/client/ui/pages_logic/ServerConfiguringProgressLogic.h index 9f10bc87..b3fb8ad1 100644 --- a/client/ui/pages_logic/ServerConfiguringProgressLogic.h +++ b/client/ui/pages_logic/ServerConfiguringProgressLogic.h @@ -55,6 +55,7 @@ public: friend class ShadowSocksLogic; friend class CloakLogic; friend class UiLogic; + friend class NextcloudLogic; void onUpdatePage() override; ErrorCode doInstallAction(const std::function &action); diff --git a/client/ui/pages_logic/protocols/NextcloudLogic.cpp b/client/ui/pages_logic/protocols/NextcloudLogic.cpp new file mode 100644 index 00000000..652b4dbd --- /dev/null +++ b/client/ui/pages_logic/protocols/NextcloudLogic.cpp @@ -0,0 +1,58 @@ +#include "NextcloudLogic.h" + +#include + +#include "core/servercontroller.h" +#include "ui/pages_logic/ServerConfiguringProgressLogic.h" +#include "ui/uilogic.h" + +using namespace amnezia; +using namespace PageEnumNS; + +NextcloudLogic::NextcloudLogic(UiLogic *logic, QObject *parent): + PageProtocolLogicBase(logic, parent), + m_lineNextcloudPortText{}, + m_lineAdminUserText{}, + m_lineAdminPasswordText{}, + m_pushButtonSaveVisible{false}, + m_progressBarResetVisible{false}, + m_labelInfoVisible{true}, + m_labelInfoText{}, + m_progressBarResetValue{0}, + m_progressBarResetMaximium{100} + +{ + +} + +void NextcloudLogic::updateProtocolPage(const QJsonObject &nextcloudConfig, DockerContainer container, bool haveAuthData) +{ + set_pageEnabled(haveAuthData); + set_pushButtonSaveVisible(haveAuthData); + set_progressBarResetVisible(haveAuthData); + + set_lineAdminUserText(nextcloudConfig.value(config_key::adminUser).toString(protocols::nextcloud::defaultAdminUser)); + set_lineAdminPasswordText(nextcloudConfig.value(config_key::adminPassword).toString(protocols::nextcloud::defaultAdminPassword)); +} + +QJsonObject NextcloudLogic::getProtocolConfigFromPage(QJsonObject oldConfig) +{ + oldConfig.insert(config_key::adminUser, lineAdminUserText()); + oldConfig.insert(config_key::adminPassword, lineAdminPasswordText()); + return oldConfig; +} + +void NextcloudLogic::onPushButtonSaveClicked() +{ + QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, Proto::Nextcloud); + protocolConfig = getProtocolConfigFromPage(protocolConfig); + + QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer); + QJsonObject newContainerConfig = containerConfig; + newContainerConfig.insert(ProtocolProps::protoToString(Proto::Nextcloud), protocolConfig); +} + +void NextcloudLogic::onPushButtonCancelClicked() +{ + emit uiLogic()->pageLogic()->cancelDoInstallAction(true); +} diff --git a/client/ui/pages_logic/protocols/NextcloudLogic.h b/client/ui/pages_logic/protocols/NextcloudLogic.h new file mode 100644 index 00000000..36e7e2f4 --- /dev/null +++ b/client/ui/pages_logic/protocols/NextcloudLogic.h @@ -0,0 +1,47 @@ +#ifndef NEXTCLOUDLOGIC_H +#define NEXTCLOUDLOGIC_H + +#include "PageProtocolLogicBase.h" + +class UiLogic; + +class NextcloudLogic : public PageProtocolLogicBase +{ + Q_OBJECT + + AUTO_PROPERTY(QString, lineNextcloudPortText) + AUTO_PROPERTY(QString, lineAdminUserText) + AUTO_PROPERTY(QString, lineAdminPasswordText) + + AUTO_PROPERTY(bool, labelInfoVisible) + AUTO_PROPERTY(QString, labelInfoText) + + AUTO_PROPERTY(int, progressBarResetValue) + AUTO_PROPERTY(int, progressBarResetMaximium) + AUTO_PROPERTY(bool, progressBarResetVisible) + AUTO_PROPERTY(bool, progressBarTextVisible) + AUTO_PROPERTY(QString, progressBarText) + + AUTO_PROPERTY(bool, labelServerBusyVisible) + AUTO_PROPERTY(QString, labelServerBusyText) + + AUTO_PROPERTY(bool, pushButtonSaveVisible) + AUTO_PROPERTY(bool, pushButtonCancelVisible) + +public: + Q_INVOKABLE void onPushButtonSaveClicked(); + Q_INVOKABLE void onPushButtonCancelClicked(); + +public: + explicit NextcloudLogic(UiLogic *uiLogic, QObject *parent = nullptr); + ~NextcloudLogic() = default; + + void updateProtocolPage(const QJsonObject &nextcloudConfig, DockerContainer container, bool haveAuthData) override; + QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override; + +private: + UiLogic *m_uiLogic; + +}; + +#endif // NEXTCLOUDLOGIC_H diff --git a/client/ui/qml/Pages/Protocols/PageProtoNextcloud.qml b/client/ui/qml/Pages/Protocols/PageProtoNextcloud.qml new file mode 100644 index 00000000..221975f9 --- /dev/null +++ b/client/ui/qml/Pages/Protocols/PageProtoNextcloud.qml @@ -0,0 +1,80 @@ +import QtQuick +import QtQuick.Controls +import ProtocolEnum 1.0 +import "../" +import "../../Controls" +import "../../Config" + +PageProtocolBase { + id: root + protocol: ProtocolEnum.Nextcloud + logic: UiLogic.protocolLogic(protocol) + + BackButton { + id: back + } + + Caption { + id: caption + text: qsTr("Nextcloud 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: 30 + rightPadding: 30 + spacing: 5 + + LabelType { + width: 130 + text: qsTr("Port") + } + TextFieldType { + id: tf_port_num + width: parent.width - 130 - parent.spacing - parent.leftPadding * 2 + text: logic.lineNextcloudPortText + readOnly: true + } + + LabelType { + width: 130 + text: qsTr("Admin user") + } + TextFieldType { + id: tf_admin_user + width: parent.width - 130 - parent.spacing - parent.leftPadding * 2 + text: logic.lineAdminUserText + readOnly: true + } + + LabelType { + width: 130 + text: qsTr("Admin password") + } + TextFieldType { + id: tf_admin_password + width: parent.width - 130 - parent.spacing - parent.leftPadding * 2 + text: logic.lineAdminPasswordText + readOnly: true + } + + } + } + +} diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index ceb46930..dfc99c45 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -74,6 +74,7 @@ #include "pages_logic/protocols/ShadowSocksLogic.h" #include "pages_logic/protocols/OtherProtocolsLogic.h" #include "pages_logic/protocols/WireGuardLogic.h" +#include "pages_logic/protocols/NextcloudLogic.h" using namespace amnezia; using namespace PageEnumNS; @@ -100,6 +101,7 @@ UiLogic::UiLogic(std::shared_ptr settings, std::shared_ptr