Skip to content
This repository has been archived by the owner on Dec 21, 2023. It is now read-only.

Commit

Permalink
Admission-based registrations mode (mastodon#10250)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gargron authored Mar 14, 2019
1 parent 6e3936a commit 51e154f
Show file tree
Hide file tree
Showing 92 changed files with 282 additions and 249 deletions.
4 changes: 2 additions & 2 deletions app/controllers/accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ def hashtag_scope
end
end

def set_account
@account = Account.find_local!(params[:username])
def username_param
params[:username]
end

def older_url
Expand Down
17 changes: 15 additions & 2 deletions app/controllers/admin/accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

module Admin
class AccountsController < BaseController
before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :remove_header, :enable, :unsilence, :unsuspend, :memorialize]
before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :remove_header, :enable, :unsilence, :unsuspend, :memorialize, :approve, :reject]
before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload]
before_action :require_local_account!, only: [:enable, :memorialize]
before_action :require_local_account!, only: [:enable, :memorialize, :approve, :reject]

def index
authorize :account, :index?
Expand Down Expand Up @@ -45,6 +45,18 @@ def enable
redirect_to admin_account_path(@account.id)
end

def approve
authorize @account.user, :approve?
@account.user.approve!
redirect_to admin_accounts_path(pending: '1')
end

def reject
authorize @account.user, :reject?
SuspendAccountService.new.call(@account, including_user: true, destroy: true)
redirect_to admin_accounts_path(pending: '1')
end

def unsilence
authorize @account, :unsilence?
@account.unsilence!
Expand Down Expand Up @@ -114,6 +126,7 @@ def filter_params
:remote,
:by_domain,
:active,
:pending,
:silenced,
:suspended,
:username,
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/admin/dashboard_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def index
@interactions_week = Redis.current.get("activity:interactions:#{current_week}") || 0
@relay_enabled = Relay.enabled.exists?
@single_user_mode = Rails.configuration.x.single_user_mode
@registrations_enabled = Setting.open_registrations
@registrations_enabled = Setting.registrations_mode != 'none'
@deletions_enabled = Setting.open_deletion
@invites_enabled = Setting.min_invite_role == 'user'
@search_enabled = Chewy.enabled?
Expand Down
3 changes: 1 addition & 2 deletions app/controllers/admin/settings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class SettingsController < BaseController
site_description
site_extended_description
site_terms
open_registrations
registrations_mode
closed_registrations_message
open_deletion
timeline_preview
Expand All @@ -30,7 +30,6 @@ class SettingsController < BaseController
).freeze

BOOLEAN_SETTINGS = %w(
open_registrations
open_deletion
timeline_preview
show_staff_badge
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/api/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ def require_user!
elsif current_user.disabled?
render json: { error: 'Your login is currently disabled' }, status: 403
elsif !current_user.confirmed?
render json: { error: 'Email confirmation is not completed' }, status: 403
render json: { error: 'Your login is missing a confirmed e-mail address' }, status: 403
elsif !current_user.approved?
render json: { error: 'Your login is currently pending approval' }, status: 403
else
set_user_activity
end
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/api/v1/accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ def account_params
end

def check_enabled_registrations
forbidden if single_user_mode? || !Setting.open_registrations
forbidden if single_user_mode? || !allowed_registrations?
end

def allowed_registrations?
Setting.registrations_mode != 'none'
end
end
2 changes: 1 addition & 1 deletion app/controllers/auth/registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def check_enabled_registrations
end

def allowed_registrations?
Setting.open_registrations || @invite&.valid_for_use?
Setting.registrations_mode != 'none' || @invite&.valid_for_use?
end

def invite_code
Expand Down
14 changes: 12 additions & 2 deletions app/controllers/concerns/account_controller_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ module AccountControllerConcern

included do
layout 'public'

before_action :set_account
before_action :check_account_approval
before_action :check_account_suspension
before_action :set_instance_presenter
before_action :set_link_headers
before_action :check_account_suspension
end

private

def set_account
@account = Account.find_local!(params[:account_username])
@account = Account.find_local!(username_param)
end

def set_instance_presenter
Expand All @@ -33,6 +35,10 @@ def set_link_headers
)
end

def username_param
params[:account_username]
end

def webfinger_account_link
[
webfinger_account_url,
Expand All @@ -58,6 +64,10 @@ def webfinger_account_url
webfinger_url(resource: @account.to_webfinger_s)
end

def check_account_approval
not_found if @account.user_pending?
end

def check_account_suspension
gone if @account.suspended?
end
Expand Down
2 changes: 1 addition & 1 deletion app/helpers/admin/filter_helper.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

module Admin::FilterHelper
ACCOUNT_FILTERS = %i(local remote by_domain active silenced suspended username display_name email ip staff).freeze
ACCOUNT_FILTERS = %i(local remote by_domain active pending silenced suspended username display_name email ip staff).freeze
REPORT_FILTERS = %i(resolved account_id target_account_id).freeze
INVITE_FILTER = %i(available expired).freeze
CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze
Expand Down
18 changes: 17 additions & 1 deletion app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,23 @@ def show_landing_strip?
end

def open_registrations?
Setting.open_registrations
Setting.registrations_mode == 'open'
end

def approved_registrations?
Setting.registrations_mode == 'approved'
end

def closed_registrations?
Setting.registrations_mode == 'none'
end

def available_sign_up_path
if closed_registrations?
'https://joinmastodon.org/#getting-started'
else
new_user_registration_path
end
end

def open_deletion?
Expand Down
10 changes: 10 additions & 0 deletions app/helpers/home_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,14 @@ def optional_link_to(condition, path, options = {}, &block)
content_tag(:div, &block)
end
end

def sign_up_message
if closed_registrations?
t('auth.registration_closed', instance: site_hostname)
elsif open_registrations?
t('auth.register')
elsif approved_registrations?
t('auth.apply_for_account')
end
end
end
8 changes: 8 additions & 0 deletions app/javascript/styles/mastodon/admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -689,3 +689,11 @@ a.name-tag,
overflow: hidden;
text-overflow: ellipsis;
}

.ellipsized-ip {
display: inline-block;
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
}
10 changes: 10 additions & 0 deletions app/mailers/admin_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,14 @@ def new_report(recipient, report)
mail to: @me.user_email, subject: I18n.t('admin_mailer.new_report.subject', instance: @instance, id: @report.id)
end
end

def new_pending_account(recipient, account)
@account = account
@me = recipient
@instance = Rails.configuration.x.local_domain

locale_for_account(@me) do
mail to: @me.user_email, subject: I18n.t('admin_mailer.new_pending_account.subject', instance: @instance, username: @account.username)
end
end
end
2 changes: 2 additions & 0 deletions app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class Account < ApplicationRecord
:current_sign_in_ip,
:current_sign_in_at,
:confirmed?,
:approved?,
:pending?,
:admin?,
:moderator?,
:staff?,
Expand Down
4 changes: 3 additions & 1 deletion app/models/account_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def results

def set_defaults!
params['local'] = '1' if params['remote'].blank?
params['active'] = '1' if params['suspended'].blank? && params['silenced'].blank?
params['active'] = '1' if params['suspended'].blank? && params['silenced'].blank? && params['pending'].blank?
end

def scope_for(key, value)
Expand All @@ -35,6 +35,8 @@ def scope_for(key, value)
Account.where(domain: value)
when 'active'
Account.without_suspended
when 'pending'
accounts_with_users.merge User.pending
when 'silenced'
Account.silenced
when 'suspended'
Expand Down
4 changes: 2 additions & 2 deletions app/models/form/admin_settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class Form::AdminSettings
:site_extended_description=,
:site_terms,
:site_terms=,
:open_registrations,
:open_registrations=,
:registrations_mode,
:registrations_mode=,
:closed_registrations_message,
:closed_registrations_message=,
:open_deletion,
Expand Down
42 changes: 40 additions & 2 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
# remember_token :string
# chosen_languages :string is an Array
# created_by_application_id :bigint(8)
# approved :boolean default(TRUE), not null
#

class User < ApplicationRecord
Expand Down Expand Up @@ -79,6 +80,8 @@ class User < ApplicationRecord
validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create

scope :recent, -> { order(id: :desc) }
scope :pending, -> { where(approved: false) }
scope :approved, -> { where(approved: true) }
scope :confirmed, -> { where.not(confirmed_at: nil) }
scope :enabled, -> { where(disabled: false) }
scope :inactive, -> { where(arel_table[:current_sign_in_at].lt(ACTIVE_DURATION.ago)) }
Expand All @@ -87,6 +90,7 @@ class User < ApplicationRecord
scope :emailable, -> { confirmed.enabled.joins(:account).merge(Account.searchable) }

before_validation :sanitize_languages
before_create :set_approved

# This avoids a deprecation warning from Rails 5.1
# It seems possible that a future release of devise-two-factor will
Expand Down Expand Up @@ -124,7 +128,11 @@ def confirm

super

prepare_new_user! if new_user
if new_user && approved?
prepare_new_user!
elsif new_user
notify_staff_about_pending_account!
end
end

def confirm!
Expand All @@ -133,7 +141,26 @@ def confirm!
skip_confirmation!
save!

prepare_new_user! if new_user
prepare_new_user! if new_user && approved?
end

def pending?
!approved?
end

def active_for_authentication?
super && approved?
end

def inactive_message
!approved? ? :pending : super
end

def approve!
return if approved?

update!(approved: true)
prepare_new_user!
end

def update_tracked_fields!(request)
Expand Down Expand Up @@ -236,6 +263,10 @@ def send_devise_notification(notification, *args)

private

def set_approved
self.approved = Setting.registrations_mode == 'open' || invited?
end

def sanitize_languages
return if chosen_languages.nil?
chosen_languages.reject!(&:blank?)
Expand All @@ -253,6 +284,13 @@ def prepare_returning_user!
regenerate_feed! if needs_feed_update?
end

def notify_staff_about_pending_account!
User.staff.includes(:account).each do |u|
next unless u.allows_report_emails?
AdminMailer.new_pending_account(u.account, self).deliver_later
end
end

def regenerate_feed!
return unless Redis.current.setnx("account:#{account_id}:regeneration", true)
Redis.current.expire("account:#{account_id}:regeneration", 1.day.seconds)
Expand Down
10 changes: 9 additions & 1 deletion app/policies/user_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ def enable?
staff?
end

def approve?
staff? && !record.approved?
end

def reject?
staff? && !record.approved?
end

def disable?
staff? && !record.admin?
end
Expand All @@ -36,7 +44,7 @@ def demote?
private

def promoteable?
!record.staff? || !record.admin?
record.approved? && (!record.staff? || !record.admin?)
end

def demoteable?
Expand Down
2 changes: 0 additions & 2 deletions app/presenters/instance_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

class InstancePresenter
delegate(
:closed_registrations_message,
:site_contact_email,
:open_registrations,
:site_title,
:site_short_description,
:site_description,
Expand Down
2 changes: 1 addition & 1 deletion app/serializers/rest/instance_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def languages
end

def registrations
Setting.open_registrations && !Rails.configuration.x.single_user_mode
Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode
end

private
Expand Down
Loading

0 comments on commit 51e154f

Please sign in to comment.