Skip to content

Commit 7566fd6

Browse files
committed
Merge branch 'ews'
2 parents 12abe14 + f6af1d5 commit 7566fd6

File tree

6 files changed

+111
-8
lines changed

6 files changed

+111
-8
lines changed

exch/ews/context.cpp

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,6 +1997,59 @@ void EWSContext::toContent(const std::string& dir, tCalendarItem& item, sShape&
19971997
shape.write(NtGlobalObjectId, TAGGED_PROPVAL{PT_BINARY, goid});
19981998
shape.write(NtCleanGlobalObjectId, TAGGED_PROPVAL{PT_BINARY, goid});
19991999
}
2000+
2001+
size_t recipients = (item.RequiredAttendees ? item.RequiredAttendees->size() : 0) +
2002+
(item.OptionalAttendees ? item.OptionalAttendees->size() : 0) +
2003+
(item.Resources ? item.Resources->size() : 0);
2004+
if (recipients) {
2005+
if (!content->children.prcpts && !(content->children.prcpts = tarray_set_init()))
2006+
throw EWSError::NotEnoughMemory(E3288);
2007+
TARRAY_SET* rcpts = content->children.prcpts;
2008+
if (item.RequiredAttendees)
2009+
for (const auto &att : *item.RequiredAttendees)
2010+
att.Mailbox.mkRecipient(rcpts->emplace(), MAPI_TO);
2011+
if (item.OptionalAttendees)
2012+
for (const auto &att : *item.OptionalAttendees)
2013+
att.Mailbox.mkRecipient(rcpts->emplace(), MAPI_CC);
2014+
if (item.Resources)
2015+
for (const auto &att : *item.Resources)
2016+
att.Mailbox.mkRecipient(rcpts->emplace(), MAPI_TO);
2017+
std::string dispName;
2018+
if (!mysql_adaptor_get_user_displayname(m_auth_info.username, dispName))
2019+
throw DispatchError(E3302);
2020+
auto displayName = deconst(dispName.c_str());
2021+
shape.write(TAGGED_PROPVAL{PR_SENT_REPRESENTING_NAME, displayName});
2022+
shape.write(TAGGED_PROPVAL{PR_SENDER_NAME, displayName});
2023+
auto username = deconst(m_auth_info.username);
2024+
shape.write(TAGGED_PROPVAL{PR_SENT_REPRESENTING_SMTP_ADDRESS, username});
2025+
shape.write(TAGGED_PROPVAL{PR_SENDER_SMTP_ADDRESS, username});
2026+
auto addrType = deconst("SMTP");
2027+
shape.write(TAGGED_PROPVAL{PR_SENT_REPRESENTING_ADDRTYPE, addrType});
2028+
shape.write(TAGGED_PROPVAL{PR_SENDER_ADDRTYPE, addrType});
2029+
auto uint0 = construct<uint8_t>(0);
2030+
auto uint1 = construct<uint32_t>(1);
2031+
auto uint5 = construct<uint32_t>(5);
2032+
shape.write(NtMeetingType, TAGGED_PROPVAL{PT_LONG, uint1});
2033+
shape.write(NtPrivate, TAGGED_PROPVAL{PT_BOOLEAN, uint0});
2034+
shape.write(NtAppointmentStateFlags, TAGGED_PROPVAL{PT_LONG, uint1});
2035+
shape.write(NtResponseStatus, TAGGED_PROPVAL{PT_LONG, uint5});
2036+
std::string essdn;
2037+
if (cvt_username_to_essdn(m_auth_info.username, m_plugin.x500_org_name.c_str(),
2038+
mysql_adaptor_get_user_ids, mysql_adaptor_get_domain_ids, essdn) != ecSuccess)
2039+
throw DispatchError(E3085);
2040+
shape.write(TAGGED_PROPVAL{PR_SENT_REPRESENTING_EMAIL_ADDRESS, strcpy(alloc<char>(essdn.size() + 1), essdn.c_str())});
2041+
shape.write(TAGGED_PROPVAL{PR_SENDER_EMAIL_ADDRESS, strcpy(alloc<char>(essdn.size() + 1), essdn.c_str())});
2042+
EMSAB_ENTRYID abEid{0, DT_MAILUSER, essdn.data()};
2043+
EXT_PUSH ext_push;
2044+
static constexpr size_t ABEIDBUFFSIZE = 1280;
2045+
uint8_t* abEidBuff = alloc<uint8_t>(ABEIDBUFFSIZE);
2046+
if (!ext_push.init(abEidBuff, ABEIDBUFFSIZE, EXT_FLAG_UTF16) ||
2047+
ext_push.p_abk_eid(abEid) != pack_result::ok)
2048+
throw DispatchError(E3085);
2049+
BINARY* abEidContainer = construct<BINARY>(BINARY{ext_push.m_offset, {abEidBuff}});
2050+
shape.write(TAGGED_PROPVAL{PR_SENT_REPRESENTING_ENTRYID, abEidContainer});
2051+
shape.write(TAGGED_PROPVAL{PR_SENDER_ENTRYID, abEidContainer});
2052+
}
20002053
}
20012054

20022055
/**
@@ -2165,7 +2218,7 @@ void EWSContext::toContent(const std::string& dir, tItem& item, sShape& shape, M
21652218
if (item.Subject)
21662219
shape.write(TAGGED_PROPVAL{PR_SUBJECT, deconst(item.Subject->c_str())});
21672220

2168-
auto now = EWSContext::construct<uint64_t>(rop_util_current_nttime());
2221+
auto now = EWSContext::construct<mapitime_t>(rop_util_current_nttime());
21692222
shape.write(TAGGED_PROPVAL{PR_CREATION_TIME, now});
21702223
shape.write(TAGGED_PROPVAL{PR_LOCAL_COMMIT_TIME, now});
21712224

@@ -2353,8 +2406,8 @@ void EWSContext::updated(const std::string& dir, const sMessageEntryId& mid, sSh
23532406
if (!m_plugin.exmdb.allocate_cn(dir.c_str(), &changeNum))
23542407
throw DispatchError(E3084);
23552408
uint64_t localCommitTime = rop_util_current_nttime();
2356-
shape.write(TAGGED_PROPVAL{PR_LOCAL_COMMIT_TIME, construct<uint64_t>(localCommitTime)});
2357-
shape.write(TAGGED_PROPVAL{PR_LAST_MODIFICATION_TIME, construct<uint64_t>(localCommitTime)});
2409+
shape.write(TAGGED_PROPVAL{PR_LOCAL_COMMIT_TIME, construct<mapitime_t>(localCommitTime)});
2410+
shape.write(TAGGED_PROPVAL{PR_LAST_MODIFICATION_TIME, construct<mapitime_t>(localCommitTime)});
23582411

23592412
std::string displayName;
23602413
if (mysql_adaptor_get_user_displayname(m_auth_info.username,

exch/ews/exceptions.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ inline std::string E3297(const char* uid) {return fmt::format("E-3297: Failed to
429429
E(3298, "Failed to allocate memory for goid data");
430430
E(3299, "Failed to generate goid data");
431431
E(3300, "Failed to get offset from the timezone definition");
432+
E(3301, "Failed to copy message to sent items");
433+
E(3302, "Failed to get the display name");
432434

433435
#undef E
434436
}

exch/ews/namedtags.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// Follow the order in mapitags.hpp
1010
static const PROPERTY_NAME NtGlobalObjectId = {MNID_ID, PSETID_Meeting, PidLidGlobalObjectId};
1111
static const PROPERTY_NAME NtCleanGlobalObjectId = {MNID_ID, PSETID_Meeting, PidLidCleanGlobalObjectId};
12+
static const PROPERTY_NAME NtMeetingType = {MNID_ID, PSETID_Meeting, PidLidMeetingType};
1213
static const PROPERTY_NAME NtCategories = {MNID_STRING, PS_PUBLIC_STRINGS, 0, deconst("Keywords")};
1314

1415
/* PSETID_Address */
@@ -66,6 +67,7 @@ static const PROPERTY_NAME NtAppointmentTimeZoneDefinitionEndDisplay = {MNID_ID,
6667
static const PROPERTY_NAME NtReminderDelta = {MNID_ID, PSETID_Common, PidLidReminderDelta};
6768
static const PROPERTY_NAME NtReminderTime = {MNID_ID, PSETID_Common, PidLidReminderTime};
6869
static const PROPERTY_NAME NtReminderSet = {MNID_ID, PSETID_Common, PidLidReminderSet};
70+
static const PROPERTY_NAME NtPrivate = {MNID_ID, PSETID_Common, PidLidPrivate};
6971
static const PROPERTY_NAME NtCommonStart = {MNID_ID, PSETID_Common, PidLidCommonStart};
7072
static const PROPERTY_NAME NtCommonEnd = {MNID_ID, PSETID_Common, PidLidCommonEnd};
7173
static const PROPERTY_NAME NtMileage = {MNID_ID, PSETID_Common, PidLidMileage};

exch/ews/requests.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,10 @@ void process(mCreateItemRequest&& request, XMLElement* response, const EWSContex
243243
request.MessageDisposition = Enum::SaveOnly;
244244
if (!request.SendMeetingInvitations)
245245
request.SendMeetingInvitations = Enum::SendToNone;
246-
bool sendMessages = request.MessageDisposition == Enum::SendOnly || request.MessageDisposition == Enum::SendAndSaveCopy;
246+
bool sendMessages = request.MessageDisposition == Enum::SendOnly
247+
|| request.MessageDisposition == Enum::SendAndSaveCopy
248+
|| request.SendMeetingInvitations == Enum::SendOnlyToAll
249+
|| request.SendMeetingInvitations == Enum::SendToAllAndSaveCopy;
247250

248251
data.ResponseMessages.reserve(request.Items.size());
249252
for (sItem &item : request.Items) try {
@@ -252,10 +255,44 @@ void process(mCreateItemRequest&& request, XMLElement* response, const EWSContex
252255

253256
mCreateItemResponseMessage msg;
254257
bool persist = !(std::holds_alternative<tMessage>(item) && request.MessageDisposition == Enum::SendOnly);
255-
bool send = std::holds_alternative<tMessage>(item) && sendMessages;
258+
bool send = std::holds_alternative<tMessage>(item) && sendMessages;
256259
auto content = ctx.toContent(dir, *targetFolder, item, persist);
257260
if (persist)
258261
msg.Items.emplace_back(ctx.create(dir, *targetFolder, *content));
262+
if (std::holds_alternative<tCalendarItem>(item) && sendMessages &&
263+
request.SendMeetingInvitations == Enum::SendToAllAndSaveCopy) {
264+
sFolderSpec sentitems = ctx.resolveFolder(tDistinguishedFolderId(Enum::sentitems));
265+
uint64_t newMid;
266+
if (!ctx.plugin().exmdb.allocate_message_id(dir.c_str(),
267+
sentitems.folderId, &newMid))
268+
throw EWSError::InternalServerError(E3132);
269+
BOOL result;
270+
auto messageId = *content->proplist.get<const uint64_t>(PidTagMid);
271+
if (!ctx.plugin().exmdb.movecopy_message(dir.c_str(), CP_ACP,
272+
messageId, sentitems.folderId, newMid, false, &result)
273+
|| !result)
274+
throw EWSError::InternalServerError(E3301);
275+
const char* username = ctx.effectiveUser(sentitems);
276+
auto now = EWSContext::construct<uint64_t>(rop_util_current_nttime());
277+
static constexpr uint8_t proptrue = 1;
278+
TAGGED_PROPVAL props[] = {
279+
{PR_MESSAGE_CLASS, deconst("IPM.Schedule.Meeting.Request")},
280+
{PR_RESPONSE_REQUESTED, deconst(&proptrue)},
281+
{PR_CLIENT_SUBMIT_TIME, now},
282+
{PR_MESSAGE_DELIVERY_TIME, now},
283+
};
284+
TPROPVAL_ARRAY proplist{std::size(props), props};
285+
PROBLEM_ARRAY problems;
286+
if (!ctx.plugin().exmdb.set_message_properties(dir.c_str(),
287+
username, CP_ACP, newMid, &proplist, &problems))
288+
throw EWSError::ItemSave(E3092);
289+
MESSAGE_CONTENT *sendcontent = nullptr;
290+
if (!ctx.plugin().exmdb.read_message(dir.c_str(),
291+
username, CP_ACP, newMid, &sendcontent)
292+
|| sendcontent == nullptr)
293+
throw EWSError::ItemNotFound(E3143);
294+
ctx.send(dir, messageId, *sendcontent);
295+
}
259296
if (send)
260297
ctx.send(dir, 0, *content);
261298
msg.success();

exch/ews/serialization.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -647,9 +647,9 @@ tCalendarItem::tCalendarItem(const tinyxml2::XMLElement* xml) :
647647
XMLINIT(IsResponseRequested),
648648
XMLINIT(MyResponseType),
649649
XMLINIT(Organizer),
650-
// XMLINIT(RequiredAttendees),
651-
// XMLINIT(OptionalAttendees),
652-
// XMLINIT(Resources),
650+
XMLINIT(RequiredAttendees),
651+
XMLINIT(OptionalAttendees),
652+
XMLINIT(Resources),
653653
XMLINIT(AppointmentReplyTime),
654654
XMLINIT(AppointmentSequenceNumber),
655655
XMLINIT(AppointmentState),
@@ -1341,6 +1341,14 @@ void tSingleRecipient::serialize(XMLElement* xml) const
13411341
XMLDUMPT(Mailbox);
13421342
}
13431343

1344+
tAttendee::tAttendee(const tinyxml2::XMLElement* xml) :
1345+
XMLINIT(Mailbox),
1346+
XMLINIT(ResponseType),
1347+
XMLINIT(LastResponseTime),
1348+
XMLINIT(ProposedStart),
1349+
XMLINIT(ProposedEnd)
1350+
{}
1351+
13441352
void tAttendee::serialize(XMLElement* xml) const
13451353
{
13461354
XMLDUMPT(Mailbox);

exch/ews/structures.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,7 @@ struct tAttendee : public NS_EWS_Types {
14101410

14111411
tAttendee() = default;
14121412
explicit tAttendee(const TPROPVAL_ARRAY&);
1413+
explicit tAttendee(const tinyxml2::XMLElement*);
14131414
};
14141415

14151416
/**

0 commit comments

Comments
 (0)