1
0
Fork 0
forked from gitea/nas

Merge commit 'ab85f59c30' into kb_migration

This commit is contained in:
KMY 2023-03-17 09:39:40 +09:00
commit c8a0050660
30 changed files with 321 additions and 63 deletions

View file

@ -0,0 +1,27 @@
# frozen_string_literal: true
class BackupsController < ApplicationController
include RoutingHelper
skip_before_action :require_functional!
before_action :authenticate_user!
before_action :set_backup
def download
case Paperclip::Attachment.default_options[:storage]
when :s3
redirect_to @backup.dump.expiring_url(10)
when :fog
redirect_to @backup.dump.expiring_url(Time.now.utc + 10)
when :filesystem
redirect_to full_asset_url(@backup.dump.url)
end
end
private
def set_backup
@backup = current_user.backups.find(params[:id])
end
end

View file

@ -52,7 +52,7 @@ module Settings
end
else
flash[:error] = I18n.t('webauthn_credentials.create.error')
status = :internal_server_error
status = :unprocessable_entity
end
else
flash[:error] = t('webauthn_credentials.create.error')

View file

@ -2,6 +2,7 @@
class Admin::SystemCheck
ACTIVE_CHECKS = [
Admin::SystemCheck::MediaPrivacyCheck,
Admin::SystemCheck::DatabaseSchemaCheck,
Admin::SystemCheck::SidekiqProcessCheck,
Admin::SystemCheck::RulesCheck,

View file

@ -31,7 +31,7 @@ class Admin::SystemCheck::ElasticsearchCheck < Admin::SystemCheck::BaseCheck
def running_version
@running_version ||= begin
Chewy.client.info['version']['number']
rescue Faraday::ConnectionFailed
rescue Faraday::ConnectionFailed, Elasticsearch::Transport::Transport::Error
nil
end
end

View file

@ -0,0 +1,105 @@
# frozen_string_literal: true
class Admin::SystemCheck::MediaPrivacyCheck < Admin::SystemCheck::BaseCheck
include RoutingHelper
def skip?
!current_user.can?(:view_devops)
end
def pass?
check_media_uploads!
@failure_message.nil?
end
def message
Admin::SystemCheck::Message.new(@failure_message, @failure_value, @failure_action, true)
end
private
def check_media_uploads!
if Rails.configuration.x.use_s3
check_media_listing_inaccessible_s3!
else
check_media_listing_inaccessible!
end
end
def check_media_listing_inaccessible!
full_url = full_asset_url(media_attachment.file.url(:original, false))
# Check if we can list the uploaded file. If true, that's an error
directory_url = Addressable::URI.parse(full_url)
directory_url.query = nil
filename = directory_url.path.gsub(%r{.*/}, '')
directory_url.path = directory_url.path.gsub(%r{/[^/]+\Z}, '/')
Request.new(:get, directory_url, allow_local: true).perform do |res|
if res.truncated_body&.include?(filename)
@failure_message = use_storage? ? :upload_check_privacy_error_object_storage : :upload_check_privacy_error
@failure_action = 'https://docs.joinmastodon.org/admin/optional/object-storage/#FS'
end
end
rescue
nil
end
def check_media_listing_inaccessible_s3!
urls_to_check = []
paperclip_options = Paperclip::Attachment.default_options
s3_protocol = paperclip_options[:s3_protocol]
s3_host_alias = paperclip_options[:s3_host_alias]
s3_host_name = paperclip_options[:s3_host_name]
bucket_name = paperclip_options.dig(:s3_credentials, :bucket)
urls_to_check << "#{s3_protocol}://#{s3_host_alias}/" if s3_host_alias.present?
urls_to_check << "#{s3_protocol}://#{s3_host_name}/#{bucket_name}/"
urls_to_check.uniq.each do |full_url|
check_s3_listing!(full_url)
break if @failure_message.present?
end
rescue
nil
end
def check_s3_listing!(full_url)
bucket_url = Addressable::URI.parse(full_url)
bucket_url.path = bucket_url.path.delete_suffix(media_attachment.file.path(:original))
bucket_url.query = "max-keys=1&x-random=#{SecureRandom.hex(10)}"
Request.new(:get, bucket_url, allow_local: true).perform do |res|
if res.truncated_body&.include?('ListBucketResult')
@failure_message = :upload_check_privacy_error_object_storage
@failure_action = 'https://docs.joinmastodon.org/admin/optional/object-storage/#S3'
end
end
end
def media_attachment
@media_attachment ||= begin
attachment = Account.representative.media_attachments.first
if attachment.present?
attachment.touch # rubocop:disable Rails/SkipsModelValidations
attachment
else
create_test_attachment!
end
end
end
def create_test_attachment!
Tempfile.create(%w(test-upload .jpg), binmode: true) do |tmp_file|
tmp_file.write(
Base64.decode64(
'/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA' \
'AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA' \
'QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE' \
'BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/x' \
'ABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAA' \
'AAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q=='
)
)
tmp_file.flush
Account.representative.media_attachments.create!(file: tmp_file)
end
end
end

View file

@ -1,11 +1,12 @@
# frozen_string_literal: true
class Admin::SystemCheck::Message
attr_reader :key, :value, :action
attr_reader :key, :value, :action, :critical
def initialize(key, value = nil, action = nil)
@key = key
@value = value
@action = action
def initialize(key, value = nil, action = nil, critical = false)
@key = key
@value = value
@action = action
@critical = critical
end
end

View file

@ -20,4 +20,10 @@ class ApplicationMailer < ActionMailer::Base
headers['X-Auto-Response-Suppress'] = 'All'
headers['Auto-Submitted'] = 'auto-generated'
end
def set_autoreply_headers!
headers['Precedence'] = 'list'
headers['X-Auto-Response-Suppress'] = 'All'
headers['Auto-Submitted'] = 'auto-generated'
end
end

View file

@ -18,6 +18,6 @@
class Backup < ApplicationRecord
belongs_to :user, inverse_of: :backups
has_attached_file :dump
validates_attachment_content_type :dump, content_type: /\Aapplication/
has_attached_file :dump, s3_permissions: 'private'
do_not_validate_attachment_file_type :dump
end

View file

@ -12,7 +12,7 @@
- unless @system_checks.empty?
.flash-message-stack
- @system_checks.each do |message|
.flash-message.warning
.flash-message{ class: message.critical ? 'alert' : 'warning' }
= t("admin.system_checks.#{message.key}.message_html", value: message.value ? content_tag(:strong, message.value) : nil)
- if message.action
= link_to t("admin.system_checks.#{message.key}.action"), message.action

View file

@ -54,15 +54,15 @@
.strike-card__statuses-list__item
- if (status = status_map[status_id.to_i])
.one-liner
= link_to short_account_status_url(@report.target_account, status_id), class: 'emojify' do
= one_line_preview(status)
.emojify= one_line_preview(status)
- status.ordered_media_attachments.each do |media_attachment|
%abbr{ title: media_attachment.description }
= fa_icon 'link'
= media_attachment.file_file_name
- status.ordered_media_attachments.each do |media_attachment|
%abbr{ title: media_attachment.description }
= fa_icon 'link'
= media_attachment.file_file_name
.strike-card__statuses-list__item__meta
%time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
= link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank' do
%time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
- unless status.application.nil?
·
= status.application.name

View file

@ -0,0 +1,16 @@
.hero-widget
.hero-widget__img
= image_tag @instance_presenter.thumbnail&.file&.url(:'@1x') || asset_pack_path('media/images/preview.png'), alt: @instance_presenter.title
.hero-widget__text
%p= @instance_presenter.description.presence || t('about.about_mastodon_html')
- if Setting.trends && !(user_signed_in? && !current_user.setting_trends)
- trends = Trends.tags.query.allowed.limit(3)
- unless trends.empty?
.endorsements-widget.trends-widget
%h4.emojify= t('footer.trending_now')
- trends.each do |tag|
= react_component :hashtag, hashtag: ActiveModelSerializers::SerializableResource.new(tag, serializer: REST::TagSerializer, scope: current_user, scope_name: :current_user).as_json

View file

@ -50,15 +50,15 @@
.strike-card__statuses-list__item
- if (status = status_map[status_id.to_i])
.one-liner
= link_to short_account_status_url(@strike.target_account, status_id), class: 'emojify' do
= one_line_preview(status)
.emojify= one_line_preview(status)
- status.ordered_media_attachments.each do |media_attachment|
%abbr{ title: media_attachment.description }
= fa_icon 'link'
= media_attachment.file_file_name
- status.ordered_media_attachments.each do |media_attachment|
%abbr{ title: media_attachment.description }
= fa_icon 'link'
= media_attachment.file_file_name
.strike-card__statuses-list__item__meta
%time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
= link_to ActivityPub::TagManager.instance.url_for(status), target: '_blank' do
%time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
- unless status.application.nil?
·
= status.application.name

View file

@ -64,6 +64,6 @@
%td= l backup.created_at
- if backup.processed?
%td= number_to_human_size backup.dump_file_size
%td= table_link_to 'download', t('exports.archive_takeout.download'), backup.dump.url
%td= table_link_to 'download', t('exports.archive_takeout.download'), download_backup_url(backup)
- else
%td{ colspan: 2 }= t('exports.archive_takeout.in_progress')

View file

@ -55,5 +55,5 @@
%tbody
%tr
%td.button-primary
= link_to full_asset_url(@backup.dump.url) do
= link_to download_backup_url(@backup) do
%span= t 'exports.archive_takeout.download'

View file

@ -4,4 +4,4 @@
<%= t 'user_mailer.backup_ready.explanation' %>
=> <%= full_asset_url(@backup.dump.url) %>
=> <%= download_backup_url(@backup) %>

View file

@ -11,7 +11,7 @@ class ActivityPub::MigratedFollowDeliveryWorker < ActivityPub::DeliveryWorker
def unfollow_old_account!(old_target_account_id)
old_target_account = Account.find(old_target_account_id)
UnfollowService.new.call(@source_account, old_target_account, skip_unmerge: true)
rescue
rescue StandardError
true
end
end