Send a rejection email if incoming emails are too large
What does this MR do and why?
For gitlab-com/gl-infra/scalability#1488 (closed)
In !76724 (merged), we implemented an internal endpoint listening to MailRoom component's webhooks. The webhook requests attach the raw email content in their body. If an email contains a file attachment, the raw encoded email content may be too heavy. As a result, the endpoint refuses to process the email, and returns 400 status code. At the moment, those requests are faded into void without the senders' awareness. This MR is to send a rejection email notifying the senders about this situation.
The solution is simple. The limit exceed exception is caught inside the endpoint. When so, EmailRejectionMailer is triggered. As the failure handler is now inside EmailReceiverWorker, this MR also extracts those logic to Gitlab::Email::FailureHandler
so that it can be re-used in the new endpoint.
Screenshots or screen recordings
This is the responding email when an email is too heavy.
How to set up and validate locally
- Set the background job limit to a reasonable number for testing purpose. A recommended number is 4000 (bytes) compressing threshold and 5000 (bytes) limit.
- Point the mail_room gem
0.0.17
(https://gitlab.com/gitlab-org/gitlab-mail_room/-/merge_requests/45#note_797929096) - Create a temporary secret file.
echo "eao1Q7WZpH41L3tPdr0+NbUC6h8nHcQ9XE78mHxs5+A=" > /path/to/gdk/gitlab_mailroom_secret
- Add
secret_file
fields toincoming_email
andservice_desk_email
configurations inconfig/gitlab.yml
file. Setenabled
of both to true
incoming_email:
enabled: true
secret_file: /path/to/gdk/gitlab_mailroom_secret
service_desk_email:
enabled: true
secret_file: /path/to/gdk/gitlab_mailroom_secrett
- Start rails-web and rails-background-jobs
- Paste the following script to f console. The script snippet is to add a command and close the latest issue. This script uses the new webhook delivery method in the gem, fires a POST request of the new endpoint.
require 'mail_room/delivery/postback'
incoming_email = Gitlab.config.incoming_email[:address].gsub('%{key}', SentNotification.where(noteable_type: "Issue").last.reply_key)
content = File.read("spec/fixtures/emails/commands_in_reply.eml") + "\n\n" + SecureRandom.hex(5000)
content.gsub!("reply+59d8df8370b7e95c5a49fbf86aeb2c93@appmail.adventuretime.ooo", incoming_email)
::MailRoom::Delivery::Postback.new(MailRoom::Delivery::Postback::Options.new(MailRoom::Mailbox.new(
name: "inbox",
email: "user@example.com",
password: "password123",
delivery_options: {
delivery_url: 'http://localhost:3000/api/v4/internal/mail_room/incoming_email',
jwt_auth_header: "Gitlab-Mailroom-Api-Request",
jwt_issuer: "gitlab-mailroom",
jwt_algorithm: "HS256",
jwt_secret_path: Gitlab::MailRoom.enabled_configs[:incoming_email][:secret_file]
}
))).deliver(content)
- Ensure that email_receiver queue is drained (http://localhost:3000/admin/sidekiq/queues/email_receiver)
- Open letter_opener dashboard, you'll see the rejection email:
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.