mirror of
https://github.com/discourse/discourse.git
synced 2024-12-01 04:53:51 +08:00
0134e41286
This cleans up an error condition where UI thinks a user is logged on but the user is not. If this happens user will be prompted to refresh.
199 lines
5.5 KiB
Ruby
199 lines
5.5 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe SessionController do
|
|
let(:email_token) { Fabricate(:email_token) }
|
|
let(:user) { email_token.user }
|
|
|
|
describe '#email_login' do
|
|
before do
|
|
SiteSetting.enable_local_logins_via_email = true
|
|
end
|
|
|
|
context 'missing token' do
|
|
it 'returns the right response' do
|
|
get "/session/email-login"
|
|
expect(response.status).to eq(404)
|
|
end
|
|
end
|
|
|
|
context 'invalid token' do
|
|
it 'returns the right response' do
|
|
get "/session/email-login/adasdad"
|
|
|
|
expect(response).to be_success
|
|
|
|
expect(CGI.unescapeHTML(response.body)).to match(
|
|
I18n.t('email_login.invalid_token')
|
|
)
|
|
end
|
|
|
|
context 'when token has expired' do
|
|
it 'should return the right response' do
|
|
email_token.update!(created_at: 999.years.ago)
|
|
|
|
get "/session/email-login/#{email_token.token}"
|
|
|
|
expect(response).to be_success
|
|
|
|
expect(CGI.unescapeHTML(response.body)).to match(
|
|
I18n.t('email_login.invalid_token')
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'valid token' do
|
|
it 'returns success' do
|
|
get "/session/email-login/#{email_token.token}"
|
|
|
|
expect(response).to redirect_to("/")
|
|
end
|
|
|
|
it 'fails when local logins via email is disabled' do
|
|
SiteSetting.enable_local_logins_via_email = false
|
|
|
|
get "/session/email-login/#{email_token.token}"
|
|
|
|
expect(response.status).to eq(404)
|
|
end
|
|
|
|
it 'fails when local logins is disabled' do
|
|
SiteSetting.enable_local_logins = false
|
|
|
|
get "/session/email-login/#{email_token.token}"
|
|
|
|
expect(response.status).to eq(500)
|
|
end
|
|
|
|
it "doesn't log in the user when not approved" do
|
|
SiteSetting.must_approve_users = true
|
|
|
|
get "/session/email-login/#{email_token.token}"
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
expect(CGI.unescapeHTML(response.body)).to include(
|
|
I18n.t("login.not_approved")
|
|
)
|
|
end
|
|
|
|
context "when admin IP address is not valid" do
|
|
before do
|
|
Fabricate(:screened_ip_address,
|
|
ip_address: "111.111.11.11",
|
|
action_type: ScreenedIpAddress.actions[:allow_admin]
|
|
)
|
|
|
|
SiteSetting.use_admin_ip_whitelist = true
|
|
user.update!(admin: true)
|
|
end
|
|
|
|
it 'returns the right response' do
|
|
get "/session/email-login/#{email_token.token}"
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
expect(CGI.unescapeHTML(response.body)).to include(
|
|
I18n.t("login.admin_not_allowed_from_ip_address", username: user.username)
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when IP address is blocked" do
|
|
let(:permitted_ip_address) { '111.234.23.11' }
|
|
|
|
before do
|
|
Fabricate(:screened_ip_address,
|
|
ip_address: permitted_ip_address,
|
|
action_type: ScreenedIpAddress.actions[:block]
|
|
)
|
|
end
|
|
|
|
it 'returns the right response' do
|
|
ActionDispatch::Request.any_instance.stubs(:remote_ip).returns(permitted_ip_address)
|
|
|
|
get "/session/email-login/#{email_token.token}"
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
expect(CGI.unescapeHTML(response.body)).to include(
|
|
I18n.t("login.not_allowed_from_ip_address", username: user.username)
|
|
)
|
|
end
|
|
end
|
|
|
|
it "fails when user is suspended" do
|
|
user.update!(
|
|
suspended_till: 2.days.from_now,
|
|
suspended_at: Time.zone.now
|
|
)
|
|
|
|
get "/session/email-login/#{email_token.token}"
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
expect(CGI.unescapeHTML(response.body)).to include(I18n.t("login.suspended",
|
|
date: I18n.l(user.suspended_till, format: :date_only)
|
|
))
|
|
end
|
|
|
|
context 'user has 2-factor logins' do
|
|
let!(:user_second_factor) { Fabricate(:user_second_factor, user: user) }
|
|
|
|
describe 'requires second factor' do
|
|
it 'should return a second factor prompt' do
|
|
get "/session/email-login/#{email_token.token}"
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
response_body = CGI.unescapeHTML(response.body)
|
|
|
|
expect(response_body).to include(I18n.t(
|
|
"login.second_factor_title"
|
|
))
|
|
|
|
expect(response_body).to_not include(I18n.t(
|
|
"login.invalid_second_factor_code"
|
|
))
|
|
end
|
|
end
|
|
|
|
describe 'errors on incorrect 2-factor' do
|
|
it 'does not log in with incorrect two factor' do
|
|
post "/session/email-login/#{email_token.token}", params: { second_factor_token: "0000" }
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
expect(CGI.unescapeHTML(response.body)).to include(I18n.t(
|
|
"login.invalid_second_factor_code"
|
|
))
|
|
end
|
|
end
|
|
|
|
describe 'allows successful 2-factor' do
|
|
it 'logs in correctly' do
|
|
post "/session/email-login/#{email_token.token}", params: {
|
|
second_factor_token: ROTP::TOTP.new(user_second_factor.data).now
|
|
}
|
|
|
|
expect(response).to redirect_to("/")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'logoff support' do
|
|
it 'can log off users cleanly' do
|
|
user = Fabricate(:user)
|
|
sign_in(user)
|
|
|
|
UserAuthToken.destroy_all
|
|
|
|
# we need a route that will call current user
|
|
post '/draft.json', params: {}
|
|
expect(response.headers['Discourse-Logged-Out']).to eq("1")
|
|
end
|
|
end
|
|
end
|