File indexing completed on 2024-05-12 05:10:48

0001 /*
0002   SPDX-FileCopyrightText: 2001, 2004 Cornelius Schumacher <schumacher@kde.org>
0003   SPDX-FileCopyrightText: 2010, 2012 Sérgio Martins <iamsergio@gmail.com>
0004 
0005   SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "mailscheduler_p.h"
0009 #include "calendarbase.h"
0010 #include "calendarsettings.h"
0011 #include "utils_p.h"
0012 
0013 #include <KCalendarCore/ICalFormat>
0014 #include <KCalendarCore/ScheduleMessage>
0015 #include <KIdentityManagementCore/Identity>
0016 #include <KIdentityManagementCore/IdentityManager>
0017 
0018 #include <KLocalizedString>
0019 #include <QStandardPaths>
0020 
0021 using namespace Akonadi;
0022 using namespace KIdentityManagementCore;
0023 
0024 class Akonadi::MailSchedulerPrivate
0025 {
0026 public:
0027     [[nodiscard]] KIdentityManagementCore::Identity identityForIncidence(const KCalendarCore::IncidenceBase::Ptr &incidence) const;
0028     [[nodiscard]] KIdentityManagementCore::Identity identityForAddress(const QString &address) const;
0029 
0030     MailClient::MailPrivacyFlags privacyFlags() const
0031     {
0032         MailClient::MailPrivacyFlags flags;
0033         flags.setFlag(MailClient::MailPrivacySign, m_sign);
0034         flags.setFlag(MailClient::MailPrivacyEncrypt, m_encrypt);
0035         return flags;
0036     }
0037 
0038     KIdentityManagementCore::IdentityManager *m_identityManager = nullptr;
0039     MailClient *m_mailer = nullptr;
0040     bool m_encrypt = false;
0041     bool m_sign = false;
0042 };
0043 
0044 MailScheduler::MailScheduler(ITIPHandlerComponentFactory *factory, QObject *parent)
0045     : Scheduler(parent)
0046     , d(new MailSchedulerPrivate())
0047 {
0048     d->m_identityManager = KIdentityManagementCore::IdentityManager::self();
0049     d->m_mailer = new MailClient(factory, parent);
0050 
0051     connect(d->m_mailer, &MailClient::finished, this, &MailScheduler::onMailerFinished);
0052 }
0053 
0054 MailScheduler::~MailScheduler()
0055 {
0056     delete d->m_mailer;
0057 }
0058 
0059 KIdentityManagementCore::Identity MailSchedulerPrivate::identityForIncidence(const KCalendarCore::IncidenceBase::Ptr &incidence) const
0060 {
0061     const auto organizer = incidence->organizer();
0062     const QString organizerEmail = !organizer.isEmpty() ? organizer.email() : CalendarUtils::email();
0063     return m_identityManager->identityForAddress(organizerEmail);
0064 }
0065 
0066 KIdentityManagementCore::Identity MailSchedulerPrivate::identityForAddress(const QString &address) const
0067 {
0068     return m_identityManager->identityForAddress(address);
0069 }
0070 
0071 void MailScheduler::publish(const KCalendarCore::IncidenceBase::Ptr &incidence, const QString &recipients)
0072 {
0073     Q_ASSERT(incidence);
0074     if (!incidence) {
0075         return;
0076     }
0077 
0078     const QString messageText = mFormat->createScheduleMessage(incidence, KCalendarCore::iTIPPublish);
0079     d->m_mailer->mailTo(incidence,
0080                         d->identityForIncidence(incidence),
0081                         CalendarUtils::email(),
0082                         KCalendarCore::iTIPPublish,
0083                         CalendarSettings::self()->bcc(),
0084                         recipients,
0085                         messageText,
0086                         {},
0087                         d->privacyFlags());
0088 }
0089 
0090 void MailScheduler::performTransaction(const KCalendarCore::IncidenceBase::Ptr &incidence,
0091                                        KCalendarCore::iTIPMethod method,
0092                                        const QString &recipients,
0093                                        const QString &sender)
0094 {
0095     Q_ASSERT(incidence);
0096     if (!incidence) {
0097         return;
0098     }
0099     const QString messageText = mFormat->createScheduleMessage(incidence, method);
0100 
0101     const auto identity = sender.isEmpty() ? d->identityForIncidence(incidence) : d->identityForAddress(sender);
0102 
0103     d->m_mailer->mailTo(incidence, identity, Akonadi::CalendarUtils::email(), method, CalendarSettings::self()->bcc(), recipients, messageText, {}, d->privacyFlags());
0104 }
0105 
0106 void MailScheduler::performTransaction(const KCalendarCore::IncidenceBase::Ptr &incidence, KCalendarCore::iTIPMethod method, const QString &sender)
0107 {
0108     Q_ASSERT(incidence);
0109     if (!incidence) {
0110         return;
0111     }
0112 
0113     const QString messageText = mFormat->createScheduleMessage(incidence, method);
0114     const auto identity = sender.isEmpty() ? d->identityForIncidence(incidence) : d->identityForAddress(sender);
0115 
0116     if (method == KCalendarCore::iTIPRequest || method == KCalendarCore::iTIPCancel || method == KCalendarCore::iTIPAdd
0117         || method == KCalendarCore::iTIPDeclineCounter) {
0118         d->m_mailer->mailAttendees(incidence, identity, method, CalendarSettings::self()->bcc(), messageText, {}, d->privacyFlags());
0119     } else {
0120         QString subject;
0121         KCalendarCore::Incidence::Ptr inc = incidence.dynamicCast<KCalendarCore::Incidence>();
0122         if (inc && method == KCalendarCore::iTIPCounter) {
0123             subject = i18n("Counter proposal: %1", inc->summary());
0124         }
0125 
0126         const auto from = sender.isEmpty() ? CalendarUtils::email() : sender;
0127 
0128         d->m_mailer->mailOrganizer(incidence, identity, sender, method, CalendarSettings::self()->bcc(), messageText, subject, {}, d->privacyFlags());
0129     }
0130 }
0131 
0132 QString MailScheduler::freeBusyDir() const
0133 {
0134     return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/korganizer/freebusy");
0135 }
0136 
0137 // TODO: AKONADI_PORT review following code
0138 void MailScheduler::acceptCounterProposal(const KCalendarCore::Incidence::Ptr &incidence, const Akonadi::CalendarBase::Ptr &calendar)
0139 {
0140     Q_ASSERT(incidence);
0141     Q_ASSERT(calendar);
0142     if (!incidence || !calendar) {
0143         return;
0144     }
0145 
0146     Akonadi::Item exInc = calendar->item(incidence);
0147     if (!exInc.isValid()) {
0148         KCalendarCore::Incidence::Ptr exIncidence = calendar->incidenceFromSchedulingID(incidence->uid());
0149         if (exIncidence) {
0150             exInc = calendar->item(exIncidence);
0151         }
0152         // exInc = exIncItem.isValid() && exIncItem.hasPayload<KCalendarCore::Incidence::Ptr>() ?
0153         //        exIncItem.payload<KCalendarCore::Incidence::Ptr>() : KCalendarCore::Incidence::Ptr();
0154     }
0155 
0156     incidence->setRevision(incidence->revision() + 1);
0157     Result result = ResultSuccess;
0158 
0159     if (exInc.isValid() && exInc.hasPayload<KCalendarCore::Incidence::Ptr>()) {
0160         auto exIncPtr = exInc.payload<KCalendarCore::Incidence::Ptr>();
0161         incidence->setRevision(qMax(incidence->revision(), exIncPtr->revision() + 1));
0162         // some stuff we don't want to change, just to be safe
0163         incidence->setSchedulingID(exIncPtr->schedulingID());
0164         incidence->setUid(exIncPtr->uid());
0165 
0166         Q_ASSERT(exIncPtr && incidence);
0167 
0168         KCalendarCore::IncidenceBase::Ptr i1 = exIncPtr;
0169         KCalendarCore::IncidenceBase::Ptr i2 = incidence;
0170 
0171         if (i1->type() == i2->type()) {
0172             *i1 = *i2;
0173         }
0174 
0175         exIncPtr->updated();
0176 
0177         if (!calendar->modifyIncidence(exIncPtr)) {
0178             result = ResultModifyingError;
0179         }
0180     } else {
0181         if (!calendar->addIncidence(KCalendarCore::Incidence::Ptr(incidence->clone()))) {
0182             result = ResultCreatingError;
0183         }
0184     }
0185 
0186     if (result != ResultSuccess) {
0187         Q_EMIT transactionFinished(result, QStringLiteral("Error creating job"));
0188     } else {
0189         // Nothing to do here. Signal will be emitted when we hear back from the calendar.
0190     }
0191 }
0192 
0193 void MailScheduler::onMailerFinished(Akonadi::MailClient::Result result, const QString &errorMsg)
0194 {
0195     if (result == MailClient::ResultSuccess) {
0196         Q_EMIT transactionFinished(ResultSuccess, QString());
0197     } else {
0198         const QString message = i18n("Error sending e-mail: ") + errorMsg;
0199         Q_EMIT transactionFinished(ResultGenericError, message);
0200     }
0201 }
0202 
0203 void MailScheduler::setEncrypt(bool encrypt)
0204 {
0205     d->m_encrypt = encrypt;
0206 }
0207 
0208 void MailScheduler::setSign(bool sign)
0209 {
0210     d->m_sign = sign;
0211 }
0212 
0213 #include "moc_mailscheduler_p.cpp"