* Add: #348 新規登録の上限人数 * Fix test * Fix test * Wip * Fix test * Add invite support * Wip * Fix test * Fix test * Fix test
This commit is contained in:
parent
d7cc6b788c
commit
e317edecb8
26 changed files with 362 additions and 6 deletions
|
@ -1,9 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::Settings::RegistrationsController < Admin::SettingsController
|
||||
include RegistrationLimitationHelper
|
||||
|
||||
before_action :set_limitation_counts, only: :show # rubocop:disable Rails/LexicallyScopedActionFilter
|
||||
|
||||
private
|
||||
|
||||
def after_update_redirect_path
|
||||
admin_settings_registrations_path
|
||||
end
|
||||
|
||||
def set_limitation_counts
|
||||
@current_users_count = user_count_for_registration
|
||||
@current_users_count_today = today_increase_user_count
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||
include Auth::CaptchaConcern
|
||||
include RegistrationLimitationHelper
|
||||
|
||||
layout 'auth'
|
||||
|
||||
|
@ -16,6 +17,11 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
|
|||
skip_before_action :require_functional!
|
||||
|
||||
def show
|
||||
if reach_registrations_limit?
|
||||
render :limitation_error
|
||||
return
|
||||
end
|
||||
|
||||
old_session_values = session.to_hash
|
||||
reset_session
|
||||
session.update old_session_values.except('session_id')
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
module RegistrationHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
include RegistrationLimitationHelper
|
||||
|
||||
def allowed_registration?(remote_ip, invite)
|
||||
!Rails.configuration.x.single_user_mode && !omniauth_only? && (registrations_open? || invite&.valid_for_use?) && !ip_blocked?(remote_ip)
|
||||
!Rails.configuration.x.single_user_mode && !omniauth_only? && ((registrations_open? && !reach_registrations_limit?) || invite&.valid_for_use?) && !ip_blocked?(remote_ip)
|
||||
end
|
||||
|
||||
def registrations_open?
|
||||
|
|
55
app/helpers/registration_limitation_helper.rb
Normal file
55
app/helpers/registration_limitation_helper.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module RegistrationLimitationHelper
|
||||
def reach_registrations_limit?
|
||||
return true unless registrations_in_time?
|
||||
|
||||
((Setting.registrations_limit.presence || 0).positive? && Setting.registrations_limit <= user_count_for_registration) ||
|
||||
((Setting.registrations_limit_per_day.presence || 0).positive? && Setting.registrations_limit_per_day <= today_increase_user_count)
|
||||
end
|
||||
|
||||
def user_count_for_registration
|
||||
Rails.cache.fetch('registrations:user_count') { User.confirmed.enabled.joins(:account).merge(Account.without_suspended).count }
|
||||
end
|
||||
|
||||
def today_increase_user_count
|
||||
today_date = Time.now.utc.beginning_of_day.to_i
|
||||
count = 0
|
||||
|
||||
if Rails.cache.fetch('registrations:today_date') { today_date } == today_date
|
||||
count = Rails.cache.fetch('registrations:today_increase_user_count') { today_increase_user_count_value }
|
||||
else
|
||||
count = today_increase_user_count_value
|
||||
Rails.cache.write('registrations:today_date', today_date)
|
||||
Rails.cache.write('registrations:today_increase_user_count', count)
|
||||
end
|
||||
|
||||
count
|
||||
end
|
||||
|
||||
def today_increase_user_count_value
|
||||
User.confirmed.enabled.where('users.created_at >= ?', Time.now.utc.beginning_of_day).joins(:account).merge(Account.without_suspended).count
|
||||
end
|
||||
|
||||
def registrations_in_time?
|
||||
start_hour = Setting.registrations_start_hour || 0
|
||||
end_hour = Setting.registrations_end_hour || 24
|
||||
secondary_start_hour = Setting.registrations_secondary_start_hour || 0
|
||||
secondary_end_hour = Setting.registrations_secondary_end_hour || 0
|
||||
|
||||
return true if start_hour >= end_hour && secondary_start_hour >= secondary_end_hour
|
||||
|
||||
current_hour = Time.now.utc.hour
|
||||
primary_permitted = false
|
||||
primary_permitted = start_hour <= current_hour && current_hour < end_hour if start_hour < end_hour && end_hour.positive?
|
||||
secondary_permitted = false
|
||||
secondary_permitted = secondary_start_hour <= current_hour && current_hour < secondary_end_hour if secondary_start_hour < secondary_end_hour && secondary_end_hour.positive?
|
||||
|
||||
primary_permitted || secondary_permitted
|
||||
end
|
||||
|
||||
def reset_registration_limit_caches!
|
||||
Rails.cache.delete('registrations:user_count')
|
||||
Rails.cache.delete('registrations:today_increase_user_count')
|
||||
end
|
||||
end
|
|
@ -4,7 +4,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
|||
import { connect } from 'react-redux';
|
||||
|
||||
import { fetchServer } from 'mastodon/actions/server';
|
||||
import { domain } from 'mastodon/initial_state';
|
||||
import { domain, registrationsReachLimit } from 'mastodon/initial_state';
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
message: state.getIn(['server', 'server', 'registrations', 'message']),
|
||||
|
@ -27,6 +27,16 @@ class ClosedRegistrationsModal extends ImmutablePureComponent {
|
|||
dangerouslySetInnerHTML={{ __html: this.props.message }}
|
||||
/>
|
||||
);
|
||||
} else if (registrationsReachLimit) {
|
||||
closedRegistrationsMessage = (
|
||||
<p className='prose'>
|
||||
<FormattedMessage
|
||||
id='closed_registrations_modal.description_when_reaching_limit'
|
||||
defaultMessage='New registrations are currently temporarily restricted. Either the maximum number of registrations has been reached or it is outside the time frame available for registration. Please contact the administrator for more information or wait until the restriction is lifted.'
|
||||
values={{ domain: <strong>{domain}</strong> }}
|
||||
/>
|
||||
</p>
|
||||
);
|
||||
} else {
|
||||
closedRegistrationsMessage = (
|
||||
<p className='prose'>
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
* @property {string=} owner
|
||||
* @property {boolean} profile_directory
|
||||
* @property {boolean} registrations_open
|
||||
* @property {boolean} registrations_reach_limit
|
||||
* @property {boolean} reduce_motion
|
||||
* @property {string} repository
|
||||
* @property {boolean} search_enabled
|
||||
|
@ -134,6 +135,7 @@ export const owner = getMeta('owner');
|
|||
export const profile_directory = getMeta('profile_directory');
|
||||
export const reduceMotion = getMeta('reduce_motion');
|
||||
export const registrationsOpen = getMeta('registrations_open');
|
||||
export const registrationsReachLimit = getMeta('registrations_reach_limit');
|
||||
export const repository = getMeta('repository');
|
||||
export const searchEnabled = getMeta('search_enabled');
|
||||
export const trendsEnabled = getMeta('trends_enabled');
|
||||
|
|
|
@ -113,6 +113,7 @@
|
|||
"circles.edit": "Edit circle",
|
||||
"closed_registrations.other_server_instructions": "Since Mastodon is decentralized, you can create an account on another server and still interact with this one.",
|
||||
"closed_registrations_modal.description": "Creating an account on {domain} is currently not possible, but please keep in mind that you do not need an account specifically on {domain} to use Mastodon.",
|
||||
"closed_registrations_modal.description_when_reaching_limit": "New registrations are currently temporarily restricted. Either the maximum number of registrations has been reached or it is outside the time frame available for registration. Please contact the administrator for more information or wait until the restriction is lifted.",
|
||||
"closed_registrations_modal.find_another_server": "Find another server",
|
||||
"closed_registrations_modal.preamble": "Mastodon is decentralized, so no matter where you create your account, you will be able to follow and interact with anyone on this server. You can even self-host it!",
|
||||
"closed_registrations_modal.title": "Signing up on Mastodon",
|
||||
|
|
|
@ -170,6 +170,7 @@
|
|||
"circles.subheading": "あなたのサークル",
|
||||
"closed_registrations.other_server_instructions": "Mastodonは分散型なので他のサーバーにアカウントを作ってもこのサーバーとやり取りできます。",
|
||||
"closed_registrations_modal.description": "現在{domain}でアカウント作成はできませんがMastodonは{domain}のアカウントでなくても利用できます。",
|
||||
"closed_registrations_modal.description_when_reaching_limit": "新規登録は現在一時的に制限されています。登録の上限人数に達したか、または登録可能な時間帯の範囲外です。詳細を管理人に問い合わせるか、制限が解除されるまでお待ち下さい。",
|
||||
"closed_registrations_modal.find_another_server": "別のサーバーを探す",
|
||||
"closed_registrations_modal.preamble": "Mastodonは分散型なのでどのサーバーでアカウントを作成してもこのサーバーのユーザーを誰でもフォローして交流することができます。また自分でホスティングすることもできます!",
|
||||
"closed_registrations_modal.title": "Mastodonでアカウントを作成",
|
||||
|
|
|
@ -15,6 +15,12 @@ class Form::AdminSettings
|
|||
registrations_mode
|
||||
closed_registrations_message
|
||||
registration_button_message
|
||||
registrations_limit
|
||||
registrations_limit_per_day
|
||||
registrations_start_hour
|
||||
registrations_end_hour
|
||||
registrations_secondary_start_hour
|
||||
registrations_secondary_end_hour
|
||||
timeline_preview
|
||||
bootstrap_timeline_accounts
|
||||
theme
|
||||
|
@ -61,6 +67,12 @@ class Form::AdminSettings
|
|||
content_cache_retention_period
|
||||
backups_retention_period
|
||||
post_hash_tags_max
|
||||
registrations_limit
|
||||
registrations_limit_per_day
|
||||
registrations_start_hour
|
||||
registrations_end_hour
|
||||
registrations_secondary_start_hour
|
||||
registrations_secondary_end_hour
|
||||
).freeze
|
||||
|
||||
BOOLEAN_KEYS = %i(
|
||||
|
|
|
@ -55,6 +55,7 @@ class User < ApplicationRecord
|
|||
|
||||
include LanguagesHelper
|
||||
include Redisable
|
||||
include RegistrationLimitationHelper
|
||||
include User::HasSettings
|
||||
include User::LdapAuthenticable
|
||||
include User::Omniauthable
|
||||
|
@ -192,6 +193,8 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def confirm
|
||||
raise Mastodon::ValidationError, I18n.t('devise.registrations.sign_up_failed_because_reach_limit') if !invited? && reach_registrations_limit?
|
||||
|
||||
wrap_email_confirmation do
|
||||
super
|
||||
end
|
||||
|
@ -482,6 +485,7 @@ class User < ApplicationRecord
|
|||
ActivityTracker.record('activity:logins', id)
|
||||
UserMailer.welcome(self).deliver_later
|
||||
TriggerWebhookWorker.perform_async('account.approved', 'Account', account_id)
|
||||
reset_registration_limit_caches!
|
||||
end
|
||||
|
||||
def prepare_returning_user!
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
class InitialStateSerializer < ActiveModel::Serializer
|
||||
include RoutingHelper
|
||||
include DtlHelper
|
||||
include RegistrationLimitationHelper
|
||||
|
||||
attributes :meta, :compose, :accounts,
|
||||
:media_attachments, :settings,
|
||||
|
@ -122,7 +123,8 @@ class InitialStateSerializer < ActiveModel::Serializer
|
|||
locale: I18n.locale,
|
||||
mascot: instance_presenter.mascot&.file&.url,
|
||||
profile_directory: Setting.profile_directory,
|
||||
registrations_open: Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode,
|
||||
registrations_open: Setting.registrations_mode != 'none' && !reach_registrations_limit? && !Rails.configuration.x.single_user_mode,
|
||||
registrations_reach_limit: Setting.registrations_mode != 'none' && reach_registrations_limit?,
|
||||
repository: Mastodon::Version.repository,
|
||||
search_enabled: Chewy.enabled?,
|
||||
single_user_mode: Rails.configuration.x.single_user_mode,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
class NodeInfo::Serializer < ActiveModel::Serializer
|
||||
include RoutingHelper
|
||||
include KmyblueCapabilitiesHelper
|
||||
include RegistrationLimitationHelper
|
||||
|
||||
attributes :version, :software, :protocols, :services, :usage, :open_registrations, :metadata
|
||||
|
||||
|
@ -35,7 +36,7 @@ class NodeInfo::Serializer < ActiveModel::Serializer
|
|||
end
|
||||
|
||||
def open_registrations
|
||||
Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode
|
||||
Setting.registrations_mode != 'none' && !reach_registrations_limit? && !Rails.configuration.x.single_user_mode
|
||||
end
|
||||
|
||||
def metadata
|
||||
|
|
|
@ -9,6 +9,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
|
|||
|
||||
include RoutingHelper
|
||||
include KmyblueCapabilitiesHelper
|
||||
include RegistrationLimitationHelper
|
||||
|
||||
attributes :domain, :title, :version, :source_url, :description,
|
||||
:usage, :thumbnail, :languages, :configuration,
|
||||
|
@ -110,6 +111,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
|
|||
{
|
||||
enabled: registrations_enabled?,
|
||||
approval_required: Setting.registrations_mode == 'approved',
|
||||
limit_reached: Setting.registrations_mode != 'none' && reach_registrations_limit?,
|
||||
message: registrations_enabled? ? nil : registrations_message,
|
||||
url: ENV.fetch('SSO_ACCOUNT_SIGN_UP', nil),
|
||||
}
|
||||
|
@ -118,7 +120,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
|
|||
private
|
||||
|
||||
def registrations_enabled?
|
||||
Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode
|
||||
Setting.registrations_mode != 'none' && !reach_registrations_limit? && !Rails.configuration.x.single_user_mode
|
||||
end
|
||||
|
||||
def registrations_message
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
class REST::V1::InstanceSerializer < ActiveModel::Serializer
|
||||
include RoutingHelper
|
||||
include KmyblueCapabilitiesHelper
|
||||
include RegistrationLimitationHelper
|
||||
|
||||
attributes :uri, :title, :short_description, :description, :email,
|
||||
:version, :urls, :stats, :thumbnail,
|
||||
|
@ -109,7 +110,7 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer
|
|||
end
|
||||
|
||||
def registrations
|
||||
Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode
|
||||
Setting.registrations_mode != 'none' && !reach_registrations_limit? && !Rails.configuration.x.single_user_mode
|
||||
end
|
||||
|
||||
def approval_required
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class DeleteAccountService < BaseService
|
||||
include Payloadable
|
||||
include RegistrationLimitationHelper
|
||||
|
||||
ASSOCIATIONS_ON_SUSPEND = %w(
|
||||
account_notes
|
||||
|
@ -143,6 +144,8 @@ class DeleteAccountService < BaseService
|
|||
else
|
||||
@account.user.destroy
|
||||
end
|
||||
|
||||
reset_registration_limit_caches!
|
||||
end
|
||||
|
||||
def purge_content!
|
||||
|
|
|
@ -27,5 +27,19 @@
|
|||
.fields-group
|
||||
= f.input :registration_button_message, as: :text, kmyblue: true, hint: false, wrapper: :with_label, input_html: { rows: 2 }
|
||||
|
||||
.fields-group
|
||||
= f.input :registrations_limit, kmyblue: true, wrapper: :with_label, input_html: { pattern: '[0-9]+' }, label: I18n.t('simple_form.labels.form_admin_settings.registrations_limit', count: @current_users_count)
|
||||
|
||||
.fields-group
|
||||
= f.input :registrations_limit_per_day, kmyblue: true, wrapper: :with_label, input_html: { pattern: '[0-9]+' }, label: I18n.t('simple_form.labels.form_admin_settings.registrations_limit_per_day', count: @current_users_count_today)
|
||||
|
||||
.fields-group
|
||||
= f.input :registrations_start_hour, kmyblue: true, wrapper: :with_label, input_html: { pattern: '[0-9]+' }
|
||||
= f.input :registrations_end_hour, kmyblue: true, wrapper: :with_label, input_html: { pattern: '[0-9]+' }
|
||||
|
||||
.fields-group
|
||||
= f.input :registrations_secondary_start_hour, kmyblue: true, wrapper: :with_label, input_html: { pattern: '[0-9]+' }
|
||||
= f.input :registrations_secondary_end_hour, kmyblue: true, wrapper: :with_label, input_html: { pattern: '[0-9]+' }
|
||||
|
||||
.actions
|
||||
= f.button :button, t('generic.save_changes'), type: :submit
|
||||
|
|
11
app/views/auth/confirmations/limitation_error.html.haml
Normal file
11
app/views/auth/confirmations/limitation_error.html.haml
Normal file
|
@ -0,0 +1,11 @@
|
|||
- content_for :page_title do
|
||||
= t('auth.registration_limit.title')
|
||||
|
||||
= form_tag root_url, method: 'GET', class: 'simple_form' do
|
||||
= render 'auth/shared/progress', stage: 'confirm'
|
||||
|
||||
%h1.title= t('auth.registration_limit.title')
|
||||
%p.lead= t('auth.registration_limit.hint_html')
|
||||
|
||||
.actions
|
||||
= button_tag t('challenge.confirm'), class: 'button', type: :submit
|
|
@ -93,6 +93,7 @@ en:
|
|||
updated_not_active: Your password has been changed successfully.
|
||||
registrations:
|
||||
destroyed: Bye! Your account has been successfully cancelled. We hope to see you again soon.
|
||||
sign_up_failed_because_reach_limit: You cannot create account because reaching limit.
|
||||
signed_up: Welcome! You have signed up successfully.
|
||||
signed_up_but_inactive: You have signed up successfully. However, we could not sign you in because your account is not yet activated.
|
||||
signed_up_but_locked: You have signed up successfully. However, we could not sign you in because your account is locked.
|
||||
|
|
|
@ -93,6 +93,7 @@ ja:
|
|||
updated_not_active: パスワードは正常に更新されました。
|
||||
registrations:
|
||||
destroyed: アカウントの作成はキャンセルされました。またのご利用をお待ちしています。
|
||||
sign_up_failed_because_reach_limit: 制限に到達しているため、アカウントを作成できません。
|
||||
signed_up: アカウントの作成が完了しました。Mastodonへようこそ。
|
||||
signed_up_but_inactive: アカウントの作成が完了しました。しかし、アカウントが有効化されていないためログインできませんでした。
|
||||
signed_up_but_locked: アカウントの作成が完了しました。しかし、アカウントがロックされているためログインできませんでした。
|
||||
|
|
|
@ -1267,6 +1267,9 @@ en:
|
|||
saml: SAML
|
||||
register: Sign up
|
||||
registration_closed: "%{instance} is not accepting new members"
|
||||
registration_limit:
|
||||
hint_html: The maximum number of new registrations allowed, or the time of day, is restricted by the administrator. You will not be able to complete authentication while the restriction is in effect. Please contact the administrator or wait until the restriction is lifted. If you have reached the limit, you will need to register again.
|
||||
title: New registrations are currently restricted
|
||||
resend_confirmation: Resend confirmation link
|
||||
reset_password: Reset password
|
||||
rules:
|
||||
|
|
|
@ -1255,6 +1255,9 @@ ja:
|
|||
saml: SAML
|
||||
register: 登録する
|
||||
registration_closed: "%{instance}は現在、新規登録停止中です"
|
||||
registration_limit:
|
||||
hint_html: 新規登録可能な上限人数、もしくは時間帯は、管理者によって制限されています。制限中は認証を完了することができません。管理者に問い合わせるか、制限が解除されるまでお待ちください。なお認証期限に達した場合は、再度新規登録を行う必要があります。
|
||||
title: 新規登録は現在制限中です
|
||||
resend_confirmation: 確認メールを再送
|
||||
reset_password: パスワードを再発行
|
||||
rules:
|
||||
|
|
|
@ -354,7 +354,13 @@ en:
|
|||
profile_directory: Enable profile directory
|
||||
receive_other_servers_emoji_reaction: Receive emoji reaction between other server users
|
||||
registration_button_message: Register button message
|
||||
registrations_limit: User registration limit
|
||||
registrations_limit_per_day: User registration limit per day
|
||||
registrations_mode: Who can sign-up
|
||||
registrations_end_hour: Registration end hour (UTC 0-24)
|
||||
registrations_start_hour: Registration start hour (UTC 0-24)
|
||||
registrations_secondary_end_hour: Secondary registration end hour (UTC 0-24) If input 0, secondary hour is disabled.
|
||||
registrations_secondary_start_hour: Secondary registration start hour (UTC 0-24)
|
||||
require_invite_text: Require a reason to join
|
||||
show_domain_blocks: Show domain blocks
|
||||
show_domain_blocks_rationale: Show why domains were blocked
|
||||
|
|
|
@ -117,6 +117,10 @@ ja:
|
|||
peers_api_enabled: このサーバーが Fediverse で遭遇したドメイン名のリストです。このサーバーが知っているだけで、特定のサーバーと連合しているかのデータは含まれません。これは一般的に Fediverse に関する統計情報を収集するサービスによって使用されます。
|
||||
profile_directory: ディレクトリには、掲載する設定をしたすべてのユーザーが一覧表示されます。
|
||||
receive_other_servers_emoji_reaction: 負荷の原因になります。人が少ない場合にのみ有効にすることをおすすめします。
|
||||
registrations_limit: 現在のユーザー数がこれを超過すると、管理者がこの数値を増やさない限り新規登録できません。0を指定すると、この制限を無効化します。
|
||||
registrations_limit_per_day: 本日登録されたユーザー数がこれを超過すると、UTC時刻で翌日0時にならない限り新規登録できません。0を指定すると、この制限を無効化します。
|
||||
registrations_end_hour: 新規登録可能な時間帯の開始時間を指定します。これより前の時間に登録することはできません。終了時間より後にすることはできません。
|
||||
registrations_start_hour: 新規登録可能な時間帯の終了時間を指定します。これより後の時間に登録することはできません。開始時間より前にすることはできません。
|
||||
require_invite_text: アカウント登録が承認制の場合、登録の際の申請事由の入力を必須にします
|
||||
site_contact_email: 法律またはサポートに関する問い合わせ先
|
||||
site_contact_username: マストドンでの連絡方法
|
||||
|
@ -363,7 +367,13 @@ ja:
|
|||
profile_directory: プロフィール一覧を有効にする
|
||||
receive_other_servers_emoji_reaction: 他のサーバーのユーザーが他のサーバーの投稿につけた絵文字リアクションを受け入れる
|
||||
registration_button_message: 新規登録ボタンの直上に表示するメッセージ
|
||||
registrations_limit: 登録ユーザー数上限 (現在 %{count} 名)
|
||||
registrations_limit_per_day: 1日あたり登録ユーザー数上限 (現在 %{count} 名)
|
||||
registrations_mode: 新規登録が可能な人
|
||||
registrations_end_hour: 登録受付終了時間 A (UTC 0〜24)
|
||||
registrations_start_hour: 登録受付開始時間 A (UTC 0〜24)
|
||||
registrations_secondary_end_hour: 登録受付終了時間 B (UTC 0〜24) ここで0を指定した場合、時間Bの設定は無効化されます
|
||||
registrations_secondary_start_hour: 登録受付開始時間 B (UTC 0〜24)
|
||||
require_invite_text: 申請事由の入力を必須にする
|
||||
show_domain_blocks: ドメインブロックを表示
|
||||
show_domain_blocks_rationale: ドメインがブロックされた理由を表示
|
||||
|
|
|
@ -10,6 +10,12 @@ defaults: &defaults
|
|||
site_contact_username: ''
|
||||
site_contact_email: ''
|
||||
registrations_mode: 'open'
|
||||
registrations_limit: 0
|
||||
registrations_limit_per_day: 0
|
||||
registrations_start_hour: 0
|
||||
registrations_end_hour: 24
|
||||
registrations_secondary_start_hour: 0
|
||||
registrations_secondary_end_hour: 0
|
||||
profile_directory: true
|
||||
closed_registrations_message: ''
|
||||
timeline_preview: true
|
||||
|
|
|
@ -280,6 +280,164 @@ RSpec.describe Auth::RegistrationsController do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when max user count is set' do
|
||||
subject do
|
||||
post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } }
|
||||
end
|
||||
|
||||
let(:users_max) { 3 }
|
||||
|
||||
before do
|
||||
Fabricate(:user)
|
||||
Fabricate(:user)
|
||||
Setting.registrations_mode = 'open'
|
||||
Setting.registrations_limit = users_max
|
||||
request.headers['Accept-Language'] = accept_language
|
||||
end
|
||||
|
||||
it 'redirects to setup' do
|
||||
subject
|
||||
expect(response).to redirect_to auth_setup_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)
|
||||
end
|
||||
|
||||
context 'when limit is reached' do
|
||||
let(:users_max) { 2 }
|
||||
|
||||
it 'does not create user' do
|
||||
subject
|
||||
user = User.find_by(email: 'test@example.com')
|
||||
expect(user).to be_nil
|
||||
end
|
||||
|
||||
context 'with invite' do
|
||||
subject do
|
||||
post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', invite_code: invite.code, agreement: 'true' } }
|
||||
end
|
||||
|
||||
let(:invite) { Fabricate(:invite) }
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when max user count per day is set' do
|
||||
subject do
|
||||
post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } }
|
||||
end
|
||||
|
||||
let(:users_max) { 2 }
|
||||
let(:created_at) { Time.now.utc }
|
||||
let(:precreate_users) { true }
|
||||
|
||||
before do
|
||||
Fabricate(:user, created_at: created_at) if precreate_users
|
||||
Setting.registrations_mode = 'open'
|
||||
Setting.registrations_limit_per_day = users_max
|
||||
request.headers['Accept-Language'] = accept_language
|
||||
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)
|
||||
end
|
||||
|
||||
context 'when limit is reached' do
|
||||
let(:users_max) { 2 }
|
||||
let(:created_at) { Time.now.utc - 1.day }
|
||||
let(:precreate_users) { false }
|
||||
|
||||
before do
|
||||
travel_to Time.now.utc - 1.day
|
||||
Fabricate(:user)
|
||||
create_other_user
|
||||
end
|
||||
|
||||
it 'does not create user yesterday' do
|
||||
subject
|
||||
user = User.find_by(email: 'test@example.com')
|
||||
expect(user).to be_nil
|
||||
end
|
||||
|
||||
it 'creates user' do
|
||||
travel_to Time.now.utc + 1.day
|
||||
subject
|
||||
user = User.find_by(email: 'test@example.com')
|
||||
expect(user).to_not be_nil
|
||||
expect(user.locale).to eq(accept_language)
|
||||
end
|
||||
end
|
||||
|
||||
def create_other_user
|
||||
post :create, params: { user: { account_attributes: { username: 'ohagi' }, email: 'test@ohagi.com', password: 'ohagi_must_be_tsubuan', password_confirmation: 'ohagi_must_be_tsubuan', agreement: 'true' } }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when registration time range is set' do
|
||||
subject do
|
||||
post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } }
|
||||
end
|
||||
|
||||
shared_examples 'registration with time' do |header, start_hour_val, end_hour_val, secondary_start_hour_val, secondary_end_hour_val, result| # rubocop:disable Metrics/ParameterLists
|
||||
context header do
|
||||
let(:start_hour) { start_hour_val }
|
||||
let(:end_hour) { end_hour_val }
|
||||
let(:secondary_start_hour) { secondary_start_hour_val }
|
||||
let(:secondary_end_hour) { secondary_end_hour_val }
|
||||
|
||||
before do
|
||||
Setting.registrations_mode = 'open'
|
||||
Setting.registrations_start_hour = start_hour
|
||||
Setting.registrations_end_hour = end_hour
|
||||
Setting.registrations_secondary_start_hour = secondary_start_hour
|
||||
Setting.registrations_secondary_end_hour = secondary_end_hour
|
||||
request.headers['Accept-Language'] = accept_language
|
||||
|
||||
travel_to Time.now.utc.beginning_of_day + 10.hours
|
||||
end
|
||||
|
||||
if result
|
||||
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)
|
||||
end
|
||||
else
|
||||
it 'does not create user' do
|
||||
subject
|
||||
user = User.find_by(email: 'test@example.com')
|
||||
expect(user).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'registration with time', 'time range is not set', 0, 24, 0, 0, true
|
||||
it_behaves_like 'registration with time', 'time range is set', 9, 12, 0, 0, true
|
||||
it_behaves_like 'registration with time', 'time range is out of range', 12, 15, 0, 0, false
|
||||
it_behaves_like 'registration with time', 'time range is invalid', 20, 15, 0, 0, true
|
||||
it_behaves_like 'registration with time', 'secondary time range is set', 0, 4, 9, 12, true
|
||||
it_behaves_like 'registration with time', 'secondary time range is out of range', 0, 4, 12, 15, false
|
||||
it_behaves_like 'registration with time', 'secondary time range is invalid', 0, 4, 20, 15, false
|
||||
it_behaves_like 'registration with time', 'both time range are invalid', 4, 0, 20, 15, true
|
||||
it_behaves_like 'registration with time', 'only secondary time range is set', 0, 0, 9, 12, true
|
||||
end
|
||||
|
||||
include_examples 'checks for enabled registrations', :create
|
||||
end
|
||||
|
||||
|
|
|
@ -233,6 +233,38 @@ RSpec.describe User do
|
|||
expect(TriggerWebhookWorker).to_not have_received(:perform_async).with('account.approved', 'Account', user.account_id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when max user count is set' do
|
||||
let(:users_max) { 3 }
|
||||
|
||||
before do
|
||||
Fabricate(:user)
|
||||
Fabricate(:user)
|
||||
Setting.registrations_limit = users_max
|
||||
end
|
||||
|
||||
it 'creates user' do
|
||||
expect { subject }.to_not raise_error
|
||||
expect(user.confirmed?).to be true
|
||||
end
|
||||
|
||||
context 'with limit is reached' do
|
||||
let(:users_max) { 2 }
|
||||
|
||||
it 'does not create user' do
|
||||
expect { subject }.to raise_error Mastodon::ValidationError
|
||||
expect(user.confirmed?).to be false
|
||||
end
|
||||
|
||||
it 'but creates user when invited' do
|
||||
invite = Fabricate(:invite, user: Fabricate(:user), max_uses: nil, expires_at: 1.hour.from_now)
|
||||
user.update!(invite: invite)
|
||||
|
||||
expect { subject }.to_not raise_error
|
||||
expect(user.confirmed?).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue