server icon indicating copy to clipboard operation
server copied to clipboard

Support iMIP invitations from Mail

Open miaulalala opened this issue 3 years ago • 9 comments

Fixes https://github.com/nextcloud/mail/issues/160

To Do:

  • [ ] Write updated or accepted calendar events to CalDAV
  • [ ] Tests

Don't do "Fix CANCEL method for emails that are updated from UI (https://github.com/nextcloud/server/issues/33008) - the STATUS CANCELLED should also lead to an iMIP message with method CANCEL, not reply" as we're using a systemwide email address which could lead to cancellation email addresses not being processed by other mail clients.

Considerations:

  • Extend the CalendarImpl to handle these requests
  • Preconditions as specified in the RFC must be met, and the VEVENT that should be written needs to be compared to the original for both ORGANIZER and ATTENDEE
  • CANCEL requests must be from the right email address and the right organiser or they shouldn't be processed. (but what if we send them from NC from the system email? Will that work? maybe accepting the system email as a secondary email address as specified in the RFC could work.)

miaulalala avatar Jun 23 '22 20:06 miaulalala

I think I know why Georg made this email a REPLY and not a CANCEL. As the email sender is our system internal email address, a correct implementation of iMIP would not process such a message - only a CANCEL directly from the ORGANIZER should be accepted.

I would like to work around this by also allowing such email addresses from the SMTP calendar email address. @ChristophWurst your thoughts?

miaulalala avatar Jun 29 '22 16:06 miaulalala

I would like to work around this by also allowing such email addresses from the SMTP calendar email address. @ChristophWurst your thoughts?

How do you know if the email is a system email?

For cancellations on the same instance we don't need email anyway, scheduling will already remove the attendee event copy when the organizer deletes their original, right?

I think I'm missing something. If the message from an external solution lands in Mail we can't tell if the message was sent from a system account (legit) or a scammer.

ChristophWurst avatar Jun 29 '22 17:06 ChristophWurst

Yeah I was more thinking NC to NC internally.

miaulalala avatar Jun 29 '22 17:06 miaulalala

@st3iny sorry I forgot to tell you: there will be two new endpoints for processing the invitations/responses but you can use them almost the same as the createFromString. I just need a recipient and sender for both to do the security checks as mentioned in the RFC.

miaulalala avatar Jul 01 '22 10:07 miaulalala

CANCEL requests must be from the right email address and the right organiser or they shouldn't be processed. (but what if we send them from NC from the system email? Will that work? maybe accepting the system email as a secondary email address as specified in the RFC could work.)

I don't get when this is an issue. There's no security precautions at this level. For sending, we just use the Reply-To mail header, which matches the organizer, instead of the Sender one. The receiving end (in this case the mail app) should just update their version of the event directly, without sending the iMip message to the server, without knowing if it's indeed from the actual organizer, but the same issue exists with REQUEST as well.

I'm guessing it's related, but I also don't understand the need to have a PHP public API implementation in CalendarImpl.

tcitworld avatar Jul 04 '22 13:07 tcitworld

CANCEL requests must be from the right email address and the right organiser or they shouldn't be processed. (but what if we send them from NC from the system email? Will that work? maybe accepting the system email as a secondary email address as specified in the RFC could work.)

I don't get when this is an issue. There's no security precautions at this level. For sending, we just use the Reply-To mail header, which matches the organizer, instead of the Sender one. The receiving end (in this case the mail app) should just update their version of the event directly, without sending the iMip message to the server, without knowing if it's indeed from the actual organizer, but the same issue exists with REQUEST as well.

This is indeed an Issue when working with iMIP requests and is explicitly mentioned in the RFC as a security consideration.

I'm guessing it's related, but I also don't understand the need to have a PHP public API implementation in CalendarImpl.

Well we don't want private dependecies in other apps but we still want to write to CalDAV...

miaulalala avatar Jul 06 '22 13:07 miaulalala

Well we don't want private dependecies in other apps but we still want to write to CalDAV...

Why not just use CalDAV over HTTP then?

tcitworld avatar Jul 06 '22 13:07 tcitworld

Well we don't want private dependecies in other apps but we still want to write to CalDAV...

Why not just use CalDAV over HTTP then?

Be my guest. You can refactor the Mail app and the appointments any time.

miaulalala avatar Jul 06 '22 13:07 miaulalala

image

F*CK YEAH

miaulalala avatar Jul 19 '22 21:07 miaulalala

Thank you :+1:

Looks good to me. Did a test run with 4 users.

  • Organizer Admin
  • Local guest User2
  • Local guest User3
  • External guest with Gmail account

The invitation is properly sent to all 4 guests. External guest with Gmail account accepted the invitation. Response went to Admin's inbox and IMipService updated the attendance for Admin, User2 and User 3 :partying_face: :partying_face:

Updating the calendar attendance may take a while. On mailbox refresh the message is flagged as imip message and processed by a background job later. We recommend to run the background job every 5 minutes. I understand the technical reasoning yet it's not ideal.

image

image

Thunderbird shows a hint when a message contains an imip reply/cancel and if the data is already processed. I believe that would be a nice enhancement.

Run into the following "bug" while testing this PR. It seems unrelated and should not block it:

image

I accepted the invitation for User2 via Calendar. The vcard is updated properly but the imip processing does not work. Only my (the copy in my personal calendar) is updated. Organizer and other attendees don't see the updated attendance. Looked at it with Xdebug for a second but could not figure it out. The imip logic is executed however it does not emit an imip message. A starting point for further debugging could be the InviteResponseController as it works over there.

kesselb avatar Aug 17 '22 13:08 kesselb

I accepted the invitation for User2 via Calendar. The vcard is updated properly but the imip processing does not work. Only my (the copy in my personal calendar) is updated. Organizer and other attendees don't see the updated attendance. Looked at it with Xdebug for a second but could not figure it out. The imip logic is executed however it does not emit an imip message. A starting point for further debugging could be the InviteResponseController as it works over there.

Sorry I think I "steh auf der Leitung":

So you accepted an Invitation from Admin to User2 via Calendar, and the calendar doesn't distribute the changes to the other Attendees/ Guests?

This sounds like a bug I've seen before... @st3iny how did you implement the Accept/Decline from Calendar? Does that do a PROPPATCH?

miaulalala avatar Aug 18 '22 09:08 miaulalala

This sounds like a bug I've seen before... @st3iny how did you implement the Accept/Decline from Calendar? Does that do a PROPPATCH?

I just set the participation status of the attendee on the local copy and then save the ics again (via PUT). The rest is handled by Sabre and wasn't touched by me.

st3iny avatar Aug 23 '22 07:08 st3iny

This sounds like a bug I've seen before... @st3iny how did you implement the Accept/Decline from Calendar? Does that do a PROPPATCH?

I just set the participation status of the attendee on the local copy and then save the ics again (via PUT). The rest is handled by Sabre and wasn't touched by me.

It was the plus sign in Daniel's test email that makes it break :detective:

miaulalala avatar Aug 23 '22 08:08 miaulalala