about summary refs log tree commit diff
path: root/app/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/accounts_controller.rb14
-rw-r--r--app/controllers/activitypub/collections_controller.rb17
-rw-r--r--app/controllers/activitypub/inboxes_controller.rb2
-rw-r--r--app/controllers/activitypub/outboxes_controller.rb6
-rw-r--r--app/controllers/activitypub/replies_controller.rb21
-rw-r--r--app/controllers/admin/instances_controller.rb2
-rw-r--r--app/controllers/api/v1/polls/votes_controller.rb2
-rw-r--r--app/controllers/api/v1/polls_controller.rb2
-rw-r--r--app/controllers/api/v1/push/subscriptions_controller.rb11
-rw-r--r--app/controllers/api/v1/statuses/mutes_controller.rb3
-rw-r--r--app/controllers/api/v1/statuses_controller.rb2
-rw-r--r--app/controllers/media_controller.rb2
-rw-r--r--app/controllers/remote_interaction_controller.rb2
-rw-r--r--app/controllers/settings/pictures_controller.rb37
-rw-r--r--app/controllers/statuses_controller.rb2
-rw-r--r--app/controllers/tags_controller.rb9
16 files changed, 94 insertions, 40 deletions
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index ee48da177..52d09cff8 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -28,7 +28,7 @@ class AccountsController < ApplicationController
         end
 
         @pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
-        @statuses        = filtered_status_page(params)
+        @statuses        = filtered_status_page
         @statuses        = cache_collection(@statuses, Status)
         @rss_url         = rss_url
 
@@ -141,12 +141,12 @@ class AccountsController < ApplicationController
     request.path.split('.').first.ends_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
   end
 
-  def filtered_status_page(params)
-    if params[:min_id].present?
-      filtered_statuses.paginate_by_min_id(PAGE_SIZE, params[:min_id]).reverse
-    else
-      filtered_statuses.paginate_by_max_id(PAGE_SIZE, params[:max_id], params[:since_id]).to_a
-    end
+  def filtered_status_page
+    filtered_statuses.paginate_by_id(PAGE_SIZE, params_slice(:max_id, :min_id, :since_id))
+  end
+
+  def params_slice(*keys)
+    params.slice(*keys).permit(*keys)
   end
 
   def restrict_fields_to
diff --git a/app/controllers/activitypub/collections_controller.rb b/app/controllers/activitypub/collections_controller.rb
index 910fefb1c..c1e7aa550 100644
--- a/app/controllers/activitypub/collections_controller.rb
+++ b/app/controllers/activitypub/collections_controller.rb
@@ -24,20 +24,23 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
   def set_size
     case params[:id]
     when 'featured'
-      @account.pinned_statuses.count
+      @size = @account.pinned_statuses.count
     else
-      raise ActiveRecord::RecordNotFound
+      not_found
     end
   end
 
   def scope_for_collection
     case params[:id]
     when 'featured'
-      return Status.none if @account.blocking?(signed_request_account)
-
-      @account.pinned_statuses
-    else
-      raise ActiveRecord::RecordNotFound
+      # Because in public fetch mode we cache the response, there would be no
+      # benefit from performing the check below, since a blocked account or domain
+      # would likely be served the cache from the reverse proxy anyway
+      if authorized_fetch_mode? && !signed_request_account.nil? && (@account.blocking?(signed_request_account) || (!signed_request_account.domain.nil? && @account.domain_blocking?(signed_request_account.domain)))
+        Status.none
+      else
+        @account.pinned_statuses
+      end
     end
   end
 
diff --git a/app/controllers/activitypub/inboxes_controller.rb b/app/controllers/activitypub/inboxes_controller.rb
index 291eec19a..0a561e7f0 100644
--- a/app/controllers/activitypub/inboxes_controller.rb
+++ b/app/controllers/activitypub/inboxes_controller.rb
@@ -49,7 +49,7 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
       ResolveAccountWorker.perform_async(signed_request_account.acct)
     end
 
-    DeliveryFailureTracker.track_inverse_success!(signed_request_account)
+    DeliveryFailureTracker.reset!(signed_request_account.inbox_url)
   end
 
   def process_payload
diff --git a/app/controllers/activitypub/outboxes_controller.rb b/app/controllers/activitypub/outboxes_controller.rb
index 891756b7e..e25a4bc07 100644
--- a/app/controllers/activitypub/outboxes_controller.rb
+++ b/app/controllers/activitypub/outboxes_controller.rb
@@ -11,7 +11,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
   before_action :set_cache_headers
 
   def show
-    expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode?)
+    expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode? && !(signed_request_account.present? && page_requested?))
     render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
   end
 
@@ -50,12 +50,12 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
     return unless page_requested?
 
     @statuses = @account.statuses.permitted_for(@account, signed_request_account)
-    @statuses = params[:min_id].present? ? @statuses.paginate_by_min_id(LIMIT, params[:min_id]).reverse : @statuses.paginate_by_max_id(LIMIT, params[:max_id])
+    @statuses = @statuses.paginate_by_id(LIMIT, params_slice(:max_id, :min_id, :since_id))
     @statuses = cache_collection(@statuses, Status)
   end
 
   def page_requested?
-    params[:page] == 'true'
+    truthy_param?(:page)
   end
 
   def page_params
diff --git a/app/controllers/activitypub/replies_controller.rb b/app/controllers/activitypub/replies_controller.rb
index c62061555..43bf4e657 100644
--- a/app/controllers/activitypub/replies_controller.rb
+++ b/app/controllers/activitypub/replies_controller.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class ActivityPub::RepliesController < ActivityPub::BaseController
-  include SignatureAuthentication
+  include SignatureVerification
   include Authorization
   include AccountOwnedConcern
 
@@ -19,15 +19,19 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
 
   private
 
+  def pundit_user
+    signed_request_account
+  end
+
   def set_status
     @status = @account.statuses.find(params[:status_id])
     authorize @status, :show?
   rescue Mastodon::NotPermittedError
-    raise ActiveRecord::RecordNotFound
+    not_found
   end
 
   def set_replies
-    @replies = page_params[:only_other_accounts] ? Status.where.not(account_id: @account.id) : @account.statuses
+    @replies = only_other_accounts? ? Status.where.not(account_id: @account.id) : @account.statuses
     @replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted])
     @replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
   end
@@ -38,7 +42,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
       type: :unordered,
       part_of: account_status_replies_url(@account, @status),
       next: next_page,
-      items: @replies.map { |status| status.local ? status : status.uri }
+      items: @replies.map { |status| status.local? ? status : status.uri }
     )
 
     return page if page_requested?
@@ -51,16 +55,21 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
   end
 
   def page_requested?
-    params[:page] == 'true'
+    truthy_param?(:page)
+  end
+
+  def only_other_accounts?
+    truthy_param?(:only_other_accounts)
   end
 
   def next_page
     only_other_accounts = !(@replies&.last&.account_id == @account.id && @replies.size == DESCENDANTS_LIMIT)
+
     account_status_replies_url(
       @account,
       @status,
       page: true,
-      min_id: only_other_accounts && !page_params[:only_other_accounts] ? nil : @replies&.last&.id,
+      min_id: only_other_accounts && !only_other_accounts? ? nil : @replies&.last&.id,
       only_other_accounts: only_other_accounts
     )
   end
diff --git a/app/controllers/admin/instances_controller.rb b/app/controllers/admin/instances_controller.rb
index 2fc041207..1790becbf 100644
--- a/app/controllers/admin/instances_controller.rb
+++ b/app/controllers/admin/instances_controller.rb
@@ -19,7 +19,7 @@ module Admin
       @followers_count = Follow.where(target_account: Account.where(domain: params[:id])).count
       @reports_count   = Report.where(target_account: Account.where(domain: params[:id])).count
       @blocks_count    = Block.where(target_account: Account.where(domain: params[:id])).count
-      @available       = DeliveryFailureTracker.available?(Account.select(:shared_inbox_url).where(domain: params[:id]).first&.shared_inbox_url)
+      @available       = DeliveryFailureTracker.available?(params[:id])
       @media_storage   = MediaAttachment.where(account: Account.where(domain: params[:id])).sum(:file_file_size)
       @private_comment = @domain_block&.private_comment
       @public_comment  = @domain_block&.public_comment
diff --git a/app/controllers/api/v1/polls/votes_controller.rb b/app/controllers/api/v1/polls/votes_controller.rb
index e1d26106a..513b937ef 100644
--- a/app/controllers/api/v1/polls/votes_controller.rb
+++ b/app/controllers/api/v1/polls/votes_controller.rb
@@ -18,7 +18,7 @@ class Api::V1::Polls::VotesController < Api::BaseController
     @poll = Poll.attached.find(params[:poll_id])
     authorize @poll.status, :show?
   rescue Mastodon::NotPermittedError
-    raise ActiveRecord::RecordNotFound
+    not_found
   end
 
   def vote_params
diff --git a/app/controllers/api/v1/polls_controller.rb b/app/controllers/api/v1/polls_controller.rb
index 744baf7bb..6435e9f0d 100644
--- a/app/controllers/api/v1/polls_controller.rb
+++ b/app/controllers/api/v1/polls_controller.rb
@@ -17,7 +17,7 @@ class Api::V1::PollsController < Api::BaseController
     @poll = Poll.attached.find(params[:id])
     authorize @poll.status, :show?
   rescue Mastodon::NotPermittedError
-    raise ActiveRecord::RecordNotFound
+    not_found
   end
 
   def refresh_poll
diff --git a/app/controllers/api/v1/push/subscriptions_controller.rb b/app/controllers/api/v1/push/subscriptions_controller.rb
index 1cbc92b93..d34b333eb 100644
--- a/app/controllers/api/v1/push/subscriptions_controller.rb
+++ b/app/controllers/api/v1/push/subscriptions_controller.rb
@@ -4,6 +4,7 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
   before_action -> { doorkeeper_authorize! :push }
   before_action :require_user!
   before_action :set_web_push_subscription
+  before_action :check_web_push_subscription, only: [:show, :update]
 
   def create
     @web_subscription&.destroy!
@@ -21,16 +22,11 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
   end
 
   def show
-    raise ActiveRecord::RecordNotFound if @web_subscription.nil?
-
     render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
   end
 
   def update
-    raise ActiveRecord::RecordNotFound if @web_subscription.nil?
-
     @web_subscription.update!(data: data_params)
-
     render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
   end
 
@@ -45,12 +41,17 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
     @web_subscription = ::Web::PushSubscription.find_by(access_token_id: doorkeeper_token.id)
   end
 
+  def check_web_push_subscription
+    not_found if @web_subscription.nil?
+  end
+
   def subscription_params
     params.require(:subscription).permit(:endpoint, keys: [:auth, :p256dh])
   end
 
   def data_params
     return {} if params[:data].blank?
+
     params.require(:data).permit(alerts: [:follow, :follow_request, :favourite, :reblog, :mention, :poll])
   end
 end
diff --git a/app/controllers/api/v1/statuses/mutes_controller.rb b/app/controllers/api/v1/statuses/mutes_controller.rb
index 43c7a525a..87071a2b9 100644
--- a/app/controllers/api/v1/statuses/mutes_controller.rb
+++ b/app/controllers/api/v1/statuses/mutes_controller.rb
@@ -28,8 +28,7 @@ class Api::V1::Statuses::MutesController < Api::BaseController
     @status = Status.find(params[:status_id])
     authorize @status, :show?
   rescue Mastodon::NotPermittedError
-    # Reraise in order to get a 404 instead of a 403 error code
-    raise ActiveRecord::RecordNotFound
+    not_found
   end
 
   def set_conversation
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index 29ae91762..b3edce676 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -68,7 +68,7 @@ class Api::V1::StatusesController < Api::BaseController
     @status = Status.find(params[:id])
     authorize @status, :show?
   rescue Mastodon::NotPermittedError
-    raise ActiveRecord::RecordNotFound
+    not_found
   end
 
   def set_thread
diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb
index 05cf09c28..1d166d6e7 100644
--- a/app/controllers/media_controller.rb
+++ b/app/controllers/media_controller.rb
@@ -33,7 +33,7 @@ class MediaController < ApplicationController
   def verify_permitted_status!
     authorize @media_attachment.status, :show?
   rescue Mastodon::NotPermittedError
-    raise ActiveRecord::RecordNotFound
+    not_found
   end
 
   def check_playable
diff --git a/app/controllers/remote_interaction_controller.rb b/app/controllers/remote_interaction_controller.rb
index e058d0ed5..51bb9bdea 100644
--- a/app/controllers/remote_interaction_controller.rb
+++ b/app/controllers/remote_interaction_controller.rb
@@ -42,7 +42,7 @@ class RemoteInteractionController < ApplicationController
     @status = Status.find(params[:id])
     authorize @status, :show?
   rescue Mastodon::NotPermittedError
-    raise ActiveRecord::RecordNotFound
+    not_found
   end
 
   def set_body_classes
diff --git a/app/controllers/settings/pictures_controller.rb b/app/controllers/settings/pictures_controller.rb
new file mode 100644
index 000000000..73926707b
--- /dev/null
+++ b/app/controllers/settings/pictures_controller.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Settings
+  class PicturesController < BaseController
+    before_action :authenticate_user!
+    before_action :set_account
+    before_action :set_picture
+
+    def destroy
+      if valid_picture
+        account_params = {
+          @picture => nil,
+          (@picture + '_remote_url') => nil,
+        }
+
+        msg = UpdateAccountService.new.call(@account, account_params) ? I18n.t('generic.changes_saved_msg') : nil
+        redirect_to settings_profile_path, notice: msg, status: 303
+      else
+        bad_request
+      end
+    end
+
+    private
+
+    def set_account
+      @account = current_account
+    end
+
+    def set_picture
+      @picture = params[:id]
+    end
+
+    def valid_picture
+      @picture == 'avatar' || @picture == 'header'
+    end
+  end
+end
diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb
index 588063d01..a1b7f4320 100644
--- a/app/controllers/statuses_controller.rb
+++ b/app/controllers/statuses_controller.rb
@@ -49,7 +49,7 @@ class StatusesController < ApplicationController
 
   def embed
     use_pack 'embed'
-    return not_found if @status.hidden?
+    return not_found if @status.hidden? || @status.reblog?
 
     expires_in 180, public: true
     response.headers['X-Frame-Options'] = 'ALLOWALL'
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index c59446efc..3d12c9eaf 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -10,6 +10,7 @@ class TagsController < ApplicationController
   before_action :require_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
   before_action :authenticate_user!, if: :whitelist_mode?
   before_action :set_tag
+  before_action :set_local
   before_action :set_body_classes
   before_action :set_instance_presenter
 
@@ -25,7 +26,7 @@ class TagsController < ApplicationController
       format.rss do
         expires_in 0, public: true
 
-        @statuses = HashtagQueryService.new.call(@tag, filter_params).limit(PAGE_SIZE)
+        @statuses = HashtagQueryService.new.call(@tag, filter_params, nil, @local).limit(PAGE_SIZE)
         @statuses = cache_collection(@statuses, Status)
 
         render xml: RSS::TagSerializer.render(@tag, @statuses)
@@ -34,7 +35,7 @@ class TagsController < ApplicationController
       format.json do
         expires_in 3.minutes, public: public_fetch_mode?
 
-        @statuses = HashtagQueryService.new.call(@tag, filter_params, current_account, params[:local]).paginate_by_max_id(PAGE_SIZE, params[:max_id])
+        @statuses = HashtagQueryService.new.call(@tag, filter_params, current_account, @local).paginate_by_max_id(PAGE_SIZE, params[:max_id])
         @statuses = cache_collection(@statuses, Status)
 
         render json: collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
@@ -48,6 +49,10 @@ class TagsController < ApplicationController
     @tag = Tag.usable.find_normalized!(params[:id])
   end
 
+  def set_local
+    @local = truthy_param?(:local)
+  end
+
   def set_body_classes
     @body_classes = 'with-modals'
   end