summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2019-03-14 05:28:30 +0100
committerGitHub <noreply@github.com>2019-03-14 05:28:30 +0100
commit51e154f5e87968d6bb115e053689767ab33e80cd (patch)
treed86ba475bfc61ba7a774bf36e24704dc82f68991 /app
parent6e3936aa6f4296ac202b54c0b178b4fa825d7885 (diff)
Admission-based registrations mode (#10250)
Fix #6856 Fix #6951
Diffstat (limited to 'app')
-rw-r--r--app/controllers/accounts_controller.rb4
-rw-r--r--app/controllers/admin/accounts_controller.rb17
-rw-r--r--app/controllers/admin/dashboard_controller.rb2
-rw-r--r--app/controllers/admin/settings_controller.rb3
-rw-r--r--app/controllers/api/base_controller.rb4
-rw-r--r--app/controllers/api/v1/accounts_controller.rb6
-rw-r--r--app/controllers/auth/registrations_controller.rb2
-rw-r--r--app/controllers/concerns/account_controller_concern.rb14
-rw-r--r--app/helpers/admin/filter_helper.rb2
-rw-r--r--app/helpers/application_helper.rb18
-rw-r--r--app/helpers/home_helper.rb10
-rw-r--r--app/javascript/styles/mastodon/admin.scss8
-rw-r--r--app/mailers/admin_mailer.rb10
-rw-r--r--app/models/account.rb2
-rw-r--r--app/models/account_filter.rb4
-rw-r--r--app/models/form/admin_settings.rb4
-rw-r--r--app/models/user.rb42
-rw-r--r--app/policies/user_policy.rb10
-rw-r--r--app/presenters/instance_presenter.rb2
-rw-r--r--app/serializers/rest/instance_serializer.rb2
-rw-r--r--app/services/app_sign_up_service.rb2
-rw-r--r--app/views/about/_registration.html.haml12
-rw-r--r--app/views/admin/accounts/_account.html.haml10
-rw-r--r--app/views/admin/accounts/index.html.haml7
-rw-r--r--app/views/admin/accounts/show.html.haml16
-rw-r--r--app/views/admin/settings/edit.html.haml10
-rw-r--r--app/views/admin_mailer/new_pending_account.text.erb8
-rw-r--r--app/views/auth/registrations/new.html.haml2
-rw-r--r--app/views/auth/shared/_links.html.haml2
-rw-r--r--app/views/layouts/public.html.haml5
-rw-r--r--app/views/remote_follow/new.html.haml2
-rw-r--r--app/views/remote_interaction/new.html.haml2
-rw-r--r--app/views/user_mailer/confirmation_instructions.html.haml2
-rw-r--r--app/views/user_mailer/confirmation_instructions.text.erb2
34 files changed, 193 insertions, 55 deletions
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index dfbe5bffcf3..a3410c1efec 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -89,8 +89,8 @@ class AccountsController < ApplicationController
end
end
- def set_account
- @account = Account.find_local!(params[:username])
+ def username_param
+ params[:username]
end
def older_url
diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb
index 562fba9960d..e160c603a82 100644
--- a/app/controllers/admin/accounts_controller.rb
+++ b/app/controllers/admin/accounts_controller.rb
@@ -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?
@@ -45,6 +45,18 @@ module Admin
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!
@@ -114,6 +126,7 @@ module Admin
:remote,
:by_domain,
:active,
+ :pending,
:silenced,
:suspended,
:username,
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb
index bb923c18594..22bbcec19e7 100644
--- a/app/controllers/admin/dashboard_controller.rb
+++ b/app/controllers/admin/dashboard_controller.rb
@@ -10,7 +10,7 @@ module Admin
@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?
diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb
index 4a049fc2356..a763597f20e 100644
--- a/app/controllers/admin/settings_controller.rb
+++ b/app/controllers/admin/settings_controller.rb
@@ -10,7 +10,7 @@ module Admin
site_description
site_extended_description
site_terms
- open_registrations
+ registrations_mode
closed_registrations_message
open_deletion
timeline_preview
@@ -30,7 +30,6 @@ module Admin
).freeze
BOOLEAN_SETTINGS = %w(
- open_registrations
open_deletion
timeline_preview
show_staff_badge
diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
index a1dd30918f3..3a92ee4e4d7 100644
--- a/app/controllers/api/base_controller.rb
+++ b/app/controllers/api/base_controller.rb
@@ -73,7 +73,9 @@ class Api::BaseController < ApplicationController
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
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index 2ccbc3cbbdf..b0c62778e65 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -80,6 +80,10 @@ class Api::V1::AccountsController < Api::BaseController
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
diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb
index ad7b1859f68..16a3ec67adf 100644
--- a/app/controllers/auth/registrations_controller.rb
+++ b/app/controllers/auth/registrations_controller.rb
@@ -65,7 +65,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
end
def allowed_registrations?
- Setting.open_registrations || @invite&.valid_for_use?
+ Setting.registrations_mode != 'none' || @invite&.valid_for_use?
end
def invite_code
diff --git a/app/controllers/concerns/account_controller_concern.rb b/app/controllers/concerns/account_controller_concern.rb
index 6c27ef330b9..8817fd7de46 100644
--- a/app/controllers/concerns/account_controller_concern.rb
+++ b/app/controllers/concerns/account_controller_concern.rb
@@ -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
@@ -33,6 +35,10 @@ module AccountControllerConcern
)
end
+ def username_param
+ params[:account_username]
+ end
+
def webfinger_account_link
[
webfinger_account_url,
@@ -58,6 +64,10 @@ module AccountControllerConcern
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
diff --git a/app/helpers/admin/filter_helper.rb b/app/helpers/admin/filter_helper.rb
index 275b5f2fe0d..8f78bf5f846 100644
--- a/app/helpers/admin/filter_helper.rb
+++ b/app/helpers/admin/filter_helper.rb
@@ -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
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 5097a0953e8..b42b1bbdf76 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -20,7 +20,23 @@ module ApplicationHelper
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?
diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb
index 1f648649fe3..df60b7dd7ac 100644
--- a/app/helpers/home_helper.rb
+++ b/app/helpers/home_helper.rb
@@ -64,4 +64,14 @@ module HomeHelper
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
diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss
index 6d785707c97..f6bfe44cf8f 100644
--- a/app/javascript/styles/mastodon/admin.scss
+++ b/app/javascript/styles/mastodon/admin.scss
@@ -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;
+}
diff --git a/app/mailers/admin_mailer.rb b/app/mailers/admin_mailer.rb
index a30468eb8b5..ecbbe745b49 100644
--- a/app/mailers/admin_mailer.rb
+++ b/app/mailers/admin_mailer.rb
@@ -14,4 +14,14 @@ class AdminMailer < ApplicationMailer
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
diff --git a/app/models/account.rb b/app/models/account.rb
index d6d718354b8..c2a0709f99b 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -104,6 +104,8 @@ class Account < ApplicationRecord
:current_sign_in_ip,
:current_sign_in_at,
:confirmed?,
+ :approved?,
+ :pending?,
:admin?,
:moderator?,
:staff?,
diff --git a/app/models/account_filter.rb b/app/models/account_filter.rb
index b10f50db778..d2503100cfc 100644
--- a/app/models/account_filter.rb
+++ b/app/models/account_filter.rb
@@ -22,7 +22,7 @@ class AccountFilter
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)
@@ -35,6 +35,8 @@ class AccountFilter
Account.where(domain: value)
when 'active'
Account.without_suspended
+ when 'pending'
+ accounts_with_users.merge User.pending
when 'silenced'
Account.silenced
when 'suspended'
diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb
index eca71bf6214..a21394a52a8 100644
--- a/app/models/form/admin_settings.rb
+++ b/app/models/form/admin_settings.rb
@@ -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,
diff --git a/app/models/user.rb b/app/models/user.rb
index a9d6adf706b..9d0d49676be 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -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
@@ -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)) }
@@ -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
@@ -124,7 +128,11 @@ class User < ApplicationRecord
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!
@@ -133,7 +141,26 @@ class User < ApplicationRecord
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)
@@ -236,6 +263,10 @@ class User < ApplicationRecord
private
+ def set_approved
+ self.approved = Setting.registrations_mode == 'open' || invited?
+ end
+
def sanitize_languages
return if chosen_languages.nil?
chosen_languages.reject!(&:blank?)
@@ -253,6 +284,13 @@ class User < ApplicationRecord
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)
diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb
index 57af5c61c86..d832bff75d4 100644
--- a/app/policies/user_policy.rb
+++ b/app/policies/user_policy.rb
@@ -21,6 +21,14 @@ class UserPolicy < ApplicationPolicy
staff?
end
+ def approve?
+ staff? && !record.approved?
+ end
+
+ def reject?
+ staff? && !record.approved?