From 1cf2c3a810bba937c7702c342a3ff37c3d37391a Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 22 Dec 2020 17:14:32 +0100 Subject: [PATCH] Fix external user creation failing when invite request text is required (#15405) * Fix external user creation failing when invite request text is required Also fixes tootctl-based user creation. * Add test about invites when invite request text is otherwise required Co-authored-by: Claire --- app/models/user.rb | 12 ++++++++++-- lib/mastodon/accounts_cli.rb | 2 +- lib/tasks/mastodon.rake | 2 +- .../auth/registrations_controller_spec.rb | 5 ++++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index dd96bbf8ce..f8c8a6ab55 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -83,7 +83,7 @@ class User < ApplicationRecord has_one :invite_request, class_name: 'UserInviteRequest', inverse_of: :user, dependent: :destroy accepts_nested_attributes_for :invite_request, reject_if: ->(attributes) { attributes['text'].blank? && !Setting.require_invite_text } - validates :invite_request, presence: true, on: :create, if: -> { Setting.require_invite_text && !invited? } + validates :invite_request, presence: true, on: :create, if: :invite_text_required? validates :locale, inclusion: I18n.available_locales.map(&:to_s), if: :locale? validates_with BlacklistedEmailValidator, on: :create @@ -128,7 +128,7 @@ class User < ApplicationRecord to: :settings, prefix: :setting, allow_nil: false attr_reader :invite_code, :sign_in_token_attempt - attr_writer :external + attr_writer :external, :bypass_invite_request_check def confirmed? confirmed_at.present? @@ -429,6 +429,10 @@ class User < ApplicationRecord !!@external end + def bypass_invite_request_check? + @bypass_invite_request_check + end + def sanitize_languages return if chosen_languages.nil? chosen_languages.reject!(&:blank?) @@ -466,4 +470,8 @@ class User < ApplicationRecord def validate_email_dns? email_changed? && !(Rails.env.test? || Rails.env.development?) end + + def invite_text_required? + Setting.require_invite_text && !invited? && !external? && !bypass_invite_request_check? + end end diff --git a/lib/mastodon/accounts_cli.rb b/lib/mastodon/accounts_cli.rb index 5275f04cf6..cdd1db9954 100644 --- a/lib/mastodon/accounts_cli.rb +++ b/lib/mastodon/accounts_cli.rb @@ -77,7 +77,7 @@ module Mastodon def create(username) account = Account.new(username: username) password = SecureRandom.hex - user = User.new(email: options[:email], password: password, agreement: true, approved: true, admin: options[:role] == 'admin', moderator: options[:role] == 'moderator', confirmed_at: options[:confirmed] ? Time.now.utc : nil) + user = User.new(email: options[:email], password: password, agreement: true, approved: true, admin: options[:role] == 'admin', moderator: options[:role] == 'moderator', confirmed_at: options[:confirmed] ? Time.now.utc : nil, bypass_invite_request_check: true) if options[:reattach] account = Account.find_local(username) || Account.new(username: username) diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake index 9e80989ef0..2ad1e778ba 100644 --- a/lib/tasks/mastodon.rake +++ b/lib/tasks/mastodon.rake @@ -412,7 +412,7 @@ namespace :mastodon do password = SecureRandom.hex(16) - user = User.new(admin: true, email: email, password: password, confirmed_at: Time.now.utc, account_attributes: { username: username }) + user = User.new(admin: true, email: email, password: password, confirmed_at: Time.now.utc, account_attributes: { username: username }, bypass_invite_request_check: true) user.save(validate: false) prompt.ok "You can login with the password: #{password}" diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb index c701a3b8bc..ccf304a930 100644 --- a/spec/controllers/auth/registrations_controller_spec.rb +++ b/spec/controllers/auth/registrations_controller_spec.rb @@ -195,16 +195,19 @@ RSpec.describe Auth::RegistrationsController, type: :controller do end end - context 'approval-based registrations with valid invite' do + context 'approval-based registrations with valid invite and required invite text' do around do |example| registrations_mode = Setting.registrations_mode + require_invite_text = Setting.require_invite_text example.run + Setting.require_invite_text = require_invite_text Setting.registrations_mode = registrations_mode end subject do inviter = Fabricate(:user, confirmed_at: 2.days.ago) Setting.registrations_mode = 'approved' + Setting.require_invite_text = true request.headers["Accept-Language"] = accept_language invite = Fabricate(:invite, user: inviter, 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, agreement: 'true' } }