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.
101 lines
3.3 KiB
Ruby
101 lines
3.3 KiB
Ruby
require 'test_helper'
|
|
|
|
class SessionsControllerTest < ActionDispatch::IntegrationTest
|
|
context "the sessions controller" do
|
|
setup do
|
|
@user = create(:user, password: "password")
|
|
end
|
|
|
|
context "new action" do
|
|
should "render" do
|
|
get new_session_path
|
|
assert_response :success
|
|
end
|
|
end
|
|
|
|
context "create action" do
|
|
should "log the user in when given the correct password" do
|
|
post session_path, params: { name: @user.name, password: "password" }
|
|
|
|
assert_redirected_to posts_path
|
|
assert_equal(@user.id, session[:user_id])
|
|
assert_not_nil(@user.reload.last_ip_addr)
|
|
assert_equal(true, @user.user_events.login.exists?)
|
|
end
|
|
|
|
should "not log the user in when given an incorrect password" do
|
|
post session_path, params: { name: @user.name, password: "wrong"}
|
|
|
|
assert_response 401
|
|
assert_nil(nil, session[:user_id])
|
|
assert_equal(true, @user.user_events.failed_login.exists?)
|
|
end
|
|
|
|
should "not log the user in when given an incorrect username" do
|
|
post session_path, params: { name: "dne", password: "password" }
|
|
|
|
assert_response 401
|
|
assert_nil(nil, session[:user_id])
|
|
end
|
|
|
|
should "redirect the user when given an url param" do
|
|
post session_path, params: { name: @user.name, password: "password", url: tags_path }
|
|
assert_redirected_to tags_path
|
|
end
|
|
|
|
should "not allow IP banned users to login" do
|
|
@ip_ban = create(:ip_ban, category: :full, ip_addr: "1.2.3.4")
|
|
post session_path, params: { name: @user.name, password: "password" }, headers: { REMOTE_ADDR: "1.2.3.4" }
|
|
|
|
assert_response 403
|
|
assert_not_equal(@user.id, session[:user_id])
|
|
assert_equal(1, @ip_ban.reload.hit_count)
|
|
assert(@ip_ban.last_hit_at > 1.minute.ago)
|
|
end
|
|
|
|
should "allow partial IP banned users to login" do
|
|
@ip_ban = create(:ip_ban, category: :partial, ip_addr: "1.2.3.4")
|
|
post session_path, params: { name: @user.name, password: "password" }, headers: { REMOTE_ADDR: "1.2.3.4" }
|
|
|
|
assert_redirected_to posts_path
|
|
assert_equal(@user.id, session[:user_id])
|
|
assert_equal(0, @ip_ban.reload.hit_count)
|
|
assert_nil(@ip_ban.last_hit_at)
|
|
end
|
|
|
|
should "ignore deleted IP bans when logging in" do
|
|
@ip_ban = create(:ip_ban, is_deleted: true, category: :full, ip_addr: "1.2.3.4")
|
|
post session_path, params: { name: @user.name, password: "password" }, headers: { REMOTE_ADDR: "1.2.3.4" }
|
|
|
|
assert_redirected_to posts_path
|
|
assert_equal(@user.id, session[:user_id])
|
|
assert_equal(0, @ip_ban.reload.hit_count)
|
|
assert_nil(@ip_ban.last_hit_at)
|
|
end
|
|
end
|
|
|
|
context "destroy action" do
|
|
setup do
|
|
delete_auth session_path, @user
|
|
end
|
|
|
|
should "clear the session" do
|
|
assert_redirected_to posts_path
|
|
assert_nil(session[:user_id])
|
|
end
|
|
|
|
should "generate a logout event" do
|
|
assert_equal(true, @user.user_events.logout.exists?)
|
|
end
|
|
end
|
|
|
|
context "sign_out action" do
|
|
should "clear the session" do
|
|
get_auth sign_out_session_path, @user
|
|
assert_redirected_to posts_path
|
|
assert_nil(session[:user_id])
|
|
end
|
|
end
|
|
end
|
|
end
|