From f27d7093513c0265010d019adc01b3f7ea02ef47 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 25 Apr 2019 02:49:06 +0200 Subject: Fix not being able to save e-mail preference for new pending accounts (#10622) --- app/controllers/settings/notifications_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/controllers') diff --git a/app/controllers/settings/notifications_controller.rb b/app/controllers/settings/notifications_controller.rb index da8a03d96..b2ce83e42 100644 --- a/app/controllers/settings/notifications_controller.rb +++ b/app/controllers/settings/notifications_controller.rb @@ -25,7 +25,7 @@ class Settings::NotificationsController < Settings::BaseController def user_settings_params params.require(:user).permit( - notification_emails: %i(follow follow_request reblog favourite mention digest report), + notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account), interactions: %i(must_be_follower must_be_following must_be_following_dm) ) end -- cgit From 21a73c52a7d0d0149e1058aeec155fe1c87aaeff Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 2 May 2019 04:30:12 +0200 Subject: Check that an invite link is valid before bypassing approval mode (#10657) * Check that an invite link is valid before bypassing approval mode Fixes #10656 * Add tests * Only consider valid invite links in registration controller * fixup --- app/controllers/auth/registrations_controller.rb | 3 +- app/models/user.rb | 2 +- .../auth/registrations_controller_spec.rb | 83 ++++++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index 5c1ff769a..83797cf1f 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -91,7 +91,8 @@ class Auth::RegistrationsController < Devise::RegistrationsController end def set_invite - @invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil + invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil + @invite = invite&.valid_for_use? ? invite : nil end def determine_layout diff --git a/app/models/user.rb b/app/models/user.rb index c42f6ad8d..432078651 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -114,7 +114,7 @@ class User < ApplicationRecord end def invited? - invite_id.present? + invite_id.present? && invite.valid_for_use? end def disable! diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb index 1095df034..a4337039e 100644 --- a/spec/controllers/auth/registrations_controller_spec.rb +++ b/spec/controllers/auth/registrations_controller_spec.rb @@ -107,6 +107,89 @@ RSpec.describe Auth::RegistrationsController, type: :controller do end end + context 'approval-based registrations without invite' do + around do |example| + registrations_mode = Setting.registrations_mode + example.run + Setting.registrations_mode = registrations_mode + end + + subject do + Setting.registrations_mode = 'approved' + request.headers["Accept-Language"] = accept_language + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678' } } + end + + it 'redirects to login page' do + subject + expect(response).to redirect_to new_user_session_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) + expect(user.approved).to eq(false) + end + end + + context 'approval-based registrations with expired invite' do + around do |example| + registrations_mode = Setting.registrations_mode + example.run + Setting.registrations_mode = registrations_mode + end + + subject do + Setting.registrations_mode = 'approved' + request.headers["Accept-Language"] = accept_language + invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.ago) + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code } } + end + + it 'redirects to login page' do + subject + expect(response).to redirect_to new_user_session_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) + expect(user.approved).to eq(false) + end + end + + context 'approval-based registrations with valid invite' do + around do |example| + registrations_mode = Setting.registrations_mode + example.run + Setting.registrations_mode = registrations_mode + end + + subject do + Setting.registrations_mode = 'approved' + request.headers["Accept-Language"] = accept_language + invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.from_now) + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code } } + end + + it 'redirects to login page' do + subject + expect(response).to redirect_to new_user_session_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) + expect(user.approved).to eq(true) + end + end + it 'does nothing if user already exists' do Fabricate(:user, account: Fabricate(:account, username: 'test')) subject -- cgit From 011b032300657ccca4a42866749afc6ec2588ecc Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 3 May 2019 20:36:36 +0200 Subject: Provide a link to existing domain block when trying to block an already-blocked domain (#10663) * When trying to block an already-blocked domain, provide a link to the block * Fix styling for links in flash messages * Allow blocks to be upgraded but not downgraded --- app/controllers/admin/domain_blocks_controller.rb | 22 +++++++++++---- app/javascript/styles/mastodon/forms.scss | 11 ++++++++ app/models/domain_block.rb | 7 +++++ config/locales/en.yml | 1 + .../admin/domain_blocks_controller_spec.rb | 13 ++++++++- spec/models/domain_block_spec.rb | 31 ++++++++++++++++++++++ 6 files changed, 79 insertions(+), 6 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb index 5f307ddee..dd3f83389 100644 --- a/app/controllers/admin/domain_blocks_controller.rb +++ b/app/controllers/admin/domain_blocks_controller.rb @@ -13,13 +13,25 @@ module Admin authorize :domain_block, :create? @domain_block = DomainBlock.new(resource_params) + existing_domain_block = resource_params[:domain].present? ? DomainBlock.find_by(domain: resource_params[:domain]) : nil - if @domain_block.save - DomainBlockWorker.perform_async(@domain_block.id) - log_action :create, @domain_block - redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg') - else + if existing_domain_block.present? && !@domain_block.stricter_than?(existing_domain_block) + @domain_block.save + flash[:alert] = I18n.t('admin.domain_blocks.existing_domain_block_html', name: existing_domain_block.domain, unblock_url: admin_domain_block_path(existing_domain_block)).html_safe # rubocop:disable Rails/OutputSafety + @domain_block.errors[:domain].clear render :new + else + if existing_domain_block.present? + @domain_block = existing_domain_block + @domain_block.update(resource_params) + end + if @domain_block.save + DomainBlockWorker.perform_async(@domain_block.id) + log_action :create, @domain_block + redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg') + else + render :new + end end end diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index 91888d305..2b8d7a682 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -533,6 +533,17 @@ code { color: $error-value-color; } + a { + display: inline-block; + color: $darker-text-color; + text-decoration: none; + + &:hover { + color: $primary-text-color; + text-decoration: underline; + } + } + p { margin-bottom: 15px; } diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb index 069cda367..0b12617c6 100644 --- a/app/models/domain_block.rb +++ b/app/models/domain_block.rb @@ -29,4 +29,11 @@ class DomainBlock < ApplicationRecord def self.blocked?(domain) where(domain: domain, severity: :suspend).exists? end + + def stricter_than?(other_block) + return true if suspend? + return false if other_block.suspend? && (silence? || noop?) + return false if other_block.silence? && noop? + (reject_media || !other_block.reject_media) && (reject_reports || !other_block.reject_reports) + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 405b0eda5..6d59411a5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -269,6 +269,7 @@ en: created_msg: Domain block is now being processed destroyed_msg: Domain block has been undone domain: Domain + existing_domain_block_html: You have already imposed stricter limits on %{name}, you need to unblock it first. new: create: Create block hint: The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts. diff --git a/spec/controllers/admin/domain_blocks_controller_spec.rb b/spec/controllers/admin/domain_blocks_controller_spec.rb index 129bf8883..2a8675c21 100644 --- a/spec/controllers/admin/domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/domain_blocks_controller_spec.rb @@ -37,7 +37,7 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do end it 'renders new when failed to save' do - Fabricate(:domain_block, domain: 'example.com') + Fabricate(:domain_block, domain: 'example.com', severity: 'suspend') allow(DomainBlockWorker).to receive(:perform_async).and_return(true) post :create, params: { domain_block: { domain: 'example.com', severity: 'silence' } } @@ -45,6 +45,17 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do expect(DomainBlockWorker).not_to have_received(:perform_async) expect(response).to render_template :new end + + it 'allows upgrading a block' do + Fabricate(:domain_block, domain: 'example.com', severity: 'silence') + allow(DomainBlockWorker).to receive(:perform_async).and_return(true) + + post :create, params: { domain_block: { domain: 'example.com', severity: 'silence', reject_media: true, reject_reports: true } } + + expect(DomainBlockWorker).to have_received(:perform_async) + expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.created_msg') + expect(response).to redirect_to(admin_instances_path(limited: '1')) + end end describe 'DELETE #destroy' do diff --git a/spec/models/domain_block_spec.rb b/spec/models/domain_block_spec.rb index 89cadccfe..0035fd0ff 100644 --- a/spec/models/domain_block_spec.rb +++ b/spec/models/domain_block_spec.rb @@ -36,4 +36,35 @@ RSpec.describe DomainBlock, type: :model do expect(DomainBlock.blocked?('domain')).to eq false end end + + describe 'stricter_than?' do + it 'returns true if the new block has suspend severity while the old has lower severity' do + suspend = DomainBlock.new(domain: 'domain', severity: :suspend) + silence = DomainBlock.new(domain: 'domain', severity: :silence) + noop = DomainBlock.new(domain: 'domain', severity: :noop) + expect(suspend.stricter_than?(silence)).to be true + expect(suspend.stricter_than?(noop)).to be true + end + + it 'returns false if the new block has lower severity than the old one' do + suspend = DomainBlock.new(domain: 'domain', severity: :suspend) + silence = DomainBlock.new(domain: 'domain', severity: :silence) + noop = DomainBlock.new(domain: 'domain', severity: :noop) + expect(silence.stricter_than?(suspend)).to be false + expect(noop.stricter_than?(suspend)).to be false + expect(noop.stricter_than?(silence)).to be false + end + + it 'returns false if the new block does is less strict regarding reports' do + older = DomainBlock.new(domain: 'domain', severity: :silence, reject_reports: true) + newer = DomainBlock.new(domain: 'domain', severity: :silence, reject_reports: false) + expect(newer.stricter_than?(older)).to be false + end + + it 'returns false if the new block does is less strict regarding media' do + older = DomainBlock.new(domain: 'domain', severity: :silence, reject_media: true) + newer = DomainBlock.new(domain: 'domain', severity: :silence, reject_media: false) + expect(newer.stricter_than?(older)).to be false + end + end end -- cgit From 91634947f88fb3004b5e853598f02fbe39a55768 Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 3 May 2019 20:39:19 +0200 Subject: Explicitly disable storage of REST API results (#10655) Fixes #10652 --- app/controllers/api/base_controller.rb | 6 ++++++ app/controllers/api/v1/custom_emojis_controller.rb | 2 ++ app/controllers/api/v1/instances/activity_controller.rb | 1 + app/controllers/api/v1/instances/peers_controller.rb | 1 + app/controllers/api/v1/instances_controller.rb | 1 + 5 files changed, 11 insertions(+) (limited to 'app/controllers') diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index 3a92ee4e4..eca558f42 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -9,6 +9,8 @@ class Api::BaseController < ApplicationController skip_before_action :store_current_location skip_before_action :check_user_permissions + before_action :set_cache_headers + protect_from_forgery with: :null_session rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e| @@ -88,4 +90,8 @@ class Api::BaseController < ApplicationController def authorize_if_got_token!(*scopes) doorkeeper_authorize!(*scopes) if doorkeeper_token end + + def set_cache_headers + response.headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate' + end end diff --git a/app/controllers/api/v1/custom_emojis_controller.rb b/app/controllers/api/v1/custom_emojis_controller.rb index 7bac27da4..1bb19a09d 100644 --- a/app/controllers/api/v1/custom_emojis_controller.rb +++ b/app/controllers/api/v1/custom_emojis_controller.rb @@ -3,6 +3,8 @@ class Api::V1::CustomEmojisController < Api::BaseController respond_to :json + skip_before_action :set_cache_headers + def index render_cached_json('api:v1:custom_emojis', expires_in: 1.minute) do ActiveModelSerializers::SerializableResource.new(CustomEmoji.local.where(disabled: false), each_serializer: REST::CustomEmojiSerializer) diff --git a/app/controllers/api/v1/instances/activity_controller.rb b/app/controllers/api/v1/instances/activity_controller.rb index e14e0aee8..09edfe365 100644 --- a/app/controllers/api/v1/instances/activity_controller.rb +++ b/app/controllers/api/v1/instances/activity_controller.rb @@ -2,6 +2,7 @@ class Api::V1::Instances::ActivityController < Api::BaseController before_action :require_enabled_api! + skip_before_action :set_cache_headers respond_to :json diff --git a/app/controllers/api/v1/instances/peers_controller.rb b/app/controllers/api/v1/instances/peers_controller.rb index 2070c487d..a8891d126 100644 --- a/app/controllers/api/v1/instances/peers_controller.rb +++ b/app/controllers/api/v1/instances/peers_controller.rb @@ -2,6 +2,7 @@ class Api::V1::Instances::PeersController < Api::BaseController before_action :require_enabled_api! + skip_before_action :set_cache_headers respond_to :json diff --git a/app/controllers/api/v1/instances_controller.rb b/app/controllers/api/v1/instances_controller.rb index 5686e8d7c..8c83a1801 100644 --- a/app/controllers/api/v1/instances_controller.rb +++ b/app/controllers/api/v1/instances_controller.rb @@ -2,6 +2,7 @@ class Api::V1::InstancesController < Api::BaseController respond_to :json + skip_before_action :set_cache_headers def show render_cached_json('api:v1:instances', expires_in: 5.minutes) do -- cgit