Commit 748a422c authored by ikuradon's avatar ikuradon 🐈

Merge remote-tracking branch 'upstream/master' into comm.cx

parents 3e667440 6172263a
Pipeline #373 passed with stage
in 24 minutes and 56 seconds
......@@ -15,7 +15,7 @@ gem 'makara', '~> 0.4'
gem 'pghero', '~> 2.2'
gem 'dotenv-rails', '~> 2.7'
gem 'aws-sdk-s3', '~> 1.43', require: false
gem 'aws-sdk-s3', '~> 1.45', require: false
gem 'fog-core', '<= 2.1.0'
gem 'fog-openstack', '~> 0.3', require: false
gem 'paperclip', '~> 6.0'
......@@ -114,7 +114,7 @@ group :test do
gem 'microformats', '~> 4.1'
gem 'rails-controller-testing', '~> 1.0'
gem 'rspec-sidekiq', '~> 3.0'
gem 'simplecov', '~> 0.16', require: false
gem 'simplecov', '~> 0.17', require: false
gem 'webmock', '~> 3.6'
gem 'parallel_tests', '~> 2.29'
end
......
......@@ -76,17 +76,17 @@ GEM
av (0.9.0)
cocaine (~> 0.5.3)
aws-eventstream (1.0.3)
aws-partitions (1.177.0)
aws-sdk-core (3.56.0)
aws-partitions (1.184.0)
aws-sdk-core (3.59.0)
aws-eventstream (~> 1.0, >= 1.0.2)
aws-partitions (~> 1.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.22.0)
aws-sdk-core (~> 3, >= 3.56.0)
aws-sdk-kms (1.23.0)
aws-sdk-core (~> 3, >= 3.58.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.43.0)
aws-sdk-core (~> 3, >= 3.56.0)
aws-sdk-s3 (1.45.0)
aws-sdk-core (~> 3, >= 3.58.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.1.0)
......@@ -183,7 +183,7 @@ GEM
devise (>= 4.0.0)
rpam2 (~> 4.0)
diff-lcs (1.3)
docile (1.3.0)
docile (1.3.2)
domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0)
doorkeeper (5.1.0)
......@@ -208,7 +208,7 @@ GEM
tzinfo
excon (0.62.0)
fabrication (2.20.2)
faker (1.9.3)
faker (1.9.6)
i18n (>= 0.7)
faraday (0.15.0)
multipart-post (>= 1.2, < 3)
......@@ -231,7 +231,7 @@ GEM
fugit (1.1.6)
et-orbi (~> 1.1, >= 1.1.6)
raabro (~> 1.1)
fuubar (2.4.0)
fuubar (2.4.1)
rspec-core (~> 3.0)
ruby-progressbar (~> 1.4)
get_process_mem (0.2.3)
......@@ -289,7 +289,7 @@ GEM
iso-639 (0.2.8)
jaro_winkler (1.5.3)
jmespath (1.4.0)
json (2.1.0)
json (2.2.0)
json-ld (3.0.2)
multi_json (~> 1.12)
rdf (>= 2.2.8, < 4.0)
......@@ -578,7 +578,7 @@ GEM
simple_form (4.1.0)
actionpack (>= 5.0)
activemodel (>= 5.0)
simplecov (0.16.1)
simplecov (0.17.0)
docile (~> 1.1)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
......@@ -625,7 +625,7 @@ GEM
unf (~> 0.1.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
tzinfo-data (1.2019.1)
tzinfo-data (1.2019.2)
tzinfo (>= 1.0.0)
unf (0.1.4)
unf_ext
......@@ -660,7 +660,7 @@ DEPENDENCIES
active_record_query_trace (~> 1.6)
addressable (~> 2.6)
annotate (~> 2.7)
aws-sdk-s3 (~> 1.43)
aws-sdk-s3 (~> 1.45)
better_errors (~> 2.5)
binding_of_caller (~> 0.7)
blurhash (~> 0.1)
......@@ -763,7 +763,7 @@ DEPENDENCIES
sidekiq-unique-jobs (~> 6.0)
simple-navigation (~> 4.0)
simple_form (~> 4.1)
simplecov (~> 0.16)
simplecov (~> 0.17)
sprockets-rails (~> 3.2)
stackprof
stoplight (~> 2.1.3)
......
......@@ -3,11 +3,11 @@
class AboutController < ApplicationController
layout 'public'
before_action :set_instance_presenter, only: [:show, :more, :terms]
before_action :set_body_classes, only: :show
before_action :set_instance_presenter
before_action :set_expires_in
def show
@hide_navbar = true
end
def show; end
def more; end
......@@ -27,4 +27,12 @@ class AboutController < ApplicationController
def set_instance_presenter
@instance_presenter = InstancePresenter.new
end
def set_body_classes
@hide_navbar = true
end
def set_expires_in
expires_in 0, public: true
end
end
......@@ -6,13 +6,13 @@ class AccountsController < ApplicationController
include AccountControllerConcern
before_action :set_cache_headers
before_action :set_body_classes
def show
respond_to do |format|
format.html do
mark_cacheable! unless user_signed_in?
expires_in 0, public: true unless user_signed_in?
@body_classes = 'with-modals'
@pinned_statuses = []
@endorsed_accounts = @account.endorsed_accounts.to_a.sample(4)
......@@ -31,30 +31,26 @@ class AccountsController < ApplicationController
end
end
format.atom do
mark_cacheable!
@entries = @account.stream_entries.where(hidden: false).with_includes.paginate_by_max_id(PAGE_SIZE, params[:max_id], params[:since_id])
render xml: OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.feed(@account, @entries.reject { |entry| entry.status.nil? }))
end
format.rss do
mark_cacheable!
expires_in 0, public: true
@statuses = cache_collection(default_statuses.without_reblogs.without_replies.limit(PAGE_SIZE), Status)
render xml: RSS::AccountSerializer.render(@account, @statuses)
end
format.json do
render_cached_json(['activitypub', 'actor', @account], content_type: 'application/activity+json') do
ActiveModelSerializers::SerializableResource.new(@account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter)
end
expires_in 3.minutes, public: true
render json: @account, content_type: 'application/activity+json', serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter
end
end
end
private
def set_body_classes
@body_classes = 'with-modals'
end
def show_pinned_statuses?
[replies_requested?, media_requested?, tag_requested?, params[:max_id].present?, params[:min_id].present?].none?
end
......
......@@ -2,29 +2,19 @@
class ActivityPub::CollectionsController < Api::BaseController
include SignatureVerification
include AccountOwnedConcern
before_action :set_account
before_action :set_size
before_action :set_statuses
before_action :set_cache_headers
def show
render_cached_json(['activitypub', 'collection', @account, params[:id]], content_type: 'application/activity+json') do
ActiveModelSerializers::SerializableResource.new(
collection_presenter,
serializer: ActivityPub::CollectionSerializer,
adapter: ActivityPub::Adapter,
skip_activities: true
)
end
expires_in 3.minutes, public: true
render json: collection_presenter, content_type: 'application/activity+json', serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, skip_activities: true
end
private
def set_account
@account = Account.find_local!(params[:account_username])
end
def set_statuses
@statuses = scope_for_collection
@statuses = cache_collection(@statuses, Status)
......
......@@ -3,8 +3,7 @@
class ActivityPub::InboxesController < Api::BaseController
include SignatureVerification
include JsonLdHelper
before_action :set_account
include AccountOwnedConcern
def create
if unknown_deleted_account?
......@@ -27,8 +26,8 @@ class ActivityPub::InboxesController < Api::BaseController
false
end
def set_account
@account = Account.find_local!(params[:account_username]) if params[:account_username]
def account_required?
params[:account_username].present?
end
def body
......@@ -44,7 +43,6 @@ class ActivityPub::InboxesController < Api::BaseController
ResolveAccountWorker.perform_async(signed_request_account.acct)
end
Pubsubhubbub::UnsubscribeWorker.perform_async(signed_request_account.id) if signed_request_account.subscribed?
DeliveryFailureTracker.track_inverse_success!(signed_request_account)
end
......
......@@ -4,8 +4,8 @@ class ActivityPub::OutboxesController < Api::BaseController
LIMIT = 20
include SignatureVerification
include AccountOwnedConcern
before_action :set_account
before_action :set_statuses
before_action :set_cache_headers
......@@ -17,10 +17,6 @@ class ActivityPub::OutboxesController < Api::BaseController
private
def set_account
@account = Account.find_local!(params[:account_username])
end
def outbox_presenter
if page_requested?
ActivityPub::CollectionPresenter.new(
......
# frozen_string_literal: true
class ActivityPub::RepliesController < Api::BaseController
include SignatureAuthentication
include Authorization
include AccountOwnedConcern
DESCENDANTS_LIMIT = 60
before_action :set_status
before_action :set_cache_headers
before_action :set_replies
def index
render json: replies_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', skip_activities: true
end
private
def set_status
@status = @account.statuses.find(params[:status_id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
raise ActiveRecord::RecordNotFound
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 replies_collection_presenter
page = ActivityPub::CollectionPresenter.new(
id: account_status_replies_url(@account, @status, page_params),
type: :unordered,
part_of: account_status_replies_url(@account, @status),
next: next_page,
items: @replies.map { |status| status.local ? status : status.id }
)
return page if page_requested?
ActivityPub::CollectionPresenter.new(
id: account_status_replies_url(@account, @status),
type: :unordered,
first: page
)
end
def page_requested?
params[:page] == 'true'
end
def next_page
account_status_replies_url(
@account,
@status,
page: true,
min_id: @replies&.last&.id,
other_accounts: !(@replies&.last&.account_id == @account.id && @replies.size == DESCENDANTS_LIMIT)
)
end
def page_params
params_slice(:other_accounts, :min_id).merge(page: true)
end
end
......@@ -2,8 +2,8 @@
module Admin
class AccountsController < BaseController
before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :remove_header, :enable, :unsilence, :unsuspend, :memorialize, :approve, :reject]
before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload]
before_action :set_account, only: [:show, :redownload, :remove_avatar, :remove_header, :enable, :unsilence, :unsuspend, :memorialize, :approve, :reject]
before_action :require_remote_account!, only: [:redownload]
before_action :require_local_account!, only: [:enable, :memorialize, :approve, :reject]
def index
......@@ -19,18 +19,6 @@ module Admin
@warnings = @account.targeted_account_warnings.latest.custom
end
def subscribe
authorize @account, :subscribe?
Pubsubhubbub::SubscribeWorker.perform_async(@account.id)
redirect_to admin_account_path(@account.id)
end
def unsubscribe
authorize @account, :unsubscribe?
Pubsubhubbub::UnsubscribeWorker.perform_async(@account.id)
redirect_to admin_account_path(@account.id)
end
def memorialize
authorize @account, :memorialize?
@account.memorialize!
......
# frozen_string_literal: true
class Api::ProofsController < Api::BaseController
before_action :set_account
include AccountOwnedConcern
before_action :set_provider
before_action :check_account_approval
before_action :check_account_suspension
def index
render json: @account, serializer: @provider.serializer_class
......@@ -16,15 +15,7 @@ class Api::ProofsController < Api::BaseController
@provider = ProofProvider.find(params[:provider]) || raise(ActiveRecord::RecordNotFound)
end
def set_account
@account = Account.find_local!(params[:username])
end
def check_account_approval
not_found if @account.user_pending?
end
def check_account_suspension
gone if @account.suspended?
def username_param
params[:username]
end
end
# frozen_string_literal: true
class Api::PushController < Api::BaseController
include SignatureVerification
def update
response, status = process_push_request
render plain: response, status: status
end
private
def process_push_request
case hub_mode
when 'subscribe'
Pubsubhubbub::SubscribeService.new.call(account_from_topic, hub_callback, hub_secret, hub_lease_seconds, verified_domain)
when 'unsubscribe'
Pubsubhubbub::UnsubscribeService.new.call(account_from_topic, hub_callback)
else
["Unknown mode: #{hub_mode}", 422]
end
end
def hub_mode
params['hub.mode']
end
def hub_topic
params['hub.topic']
end
def hub_callback
params['hub.callback']
end
def hub_lease_seconds
params['hub.lease_seconds']
end
def hub_secret
params['hub.secret']
end
def account_from_topic
if hub_topic.present? && local_domain? && account_feed_path?
Account.find_local(hub_topic_params[:username])
end
end
def hub_topic_params
@_hub_topic_params ||= Rails.application.routes.recognize_path(hub_topic_uri.path)
end
def hub_topic_uri
@_hub_topic_uri ||= Addressable::URI.parse(hub_topic).normalize
end
def local_domain?
TagManager.instance.web_domain?(hub_topic_domain)
end
def verified_domain
return signed_request_account.domain if signed_request_account
end
def hub_topic_domain
hub_topic_uri.host + (hub_topic_uri.port ? ":#{hub_topic_uri.port}" : '')
end
def account_feed_path?
hub_topic_params[:controller] == 'accounts' && hub_topic_params[:action] == 'show' && hub_topic_params[:format] == 'atom'
end
end
# frozen_string_literal: true
class Api::SalmonController < Api::BaseController
include SignatureVerification
before_action :set_account
respond_to :txt
def update
if verify_payload?
process_salmon
head 202
elsif payload.present?
render plain: signature_verification_failure_reason, status: 401
else
head 400
end
end
private
def set_account
@account = Account.find(params[:id])
end
def payload
@_payload ||= request.body.read
end
def verify_payload?
payload.present? && VerifySalmonService.new.call(payload)
end
def process_salmon
SalmonWorker.perform_async(@account.id, payload.force_encoding('UTF-8'))
end
end
# frozen_string_literal: true
class Api::SubscriptionsController < Api::BaseController
before_action :set_account
respond_to :txt
def show
if subscription.valid?(params['hub.topic'])
@account.update(subscription_expires_at: future_expires)
render plain: encoded_challenge, status: 200
else
head 404
end
end
def update
if subscription.verify(body, request.headers['HTTP_X_HUB_SIGNATURE'])
ProcessingWorker.perform_async(@account.id, body.force_encoding('UTF-8'))
end
head 200
end
private
def subscription
@_subscription ||= @account.subscription(
api_subscription_url(@account.id)
)
end
def body
@_body ||= request.body.read
end
def encoded_challenge
HTMLEntities.new.encode(params['hub.challenge'])
end
def future_expires
Time.now.utc + lease_seconds_or_default
end
def lease_seconds_or_default
(params['hub.lease_seconds'] || 1.day).to_i.seconds
end
def set_account
@account = Account.find(params[:id])
end
end
# frozen_string_literal: true
class Api::V1::FollowsController < Api::BaseController
before_action -> { doorkeeper_authorize! :follow, :'write:follows' }
before_action :require_user!
respond_to :json
def create
raise ActiveRecord::RecordNotFound if follow_params[:uri].blank?
@account = FollowService.new.call(current_user.account, target_uri).try(:target_account)
if @account.nil?
username, domain = target_uri.split('@')
@account = Account.find_remote!(username, domain)
end
render json: @account, serializer: REST::AccountSerializer
end
private
def target_uri
follow_params[:uri].strip.gsub(/\A@/, '')
end
def follow_params
params.permit(:uri)
end
end
......@@ -5,8 +5,8 @@ class Api::V1::StatusesController < Api::BaseController
before_action -> { authorize_if_got_token! :read, :'read:statuses' }, except: [:create, :destroy]
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:create, :destroy]
before_action :require_user!, except: [:show, :context, :card]
before_action :set_status, only: [:show, :context, :card]
before_action :require_user!, except: [:show, :context]
before_action :set_status, only: [:show, :context]
respond_to :json
......@@ -33,16 +33,6 @@ class Api::V1::StatusesController < Api::BaseController
render json: @context, serializer: REST::ContextSerializer, relationships: StatusRelationshipsPresenter.new(statuses, current_user&.account_id)
end
def card
@card = @status.preview_cards.first
if @card.nil?
render_empty
else
render json: @card, serializer: REST::PreviewCardSerializer
end
end
def create
@status = PostStatusService.new.call(current_user.