about summary refs log tree commit diff
path: root/app/controllers
diff options
context:
space:
mode:
authorThibaut Girka <thib@sitedethib.com>2019-01-10 19:12:10 +0100
committerThibaut Girka <thib@sitedethib.com>2019-01-10 21:00:30 +0100
commita2a64ecd3e3551707412c47f0d16e484dea25632 (patch)
treebc4e0b8e0ca2a2735f527bff8bd73421c0ff72dd /app/controllers
parentfb0c906c717f2b21bb63610742a357850142b522 (diff)
parent70801b850c78d7879182eeba4eae509af42fafeb (diff)
Merge branch 'master' into glitch-soc/merge-upstream
Conflicts:
- .eslintrc.yml
  Removed, as upstream removed it.
- app/controllers/admin/statuses_controller.rb
  Minor code cleanup when porting one of our features.
- app/models/account.rb
  Note length validation has changed upstream.
  We now use upstream's validation (dropped legacy glitch-soc
  account metadata stuff) but with configurable limit.
- app/services/post_status_service.rb
  Upstream has added support for scheduled toots, refactoring
  the code a bit. Adapted our changes to this refactoring.
- app/views/stream_entries/_detailed_status.html.haml
  Not a real conflict, changes too close.
- app/views/stream_entries/_simple_status.html.haml
  Not a real conflict, changes too close.
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/admin/domain_blocks_controller.rb11
-rw-r--r--app/controllers/admin/followers_controller.rb6
-rw-r--r--app/controllers/admin/instances_controller.rb27
-rw-r--r--app/controllers/admin/statuses_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts_controller.rb2
-rw-r--r--app/controllers/api/v1/custom_emojis_controller.rb4
-rw-r--r--app/controllers/api/v1/scheduled_statuses_controller.rb77
-rw-r--r--app/controllers/api/v1/statuses_controller.rb9
-rw-r--r--app/controllers/concerns/signature_verification.rb45
-rw-r--r--app/controllers/remote_interaction_controller.rb5
10 files changed, 141 insertions, 47 deletions
diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb
index 90c70275a..5f307ddee 100644
--- a/app/controllers/admin/domain_blocks_controller.rb
+++ b/app/controllers/admin/domain_blocks_controller.rb
@@ -4,14 +4,9 @@ module Admin
   class DomainBlocksController < BaseController
     before_action :set_domain_block, only: [:show, :destroy]
 
-    def index
-      authorize :domain_block, :index?
-      @domain_blocks = DomainBlock.page(params[:page])
-    end
-
     def new
       authorize :domain_block, :create?
-      @domain_block = DomainBlock.new
+      @domain_block = DomainBlock.new(domain: params[:_domain])
     end
 
     def create
@@ -22,7 +17,7 @@ module Admin
       if @domain_block.save
         DomainBlockWorker.perform_async(@domain_block.id)
         log_action :create, @domain_block
-        redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.created_msg')
+        redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
       else
         render :new
       end
@@ -36,7 +31,7 @@ module Admin
       authorize @domain_block, :destroy?
       UnblockDomainService.new.call(@domain_block, retroactive_unblock?)
       log_action :destroy, @domain_block
-      redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.destroyed_msg')
+      redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.destroyed_msg')
     end
 
     private
diff --git a/app/controllers/admin/followers_controller.rb b/app/controllers/admin/followers_controller.rb
index 819628b20..d826f47c5 100644
--- a/app/controllers/admin/followers_controller.rb
+++ b/app/controllers/admin/followers_controller.rb
@@ -8,15 +8,11 @@ module Admin
 
     def index
       authorize :account, :index?
-      @followers = followers.recent.page(params[:page]).per(PER_PAGE)
+      @followers = @account.followers.local.recent.page(params[:page]).per(PER_PAGE)
     end
 
     def set_account
       @account = Account.find(params[:account_id])
     end
-
-    def followers
-      Follow.includes(:account).where(target_account: @account)
-    end
   end
 end
diff --git a/app/controllers/admin/instances_controller.rb b/app/controllers/admin/instances_controller.rb
index 6f8eaf65c..431ce6f4d 100644
--- a/app/controllers/admin/instances_controller.rb
+++ b/app/controllers/admin/instances_controller.rb
@@ -4,14 +4,21 @@ module Admin
   class InstancesController < BaseController
     def index
       authorize :instance, :index?
+
       @instances = ordered_instances
     end
 
-    def resubscribe
-      authorize :instance, :resubscribe?
-      params.require(:by_domain)
-      Pubsubhubbub::SubscribeWorker.push_bulk(subscribeable_accounts.pluck(:id))
-      redirect_to admin_instances_path
+    def show
+      authorize :instance, :show?
+
+      @instance        = Instance.new(Account.by_domain_accounts.find_by(domain: params[:id]) || DomainBlock.find_by!(domain: params[:id]))
+      @following_count = Follow.where(account: Account.where(domain: params[:id])).count
+      @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)
+      @media_storage   = MediaAttachment.where(account: Account.where(domain: params[:id])).sum(:file_file_size)
+      @domain_block    = DomainBlock.find_by(domain: params[:id])
     end
 
     private
@@ -27,17 +34,11 @@ module Admin
     helper_method :paginated_instances
 
     def ordered_instances
-      paginated_instances.map { |account| Instance.new(account) }
-    end
-
-    def subscribeable_accounts
-      Account.remote.where(protocol: :ostatus).where(domain: params[:by_domain])
+      paginated_instances.map { |resource| Instance.new(resource) }
     end
 
     def filter_params
-      params.permit(
-        :domain_name
-      )
+      params.permit(:limited)
     end
   end
 end
diff --git a/app/controllers/admin/statuses_controller.rb b/app/controllers/admin/statuses_controller.rb
index 62f49806c..650195034 100644
--- a/app/controllers/admin/statuses_controller.rb
+++ b/app/controllers/admin/statuses_controller.rb
@@ -26,7 +26,7 @@ module Admin
       authorize :status, :index?
 
       @statuses = @account.statuses.where(id: params[:id])
-      authorize @statuses[0], :show?
+      authorize @statuses.first, :show?
 
       @form = Form::StatusBatch.new
     end
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index 6e4084c4e..2ccbc3cbb 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -76,7 +76,7 @@ class Api::V1::AccountsController < Api::BaseController
   end
 
   def account_params
-    params.permit(:username, :email, :password, :agreement)
+    params.permit(:username, :email, :password, :agreement, :locale)
   end
 
   def check_enabled_registrations
diff --git a/app/controllers/api/v1/custom_emojis_controller.rb b/app/controllers/api/v1/custom_emojis_controller.rb
index f8cd64455..7bac27da4 100644
--- a/app/controllers/api/v1/custom_emojis_controller.rb
+++ b/app/controllers/api/v1/custom_emojis_controller.rb
@@ -4,6 +4,8 @@ class Api::V1::CustomEmojisController < Api::BaseController
   respond_to :json
 
   def index
-    render json: CustomEmoji.local.where(disabled: false), each_serializer: REST::CustomEmojiSerializer
+    render_cached_json('api:v1:custom_emojis', expires_in: 1.minute) do
+      ActiveModelSerializers::SerializableResource.new(CustomEmoji.local.where(disabled: false), each_serializer: REST::CustomEmojiSerializer)
+    end
   end
 end
diff --git a/app/controllers/api/v1/scheduled_statuses_controller.rb b/app/controllers/api/v1/scheduled_statuses_controller.rb
new file mode 100644
index 000000000..9950296f3
--- /dev/null
+++ b/app/controllers/api/v1/scheduled_statuses_controller.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+class Api::V1::ScheduledStatusesController < Api::BaseController
+  include Authorization
+
+  before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, except: [:update, :destroy]
+  before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:update, :destroy]
+
+  before_action :set_statuses, only: :index
+  before_action :set_status, except: :index
+
+  after_action :insert_pagination_headers, only: :index
+
+  def index
+    render json: @statuses, each_serializer: REST::ScheduledStatusSerializer
+  end
+
+  def show
+    render json: @status, serializer: REST::ScheduledStatusSerializer
+  end
+
+  def update
+    @status.update!(scheduled_status_params)
+    render json: @status, serializer: REST::ScheduledStatusSerializer
+  end
+
+  def destroy
+    @status.destroy!
+    render_empty
+  end
+
+  private
+
+  def set_statuses
+    @statuses = current_account.scheduled_statuses.paginate_by_id(limit_param(DEFAULT_STATUSES_LIMIT), params_slice(:max_id, :since_id, :min_id))
+  end
+
+  def set_status
+    @status = current_account.scheduled_statuses.find(params[:id])
+  end
+
+  def scheduled_status_params
+    params.permit(:scheduled_at)
+  end
+
+  def pagination_params(core_params)
+    params.slice(:limit).permit(:limit).merge(core_params)
+  end
+
+  def insert_pagination_headers
+    set_pagination_headers(next_path, prev_path)
+  end
+
+  def next_path
+    if records_continue?
+      api_v1_scheduled_statuses_url pagination_params(max_id: pagination_max_id)
+    end
+  end
+
+  def prev_path
+    unless @statuses.empty?
+      api_v1_scheduled_statuses_url pagination_params(min_id: pagination_since_id)
+    end
+  end
+
+  def records_continue?
+    @statuses.size == limit_param(DEFAULT_STATUSES_LIMIT)
+  end
+
+  def pagination_max_id
+    @statuses.last.id
+  end
+
+  def pagination_since_id
+    @statuses.first.id
+  end
+end
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index 49a52f7a6..29b420c67 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -45,16 +45,17 @@ class Api::V1::StatusesController < Api::BaseController
 
   def create
     @status = PostStatusService.new.call(current_user.account,
-                                         status_params[:status],
-                                         status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]),
+                                         text: status_params[:status],
+                                         thread: status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]),
                                          media_ids: status_params[:media_ids],
                                          sensitive: status_params[:sensitive],
                                          spoiler_text: status_params[:spoiler_text],
                                          visibility: status_params[:visibility],
+                                         scheduled_at: status_params[:scheduled_at],
                                          application: doorkeeper_token.application,
                                          idempotency: request.headers['Idempotency-Key'])
 
-    render json: @status, serializer: REST::StatusSerializer
+    render json: @status, serializer: @status.is_a?(ScheduledStatus) ? REST::ScheduledStatusSerializer : REST::StatusSerializer
   end
 
   def destroy
@@ -77,7 +78,7 @@ class Api::V1::StatusesController < Api::BaseController
   end
 
   def status_params
-    params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, media_ids: [])
+    params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, :scheduled_at, media_ids: [])
   end
 
   def pagination_params(core_params)
diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb
index 887096e8b..91566c4fa 100644
--- a/app/controllers/concerns/signature_verification.rb
+++ b/app/controllers/concerns/signature_verification.rb
@@ -60,23 +60,26 @@ module SignatureVerification
     signature             = Base64.decode64(signature_params['signature'])
     compare_signed_string = build_signed_string(signature_params['headers'])
 
-    if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string)
-      @signed_request_account = account
-      @signed_request_account
-    elsif account.possibly_stale?
-      account = account.refresh!
+    return account unless verify_signature(account, signature, compare_signed_string).nil?
 
-      if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string)
-        @signed_request_account = account
-        @signed_request_account
-      else
-        @signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
-        @signed_request_account = nil
-      end
-    else
-      @signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
+    account_stoplight = Stoplight("source:#{request.ip}") { account.possibly_stale? ? account.refresh! : account_refresh_key(account) }
+      .with_fallback { nil }
+      .with_threshold(1)
+      .with_cool_off_time(5.minutes.seconds)
+      .with_error_handler { |error, handle| error.is_a?(HTTP::Error) ? handle.call(error) : raise(error) }
+
+    account = account_stoplight.run
+
+    if account.nil?
+      @signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}"
       @signed_request_account = nil
+      return
     end
+
+    return account unless verify_signature(account, signature, compare_signed_string).nil?
+
+    @signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
+    @signed_request_account = nil
   end
 
   def request_body
@@ -85,6 +88,15 @@ module SignatureVerification
 
   private
 
+  def verify_signature(account, signature, compare_signed_string)
+    if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string)
+      @signed_request_account = account
+      @signed_request_account
+    end
+  rescue OpenSSL::PKey::RSAError
+    nil
+  end
+
   def build_signed_string(signed_headers)
     signed_headers = 'date' if signed_headers.blank?
 
@@ -131,4 +143,9 @@ module SignatureVerification
       account
     end
   end
+
+  def account_refresh_key(account)
+    return if account.local? || !account.activitypub?
+    ActivityPub::FetchRemoteAccountService.new.call(account.uri, only_key: true)
+  end
 end
diff --git a/app/controllers/remote_interaction_controller.rb b/app/controllers/remote_interaction_controller.rb
index 6861f3f21..d7197d434 100644
--- a/app/controllers/remote_interaction_controller.rb
+++ b/app/controllers/remote_interaction_controller.rb
@@ -5,6 +5,7 @@ class RemoteInteractionController < ApplicationController
 
   layout 'modal'
 
+  before_action :set_interaction_type
   before_action :set_status
   before_action :set_body_classes
   before_action :set_pack
@@ -50,4 +51,8 @@ class RemoteInteractionController < ApplicationController
   def set_pack
     use_pack 'modal'
   end
+
+  def set_interaction_type
+    @interaction_type = %w(reply reblog favourite).include?(params[:type]) ? params[:type] : 'reply'
+  end
 end