Resolve "Include geographical location of IP address in "sign-in from new location" emails"

  • Please check this box if this contribution uses AI-generated content (including content generated by GitLab Duo features) as outlined in the GitLab DCO & CLA

What does this MR do and why?

To ensure backward compatibility of mailers, mails with location information will only be enabled in a subsequent MR following a two-step release.

What: Adds city and country to the email that is sent when there is a sign in from a new device.
enabled in subsequent MR

Why: Just from the IP address, it is difficult to determine for the user, if an access was legitimate or not.

Country and city information will be taken from request headers set by Cloudflare WAF. So this change only applies to Gitlab.com. See discussion in the issue

MR acceptance checklist

  • Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

Before After
image image

How to set up and validate locally

For testing locally, you have to revert the changes of !163914 (452b84cf) locally. We don't supply location and city as arguments to the newly added parameter to the mailer yet. This is to ensure backward compatibility of mailers.

  1. Go to http://gdk.local:3000/rails/mailers/notify/unknown_sign_in_email.html
  2. Check that Location and ISP information is shown in both html and plain text email

To receive the "sign in from new location" email:

  1. Go to known_sign_in.rb#verify_known_sign_in and comment out the known_remote_ip? part
def verify_known_sign_in
  return unless Gitlab::CurrentSettings.notify_on_unknown_sign_in? && current_user
  notify_user unless known_device? # || known_remote_ip? <-- IP is hard to change
  update_cookie
end
  1. Because the Cloudflare headers will not be present locally, you need to add dummy values by modifying request_info.rb:
def country
  code = request.headers['Cf-Ipcountry'] # 2-letter country code, e.g. "JP" for Japan
  I18nData.countries(I18n.locale)[code] || I18nData.countries[code] || code || "test country" # add dummy value
end

def city
  request.headers['Cf-Ipcity'] || "test city" # add dummy value
end
  1. Open an incognito window to simulate access from a unknown device. Sign in.
  2. Check that the email got delivered at http://gdk.local:3000/rails/letter_opener

Related to #296128 (closed)

Edited by Henry Helm

Merge request reports

Loading