about summary refs log tree commit diff
path: root/app/controllers/api
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/api')
-rw-r--r--app/controllers/api/base_controller.rb7
-rw-r--r--app/controllers/api/proofs_controller.rb23
-rw-r--r--app/controllers/api/v1/accounts/identity_proofs_controller.rb3
-rw-r--r--app/controllers/api/v1/accounts/statuses_controller.rb4
-rw-r--r--app/controllers/api/v1/accounts_controller.rb15
-rw-r--r--app/controllers/api/v1/admin/account_actions_controller.rb4
-rw-r--r--app/controllers/api/v1/admin/accounts_controller.rb8
-rw-r--r--app/controllers/api/v1/admin/dimensions_controller.rb25
-rw-r--r--app/controllers/api/v1/admin/measures_controller.rb24
-rw-r--r--app/controllers/api/v1/admin/reports_controller.rb16
-rw-r--r--app/controllers/api/v1/admin/retention_controller.rb23
-rw-r--r--app/controllers/api/v1/admin/trends/tags_controller.rb19
-rw-r--r--app/controllers/api/v1/instances/activity_controller.rb27
-rw-r--r--app/controllers/api/v1/statuses/histories_controller.rb21
-rw-r--r--app/controllers/api/v1/statuses/sources_controller.rb21
-rw-r--r--app/controllers/api/v1/statuses_controller.rb2
-rw-r--r--app/controllers/api/v1/trends/links_controller.rb21
-rw-r--r--app/controllers/api/v1/trends/tags_controller.rb21
-rw-r--r--app/controllers/api/v1/trends_controller.rb15
19 files changed, 231 insertions, 68 deletions
diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
index 85f4cc768..b863d8643 100644
--- a/app/controllers/api/base_controller.rb
+++ b/app/controllers/api/base_controller.rb
@@ -40,7 +40,12 @@ class Api::BaseController < ApplicationController
     render json: { error: 'This action is not allowed' }, status: 403
   end
 
-  rescue_from Mastodon::RaceConditionError, Seahorse::Client::NetworkingError, Stoplight::Error::RedLight do
+  rescue_from Seahorse::Client::NetworkingError do |e|
+    Rails.logger.warn "Storage server error: #{e}"
+    render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
+  end
+
+  rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight do
     render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
   end
 
diff --git a/app/controllers/api/proofs_controller.rb b/app/controllers/api/proofs_controller.rb
deleted file mode 100644
index dd32cd577..000000000
--- a/app/controllers/api/proofs_controller.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class Api::ProofsController < Api::BaseController
-  include AccountOwnedConcern
-
-  skip_before_action :require_authenticated_user!
-
-  before_action :set_provider
-
-  def index
-    render json: @account, serializer: @provider.serializer_class
-  end
-
-  private
-
-  def set_provider
-    @provider = ProofProvider.find(params[:provider]) || raise(ActiveRecord::RecordNotFound)
-  end
-
-  def username_param
-    params[:username]
-  end
-end
diff --git a/app/controllers/api/v1/accounts/identity_proofs_controller.rb b/app/controllers/api/v1/accounts/identity_proofs_controller.rb
index 4b5f6902c..48f293f47 100644
--- a/app/controllers/api/v1/accounts/identity_proofs_controller.rb
+++ b/app/controllers/api/v1/accounts/identity_proofs_controller.rb
@@ -5,8 +5,7 @@ class Api::V1::Accounts::IdentityProofsController < Api::BaseController
   before_action :set_account
 
   def index
-    @proofs = @account.suspended? ? [] : @account.identity_proofs.active
-    render json: @proofs, each_serializer: REST::IdentityProofSerializer
+    render json: []
   end
 
   private
diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb
index 6e44f5c01..5e5d2b19b 100644
--- a/app/controllers/api/v1/accounts/statuses_controller.rb
+++ b/app/controllers/api/v1/accounts/statuses_controller.rb
@@ -48,9 +48,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
   end
 
   def pinned_scope
-    return Status.none if @account.blocking?(current_account)
-
-    @account.pinned_statuses
+    @account.pinned_statuses.permitted_for(@account, current_account)
   end
 
   def no_replies_scope
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index 95869f554..5c47158e0 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -1,8 +1,8 @@
 # frozen_string_literal: true
 
 class Api::V1::AccountsController < Api::BaseController
-  before_action -> { authorize_if_got_token! :read, :'read:accounts' }, except: [:create, :follow, :unfollow, :block, :unblock, :mute, :unmute]
-  before_action -> { doorkeeper_authorize! :follow, :'write:follows' }, only: [:follow, :unfollow]
+  before_action -> { authorize_if_got_token! :read, :'read:accounts' }, except: [:create, :follow, :unfollow, :remove_from_followers, :block, :unblock, :mute, :unmute]
+  before_action -> { doorkeeper_authorize! :follow, :'write:follows' }, only: [:follow, :unfollow, :remove_from_followers]
   before_action -> { doorkeeper_authorize! :follow, :'write:mutes' }, only: [:mute, :unmute]
   before_action -> { doorkeeper_authorize! :follow, :'write:blocks' }, only: [:block, :unblock]
   before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:create]
@@ -53,6 +53,11 @@ class Api::V1::AccountsController < Api::BaseController
     render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
   end
 
+  def remove_from_followers
+    RemoveFromFollowersService.new.call(current_user.account, @account)
+    render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
+  end
+
   def unblock
     UnblockService.new.call(current_user.account, @account)
     render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
@@ -78,10 +83,14 @@ class Api::V1::AccountsController < Api::BaseController
   end
 
   def check_enabled_registrations
-    forbidden if single_user_mode? || !allowed_registrations?
+    forbidden if single_user_mode? || omniauth_only? || !allowed_registrations?
   end
 
   def allowed_registrations?
     Setting.registrations_mode != 'none'
   end
+
+  def omniauth_only?
+    ENV['OMNIAUTH_ONLY'] == 'true'
+  end
 end
diff --git a/app/controllers/api/v1/admin/account_actions_controller.rb b/app/controllers/api/v1/admin/account_actions_controller.rb
index 29c9b7107..15af50822 100644
--- a/app/controllers/api/v1/admin/account_actions_controller.rb
+++ b/app/controllers/api/v1/admin/account_actions_controller.rb
@@ -1,7 +1,9 @@
 # frozen_string_literal: true
 
 class Api::V1::Admin::AccountActionsController < Api::BaseController
-  before_action -> { doorkeeper_authorize! :'admin:write', :'admin:write:accounts' }
+  protect_from_forgery with: :exception
+
+  before_action -> { authorize_if_got_token! :'admin:write', :'admin:write:accounts' }
   before_action :require_staff!
   before_action :set_account
 
diff --git a/app/controllers/api/v1/admin/accounts_controller.rb b/app/controllers/api/v1/admin/accounts_controller.rb
index 63cc521ed..65330b8c8 100644
--- a/app/controllers/api/v1/admin/accounts_controller.rb
+++ b/app/controllers/api/v1/admin/accounts_controller.rb
@@ -1,13 +1,15 @@
 # frozen_string_literal: true
 
 class Api::V1::Admin::AccountsController < Api::BaseController
+  protect_from_forgery with: :exception
+
   include Authorization
   include AccountableConcern
 
   LIMIT = 100
 
-  before_action -> { doorkeeper_authorize! :'admin:read', :'admin:read:accounts' }, only: [:index, :show]
-  before_action -> { doorkeeper_authorize! :'admin:write', :'admin:write:accounts' }, except: [:index, :show]
+  before_action -> { authorize_if_got_token! :'admin:read', :'admin:read:accounts' }, only: [:index, :show]
+  before_action -> { authorize_if_got_token! :'admin:write', :'admin:write:accounts' }, except: [:index, :show]
   before_action :require_staff!
   before_action :set_accounts, only: :index
   before_action :set_account, except: :index
@@ -94,7 +96,7 @@ class Api::V1::Admin::AccountsController < Api::BaseController
   private
 
   def set_accounts
-    @accounts = filtered_accounts.order(id: :desc).includes(user: [:invite_request, :invite]).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
+    @accounts = filtered_accounts.order(id: :desc).includes(user: [:invite_request, :invite, :ips]).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
   end
 
   def set_account
diff --git a/app/controllers/api/v1/admin/dimensions_controller.rb b/app/controllers/api/v1/admin/dimensions_controller.rb
new file mode 100644
index 000000000..b1f738990
--- /dev/null
+++ b/app/controllers/api/v1/admin/dimensions_controller.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class Api::V1::Admin::DimensionsController < Api::BaseController
+  protect_from_forgery with: :exception
+
+  before_action -> { authorize_if_got_token! :'admin:read' }
+  before_action :require_staff!
+  before_action :set_dimensions
+
+  def create
+    render json: @dimensions, each_serializer: REST::Admin::DimensionSerializer
+  end
+
+  private
+
+  def set_dimensions
+    @dimensions = Admin::Metrics::Dimension.retrieve(
+      params[:keys],
+      params[:start_at],
+      params[:end_at],
+      params[:limit],
+      params
+    )
+  end
+end
diff --git a/app/controllers/api/v1/admin/measures_controller.rb b/app/controllers/api/v1/admin/measures_controller.rb
new file mode 100644
index 000000000..d64c3cdf7
--- /dev/null
+++ b/app/controllers/api/v1/admin/measures_controller.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class Api::V1::Admin::MeasuresController < Api::BaseController
+  protect_from_forgery with: :exception
+
+  before_action -> { authorize_if_got_token! :'admin:read' }
+  before_action :require_staff!
+  before_action :set_measures
+
+  def create
+    render json: @measures, each_serializer: REST::Admin::MeasureSerializer
+  end
+
+  private
+
+  def set_measures
+    @measures = Admin::Metrics::Measure.retrieve(
+      params[:keys],
+      params[:start_at],
+      params[:end_at],
+      params
+    )
+  end
+end
diff --git a/app/controllers/api/v1/admin/reports_controller.rb b/app/controllers/api/v1/admin/reports_controller.rb
index c8f4cd8d8..fbfd0ee12 100644
--- a/app/controllers/api/v1/admin/reports_controller.rb
+++ b/app/controllers/api/v1/admin/reports_controller.rb
@@ -1,13 +1,15 @@
 # frozen_string_literal: true
 
 class Api::V1::Admin::ReportsController < Api::BaseController
+  protect_from_forgery with: :exception
+
   include Authorization
   include AccountableConcern
 
   LIMIT = 100
 
-  before_action -> { doorkeeper_authorize! :'admin:read', :'admin:read:reports' }, only: [:index, :show]
-  before_action -> { doorkeeper_authorize! :'admin:write', :'admin:write:reports' }, except: [:index, :show]
+  before_action -> { authorize_if_got_token! :'admin:read', :'admin:read:reports' }, only: [:index, :show]
+  before_action -> { authorize_if_got_token! :'admin:write', :'admin:write:reports' }, except: [:index, :show]
   before_action :require_staff!
   before_action :set_reports, only: :index
   before_action :set_report, except: :index
@@ -32,6 +34,12 @@ class Api::V1::Admin::ReportsController < Api::BaseController
     render json: @report, serializer: REST::Admin::ReportSerializer
   end
 
+  def update
+    authorize @report, :update?
+    @report.update!(report_params)
+    render json: @report, serializer: REST::Admin::ReportSerializer
+  end
+
   def assign_to_self
     authorize @report, :update?
     @report.update!(assigned_account_id: current_account.id)
@@ -74,6 +82,10 @@ class Api::V1::Admin::ReportsController < Api::BaseController
     ReportFilter.new(filter_params).results
   end
 
+  def report_params
+    params.permit(:category, rule_ids: [])
+  end
+
   def filter_params
     params.permit(*FILTER_PARAMS)
   end
diff --git a/app/controllers/api/v1/admin/retention_controller.rb b/app/controllers/api/v1/admin/retention_controller.rb
new file mode 100644
index 000000000..4af5a5c4d
--- /dev/null
+++ b/app/controllers/api/v1/admin/retention_controller.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class Api::V1::Admin::RetentionController < Api::BaseController
+  protect_from_forgery with: :exception
+
+  before_action -> { authorize_if_got_token! :'admin:read' }
+  before_action :require_staff!
+  before_action :set_cohorts
+
+  def create
+    render json: @cohorts, each_serializer: REST::Admin::CohortSerializer
+  end
+
+  private
+
+  def set_cohorts
+    @cohorts = Admin::Metrics::Retention.new(
+      params[:start_at],
+      params[:end_at],
+      params[:frequency]
+    ).cohorts
+  end
+end
diff --git a/app/controllers/api/v1/admin/trends/tags_controller.rb b/app/controllers/api/v1/admin/trends/tags_controller.rb
new file mode 100644
index 000000000..4815af31e
--- /dev/null
+++ b/app/controllers/api/v1/admin/trends/tags_controller.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class Api::V1::Admin::Trends::TagsController < Api::BaseController
+  protect_from_forgery with: :exception
+
+  before_action -> { authorize_if_got_token! :'admin:read' }
+  before_action :require_staff!
+  before_action :set_tags
+
+  def index
+    render json: @tags, each_serializer: REST::Admin::TagSerializer
+  end
+
+  private
+
+  def set_tags
+    @tags = Trends.tags.get(false, limit_param(10))
+  end
+end
diff --git a/app/controllers/api/v1/instances/activity_controller.rb b/app/controllers/api/v1/instances/activity_controller.rb
index 4f6b4bcbf..bad61425a 100644
--- a/app/controllers/api/v1/instances/activity_controller.rb
+++ b/app/controllers/api/v1/instances/activity_controller.rb
@@ -14,22 +14,21 @@ class Api::V1::Instances::ActivityController < Api::BaseController
   private
 
   def activity
-    weeks = []
-
-    12.times do |i|
-      day     = i.weeks.ago.to_date
-      week_id = day.cweek
-      week    = Date.commercial(day.cwyear, week_id)
-
-      weeks << {
-        week: week.to_time.to_i.to_s,
-        statuses: Redis.current.get("activity:statuses:local:#{week_id}") || '0',
-        logins: Redis.current.pfcount("activity:logins:#{week_id}").to_s,
-        registrations: Redis.current.get("activity:accounts:local:#{week_id}") || '0',
+    statuses_tracker      = ActivityTracker.new('activity:statuses:local', :basic)
+    logins_tracker        = ActivityTracker.new('activity:logins', :unique)
+    registrations_tracker = ActivityTracker.new('activity:accounts:local', :basic)
+
+    (0...12).map do |i|
+      start_of_week = i.weeks.ago
+      end_of_week   = start_of_week + 6.days
+
+      {
+        week: start_of_week.to_i.to_s,
+        statuses: statuses_tracker.sum(start_of_week, end_of_week).to_s,
+        logins: logins_tracker.sum(start_of_week, end_of_week).to_s,
+        registrations: registrations_tracker.sum(start_of_week, end_of_week).to_s,
       }
     end
-
-    weeks
   end
 
   def require_enabled_api!
diff --git a/app/controllers/api/v1/statuses/histories_controller.rb b/app/controllers/api/v1/statuses/histories_controller.rb
new file mode 100644
index 000000000..c2c1fac5d
--- /dev/null
+++ b/app/controllers/api/v1/statuses/histories_controller.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class Api::V1::Statuses::HistoriesController < Api::BaseController
+  include Authorization
+
+  before_action -> { authorize_if_got_token! :read, :'read:statuses' }
+  before_action :set_status
+
+  def show
+    render json: @status.edits, each_serializer: REST::StatusEditSerializer
+  end
+
+  private
+
+  def set_status
+    @status = Status.find(params[:status_id])
+    authorize @status, :show?
+  rescue Mastodon::NotPermittedError
+    not_found
+  end
+end
diff --git a/app/controllers/api/v1/statuses/sources_controller.rb b/app/controllers/api/v1/statuses/sources_controller.rb
new file mode 100644
index 000000000..434086451
--- /dev/null
+++ b/app/controllers/api/v1/statuses/sources_controller.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class Api::V1::Statuses::SourcesController < Api::BaseController
+  include Authorization
+
+  before_action -> { doorkeeper_authorize! :read, :'read:statuses' }
+  before_action :set_status
+
+  def show
+    render json: @status, serializer: REST::StatusSourceSerializer
+  end
+
+  private
+
+  def set_status
+    @status = Status.find(params[:status_id])
+    authorize @status, :show?
+  rescue Mastodon::NotPermittedError
+    not_found
+  end
+end
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index c8529318f..b1390ae48 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -57,7 +57,7 @@ class Api::V1::StatusesController < Api::BaseController
     authorize @status, :destroy?
 
     @status.discard
-    RemovalWorker.perform_async(@status.id, redraft: true)
+    RemovalWorker.perform_async(@status.id, { 'redraft' => true })
     @status.account.statuses_count = @status.account.statuses_count - 1
 
     render json: @status, serializer: REST::StatusSerializer, source_requested: true
diff --git a/app/controllers/api/v1/trends/links_controller.rb b/app/controllers/api/v1/trends/links_controller.rb
new file mode 100644
index 000000000..1c3ab1e1c
--- /dev/null
+++ b/app/controllers/api/v1/trends/links_controller.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class Api::V1::Trends::LinksController < Api::BaseController
+  before_action :set_links
+
+  def index
+    render json: @links, each_serializer: REST::Trends::LinkSerializer
+  end
+
+  private
+
+  def set_links
+    @links = begin
+      if Setting.trends
+        Trends.links.get(true, limit_param(10))
+      else
+        []
+      end
+    end
+  end
+end
diff --git a/app/controllers/api/v1/trends/tags_controller.rb b/app/controllers/api/v1/trends/tags_controller.rb
new file mode 100644
index 000000000..947b53de2
--- /dev/null
+++ b/app/controllers/api/v1/trends/tags_controller.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class Api::V1::Trends::TagsController < Api::BaseController
+  before_action :set_tags
+
+  def index
+    render json: @tags, each_serializer: REST::TagSerializer
+  end
+
+  private
+
+  def set_tags
+    @tags = begin
+      if Setting.trends
+        Trends.tags.get(true, limit_param(10))
+      else
+        []
+      end
+    end
+  end
+end
diff --git a/app/controllers/api/v1/trends_controller.rb b/app/controllers/api/v1/trends_controller.rb
deleted file mode 100644
index c875e9041..000000000
--- a/app/controllers/api/v1/trends_controller.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class Api::V1::TrendsController < Api::BaseController
-  before_action :set_tags
-
-  def index
-    render json: @tags, each_serializer: REST::TagSerializer
-  end
-
-  private
-
-  def set_tags
-    @tags = TrendingTags.get(limit_param(10))
-  end
-end