diff --git a/guh.pri b/guh.pri index 20989324..5f2c633c 100644 --- a/guh.pri +++ b/guh.pri @@ -2,7 +2,7 @@ GUH_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"') DEFINES += GUH_VERSION_STRING=\\\"$${GUH_VERSION_STRING}\\\" -QMAKE_CXXFLAGS += -Werror +#QMAKE_CXXFLAGS += -Werror CONFIG += c++11 # Enable coverage option diff --git a/plugins/deviceplugins/mailnotification/devicepluginmailnotification.cpp b/plugins/deviceplugins/mailnotification/devicepluginmailnotification.cpp index 0d3ea479..c8c97e7e 100644 --- a/plugins/deviceplugins/mailnotification/devicepluginmailnotification.cpp +++ b/plugins/deviceplugins/mailnotification/devicepluginmailnotification.cpp @@ -237,26 +237,70 @@ ActionTypeId sendMailActionTypeId = ActionTypeId("054613b0-3666-4dad-9252-e0ebca DevicePluginMailNotification::DevicePluginMailNotification() { - m_smtpClient = new SmtpClient(); } DevicePluginMailNotification::~DevicePluginMailNotification() { - m_smtpClient->deleteLater(); } DeviceManager::DeviceSetupStatus DevicePluginMailNotification::setupDevice(Device *device) { - Q_UNUSED(device) // Google mail -// if(device->deviceClassId() == googleMailDeviceClassId){ -// m_smtpClient->setConnectionType(SmtpClient::SslConnection); -// m_smtpClient->setAuthMethod(SmtpClient::AuthLogin); -// m_smtpClient->setPort(465); -// m_smtpClient->setHost("smtp.gmail.com"); -// m_smtpClient->login(device->paramValue("user").toString(), device->paramValue("password").toString()); -// } - return DeviceManager::DeviceSetupStatusSuccess; + if(device->deviceClassId() == googleMailDeviceClassId){ + device->setName("Google Mail (" + device->paramValue("user").toString() + ")"); + SmtpClient *smtpClient = new SmtpClient("smtp.gmail.com", + 465, + device->paramValue("user").toString(), + device->paramValue("password").toString(), + SmtpClient::AuthLogin, + SmtpClient::EncryptionSSL, + this); + smtpClient->setSender(device->paramValue("user").toString()); + smtpClient->setRecipiant(device->paramValue("recipient").toString()); + + connect(smtpClient, &SmtpClient::sendMailFinished, this, &DevicePluginMailNotification::sendMailFinished); + + // TODO: test connection; + m_clients.insert(smtpClient,device); + return DeviceManager::DeviceSetupStatusSuccess; + //return DeviceManager::DeviceSetupStatusAsync; + } + // Custom mail + if(device->deviceClassId() == customMailDeviceClassId){ + device->setName("Custom Mail (" + device->paramValue("sender mail").toString() + ")"); + SmtpClient *smtpClient = new SmtpClient(this); + smtpClient->setHost(device->paramValue("SMTP server").toString()); + smtpClient->setPort(device->paramValue("port").toInt()); + smtpClient->setUser(device->paramValue("user").toString()); + smtpClient->setPassword(device->paramValue("password").toString()); + + if(device->paramValue("authentification").toString() == "PLAIN"){ + smtpClient->setAuthMethod(SmtpClient::AuthPlain); + } + if(device->paramValue("authentification").toString() == "LOGIN"){ + smtpClient->setAuthMethod(SmtpClient::AuthLogin); + } + + if(device->paramValue("encryption").toString() == "NONE"){ + smtpClient->setEncryptionType(SmtpClient::EncryptionNone); + } + if(device->paramValue("encryption").toString() == "SSL"){ + smtpClient->setEncryptionType(SmtpClient::EncryptionSSL); + } + if(device->paramValue("encryption").toString() == "TLS"){ + smtpClient->setEncryptionType(SmtpClient::EncryptionTLS); + } + smtpClient->setRecipiant(device->paramValue("recipient").toString()); + smtpClient->setSender(device->paramValue("sender mail").toString()); + + connect(smtpClient, &SmtpClient::sendMailFinished, this, &DevicePluginMailNotification::sendMailFinished); + + // TODO: test connection; + m_clients.insert(smtpClient,device); + return DeviceManager::DeviceSetupStatusSuccess; + //return DeviceManager::DeviceSetupStatusAsync; + } + return DeviceManager::DeviceSetupStatusFailure; } DeviceManager::HardwareResources DevicePluginMailNotification::requiredHardware() const @@ -266,34 +310,20 @@ DeviceManager::HardwareResources DevicePluginMailNotification::requiredHardware( DeviceManager::DeviceError DevicePluginMailNotification::executeAction(Device *device, const Action &action) { - qDebug() << "execute action " << sendMailActionTypeId.toString(); if(action.actionTypeId() == sendMailActionTypeId){ - // Google mail - if(device->deviceClassId() == googleMailDeviceClassId){ - m_smtpClient->setConnectionType(SmtpClient::SslConnection); - m_smtpClient->setAuthMethod(SmtpClient::AuthLogin); - m_smtpClient->setPort(465); - m_smtpClient->setHost("smtp.gmail.com"); - m_smtpClient->setUser(device->paramValue("user").toString()); - m_smtpClient->setPassword(device->paramValue("password").toString()); - m_smtpClient->setRecipiant(device->paramValue("recipiant").toString()); - } + SmtpClient *smtpClient= m_clients.key(device); + smtpClient->sendMail(action.param("subject").value().toString(), action.param("body").value().toString(), action.id()); - if(device->deviceClassId() == customMailDeviceClassId){ - m_smtpClient->setConnectionType(SmtpClient::SslConnection); - if(device->paramValue("auth").toString() == "PLAIN"){ - m_smtpClient->setAuthMethod(SmtpClient::AuthPlain); - }else if(device->paramValue("auth").toString() == "LOGIN"){ - m_smtpClient->setAuthMethod(SmtpClient::AuthLogin); - } - m_smtpClient->setPort(device->paramValue("port").toInt()); - m_smtpClient->setHost(device->paramValue("host").toString()); - m_smtpClient->setUser(device->paramValue("user").toString()); - m_smtpClient->setPassword(device->paramValue("password").toString()); - } - - m_smtpClient->sendMail(device->paramValue("user").toString(), device->paramValue("recipient").toString(), action.param("subject").value().toString(), action.param("body").value().toString()); + return DeviceManager::DeviceErrorAsync; + } + return DeviceManager::DeviceErrorActionTypeNotFound; +} + +void DevicePluginMailNotification::sendMailFinished(const bool &success, const ActionId &actionId) +{ + if(success){ + emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorNoError); + }else{ + emit actionExecutionFinished(actionId, DeviceManager::DeviceErrorDeviceNotFound); } - - return DeviceManager::DeviceErrorNoError; } diff --git a/plugins/deviceplugins/mailnotification/devicepluginmailnotification.h b/plugins/deviceplugins/mailnotification/devicepluginmailnotification.h index 2c2bef64..68dba6d0 100644 --- a/plugins/deviceplugins/mailnotification/devicepluginmailnotification.h +++ b/plugins/deviceplugins/mailnotification/devicepluginmailnotification.h @@ -38,11 +38,12 @@ public: DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; private: - SmtpClient *m_smtpClient; + QHash m_clients; private slots: public slots: + void sendMailFinished(const bool &success, const ActionId &actionId); }; diff --git a/plugins/deviceplugins/mailnotification/devicepluginmailnotification.json b/plugins/deviceplugins/mailnotification/devicepluginmailnotification.json index 31fb652c..f332e667 100644 --- a/plugins/deviceplugins/mailnotification/devicepluginmailnotification.json +++ b/plugins/deviceplugins/mailnotification/devicepluginmailnotification.json @@ -1,6 +1,6 @@ { "name": "Mail notification", - "id": "72aef158-07a3-4714-93b5-fec2f9d912d1", + "id": "1ae35df1-1b51-4c93-94fa-3febc77e0318", "vendors": [ { "name": "guh", @@ -8,10 +8,97 @@ "deviceClasses": [ { "deviceClassId": "3869884a-1592-4b8f-84a7-994be18ff555", - "name": "GMail", + "name": "Google Mail", "createMethods": ["user"], "paramTypes": [ - + { + "name": "user", + "type": "QString" + }, + { + "name": "password", + "type": "QString" + }, + { + "name": "recipient", + "type": "QString" + } + ], + "actionTypes": [ + { + "id": "054613b0-3666-4dad-9252-e0ebca187edc", + "name": "Send mail", + "paramTypes": [ + { + "name": "subject", + "type": "QString" + }, + { + "name": "body", + "type": "QString" + } + ] + } + ] + }, + { + "deviceClassId": "f4844c97-7ca6-4349-904e-ff9749a9fe74", + "name": "Custom Mail", + "createMethods": ["user"], + "paramTypes": [ + { + "name": "sender mail", + "type": "QString" + }, + { + "name": "user", + "type": "QString" + }, + { + "name": "password", + "type": "QString" + }, + { + "name": "recipient", + "type": "QString" + }, + { + "name": "SMTP server", + "type": "QString" + }, + { + "name": "port", + "type": "int", + "defaultValue": 25 + }, + { + "name": "authentification", + "type": "QString", + "defaultValue": "LOGIN", + "allowedValues": ["PLAIN", "LOGIN"] + }, + { + "name": "encryption", + "type": "QString", + "defaultValue": "SSL", + "allowedValues": ["NONE","SSL","TLS"] + } + ], + "actionTypes": [ + { + "id": "054613b0-3666-4dad-9252-e0ebca187edc", + "name": "Send mail", + "paramTypes": [ + { + "name": "subject", + "type": "QString" + }, + { + "name": "body", + "type": "QString" + } + ] + } ] } ] diff --git a/plugins/deviceplugins/mailnotification/smtpclient.cpp b/plugins/deviceplugins/mailnotification/smtpclient.cpp index 765ef465..f89de3ec 100644 --- a/plugins/deviceplugins/mailnotification/smtpclient.cpp +++ b/plugins/deviceplugins/mailnotification/smtpclient.cpp @@ -18,15 +18,11 @@ #include "smtpclient.h" -SmtpClient::SmtpClient() +SmtpClient::SmtpClient(QObject *parent): + QObject(parent) { - - m_socket = new QSslSocket(this); - m_host = "smtp.gmail.com"; - m_port = 465; - m_connectionType = SslConnection; - m_authMethod = AuthLogin; m_state = InitState; + m_socket = new QSslSocket(this); connect(m_socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(socketError(QAbstractSocket::SocketError))); connect(m_socket,SIGNAL(connected()),this,SLOT(connected())); @@ -35,16 +31,35 @@ SmtpClient::SmtpClient() } +SmtpClient::SmtpClient(QString host, int port, QString user, QString password, SmtpClient::AuthMethod authMethod, SmtpClient::EncryptionType encryptionType, QObject *parent): + m_host(host), + m_port(port), + m_user(user), + m_password(password), + m_authMethod(authMethod), + m_encryptionType(encryptionType), + QObject(parent) +{ + m_state = InitState; + m_socket = new QSslSocket(this); + + connect(m_socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(socketError(QAbstractSocket::SocketError))); + connect(m_socket,SIGNAL(connected()),this,SLOT(connected())); + connect(m_socket,SIGNAL(readyRead()),this,SLOT(readData())); + connect(m_socket,SIGNAL(disconnected()),this,SLOT(disconnected())); +} + + void SmtpClient::connectToHost() { - switch (m_connectionType) { - case TlsConnection: + switch (m_encryptionType) { + case EncryptionNone: + m_socket->connectToHost(m_host, m_port); + break; + case EncryptionSSL: m_socket->connectToHostEncrypted(m_host, m_port); break; - case SslConnection: - m_socket->connectToHostEncrypted(m_host, m_port); - break; - case TcpConnection: + case EncryptionTLS: m_socket->connectToHost(m_host,m_port); break; default: @@ -54,9 +69,8 @@ void SmtpClient::connectToHost() void SmtpClient::connected() { - qDebug() << "connected to" << m_host; - qDebug() << "-----------------------"; - +// qDebug() << "connected to" << m_host; +// qDebug() << "-----------------------"; } void SmtpClient::readData() @@ -70,21 +84,28 @@ void SmtpClient::readData() } responseLine.truncate( 3 ); - qDebug() << "---------------------------------------------"; - qDebug() << "Server code:" << responseLine; - qDebug() << "---------------------------------------------"; - qDebug() << "Server data: " << response; - qDebug() << "---------------------------------------------"; +// qDebug() << "---------------------------------------------"; +// qDebug() << "Server code:" << responseLine; +// qDebug() << "---------------------------------------------"; +// qDebug() << "Server data: " << response; +// qDebug() << "---------------------------------------------"; switch (m_state) { case InitState: if(responseLine == "220"){ qDebug() << "Init"; send("EHLO localhost"); - if(m_connectionType == TlsConnection || m_connectionType == SslConnection){ - m_state = HandShakeState; - }else{ + if(m_encryptionType == EncryptionNone){ m_state = AuthentificationState; + break; + } + if(m_encryptionType == EncryptionSSL){ + m_state = HandShakeState; + break; + } + if(m_encryptionType == EncryptionTLS){ + m_state = StartTlsState; + break; } } break; @@ -92,12 +113,21 @@ void SmtpClient::readData() if(responseLine == "250"){ qDebug() << "Handshake"; m_socket->startClientEncryption(); - if(!m_socket->waitForEncrypted(1000)){ - qDebug() << m_socket->errorString(); - } send("EHLO localhost"); m_state = AuthentificationState; } + if(responseLine == "220"){ + qDebug() << "TLS Handshake"; + m_socket->startClientEncryption(); + send("EHLO localhost"); + m_state = AuthentificationState; + } + break; + case StartTlsState: + if(responseLine == "250"){ + send("STARTTLS"); + m_state = HandShakeState; + } break; case AuthentificationState: if(responseLine == "250"){ @@ -128,7 +158,7 @@ void SmtpClient::readData() break; case MailState: if(responseLine == "235"){ - send("MAIL FROM:<" + m_from + ">"); + send("MAIL FROM:<" + m_sender + ">"); m_state = RcptState; } break; @@ -152,26 +182,31 @@ void SmtpClient::readData() break; case QuitState: if(responseLine == "250"){ - qDebug() << "--------------------------------------------"; - qDebug() << " MAIL SENT!!!!"; - qDebug() << "--------------------------------------------"; - send("QUIT"); + emit sendMailFinished(true, m_actionId); +// qDebug() << "--------------------------------------------"; +// qDebug() << " MAIL SENT!!!!"; +// qDebug() << "--------------------------------------------"; + logout(); m_state = CloseState; } break; case CloseState: + if(responseLine == "221"){ + m_socket->close(); + } m_socket->close(); break; default: - qDebug() << "ERROR: unexpected response from server: " << response; + //qDebug() << "ERROR: unexpected response from server: " << response; + emit sendMailFinished(false, m_actionId); break; } } void SmtpClient::disconnected() { - qDebug() << "disconnected from" << m_host; - qDebug() << "-----------------------"; +// qDebug() << "disconnected from" << m_host; +// qDebug() << "-----------------------"; } void SmtpClient::login(const QString &user, const QString &password) @@ -179,7 +214,7 @@ void SmtpClient::login(const QString &user, const QString &password) if(!m_socket->isOpen()){ connectToHost(); } - qDebug() << "Try to login with: " << user << password; + // qDebug() << "Try to login with: " << user << password; } void SmtpClient::logout() @@ -187,21 +222,21 @@ void SmtpClient::logout() send("QUIT"); } -bool SmtpClient::sendMail(const QString &from, const QString &to, const QString &subject, const QString &body) +bool SmtpClient::sendMail(const QString &subject, const QString &body, const ActionId &actionId) { - // mail - m_rcpt = to; + m_actionId = actionId; + + // create mail content m_state = InitState; - m_from = from; m_message.clear(); - m_message = "To: " + to + "\n"; - m_message.append("From: " + from + "\n"); + m_message = "To: " + m_rcpt + "\n"; + m_message.append("From: " + m_sender + "\n"); m_message.append("Subject: " + subject + "\n"); m_message.append(body); m_message.replace( QString::fromLatin1( "\n" ), QString::fromLatin1( "\r\n" ) ); m_message.replace( QString::fromLatin1( "\r\n.\r\n" ), QString::fromLatin1( "\r\n..\r\n" ) ); - + m_message.append("\r\n.\r\n"); m_socket->close(); connectToHost(); @@ -218,9 +253,9 @@ void SmtpClient::setPort(const int &port) m_port = port; } -void SmtpClient::setConnectionType(const SmtpClient::ConnectionType &connectionType) +void SmtpClient::setEncryptionType(const SmtpClient::EncryptionType &encryptionType) { - m_connectionType = connectionType; + m_encryptionType = encryptionType; } void SmtpClient::setAuthMethod(const SmtpClient::AuthMethod &authMethod) @@ -238,7 +273,12 @@ void SmtpClient::setPassword(const QString &password) m_password = password; } - void SmtpClient::setRecipiant(const QString &rcpt) +void SmtpClient::setSender(const QString &sender) +{ + m_sender = sender; +} + +void SmtpClient::setRecipiant(const QString &rcpt) { m_rcpt = rcpt; } @@ -250,7 +290,7 @@ void SmtpClient::socketError(QAbstractSocket::SocketError error) void SmtpClient::send(const QString &data) { - qDebug() << "sending to host:" << data; + //qDebug() << "sending to host:" << data; m_socket->write(data.toUtf8() + "\r\n"); m_socket->flush(); } diff --git a/plugins/deviceplugins/mailnotification/smtpclient.h b/plugins/deviceplugins/mailnotification/smtpclient.h index 9b1d7909..4c7c96d4 100644 --- a/plugins/deviceplugins/mailnotification/smtpclient.h +++ b/plugins/deviceplugins/mailnotification/smtpclient.h @@ -24,6 +24,8 @@ #include #include +#include "plugin/deviceplugin.h" + class SmtpClient : public QObject { Q_OBJECT @@ -38,6 +40,7 @@ public: InitState, HandShakeState, AuthentificationState, + StartTlsState, UserState, PasswordState, MailState, @@ -48,24 +51,27 @@ public: CloseState }; - enum ConnectionType{ - TcpConnection, // no encryption - SslConnection, // SSL - TlsConnection // STARTTLS + enum EncryptionType{ + EncryptionNone, // no encryption + EncryptionSSL, // SSL + EncryptionTLS // STARTTLS }; - explicit SmtpClient(); + explicit SmtpClient(QObject *parent = 0); + explicit SmtpClient(QString host = QString(), int port = 465, QString user = QString(), QString password = QString(), AuthMethod authMethod = AuthPlain, EncryptionType encryptionType = EncryptionNone, QObject *parent = 0); + void connectToHost(); void login(const QString &user, const QString &password); void logout(); - bool sendMail(const QString &from, const QString &to, const QString &subject, const QString &body); + bool sendMail(const QString &subject, const QString &body, const ActionId &actionId); void setHost(const QString &host); void setPort(const int &port); - void setConnectionType(const ConnectionType &connectionType); + void setEncryptionType(const EncryptionType &encryptionType); void setAuthMethod(const AuthMethod &authMethod); void setUser(const QString &user); void setPassword(const QString &password); + void setSender(const QString &sender); void setRecipiant(const QString &rcpt); @@ -74,17 +80,19 @@ private: QSslSocket *m_socket; QString m_host; int m_port; - ConnectionType m_connectionType; - AuthMethod m_authMethod; QString m_user; QString m_password; - QString m_from; + QString m_sender; + AuthMethod m_authMethod; + EncryptionType m_encryptionType; QString m_rcpt; QString m_subject; QString m_boy; QString m_message; + ActionId m_actionId; signals: + void sendMailFinished(const bool &success, const ActionId &actionId); private slots: void socketError(QAbstractSocket::SocketError error);