mirror of
https://github.com/discourse/discourse.git
synced 2025-02-06 11:28:18 +00:00
This reverts commit 20780a1eeed56b321daf18ee6bbfe681a51d1bf4. * SECURITY: re-adds accidentally reverted commit: 03d26cd6: ensure embed_url contains valid http(s) uri * when the merge commit e62a85cf was reverted, git chose the 2660c2e2 parent to land on instead of the 03d26cd6 parent (which contains security fixes)
98 lines
2.8 KiB
Ruby
98 lines
2.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module BackupRestore
|
|
class BackupFileHandler
|
|
OLD_DUMP_FILENAME = "dump.sql"
|
|
|
|
delegate :log, to: :@logger, private: true
|
|
|
|
def initialize(logger, filename, current_db, root_tmp_directory = Rails.root)
|
|
@logger = logger
|
|
@filename = filename
|
|
@current_db = current_db
|
|
@root_tmp_directory = root_tmp_directory
|
|
@is_archive = !(@filename =~ /\.sql\.gz$/)
|
|
end
|
|
|
|
def decompress
|
|
create_tmp_directory
|
|
@archive_path = File.join(@tmp_directory, @filename)
|
|
|
|
copy_archive_to_tmp_directory
|
|
decompress_archive
|
|
extract_db_dump
|
|
|
|
[@tmp_directory, @db_dump_path]
|
|
end
|
|
|
|
def clean_up
|
|
return if @tmp_directory.blank?
|
|
|
|
log "Removing tmp '#{@tmp_directory}' directory..."
|
|
FileUtils.rm_rf(@tmp_directory) if Dir[@tmp_directory].present?
|
|
rescue => ex
|
|
log "Something went wrong while removing the following tmp directory: #{@tmp_directory}", ex
|
|
end
|
|
|
|
protected
|
|
|
|
def create_tmp_directory
|
|
timestamp = Time.zone.now.strftime("%Y-%m-%d-%H%M%S")
|
|
@tmp_directory = File.join(@root_tmp_directory, "tmp", "restores", @current_db, timestamp)
|
|
ensure_directory_exists(@tmp_directory)
|
|
end
|
|
|
|
def ensure_directory_exists(directory)
|
|
log "Making sure #{directory} exists..."
|
|
FileUtils.mkdir_p(directory)
|
|
end
|
|
|
|
def copy_archive_to_tmp_directory
|
|
store = BackupRestore::BackupStore.create
|
|
|
|
if store.remote?
|
|
log "Downloading archive to tmp directory..."
|
|
failure_message = "Failed to download archive to tmp directory."
|
|
else
|
|
log "Copying archive to tmp directory..."
|
|
failure_message = "Failed to copy archive to tmp directory."
|
|
end
|
|
|
|
store.download_file(@filename, @archive_path, failure_message)
|
|
end
|
|
|
|
def decompress_archive
|
|
return if !@is_archive
|
|
|
|
log "Unzipping archive, this may take a while..."
|
|
Discourse::Utils.execute_command(
|
|
'tar', '--extract', '--gzip', '--file', @archive_path, '--directory', @tmp_directory,
|
|
failure_message: "Failed to decompress archive."
|
|
)
|
|
end
|
|
|
|
def extract_db_dump
|
|
@db_dump_path =
|
|
if @is_archive
|
|
# for compatibility with backups from Discourse v1.5 and below
|
|
old_dump_path = File.join(@tmp_directory, OLD_DUMP_FILENAME)
|
|
File.exists?(old_dump_path) ? old_dump_path : File.join(@tmp_directory, BackupRestore::DUMP_FILE)
|
|
else
|
|
File.join(@tmp_directory, @filename)
|
|
end
|
|
|
|
if File.extname(@db_dump_path) == '.gz'
|
|
log "Extracting dump file..."
|
|
Compression::Gzip.new.decompress(@tmp_directory, @db_dump_path, available_size)
|
|
@db_dump_path.delete_suffix!('.gz')
|
|
end
|
|
|
|
@db_dump_path
|
|
end
|
|
|
|
def available_size
|
|
SiteSetting.decompressed_backup_max_file_size_mb
|
|
end
|
|
end
|
|
end
|