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
This commit is contained in:
		
							parent
							
								
									c4f2433300
								
							
						
					
					
						commit
						21a73c52a7
					
				
					 3 changed files with 86 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -114,7 +114,7 @@ class User < ApplicationRecord
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def invited?
 | 
			
		||||
    invite_id.present?
 | 
			
		||||
    invite_id.present? && invite.valid_for_use?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def disable!
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Reference in a new issue