about summary refs log tree commit diff
path: root/app/controllers
diff options
context:
space:
mode:
authorReverite <github@reverite.sh>2019-03-10 19:19:52 -0700
committerReverite <github@reverite.sh>2019-03-10 19:19:52 -0700
commit229e2726cad36066afb210d7087a40cd9f955483 (patch)
treea14d55e9469f1f339fc40b777827aa4886bb7889 /app/controllers
parent715c552fe4c1b2d59bf1f281d77b6e2546bdb531 (diff)
parent3cef04610cd809c7bd01adc00d34fb3d25261a16 (diff)
Merge branch 'glitch'
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/api/v1/polls/votes_controller.rb29
-rw-r--r--app/controllers/api/v1/polls_controller.rb13
-rw-r--r--app/controllers/api/v1/statuses_controller.rb18
-rw-r--r--app/controllers/statuses_controller.rb53
4 files changed, 111 insertions, 2 deletions
diff --git a/app/controllers/api/v1/polls/votes_controller.rb b/app/controllers/api/v1/polls/votes_controller.rb
new file mode 100644
index 000000000..3fa0b6a76
--- /dev/null
+++ b/app/controllers/api/v1/polls/votes_controller.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class Api::V1::Polls::VotesController < Api::BaseController
+  include Authorization
+
+  before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
+  before_action :require_user!
+  before_action :set_poll
+
+  respond_to :json
+
+  def create
+    VoteService.new.call(current_account, @poll, vote_params[:choices])
+    render json: @poll, serializer: REST::PollSerializer
+  end
+
+  private
+
+  def set_poll
+    @poll = Poll.attached.find(params[:poll_id])
+    authorize @poll.status, :show?
+  rescue Mastodon::NotPermittedError
+    raise ActiveRecord::RecordNotFound
+  end
+
+  def vote_params
+    params.permit(choices: [])
+  end
+end
diff --git a/app/controllers/api/v1/polls_controller.rb b/app/controllers/api/v1/polls_controller.rb
new file mode 100644
index 000000000..4f4a6858d
--- /dev/null
+++ b/app/controllers/api/v1/polls_controller.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class Api::V1::PollsController < Api::BaseController
+  before_action -> { authorize_if_got_token! :read, :'read:statuses' }, only: :show
+
+  respond_to :json
+
+  def show
+    @poll = Poll.attached.find(params[:id])
+    ActivityPub::FetchRemotePollService.new.call(@poll, current_account) if user_signed_in? && @poll.possibly_stale?
+    render json: @poll, serializer: REST::PollSerializer, include_results: true
+  end
+end
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index 29b420c67..f9506971a 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -53,6 +53,7 @@ class Api::V1::StatusesController < Api::BaseController
                                          visibility: status_params[:visibility],
                                          scheduled_at: status_params[:scheduled_at],
                                          application: doorkeeper_token.application,
+                                         poll: status_params[:poll],
                                          idempotency: request.headers['Idempotency-Key'])
 
     render json: @status, serializer: @status.is_a?(ScheduledStatus) ? REST::ScheduledStatusSerializer : REST::StatusSerializer
@@ -73,12 +74,25 @@ class Api::V1::StatusesController < Api::BaseController
     @status = Status.find(params[:id])
     authorize @status, :show?
   rescue Mastodon::NotPermittedError
-    # Reraise in order to get a 404 instead of a 403 error code
     raise ActiveRecord::RecordNotFound
   end
 
   def status_params
-    params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, :scheduled_at, media_ids: [])
+    params.permit(
+      :status,
+      :in_reply_to_id,
+      :sensitive,
+      :spoiler_text,
+      :visibility,
+      :scheduled_at,
+      media_ids: [],
+      poll: [
+        :multiple,
+        :hide_totals,
+        :expires_in,
+        options: [],
+      ]
+    )
   end
 
   def pagination_params(core_params)
diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb
index 99c16157f..6f56a67ba 100644
--- a/app/controllers/statuses_controller.rb
+++ b/app/controllers/statuses_controller.rb
@@ -18,6 +18,7 @@ class StatusesController < ApplicationController
   before_action :redirect_to_original, only: [:show]
   before_action :set_referrer_policy_header, only: [:show]
   before_action :set_cache_headers
+  before_action :set_replies, only: [:replies]
 
   content_security_policy only: :embed do |p|
     p.frame_ancestors(false)
@@ -65,8 +66,37 @@ class StatusesController < ApplicationController
     render 'stream_entries/embed', layout: 'embedded'
   end
 
+  def replies
+    skip_session!
+
+    render json: replies_collection_presenter,
+           serializer: ActivityPub::CollectionSerializer,
+           adapter: ActivityPub::Adapter,
+           content_type: 'application/activity+json',
+           skip_activities: true
+  end
+
   private
 
+  def replies_collection_presenter
+    page = ActivityPub::CollectionPresenter.new(
+      id: replies_account_status_url(@account, @status, page_params),
+      type: :unordered,
+      part_of: replies_account_status_url(@account, @status),
+      next: next_page,
+      items: @replies.map { |status| status.local ? status : status.id }
+    )
+    if page_requested?
+      page
+    else
+      ActivityPub::CollectionPresenter.new(
+        id: replies_account_status_url(@account, @status),
+        type: :unordered,
+        first: page
+      )
+    end
+  end
+
   def create_descendant_thread(starting_depth, statuses)
     depth = starting_depth + statuses.size
     if depth < DESCENDANTS_DEPTH_LIMIT
@@ -176,4 +206,27 @@ class StatusesController < ApplicationController
     return if @status.public_visibility? || @status.unlisted_visibility?
     response.headers['Referrer-Policy'] = 'origin'
   end
+
+  def page_requested?
+    params[:page] == 'true'
+  end
+
+  def set_replies
+    @replies = page_params[: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
+
+  def next_page
+    last_reply = @replies.last
+    return if last_reply.nil?
+    same_account = last_reply.account_id == @account.id
+    return unless same_account || @replies.size == DESCENDANTS_LIMIT
+    same_account = false unless @replies.size == DESCENDANTS_LIMIT
+    replies_account_status_url(@account, @status, page: true, min_id: last_reply.id, other_accounts: !same_account)
+  end
+
+  def page_params
+    { page: true, other_accounts: params[:other_accounts], min_id: params[:min_id] }.compact
+  end
 end