Files
danbooru/test/functional/emails_controller_test.rb
evazion 65adcd09c2 users: track logins, signups, and other user events.
Add tracking of certain important user actions. These events include:

* Logins
* Logouts
* Failed login attempts
* Account creations
* Account deletions
* Password reset requests
* Password changes
* Email address changes

This is similar to the mod actions log, except for account activity
related to a single user.

The information tracked includes the user, the event type (login,
logout, etc), the timestamp, the user's IP address, IP geolocation
information, the user's browser user agent, and the user's session ID
from their session cookie. This information is visible to mods only.

This is done with three models. The UserEvent model tracks the event
type (login, logout, password change, etc) and the user. The UserEvent
is tied to a UserSession, which contains the user's IP address and
browser metadata. Finally, the IpGeolocation model contains the
geolocation information for IPs, including the city, country, ISP, and
whether the IP is a proxy.

This tracking will be used for a few purposes:

* Letting users view their account history, to detect things like logins
  from unrecognized IPs, failed logins attempts, password changes, etc.
* Rate limiting failed login attempts.
* Detecting sockpuppet accounts using their login history.
* Detecting unauthorized account sharing.
2021-01-08 22:34:37 -06:00

230 lines
8.1 KiB
Ruby

require "test_helper"
class EmailsControllerTest < ActionDispatch::IntegrationTest
include UsersHelper
context "in all cases" do
setup do
@user = create(:user, email_address: build(:email_address, { address: "bob@ogres.net", is_verified: false }))
@other_user = create(:user, email_address: build(:email_address, { address: "alice@ogres.net", is_verified: false }))
@restricted_user = create(:restricted_user, email_address: build(:email_address, { is_verified: false }))
end
context "#index" do
should "not let regular users see emails belonging to other users" do
get_auth emails_path, @user
assert_response 403
end
should "let mods see emails belonging to themselves and all users below mod level" do
@mod1 = create(:moderator_user, email_address: build(:email_address))
@mod2 = create(:moderator_user, email_address: build(:email_address))
get_auth emails_path, @mod1
assert_response :success
assert_select "#email-address-#{@user.email_address.id}", count: 1
assert_select "#email-address-#{@other_user.email_address.id}", count: 1
assert_select "#email-address-#{@mod1.email_address.id}", count: 1
assert_select "#email-address-#{@mod2.email_address.id}", count: 0
end
end
context "#show" do
should "render" do
get_auth user_email_path(@user), @user, as: :json
assert_response :success
end
should "not show email addresses to other users" do
get_auth user_email_path(@user), @other_user, as: :json
assert_response 403
end
end
context "#edit" do
context "for a user with an email address" do
should "render" do
get_auth edit_user_email_path(@user), @user
assert_equal true, @user.email_address.present?
assert_response :success
end
end
context "for a user without an email address" do
should "render" do
@user.email_address.destroy!
@user.reload_email_address
get_auth edit_user_email_path(@user), @user
assert_equal false, @user.email_address.present?
assert_response :success
assert_select "h1", text: "Add Email"
end
end
context "for a restricted user" do
should "render" do
get_auth edit_user_email_path(@restricted_user), @restricted_user
assert_response :success
end
end
context "for an unauthorized user" do
should "render" do
get_auth edit_user_email_path(@user), @other_user
assert_response 403
end
end
end
context "#update" do
context "with the correct password" do
should "update an existing address" do
assert_difference("EmailAddress.count", 0) do
put_auth user_email_path(@user), @user, params: { user: { password: "password", email: "abc@ogres.net" }}
end
assert_redirected_to(settings_path)
assert_equal("abc@ogres.net", @user.reload.email_address.address)
assert_equal(false, @user.email_address.is_verified)
assert_enqueued_email_with UserMailer, :email_change_confirmation, args: [@user], queue: "default"
assert_equal(true, @user.user_events.email_change.exists?)
end
should "create a new address" do
@user.email_address.destroy
assert_difference("EmailAddress.count", 1) do
put_auth user_email_path(@user), @user, params: { user: { password: "password", email: "abc@ogres.net" }}
end
assert_redirected_to(settings_path)
assert_equal("abc@ogres.net", @user.reload.email_address.address)
assert_equal(false, @user.reload.email_address.is_verified)
assert_enqueued_email_with UserMailer, :email_change_confirmation, args: [@user], queue: "default"
assert_equal(true, @user.user_events.email_change.exists?)
end
end
context "with the incorrect password" do
should "not work" do
put_auth user_email_path(@user), @user, params: { user: { password: "passwordx", email: "abc@ogres.net" }}
assert_response :success
assert_equal("bob@ogres.net", @user.reload.email_address.address)
assert_no_emails
assert_equal(false, @user.user_events.email_change.exists?)
end
end
end
context "#verify" do
context "with a correct verification key" do
should "mark the email address as verified" do
assert_equal(false, @user.reload.email_address.is_verified)
get email_verification_url(@user)
assert_redirected_to @user
assert_equal(true, @user.reload.email_address.is_verified)
end
end
context "with an incorrect verification key" do
should "not mark the email address as verified" do
get verify_user_email_path(@user, email_verification_key: @other_user.email_address.verification_key)
assert_response 403
assert_equal(false, @user.reload.email_address.is_verified)
end
end
context "for a Restricted user" do
context "with a nondisposable email address" do
should "unrestrict the user's account" do
Danbooru.config.stubs(:email_domain_verification_list).returns(["gmail.com"])
@restricted_user.email_address.update!(address: "test@gmail.com")
get email_verification_url(@restricted_user)
assert_redirected_to @restricted_user
assert_equal(true, @restricted_user.reload.email_address.is_verified)
assert_equal(false, @restricted_user.is_restricted?)
assert_equal(true, @restricted_user.is_member?)
end
end
context "with a disposable email address" do
should "leave the user's account restricted" do
Danbooru.config.stubs(:email_domain_verification_list).returns(["gmail.com"])
@restricted_user.email_address.update!(address: "test@mailinator.com")
get email_verification_url(@restricted_user)
assert_redirected_to @restricted_user
assert_equal(true, @restricted_user.reload.email_address.is_verified)
assert_equal(true, @restricted_user.is_restricted?)
assert_equal(false, @restricted_user.is_member?)
end
end
end
context "for a Gold user" do
should "not change the user's level" do
@user = create(:gold_user, email_address: build(:email_address, { address: "test@gmail.com", is_verified: false }))
Danbooru.config.stubs(:email_domain_verification_list).returns(["gmail.com"])
get email_verification_url(@user)
assert_redirected_to @user
assert_equal(true, @user.reload.email_address.is_verified)
assert_equal(false, @user.is_restricted?)
assert_equal(true, @user.is_gold?)
end
end
context "for a user without an email address" do
should "redirect to the add email page" do
@user.email_address.destroy!
get_auth verify_user_email_path(@user), @user
assert_redirected_to edit_user_email_path(@user)
end
end
context "for a user with an unverified email address" do
should "show the resend confirmation email page" do
get_auth verify_user_email_path(@user), @user
assert_response :success
end
end
context "for an unauthorized user" do
should "fail" do
get_auth verify_user_email_path(@user), @other_user
assert_response 403
end
end
end
context "#send_confirmation" do
context "for an authorized user" do
should "resend the confirmation email" do
post_auth send_confirmation_user_email_path(@user), @user
assert_redirected_to @user
assert_enqueued_emails 1
end
end
context "for an unauthorized user" do
should "fail" do
post_auth send_confirmation_user_email_path(@user), @other_user
assert_response 403
assert_no_enqueued_emails
end
end
end
end
end