From c01f13d04a1c8cab1a4173629fa2acfcd867c786 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 10 Nov 2023 11:38:09 +0100 Subject: [PATCH] Add `invite_code` to `POST /api/v1/accounts` --- app/controllers/api/v1/accounts_controller.rb | 8 ++- app/services/app_sign_up_service.rb | 8 ++- spec/services/app_sign_up_service_spec.rb | 50 ++++++++++++++----- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index a6e3a26cd7c..653529316fb 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -92,10 +92,14 @@ class Api::V1::AccountsController < Api::BaseController end def account_params - params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone) + params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone, :invite_code) + end + + def invite + Invite.find_by(code: params[:invite_code]) if params[:invite_code].present? end def check_enabled_registrations - forbidden unless allowed_registration?(request.remote_ip, nil) + forbidden unless allowed_registration?(request.remote_ip, invite) end end diff --git a/app/services/app_sign_up_service.rb b/app/services/app_sign_up_service.rb index a6076bd8f71..76658801157 100644 --- a/app/services/app_sign_up_service.rb +++ b/app/services/app_sign_up_service.rb @@ -8,7 +8,7 @@ class AppSignUpService < BaseService @remote_ip = remote_ip @params = params - raise Mastodon::NotPermittedError unless allowed_registration?(remote_ip, nil) + raise Mastodon::NotPermittedError unless allowed_registration?(remote_ip, invite) ApplicationRecord.transaction do create_user! @@ -36,8 +36,12 @@ class AppSignUpService < BaseService ) end + def invite + Invite.find_by(code: @params[:invite_code]) if @params[:invite_code].present? + end + def user_params - @params.slice(:email, :password, :agreement, :locale, :time_zone) + @params.slice(:email, :password, :agreement, :locale, :time_zone, :invite_code) end def account_params diff --git a/spec/services/app_sign_up_service_spec.rb b/spec/services/app_sign_up_service_spec.rb index 2af4e5cc68e..d5946cf9b02 100644 --- a/spec/services/app_sign_up_service_spec.rb +++ b/spec/services/app_sign_up_service_spec.rb @@ -10,6 +10,23 @@ RSpec.describe AppSignUpService, type: :service do let(:remote_ip) { IPAddr.new('198.0.2.1') } describe '#call' do + let(:params) { good_params } + + shared_examples 'successful registration' do + it 'creates an unconfirmed user with access token and the app\'s scope', :aggregate_failures do + access_token = subject.call(app, remote_ip, params) + expect(access_token).to_not be_nil + expect(access_token.scopes.to_s).to eq 'read write' + + user = User.find_by(id: access_token.resource_owner_id) + expect(user).to_not be_nil + expect(user.confirmed?).to be false + + expect(user.account).to_not be_nil + expect(user.invite_request).to be_nil + end + end + context 'when registrations are closed' do around do |example| tmp = Setting.registrations_mode @@ -23,24 +40,33 @@ RSpec.describe AppSignUpService, type: :service do it 'raises an error', :aggregate_failures do expect { subject.call(app, remote_ip, good_params) }.to raise_error Mastodon::NotPermittedError end + + context 'when using a valid invite' do + let(:params) { good_params.merge({ invite_code: invite.code }) } + let(:invite) { Fabricate(:invite) } + + before do + invite.user.approve! + end + + it_behaves_like 'successful registration' + end + + context 'when using an invalid invite' do + let(:params) { good_params.merge({ invite_code: invite.code }) } + let(:invite) { Fabricate(:invite, uses: 1, max_uses: 1) } + + it 'raises an error', :aggregate_failures do + expect { subject.call(app, remote_ip, params) }.to raise_error Mastodon::NotPermittedError + end + end end it 'raises an error when params are missing' do expect { subject.call(app, remote_ip, {}) }.to raise_error ActiveRecord::RecordInvalid end - it 'creates an unconfirmed user with access token and the app\'s scope', :aggregate_failures do - access_token = subject.call(app, remote_ip, good_params) - expect(access_token).to_not be_nil - expect(access_token.scopes.to_s).to eq 'read write' - - user = User.find_by(id: access_token.resource_owner_id) - expect(user).to_not be_nil - expect(user.confirmed?).to be false - - expect(user.account).to_not be_nil - expect(user.invite_request).to be_nil - end + it_behaves_like 'successful registration' context 'when given an invite request text' do it 'creates an account with invite request text' do