From 21a73c52a7d0d0149e1058aeec155fe1c87aaeff Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 2 May 2019 04:30:12 +0200 Subject: [PATCH] Check that an invite link is valid before bypassing approval mode (#10657) * Check that an invite link is valid before bypassing approval mode Fixes #10656 * Add tests * Only consider valid invite links in registration controller * fixup --- .../auth/registrations_controller.rb | 3 +- app/models/user.rb | 2 +- .../auth/registrations_controller_spec.rb | 83 +++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index 5c1ff769a8..83797cf1f7 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -91,7 +91,8 @@ class Auth::RegistrationsController < Devise::RegistrationsController end def set_invite - @invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil + invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil + @invite = invite&.valid_for_use? ? invite : nil end def determine_layout diff --git a/app/models/user.rb b/app/models/user.rb index c42f6ad8d8..4320786518 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -114,7 +114,7 @@ class User < ApplicationRecord end def invited? - invite_id.present? + invite_id.present? && invite.valid_for_use? end def disable! diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb index 1095df034e..a4337039e1 100644 --- a/spec/controllers/auth/registrations_controller_spec.rb +++ b/spec/controllers/auth/registrations_controller_spec.rb @@ -107,6 +107,89 @@ RSpec.describe Auth::RegistrationsController, type: :controller do end end + context 'approval-based registrations without invite' do + around do |example| + registrations_mode = Setting.registrations_mode + example.run + Setting.registrations_mode = registrations_mode + end + + subject do + Setting.registrations_mode = 'approved' + request.headers["Accept-Language"] = accept_language + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678' } } + end + + it 'redirects to login page' do + subject + expect(response).to redirect_to new_user_session_path + end + + it 'creates user' do + subject + user = User.find_by(email: 'test@example.com') + expect(user).to_not be_nil + expect(user.locale).to eq(accept_language) + expect(user.approved).to eq(false) + end + end + + context 'approval-based registrations with expired invite' do + around do |example| + registrations_mode = Setting.registrations_mode + example.run + Setting.registrations_mode = registrations_mode + end + + subject do + Setting.registrations_mode = 'approved' + request.headers["Accept-Language"] = accept_language + invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.ago) + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code } } + end + + it 'redirects to login page' do + subject + expect(response).to redirect_to new_user_session_path + end + + it 'creates user' do + subject + user = User.find_by(email: 'test@example.com') + expect(user).to_not be_nil + expect(user.locale).to eq(accept_language) + expect(user.approved).to eq(false) + end + end + + context 'approval-based registrations with valid invite' do + around do |example| + registrations_mode = Setting.registrations_mode + example.run + Setting.registrations_mode = registrations_mode + end + + subject do + Setting.registrations_mode = 'approved' + request.headers["Accept-Language"] = accept_language + invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.from_now) + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code } } + end + + it 'redirects to login page' do + subject + expect(response).to redirect_to new_user_session_path + end + + it 'creates user' do + subject + user = User.find_by(email: 'test@example.com') + expect(user).to_not be_nil + expect(user.locale).to eq(accept_language) + expect(user.approved).to eq(true) + end + end + it 'does nothing if user already exists' do Fabricate(:user, account: Fabricate(:account, username: 'test')) subject