2
0

Fix tootctl admin create not bypassing reserved username checks (#35779)

This commit is contained in:
Claire
2025-08-14 15:35:19 +02:00
parent 7a862d3308
commit ea5d1f0297
3 changed files with 13 additions and 8 deletions

View File

@@ -116,7 +116,7 @@ class Account < ApplicationRecord
# Local user validations # Local user validations
validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: USERNAME_LENGTH_LIMIT }, if: -> { local? && will_save_change_to_username? && !actor_type_application? } validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: USERNAME_LENGTH_LIMIT }, if: -> { local? && will_save_change_to_username? && !actor_type_application? }
validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? && !actor_type_application? } validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? && !actor_type_application? && !user&.bypass_registration_checks }
validates :display_name, length: { maximum: DISPLAY_NAME_LENGTH_LIMIT }, if: -> { local? && will_save_change_to_display_name? } validates :display_name, length: { maximum: DISPLAY_NAME_LENGTH_LIMIT }, if: -> { local? && will_save_change_to_display_name? }
validates :note, note_length: { maximum: NOTE_LENGTH_LIMIT }, if: -> { local? && will_save_change_to_note? } validates :note, note_length: { maximum: NOTE_LENGTH_LIMIT }, if: -> { local? && will_save_change_to_note? }
validates :fields, length: { maximum: DEFAULT_FIELDS_SIZE }, if: -> { local? && will_save_change_to_fields? } validates :fields, length: { maximum: DEFAULT_FIELDS_SIZE }, if: -> { local? && will_save_change_to_fields? }

View File

@@ -142,7 +142,9 @@ class User < ApplicationRecord
delegate :can?, to: :role delegate :can?, to: :role
attr_reader :invite_code, :date_of_birth attr_reader :invite_code, :date_of_birth
attr_writer :external, :bypass_registration_checks, :current_account attr_writer :external, :current_account
attribute :bypass_registration_checks, :boolean, default: false
def self.those_who_can(*any_of_privileges) def self.those_who_can(*any_of_privileges)
matching_role_ids = UserRole.that_can(*any_of_privileges).map(&:id) matching_role_ids = UserRole.that_can(*any_of_privileges).map(&:id)
@@ -505,10 +507,6 @@ class User < ApplicationRecord
!!@external !!@external
end end
def bypass_registration_checks?
@bypass_registration_checks
end
def sanitize_role def sanitize_role
self.role = nil if role.present? && role.everyone? self.role = nil if role.present? && role.everyone?
end end

View File

@@ -32,6 +32,7 @@ RSpec.describe Mastodon::CLI::Accounts do
describe '#create' do describe '#create' do
let(:action) { :create } let(:action) { :create }
let(:username) { 'tootctl_username' }
shared_examples 'a new user with given email address and username' do shared_examples 'a new user with given email address and username' do
it 'creates user and accounts from options and displays success message' do it 'creates user and accounts from options and displays success message' do
@@ -48,18 +49,24 @@ RSpec.describe Mastodon::CLI::Accounts do
end end
def account_from_options def account_from_options
Account.find_local('tootctl_username') Account.find_local(username)
end end
end end
context 'when required USERNAME and --email are provided' do context 'when required USERNAME and --email are provided' do
let(:arguments) { ['tootctl_username'] } let(:arguments) { [username] }
context 'with USERNAME and --email only' do context 'with USERNAME and --email only' do
let(:options) { { email: 'tootctl@example.com' } } let(:options) { { email: 'tootctl@example.com' } }
it_behaves_like 'a new user with given email address and username' it_behaves_like 'a new user with given email address and username'
context 'with a reserved username' do
let(:username) { 'security' }
it_behaves_like 'a new user with given email address and username'
end
context 'with invalid --email value' do context 'with invalid --email value' do
let(:options) { { email: 'invalid' } } let(:options) { { email: 'invalid' } }