diff options
author | Thibaut Girka <thib@sitedethib.com> | 2019-01-10 19:12:10 +0100 |
---|---|---|
committer | Thibaut Girka <thib@sitedethib.com> | 2019-01-10 21:00:30 +0100 |
commit | a2a64ecd3e3551707412c47f0d16e484dea25632 (patch) | |
tree | bc4e0b8e0ca2a2735f527bff8bd73421c0ff72dd /app/controllers | |
parent | fb0c906c717f2b21bb63610742a357850142b522 (diff) | |
parent | 70801b850c78d7879182eeba4eae509af42fafeb (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.rb | 11 | ||||
-rw-r--r-- | app/controllers/admin/followers_controller.rb | 6 | ||||
-rw-r--r-- | app/controllers/admin/instances_controller.rb | 27 | ||||
-rw-r--r-- | app/controllers/admin/statuses_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/api/v1/accounts_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/api/v1/custom_emojis_controller.rb | 4 | ||||
-rw-r--r-- | app/controllers/api/v1/scheduled_statuses_controller.rb | 77 | ||||
-rw-r--r-- | app/controllers/api/v1/statuses_controller.rb | 9 | ||||
-rw-r--r-- | app/controllers/concerns/signature_verification.rb | 45 | ||||
-rw-r--r-- | app/controllers/remote_interaction_controller.rb | 5 |
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 |