From cdb7ae4c729b6a6c51b57eeefd21574952a4b767 Mon Sep 17 00:00:00 2001 From: eportnov Date: Mon, 12 Sep 2022 16:46:44 +0300 Subject: refactoring --- CMakeLists.txt | 46 +++++---- src/main.cpp | 4 +- src/message/builder/cc.cpp | 31 ++++++ src/message/builder/cc.hpp | 21 ++++ src/message/builder/date.cpp | 16 ++++ src/message/builder/date.hpp | 17 ++++ src/message/builder/from.cpp | 22 +++++ src/message/builder/from.hpp | 19 ++++ src/message/builder/mail_to.cpp | 23 +++++ src/message/builder/mail_to.hpp | 21 ++++ src/message/builder/subject.cpp | 22 +++++ src/message/builder/subject.hpp | 19 ++++ src/message/builder/text.cpp | 24 +++++ src/message/builder/text.hpp | 19 ++++ src/message/builder/types/idecorator.hpp | 82 ++++++++++++++++ src/message/builder/types/imessage_builder.hpp | 14 +++ src/message/sender.cpp | 127 +++++++++++++++++++++++++ src/message/sender.hpp | 38 ++++++++ src/message_builder/cc.cpp | 31 ------ src/message_builder/cc.hpp | 21 ---- src/message_builder/date.cpp | 16 ---- src/message_builder/date.hpp | 17 ---- src/message_builder/from.cpp | 22 ----- src/message_builder/from.hpp | 19 ---- src/message_builder/mail_to.cpp | 23 ----- src/message_builder/mail_to.hpp | 21 ---- src/message_builder/subject.cpp | 21 ---- src/message_builder/subject.hpp | 19 ---- src/message_builder/text.cpp | 24 ----- src/message_builder/text.hpp | 19 ---- src/message_builder/types/idecorator.hpp | 82 ---------------- src/message_builder/types/imessage_build.hpp | 14 --- src/message_sender.cpp | 123 ------------------------ src/message_sender.hpp | 48 ---------- src/service/settings.cpp | 54 +++++++++++ src/service/settings.hpp | 36 +++++++ src/service/smtp.cpp | 99 +++++++++++++++++++ src/service/smtp.hpp | 35 +++++++ src/settings_storage.hpp | 14 --- src/smtp_service.cpp | 96 ------------------- src/smtp_service.hpp | 36 ------- 41 files changed, 767 insertions(+), 688 deletions(-) create mode 100644 src/message/builder/cc.cpp create mode 100644 src/message/builder/cc.hpp create mode 100644 src/message/builder/date.cpp create mode 100644 src/message/builder/date.hpp create mode 100644 src/message/builder/from.cpp create mode 100644 src/message/builder/from.hpp create mode 100644 src/message/builder/mail_to.cpp create mode 100644 src/message/builder/mail_to.hpp create mode 100644 src/message/builder/subject.cpp create mode 100644 src/message/builder/subject.hpp create mode 100644 src/message/builder/text.cpp create mode 100644 src/message/builder/text.hpp create mode 100644 src/message/builder/types/idecorator.hpp create mode 100644 src/message/builder/types/imessage_builder.hpp create mode 100644 src/message/sender.cpp create mode 100644 src/message/sender.hpp delete mode 100644 src/message_builder/cc.cpp delete mode 100644 src/message_builder/cc.hpp delete mode 100644 src/message_builder/date.cpp delete mode 100644 src/message_builder/date.hpp delete mode 100644 src/message_builder/from.cpp delete mode 100644 src/message_builder/from.hpp delete mode 100644 src/message_builder/mail_to.cpp delete mode 100644 src/message_builder/mail_to.hpp delete mode 100644 src/message_builder/subject.cpp delete mode 100644 src/message_builder/subject.hpp delete mode 100644 src/message_builder/text.cpp delete mode 100644 src/message_builder/text.hpp delete mode 100644 src/message_builder/types/idecorator.hpp delete mode 100644 src/message_builder/types/imessage_build.hpp delete mode 100644 src/message_sender.cpp delete mode 100644 src/message_sender.hpp create mode 100644 src/service/settings.cpp create mode 100644 src/service/settings.hpp create mode 100644 src/service/smtp.cpp create mode 100644 src/service/smtp.hpp delete mode 100644 src/settings_storage.hpp delete mode 100644 src/smtp_service.cpp delete mode 100644 src/smtp_service.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d93f95..7b4acc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,28 +76,34 @@ endif() include_directories(src) set(SRC_DIR src) +set(MESSAGE_DIR src/message) +set(SERVICE_DIR src/service) + set(SRC_FILES ${SRC_DIR}/main.cpp - ${SRC_DIR}/smtp_service.cpp - ${SRC_DIR}/smtp_service.hpp - ${SRC_DIR}/message_sender.hpp - ${SRC_DIR}/message_sender.cpp - ${SRC_DIR}/settings_storage.hpp - - ${SRC_DIR}/message_builder/date.hpp - ${SRC_DIR}/message_builder/date.cpp - ${SRC_DIR}/message_builder/mail_to.hpp - ${SRC_DIR}/message_builder/mail_to.cpp - ${SRC_DIR}/message_builder/cc.hpp - ${SRC_DIR}/message_builder/cc.cpp - ${SRC_DIR}/message_builder/subject.hpp - ${SRC_DIR}/message_builder/subject.cpp - ${SRC_DIR}/message_builder/text.hpp - ${SRC_DIR}/message_builder/text.cpp - ${SRC_DIR}/message_builder/from.hpp - ${SRC_DIR}/message_builder/from.cpp - - ${SRC_DIR}/message_builder/types/idecorator.hpp + + ${SERVICE_DIR}/smtp.cpp + ${SERVICE_DIR}/smtp.hpp + ${SERVICE_DIR}/settings.hpp + ${SERVICE_DIR}/settings.cpp + + ${MESSAGE_DIR}/sender.hpp + ${MESSAGE_DIR}/sender.cpp + + ${MESSAGE_DIR}/builder/date.hpp + ${MESSAGE_DIR}/builder/date.cpp + ${MESSAGE_DIR}/builder/mail_to.hpp + ${MESSAGE_DIR}/builder/mail_to.cpp + ${MESSAGE_DIR}/builder/cc.hpp + ${MESSAGE_DIR}/builder/cc.cpp + ${MESSAGE_DIR}/builder/subject.hpp + ${MESSAGE_DIR}/builder/subject.cpp + ${MESSAGE_DIR}/builder/text.hpp + ${MESSAGE_DIR}/builder/text.cpp + ${MESSAGE_DIR}/builder/from.hpp + ${MESSAGE_DIR}/builder/from.cpp + ${MESSAGE_DIR}/builder/types/imessage_builder.hpp + ${MESSAGE_DIR}/builder/types/idecorator.hpp ) add_executable(smtp ${SRC_FILES}) diff --git a/src/main.cpp b/src/main.cpp index ba2848d..96c06df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,13 +1,13 @@ #include -#include "smtp_service.hpp" +#include "service/smtp.hpp" int main() { boost::asio::io_service io_context; auto connection = std::make_shared( io_context ); - smtp::SmtpService smtp{ connection }; + smtp::service::Smtp smtp{ connection }; io_context.run(); return 0; diff --git a/src/message/builder/cc.cpp b/src/message/builder/cc.cpp new file mode 100644 index 0000000..55d70ff --- /dev/null +++ b/src/message/builder/cc.cpp @@ -0,0 +1,31 @@ +#include "cc.hpp" + +namespace smtp::message::builder +{ + Cc::Cc( std::list const& mail_to ) + : mMailTo( mail_to ) + { + + } + + std::string Cc::Get() const + { + std::string result; + if( mBase ) + { + result = mBase->Get(); + } + + if( mMailTo.empty() ) + { + return result; + } + + for(const auto& cc : mMailTo) + { + result += "Cc: " + cc + "\r\n"; + } + + return result; + } +} diff --git a/src/message/builder/cc.hpp b/src/message/builder/cc.hpp new file mode 100644 index 0000000..340c7cd --- /dev/null +++ b/src/message/builder/cc.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +#include "types/idecorator.hpp" +#include "types/imessage_builder.hpp" + +namespace smtp::message::builder +{ + class Cc : public types::IDecorator + { + public: + explicit Cc( std::list const& mail_to ); + ~Cc() override = default; + + std::string Get() const override; + private: + std::list const& mMailTo; + }; +} + diff --git a/src/message/builder/date.cpp b/src/message/builder/date.cpp new file mode 100644 index 0000000..3268935 --- /dev/null +++ b/src/message/builder/date.cpp @@ -0,0 +1,16 @@ +#include "date.hpp" + +namespace smtp::message::builder +{ + std::string Date::Get() const + { + std::string result; + + if( mBase ) + { + result = mBase->Get(); + } + result += "Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n"; + return result; + } +} diff --git a/src/message/builder/date.hpp b/src/message/builder/date.hpp new file mode 100644 index 0000000..31908ac --- /dev/null +++ b/src/message/builder/date.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "types/idecorator.hpp" +#include "types/imessage_builder.hpp" + +namespace smtp::message::builder +{ + class Date : public types::IDecorator + { + public: + Date() = default; + ~Date() override = default; + + std::string Get() const override; + }; +} + diff --git a/src/message/builder/from.cpp b/src/message/builder/from.cpp new file mode 100644 index 0000000..b19515a --- /dev/null +++ b/src/message/builder/from.cpp @@ -0,0 +1,22 @@ +#include "from.hpp" + +namespace smtp::message::builder +{ + + From::From( std::string const& mail_to ) + :mMailTo( mail_to ) + { + + } + + std::string From::Get() const + { + std::string result; + if( mBase ) + { + result = mBase->Get(); + } + result += "From: " + mMailTo + "\r\n"; + return result; + } +} diff --git a/src/message/builder/from.hpp b/src/message/builder/from.hpp new file mode 100644 index 0000000..d1f0b21 --- /dev/null +++ b/src/message/builder/from.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "types/idecorator.hpp" +#include "types/imessage_builder.hpp" + +namespace smtp::message::builder +{ + class From : public types::IDecorator + { + public: + explicit From( std::string const& mail_to ); + ~From() override = default; + + std::string Get() const override; + private: + std::string const& mMailTo; + }; +} + diff --git a/src/message/builder/mail_to.cpp b/src/message/builder/mail_to.cpp new file mode 100644 index 0000000..dab1b7f --- /dev/null +++ b/src/message/builder/mail_to.cpp @@ -0,0 +1,23 @@ +#include "mail_to.hpp" + +namespace smtp::message::builder +{ + MailTo::MailTo( std::string const& mail_to) + : mMailTo( mail_to ) + { + + } + + std::string MailTo::Get() const + { + std::string result; + if( mBase ) + { + result = mBase->Get(); + } + + result += "To: " + mMailTo +"\r\n"; + + return result; + } +} diff --git a/src/message/builder/mail_to.hpp b/src/message/builder/mail_to.hpp new file mode 100644 index 0000000..5d60d97 --- /dev/null +++ b/src/message/builder/mail_to.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +#include "types/idecorator.hpp" +#include "types/imessage_builder.hpp" + +namespace smtp::message::builder +{ + class MailTo : public types::IDecorator + { + public: + explicit MailTo( std::string const& mail_to ); + ~MailTo() override = default; + + std::string Get() const override; + private: + std::string const& mMailTo; + }; +} + diff --git a/src/message/builder/subject.cpp b/src/message/builder/subject.cpp new file mode 100644 index 0000000..166bca4 --- /dev/null +++ b/src/message/builder/subject.cpp @@ -0,0 +1,22 @@ +#include "subject.hpp" + +namespace smtp::message::builder +{ + Subject::Subject( std::string const& subject ) + : mSubject(subject) + { + + } + + std::string Subject::Get() const + { + std::string result; + if( mBase ) + { + result = mBase->Get(); + } + + result += "Subject: " + mSubject + "\r\n"; + return result; + } +} diff --git a/src/message/builder/subject.hpp b/src/message/builder/subject.hpp new file mode 100644 index 0000000..8153bc8 --- /dev/null +++ b/src/message/builder/subject.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "types/idecorator.hpp" +#include "types/imessage_builder.hpp" + +namespace smtp::message::builder +{ + class Subject : public types::IDecorator + { + public: + explicit Subject( std::string const& subject ); + ~Subject() override = default; + + std::string Get() const override; + private: + std::string const& mSubject; + }; +} + diff --git a/src/message/builder/text.cpp b/src/message/builder/text.cpp new file mode 100644 index 0000000..c478b7d --- /dev/null +++ b/src/message/builder/text.cpp @@ -0,0 +1,24 @@ +#include "text.hpp" + +namespace smtp::message::builder +{ + Text::Text( std::string const& text) + : mText( text ) + { + + } + + std::string Text::Get() const + { + std::string result; + if( mBase ) + { + result = mBase->Get(); + } + + result += "\r\n"; + result += mText + "\r\n"; + + return result; + } +} diff --git a/src/message/builder/text.hpp b/src/message/builder/text.hpp new file mode 100644 index 0000000..9715656 --- /dev/null +++ b/src/message/builder/text.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "types/idecorator.hpp" +#include "types/imessage_builder.hpp" + +namespace smtp::message::builder +{ + class Text : public types::IDecorator + { + public: + explicit Text( std::string const& text ); + ~Text() override = default; + + std::string Get() const override; + private: + std::string const& mText; + }; +} + diff --git a/src/message/builder/types/idecorator.hpp b/src/message/builder/types/idecorator.hpp new file mode 100644 index 0000000..19284ac --- /dev/null +++ b/src/message/builder/types/idecorator.hpp @@ -0,0 +1,82 @@ +#pragma once + +#include + +namespace smtp::message::builder::types +{ + +/** + * @brief Базовый интерфейс описания декоратора + * @details См. https://refactoring.guru/ru/design-patterns/decorator + * @tparam T Тип декорируемого класса, T должен обладать возможностью наследования (в том числе виртуальный деструктор) + */ + template < typename T, typename TPointerType = std::shared_ptr > class IDecorator : public T + { + public: + using PointerType = TPointerType; + using Type = IDecorator; + + ~IDecorator() override = default; + + /** + * @brief Установить указатель на декорируемый класс + * @details По возможности используйте метод Apply() как наиболее универсальный + * @param base Указатель на декорируемый класс + */ + void SetBase( PointerType const& base ) noexcept + { + mBase = base; + } + + void SetBase( PointerType&& base ) noexcept + { + mBase = std::move( base ); + } + + /** + * @brief Установить указатель на декорируемый класс (цепочка обязанностей) + * @details См. https://refactoring.guru/ru/design-patterns/chain-of-responsibility/cpp/example + * @details Цепь вызовов: декоратор1 -> декоратор2 -> базовый класс + * @param base_or_decorator Указатель на декорируемый класс или целевой декоратор + */ + Type& Apply( PointerType const& base_or_decorator ) noexcept + { + if( !base_or_decorator ) + { + return *this; + } + + SetBase( base_or_decorator ); + return GetApplyResult(); + } + + Type& Apply( PointerType&& base_or_decorator ) noexcept + { + if( !base_or_decorator ) + { + return *this; + } + + SetBase( std::move( base_or_decorator ) ); + return GetApplyResult(); + } + + private: + Type& GetApplyResult() noexcept + { + auto as_decorator = dynamic_cast< Type * >( mBase.get() ); + if( as_decorator ) + { + return *as_decorator; + } + + return *this; + } + + protected: + PointerType mBase; + }; + + template < typename T, typename TDeleter = std::default_delete > using IDecoratorUnique = IDecorator >; + +} // namespace sbis::devices::generic::types diff --git a/src/message/builder/types/imessage_builder.hpp b/src/message/builder/types/imessage_builder.hpp new file mode 100644 index 0000000..701f5f9 --- /dev/null +++ b/src/message/builder/types/imessage_builder.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include + +namespace smtp::message::builder::types +{ + class IMessageBuilder + { + public: + virtual ~IMessageBuilder() = default; + + virtual std::string Get() const = 0; + }; +} diff --git a/src/message/sender.cpp b/src/message/sender.cpp new file mode 100644 index 0000000..cabcb8f --- /dev/null +++ b/src/message/sender.cpp @@ -0,0 +1,127 @@ +#include + +#include "sender.hpp" +#include "builder/date.hpp" +#include "builder/mail_to.hpp" +#include "builder/cc.hpp" +#include "builder/subject.hpp" +#include "builder/text.hpp" +#include "builder/from.hpp" +#include + +namespace smtp::message +{ + static std::string mText = ""; + + // + // Constructors/Destructors + // + Sender::Sender( service::Settings const& settings_storage ) + : mSettingsStorage( settings_storage ) + { + + } + + // + //Public methods + // + + bool Sender::Send( std::string const& mail_from, std::string const& mail_to, std::list const& cc, + std::string const& subject, std::string const& text ) + { + CURLcode result = CURLE_OK; + curl_slist *recipients = NULL; + WriteThis upload_ctx{}; + auto curl = curl_easy_init(); + //TODO сделать инициализацию через регистратор инициализаторов + if( !InitCurl( curl, upload_ctx, mail_from ) ) + { + return false; + } + FillRecipients( curl, mail_to, cc, recipients ); + UpdateMailText( mail_from, mail_to, cc, subject, text); + + result = curl_easy_perform(curl); + + if ( result != CURLE_OK ) + { + //TODO LOG + fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror( result )); + return false; + } + //TODO сделать деинициализацию через регистратор деинициализаторов + curl_slist_free_all( recipients ); + curl_easy_cleanup( curl ); + return true; + } + + // + //Private methods + // + bool smtp::message::Sender::InitCurl( CURL* curl, WriteThis const& upload_ctx, std::string const& mail_from ) + { + if( !curl ) + { + //TODO LOG + return false; + } + curl_easy_setopt(curl, CURLOPT_USERNAME, mSettingsStorage.GetUserName().c_str()); + curl_easy_setopt(curl, CURLOPT_PASSWORD, mSettingsStorage.GetPassword().c_str()); + curl_easy_setopt(curl, CURLOPT_URL, GetHostPortData().c_str()); + + curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); + curl_easy_setopt(curl, CURLOPT_MAIL_FROM, mail_from.c_str()); + + curl_easy_setopt(curl, CURLOPT_READFUNCTION, ReadCallBack); + curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + return true; + } + + void Sender::UpdateMailText( std::string const& mail_from, std::string const& mail_to, std::list const& cc, + std::string const& subject, std::string const& text ) const + { + auto text_decorator = std::make_shared( text ); + text_decorator->Apply( std::make_shared( subject ) ) + .Apply( std::make_shared( cc ) ) + .Apply( std::make_shared( mail_from ) ) + .Apply( std::make_shared( mail_to ) ) + .Apply( std::make_shared() ); + mText = text_decorator->Get(); + std::cout << mText << std::endl; + } + + void Sender::FillRecipients( CURL* curl, std::string const& mail_to, std::list const& cc, curl_slist* recipients ) + { + recipients = curl_slist_append( recipients, mail_to.c_str() ); + + for( const auto& recipient : cc ) + { + recipients = curl_slist_append( recipients, recipient.c_str() ); + } + + curl_easy_setopt( curl, CURLOPT_MAIL_RCPT, recipients ); + } + + std::string Sender::GetHostPortData() const + { + auto result = "smtp://" + mSettingsStorage.GetHost(); + if( !mSettingsStorage.GetPort().empty() ) + { + result += ":" + mSettingsStorage.GetPort(); + } + return result; + } + //TODO Надо убрать этот ужас. Без статики!!! + size_t Sender::ReadCallBack( void *ptr, size_t size, size_t nmemb, void *userp ) + { + struct WriteThis *pooh = reinterpret_cast( userp ); + if( size * nmemb < 1 || pooh->counter++ > 0 ) + { + return 0; + } + memcpy( ptr, mText.c_str(), mText.size() ); + return mText.size(); + } +} diff --git a/src/message/sender.hpp b/src/message/sender.hpp new file mode 100644 index 0000000..e75faa8 --- /dev/null +++ b/src/message/sender.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +#include + +#include "service/settings.hpp" + +namespace smtp::message +{ + struct WriteThis + { + int counter; + }; + + class Sender + { + public: + Sender( service::Settings const& settings_storage ); + ~Sender() = default; + + bool Send( std::string const& mail_from, std::string const& mail_to, std::list const& cc, + std::string const& subject, std::string const& text ); + private: + void UpdateMailText( std::string const& mail_from, std::string const& mail_to, std::list const& cc, + std::string const& subject, std::string const& textt ) const; + void InitSenders( std::string const& mail_from, std::list const& mail_to ); + void FillRecipients( CURL* curl, std::string const& mail_to, std::list const& cc, curl_slist* recipients ); + std::string GetHostPortData() const; + static size_t ReadCallBack( void *ptr, size_t size, size_t nmemb, void *userp ); + + service::Settings const& mSettingsStorage; + bool InitCurl( CURL* curl, WriteThis const& upload_ctx, std::string const& mail_from ); + }; +} + + diff --git a/src/message_builder/cc.cpp b/src/message_builder/cc.cpp deleted file mode 100644 index c686ef2..0000000 --- a/src/message_builder/cc.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "cc.hpp" - -namespace smtp::message_builder -{ - Cc::Cc( std::list const& mail_to ) - : mMailTo( mail_to ) - { - - } - - std::string Cc::Get() const - { - std::string result; - if( mBase ) - { - result = mBase->Get(); - } - - if( mMailTo.empty() ) - { - return result; - } - - for(const auto& cc : mMailTo) - { - result += "Cc: " + cc + "\r\n"; - } - - return result; - } -} diff --git a/src/message_builder/cc.hpp b/src/message_builder/cc.hpp deleted file mode 100644 index 5062c37..0000000 --- a/src/message_builder/cc.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#include "types/idecorator.hpp" -#include "types/imessage_build.hpp" - -namespace smtp::message_builder -{ - class Cc : public types::IDecorator - { - public: - explicit Cc( std::list const& mail_to ); - ~Cc() override = default; - - std::string Get() const override; - private: - std::list const& mMailTo; - }; -} - diff --git a/src/message_builder/date.cpp b/src/message_builder/date.cpp deleted file mode 100644 index 96ee2e1..0000000 --- a/src/message_builder/date.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "date.hpp" - -namespace smtp::message_builder -{ - std::string Date::Get() const - { - std::string result; - - if( mBase ) - { - result = mBase->Get(); - } - result += "Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n"; - return result; - } -} diff --git a/src/message_builder/date.hpp b/src/message_builder/date.hpp deleted file mode 100644 index 00fb6cb..0000000 --- a/src/message_builder/date.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "types/idecorator.hpp" -#include "types/imessage_build.hpp" - -namespace smtp::message_builder -{ - class Date : public types::IDecorator - { - public: - Date() = default; - ~Date() override = default; - - std::string Get() const override; - }; -} - diff --git a/src/message_builder/from.cpp b/src/message_builder/from.cpp deleted file mode 100644 index 094e1a2..0000000 --- a/src/message_builder/from.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "from.hpp" - -namespace smtp::message_builder -{ - - From::From( std::string const& mail_to ) - :mMailTo( mail_to ) - { - - } - - std::string From::Get() const - { - std::string result; - if( mBase ) - { - result = mBase->Get(); - } - result += "From: " + mMailTo + "\r\n"; - return result; - } -} diff --git a/src/message_builder/from.hpp b/src/message_builder/from.hpp deleted file mode 100644 index 4605469..0000000 --- a/src/message_builder/from.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "types/idecorator.hpp" -#include "types/imessage_build.hpp" - -namespace smtp::message_builder -{ - class From : public types::IDecorator - { - public: - explicit From( std::string const& mail_to ); - ~From() override = default; - - std::string Get() const override; - private: - std::string const& mMailTo; - }; -} - diff --git a/src/message_builder/mail_to.cpp b/src/message_builder/mail_to.cpp deleted file mode 100644 index c73e2a7..0000000 --- a/src/message_builder/mail_to.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "mail_to.hpp" - -namespace smtp::message_builder -{ - MailTo::MailTo( std::string const& mail_to) - : mMailTo( mail_to ) - { - - } - - std::string MailTo::Get() const - { - std::string result; - if( mBase ) - { - result = mBase->Get(); - } - - result += "To: " + mMailTo +"\r\n"; - - return result; - } -} diff --git a/src/message_builder/mail_to.hpp b/src/message_builder/mail_to.hpp deleted file mode 100644 index 0245fd6..0000000 --- a/src/message_builder/mail_to.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#include "types/idecorator.hpp" -#include "types/imessage_build.hpp" - -namespace smtp::message_builder -{ - class MailTo : public types::IDecorator - { - public: - explicit MailTo( std::string const& mail_to ); - ~MailTo() override = default; - - std::string Get() const override; - private: - std::string const& mMailTo; - }; -} - diff --git a/src/message_builder/subject.cpp b/src/message_builder/subject.cpp deleted file mode 100644 index 84e7e43..0000000 --- a/src/message_builder/subject.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "subject.hpp" - -namespace smtp::message_builder -{ - Subject::Subject( std::string const& subject ) - : mSubject(subject) - { - - } - - std::string Subject::Get() const - { - std::string result; - if( mBase ) - { - result = mBase->Get(); - } - result += "Subject: " + mSubject + "\r\n"; - return result; - } -} diff --git a/src/message_builder/subject.hpp b/src/message_builder/subject.hpp deleted file mode 100644 index bf8bfab..0000000 --- a/src/message_builder/subject.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "types/idecorator.hpp" -#include "types/imessage_build.hpp" - -namespace smtp::message_builder -{ - class Subject : public types::IDecorator - { - public: - explicit Subject( std::string const& subject ); - ~Subject() override = default; - - std::string Get() const override; - private: - std::string const& mSubject; - }; -} - diff --git a/src/message_builder/text.cpp b/src/message_builder/text.cpp deleted file mode 100644 index e5e6bf0..0000000 --- a/src/message_builder/text.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "text.hpp" - -namespace smtp::message_builder -{ - Text::Text( std::string const& text) - : mText( text ) - { - - } - - std::string Text::Get() const - { - std::string result; - if( mBase ) - { - result = mBase->Get(); - } - - result += "\r\n"; - result += mText + "\r\n"; - - return result; - } -} diff --git a/src/message_builder/text.hpp b/src/message_builder/text.hpp deleted file mode 100644 index 4df90e1..0000000 --- a/src/message_builder/text.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "types/idecorator.hpp" -#include "types/imessage_build.hpp" - -namespace smtp::message_builder -{ - class Text : public types::IDecorator - { - public: - explicit Text( std::string const& text ); - ~Text() override = default; - - std::string Get() const override; - private: - std::string const& mText; - }; -} - diff --git a/src/message_builder/types/idecorator.hpp b/src/message_builder/types/idecorator.hpp deleted file mode 100644 index 3fabcd4..0000000 --- a/src/message_builder/types/idecorator.hpp +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include - -namespace smtp::message_builder::types -{ - -/** - * @brief Базовый интерфейс описания декоратора - * @details См. https://refactoring.guru/ru/design-patterns/decorator - * @tparam T Тип декорируемого класса, T должен обладать возможностью наследования (в том числе виртуальный деструктор) - */ - template < typename T, typename TPointerType = std::shared_ptr > class IDecorator : public T - { - public: - using PointerType = TPointerType; - using Type = IDecorator; - - ~IDecorator() override = default; - - /** - * @brief Установить указатель на декорируемый класс - * @details По возможности используйте метод Apply() как наиболее универсальный - * @param base Указатель на декорируемый класс - */ - void SetBase( PointerType const& base ) noexcept - { - mBase = base; - } - - void SetBase( PointerType&& base ) noexcept - { - mBase = std::move( base ); - } - - /** - * @brief Установить указатель на декорируемый класс (цепочка обязанностей) - * @details См. https://refactoring.guru/ru/design-patterns/chain-of-responsibility/cpp/example - * @details Цепь вызовов: декоратор1 -> декоратор2 -> базовый класс - * @param base_or_decorator Указатель на декорируемый класс или целевой декоратор - */ - Type& Apply( PointerType const& base_or_decorator ) noexcept - { - if( !base_or_decorator ) - { - return *this; - } - - SetBase( base_or_decorator ); - return GetApplyResult(); - } - - Type& Apply( PointerType&& base_or_decorator ) noexcept - { - if( !base_or_decorator ) - { - return *this; - } - - SetBase( std::move( base_or_decorator ) ); - return GetApplyResult(); - } - - private: - Type& GetApplyResult() noexcept - { - auto as_decorator = dynamic_cast< Type * >( mBase.get() ); - if( as_decorator ) - { - return *as_decorator; - } - - return *this; - } - - protected: - PointerType mBase; - }; - - template < typename T, typename TDeleter = std::default_delete > using IDecoratorUnique = IDecorator >; - -} // namespace sbis::devices::generic::types diff --git a/src/message_builder/types/imessage_build.hpp b/src/message_builder/types/imessage_build.hpp deleted file mode 100644 index 4c4f1b8..0000000 --- a/src/message_builder/types/imessage_build.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -namespace smtp::message_builder::types -{ - class IMessageBuilder - { - public: - virtual ~IMessageBuilder() = default; - - virtual std::string Get() const = 0; - }; -} diff --git a/src/message_sender.cpp b/src/message_sender.cpp deleted file mode 100644 index 5b2950c..0000000 --- a/src/message_sender.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include - -#include "message_sender.hpp" -#include "message_builder/date.hpp" -#include "message_builder/mail_to.hpp" -#include "message_builder/cc.hpp" -#include "message_builder/subject.hpp" -#include "message_builder/text.hpp" -#include "message_builder/from.hpp" - -namespace smtp -{ - static std::string mText = ""; - - // - // Constructors/Destructors - // - MessageSender::MessageSender( SettingsStorage const& settings_storage ) - : mSettingsStorage( settings_storage ) - { - - } - - // - //Public methods - // - bool MessageSender::Send( std::string const& mail_from, std::string const& mail_to, std::list const& cc, - std::string const& subject, std::string const& text ) - { - CURLcode result = CURLE_OK; - - struct curl_slist *recipients = NULL; - struct WriteThis upload_ctx; - - upload_ctx.counter = 0; - - auto curl = curl_easy_init(); - - if( !curl ) - { - //Error - return false; - } - mText = GetText( mail_from, mail_to, cc, subject, text); - FillRecipients( curl, mail_to, cc, recipients ); - - curl_easy_setopt(curl, CURLOPT_USERNAME, mSettingsStorage.username.c_str()); - curl_easy_setopt(curl, CURLOPT_PASSWORD, mSettingsStorage.password.c_str()); - curl_easy_setopt(curl, CURLOPT_URL, GetHostPortData().c_str()); - - curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); - curl_easy_setopt(curl, CURLOPT_MAIL_FROM, mail_from.c_str()); - - curl_easy_setopt(curl, CURLOPT_READFUNCTION, ReadCallBack); - curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx); - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - - result = curl_easy_perform(curl); - - if (result != CURLE_OK) - { - fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(result)); - return false; - } - - curl_slist_free_all(recipients); - curl_easy_cleanup(curl); - return true; - } - - // - //Private methods - // - std::string MessageSender::GetText( std::string const& mail_from, std::string const& mail_to, std::list const& cc, - std::string const& subject, std::string const& text ) const - { - auto text_decorator = std::make_shared( text ); - text_decorator->Apply( std::make_shared( subject ) ) - .Apply( std::make_shared( cc ) ) - .Apply( std::make_shared( mail_from ) ) - .Apply( std::make_shared( mail_to ) ) - .Apply( std::make_shared() ); - return text_decorator->Get(); - } - - void MessageSender::FillRecipients( CURL* curl, std::string const& mail_to, std::list const& cc, curl_slist* recipients ) - { - recipients = curl_slist_append( recipients, mail_to.c_str() ); - - for( const auto& recipient : cc ) - { - recipients = curl_slist_append( recipients, recipient.c_str() ); - } - - curl_easy_setopt( curl, CURLOPT_MAIL_RCPT, recipients ); - } - - std::string MessageSender::GetHostPortData() const - { - auto result = "smtp://" + mSettingsStorage.host; - if( !mSettingsStorage.port.empty() ) - { - result += ":" + mSettingsStorage.port; - } - return result; - } - - size_t MessageSender::ReadCallBack( void *ptr, size_t size, size_t nmemb, void *userp ) - { - struct WriteThis *pooh = reinterpret_cast( userp ); - if( size * nmemb < 1 ) - { - return 0; - } - if( pooh->counter++ > 0 ) - { - return 0; - } - memcpy( ptr, mText.c_str(), mText.size() ); - return mText.size(); - } -} diff --git a/src/message_sender.hpp b/src/message_sender.hpp deleted file mode 100644 index 0728f0e..0000000 --- a/src/message_sender.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include - -#include - -#include "settings_storage.hpp" - -namespace smtp -{ - struct WriteThis - { - int counter; - }; - - class MessageSender - { - public: - MessageSender( SettingsStorage const& settings_storage ); - ~MessageSender() = default; - - bool Send( std::string const& mail_from, std::string const& mail_to, std::list const& cc, - std::string const& subject, std::string const& text ); - private: - std::string GetText( std::string const& mail_from, std::string const& mail_to, std::list const& cc, - std::string const& subject, std::string const& textt ) const; - void InitSenders( std::string const& mail_from, std::list const& mail_to ); - void FillRecipients( CURL* curl, std::string const& mail_to, std::list const& cc, curl_slist* recipients ); - std::string GetHostPortData() const; - void ProcessSending(const std::string &mail_from, const std::list &mail_to, const std::string &subject, const std::string &text); - timeval GetNowTime() const noexcept; - bool IsTimeOut( timeval const& start_time ) const noexcept; - long GetTimeDiff( timeval const& left, timeval const& right ) const noexcept; - timeval GetTimeout() const; - int ProcessHandle( timeval& timeout ) const; - void ClearPtrs(); - static size_t ReadCallBack( void *ptr, size_t size, size_t nmemb, void *userp ); - -// CURL *curl; -// CURLM *mcurl; - struct WriteThis pooh; - struct curl_slist* recipients = NULL; - SettingsStorage const& mSettingsStorage; - }; -} - - diff --git a/src/service/settings.cpp b/src/service/settings.cpp new file mode 100644 index 0000000..075aafa --- /dev/null +++ b/src/service/settings.cpp @@ -0,0 +1,54 @@ +#include "settings.hpp" + +namespace smtp::service +{ + + Settings::Settings() + : mSettingsFields{} + { + + } + + Settings::Settings( SettingsFields data ) + : mSettingsFields(data) + { + + } + + bool Settings::CheckAndSetSettings(SettingsFields data) + { + mSettingsFields = data; + return true; + } + + bool Settings::IsNeedAuth() const noexcept + { + return mSettingsFields.is_need_auth; + } + + bool Settings::IsNeedSsl() const noexcept + { + return mSettingsFields.is_need_ssl; + } + + std::string Settings::GetUserName() const + { + return mSettingsFields.username; + } + + std::string Settings::GetPassword() const + { + return mSettingsFields.password; + } + + std::string Settings::GetHost() const + { + return mSettingsFields.host; + } + + std::string Settings::GetPort() const + { + return mSettingsFields.port; + } + +} diff --git a/src/service/settings.hpp b/src/service/settings.hpp new file mode 100644 index 0000000..b6319f6 --- /dev/null +++ b/src/service/settings.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include + +namespace smtp::service +{ + struct SettingsFields + { + bool is_need_auth; + bool is_need_ssl; + std::string username; + std::string password; + std::string host; + std::string port; + }; + + class Settings + { + public: + Settings(); + explicit Settings( SettingsFields data ); + ~Settings() = default; + + bool CheckAndSetSettings( SettingsFields data ); + + bool IsNeedAuth() const noexcept; + bool IsNeedSsl() const noexcept; + + std::string GetUserName() const; + std::string GetPassword() const; + std::string GetHost() const; + std::string GetPort() const; + private: + SettingsFields mSettingsFields; + }; +} diff --git a/src/service/smtp.cpp b/src/service/smtp.cpp new file mode 100644 index 0000000..818a4de --- /dev/null +++ b/src/service/smtp.cpp @@ -0,0 +1,99 @@ +#include "smtp.hpp" +#include "message/sender.hpp" + +namespace smtp::service +{ + static constexpr char HOST_PROPERTY[] = "Host"; + static constexpr char USER_PROPERTY[] = "User"; + static constexpr char PORT_PROPERTY[] = "Port"; + + // + // Constructors + // + + Smtp::Smtp( ConnectionPtr connection ) + { + std::string from{"claiff@mail.ru"}; + std::string to{"claiff1990@gmail.com"}; + std::list cc{"claiff@mail.ru"}; + std::string subject{"subject"}; + std::string text{"text"}; + + mSettingsStorage.CheckAndSetSettings({true, true, "claiff@mail.ru","nZZbXq7FbwWAqpPpy3YL", "smtp.mail.ru", "" }); + message::Sender{ mSettingsStorage }.Send( "claiff@mail.ru", "claiff1990@gmail.com", {"claiff@mail.ru"}, "subject", "text" ); + +// CreateService( connection ); +// CreateInterface( connection ); + } + + // + // Private methods + // + + void Smtp::CreateService( ConnectionPtr connection ) + { + static constexpr char SMTP_BUS_NAME[] = "xyz.openbmc_project.SMTP"; + + connection->request_name( SMTP_BUS_NAME ); + } + + void Smtp::CreateInterface( ConnectionPtr connection ) + { + static constexpr char SMTP_OBJECT_NAME[] = "/xyz/openbmc_project/SMTP"; + static constexpr char SMTP_INTERFACE_NAME[] = "xyz.openbmc_project.SMTP"; + + mObjectServer = std::make_shared( connection ); + mInterface = mObjectServer->add_interface( SMTP_OBJECT_NAME, SMTP_INTERFACE_NAME ); + + AddProperties(); + AddMethods(); + + mInterface->initialize(); + } + + void Smtp::AddProperties() + { + mInterface->register_property( HOST_PROPERTY, mSettingsStorage.GetHost(), sdbusplus::asio::PropertyPermission::readOnly ); + mInterface->register_property( USER_PROPERTY, mSettingsStorage.GetUserName(), sdbusplus::asio::PropertyPermission::readOnly ); + mInterface->register_property( PORT_PROPERTY, mSettingsStorage.GetPort(), sdbusplus::asio::PropertyPermission::readOnly ); + } + + void Smtp::AddMethods() + { + static constexpr char SMTP_SEND_MESSAGE_METHOD_NAME[] = "SendMail"; + static constexpr char SMTP_CHANGE_PARAMETERS_METHOD_NAME[] = "ChangeParameters"; + + mInterface->register_method(SMTP_SEND_MESSAGE_METHOD_NAME, [this]( std::string const& mail_from, + std::string const& mail_to, + std::list const& cc, + std::string const& theme, + std::string const& text ) + { return message::Sender{ mSettingsStorage }.Send( mail_from, mail_to, cc, theme, text );}); + + + mInterface->register_method(SMTP_CHANGE_PARAMETERS_METHOD_NAME, [this]( bool is_need_auth, + bool is_need_ssl, + std::string const& user, + std::string const& password, + std::string const& host, + std::string const& port ) + { return RefreshSettings( is_need_auth, is_need_ssl, user, password, host, port);}); + } + + bool Smtp::RefreshSettings( bool is_need_auth, bool is_need_ssl, + std::string const& user, std::string const& password, + std::string const& host, std::string const& port ) + { + auto is_settings_norm = mSettingsStorage.CheckAndSetSettings({is_need_auth, is_need_ssl, + user, password, host, port}); + if(!is_settings_norm) + { + return false; + } + + mInterface->set_property(HOST_PROPERTY, host); + mInterface->set_property(USER_PROPERTY, user); + mInterface->set_property(PORT_PROPERTY, port); + return true; + } +} diff --git a/src/service/smtp.hpp b/src/service/smtp.hpp new file mode 100644 index 0000000..c311645 --- /dev/null +++ b/src/service/smtp.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include +#include + +#include "settings.hpp" + +namespace smtp::service +{ + using ConnectionPtr = std::shared_ptr; + using InterfacePtr = std::shared_ptr; + using ObjectServerPtr = std::shared_ptr; + + class Smtp + { + public: + Smtp( ConnectionPtr connection ); + ~Smtp() = default; + private: + void FillStorageByDefault(); + void CreateService( ConnectionPtr bus ); + void CreateInterface( ConnectionPtr connection ); + void AddProperties(); + void AddMethods(); + bool RefreshSettings( bool is_need_auth, bool is_need_ssl, + std::string const& user, std::string const& password, + std::string const& host, std::string const& port ); + + InterfacePtr mInterface; + ObjectServerPtr mObjectServer; + Settings mSettingsStorage; + }; +} diff --git a/src/settings_storage.hpp b/src/settings_storage.hpp deleted file mode 100644 index d442d6f..0000000 --- a/src/settings_storage.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -namespace smtp -{ - struct SettingsStorage - { - std::string username; - std::string password; - std::string host; - std::string port; - }; -} diff --git a/src/smtp_service.cpp b/src/smtp_service.cpp deleted file mode 100644 index 6235e4c..0000000 --- a/src/smtp_service.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "smtp_service.hpp" -#include "message_sender.hpp" - -namespace smtp -{ - static constexpr char HOST_PROPERTY[] = "Host"; - static constexpr char USER_PROPERTY[] = "User"; - static constexpr char PORT_PROPERTY[] = "Port"; - - // - // Constructors - // - - SmtpService::SmtpService( ConnectionPtr connection ) - { - FillStorageByDefault(); - CreateService( connection ); - CreateInterface( connection ); - } - - // - // Private methods - // - - void SmtpService::FillStorageByDefault() - { - mStorage.host = ""; - mStorage.username = ""; - mStorage.password = ""; - mStorage.port = ""; - } - - void SmtpService::CreateService( ConnectionPtr connection ) - { - static constexpr char SMTP_BUS_NAME[] = "xyz.openbmc_project.SMTP"; - - connection->request_name( SMTP_BUS_NAME ); - } - - void SmtpService::CreateInterface( ConnectionPtr connection ) - { - static constexpr char SMTP_OBJECT_NAME[] = "/xyz/openbmc_project/SMTP"; - static constexpr char SMTP_INTERFACE_NAME[] = "xyz.openbmc_project.SMTP"; - - mObjectServer = std::make_shared( connection ); - mInterface = mObjectServer->add_interface( SMTP_OBJECT_NAME, SMTP_INTERFACE_NAME ); - - AddProperties(); - AddMethods(); - - mInterface->initialize(); - } - - void SmtpService::AddProperties() - { - mInterface->register_property( HOST_PROPERTY, mStorage.host, sdbusplus::asio::PropertyPermission::readOnly ); - mInterface->register_property( USER_PROPERTY, mStorage.username, sdbusplus::asio::PropertyPermission::readOnly ); - mInterface->register_property( PORT_PROPERTY, mStorage.port, sdbusplus::asio::PropertyPermission::readOnly ); - } - - void SmtpService::AddMethods() - { - static constexpr char SMTP_SEND_MESSAGE_METHOD_NAME[] = "SendMail"; - static constexpr char SMTP_CHANGE_PARAMETERS_METHOD_NAME[] = "ChangeParameters"; - - mInterface->register_method(SMTP_SEND_MESSAGE_METHOD_NAME, [this]( std::string const& mail_from, - std::string const& mail_to, - std::list const& cc, - std::string const& theme, - std::string const& text ) - { return MessageSender{ mStorage }.Send( mail_from, mail_to, cc, theme, text );}); - - - mInterface->register_method(SMTP_CHANGE_PARAMETERS_METHOD_NAME, [this]( std::string const& user, - std::string const& password, - std::string const& host, - std::string const& port ) - { return RefreshSettings(user, password, host, port);}); - } - - bool SmtpService::RefreshSettings(std::string const& user, - std::string const& password, - std::string const& host, - std::string const& port) - { - mStorage.username = user; - mStorage.password = password; - mStorage.host = host; - mStorage.port = port; - - mInterface->set_property(HOST_PROPERTY, host); - mInterface->set_property(USER_PROPERTY, user); - mInterface->set_property(PORT_PROPERTY, port); - return true; - } -} diff --git a/src/smtp_service.hpp b/src/smtp_service.hpp deleted file mode 100644 index 7149e3a..0000000 --- a/src/smtp_service.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include - -#include -#include - -#include "settings_storage.hpp" - -namespace smtp -{ - using ConnectionPtr = std::shared_ptr; - using InterfacePtr = std::shared_ptr; - using ObjectServerPtr = std::shared_ptr; - - class SmtpService - { - public: - SmtpService( ConnectionPtr connection ); - ~SmtpService() = default; - private: - void FillStorageByDefault(); - void CreateService( ConnectionPtr bus ); - void CreateInterface( ConnectionPtr connection ); - void AddProperties(); - void AddMethods(); - bool RefreshSettings(std::string const& user, - std::string const& password, - std::string const& host, - std::string const& port); - - InterfacePtr mInterface; - ObjectServerPtr mObjectServer; - SettingsStorage mStorage; - }; -} -- cgit v1.2.3