2023-10-17 17:36:08 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
class AssetSyncController < ApplicationController
|
2023-10-24 19:51:25 +08:00
|
|
|
skip_before_action :authenticate_user!, only: %i(update download)
|
|
|
|
skip_before_action :verify_authenticity_token, only: %i(update download)
|
|
|
|
before_action :authenticate_asset_sync_token!, only: %i(update download)
|
2023-11-17 14:41:12 +08:00
|
|
|
before_action :check_asset_sync
|
2023-10-17 17:36:08 +08:00
|
|
|
|
|
|
|
def show
|
2023-10-19 17:53:18 +08:00
|
|
|
asset = Asset.find_by(id: params[:asset_id])
|
2023-10-17 17:36:08 +08:00
|
|
|
|
2024-01-24 17:45:05 +08:00
|
|
|
render_error(:forbidden) and return unless asset && can_manage_asset?(asset)
|
2023-10-17 17:36:08 +08:00
|
|
|
|
|
|
|
asset_sync_token = current_user.asset_sync_tokens.find_or_create_by(asset_id: params[:asset_id])
|
|
|
|
|
|
|
|
unless asset_sync_token.token_valid?
|
|
|
|
asset_sync_token = current_user.asset_sync_tokens.create(asset_id: params[:asset_id])
|
|
|
|
end
|
|
|
|
|
|
|
|
render json: AssetSyncTokenSerializer.new(asset_sync_token).as_json
|
|
|
|
end
|
|
|
|
|
2023-10-24 19:51:25 +08:00
|
|
|
def download
|
2023-10-25 15:27:27 +08:00
|
|
|
redirect_to(@asset.file.url, allow_other_host: true)
|
2023-10-24 19:51:25 +08:00
|
|
|
end
|
|
|
|
|
2023-10-17 17:36:08 +08:00
|
|
|
def update
|
2023-11-03 16:46:05 +08:00
|
|
|
if @asset_sync_token.conflicts?(request.headers['VersionToken'])
|
2024-02-05 20:12:21 +08:00
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
conflict_response = AssetSyncTokenSerializer.new(conflicting_asset_copy_token).as_json
|
|
|
|
error_message = { message: I18n.t('assets.conflict_error', filename: @asset.file.filename) }
|
|
|
|
log_activity(:create)
|
|
|
|
render json: conflict_response.merge(error_message), status: :conflict
|
|
|
|
end
|
|
|
|
|
2023-11-03 16:46:05 +08:00
|
|
|
return
|
|
|
|
end
|
2023-10-17 17:36:08 +08:00
|
|
|
|
2024-02-05 20:12:21 +08:00
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
@asset.file.attach(io: request.body, filename: @asset.file.filename)
|
|
|
|
@asset.update(last_modified_by: current_user)
|
2023-10-17 17:36:08 +08:00
|
|
|
|
2024-02-05 20:12:21 +08:00
|
|
|
log_activity(:edit)
|
|
|
|
end
|
2023-11-23 08:12:38 +08:00
|
|
|
|
2023-10-17 17:36:08 +08:00
|
|
|
render json: AssetSyncTokenSerializer.new(@asset_sync_token).as_json
|
|
|
|
end
|
|
|
|
|
2023-11-16 16:28:31 +08:00
|
|
|
def api_url
|
|
|
|
render plain: Constants::ASSET_SYNC_URL
|
|
|
|
end
|
|
|
|
|
2024-02-05 20:12:21 +08:00
|
|
|
def log_activity(action)
|
|
|
|
case action
|
|
|
|
when :edit
|
|
|
|
log_edit_activity
|
|
|
|
when :create
|
|
|
|
log_create_activity
|
2023-11-23 08:12:38 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-11-17 14:41:12 +08:00
|
|
|
private
|
2023-10-17 17:36:08 +08:00
|
|
|
|
2024-01-24 17:45:05 +08:00
|
|
|
def render_error(status, filename = nil, message = nil)
|
|
|
|
message ||= if filename.present?
|
|
|
|
I18n.t('assets.default_error_with_filename', filename: filename)
|
|
|
|
else
|
|
|
|
I18n.t('assets.default_error')
|
|
|
|
end
|
|
|
|
|
|
|
|
render json: { message: message }, status: status
|
|
|
|
end
|
|
|
|
|
2023-11-03 16:46:05 +08:00
|
|
|
def conflicting_asset_copy_token
|
|
|
|
Asset.transaction do
|
|
|
|
new_asset = @asset.dup
|
|
|
|
new_asset.save
|
|
|
|
new_asset.file.attach(
|
|
|
|
io: request.body,
|
|
|
|
filename: "#{@asset.file.filename.base} (#{t('general.copy')}).#{@asset.file.filename.extension}"
|
|
|
|
)
|
|
|
|
|
|
|
|
case @asset.parent
|
|
|
|
when Step
|
|
|
|
StepAsset.create!(step: @asset.step, asset: new_asset)
|
|
|
|
when Result
|
|
|
|
ResultAsset.create!(result: @asset.result, asset: new_asset)
|
|
|
|
end
|
|
|
|
|
2024-02-05 20:12:21 +08:00
|
|
|
@asset = new_asset.reload
|
|
|
|
|
2023-11-03 16:46:05 +08:00
|
|
|
current_user.asset_sync_tokens.create!(asset_id: new_asset.id)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-10-17 17:36:08 +08:00
|
|
|
def authenticate_asset_sync_token!
|
|
|
|
@asset_sync_token = AssetSyncToken.find_by(token: request.headers['Authentication'])
|
|
|
|
|
2024-01-24 17:45:05 +08:00
|
|
|
render_error(:unauthorized) and return unless @asset_sync_token&.token_valid?
|
2023-10-17 17:36:08 +08:00
|
|
|
|
|
|
|
@asset = @asset_sync_token.asset
|
|
|
|
@current_user = @asset_sync_token.user
|
|
|
|
|
2024-01-24 17:45:05 +08:00
|
|
|
render_error(:forbidden, @asset.file.filename) and return unless can_manage_asset?(@asset)
|
2023-10-17 17:36:08 +08:00
|
|
|
end
|
2023-11-23 08:12:38 +08:00
|
|
|
|
2024-02-05 20:12:21 +08:00
|
|
|
def log_create_activity
|
|
|
|
assoc = @asset.step
|
|
|
|
assoc ||= @asset.result
|
|
|
|
|
|
|
|
case assoc
|
|
|
|
when Step
|
|
|
|
type_of = assoc.protocol.in_module? ? :task_step_file_added : :protocol_step_file_added
|
|
|
|
message_items = {
|
|
|
|
step: assoc.id,
|
|
|
|
step_position: { id: assoc.id,
|
|
|
|
value_for: 'position_plus_one' },
|
|
|
|
file: @asset.file_name,
|
|
|
|
my_module: assoc.protocol.in_module? ? assoc.my_module.id : nil,
|
|
|
|
protocol: assoc.protocol.in_module? ? nil : assoc.protocol.id
|
|
|
|
}.compact
|
|
|
|
project = assoc.protocol.in_module? ? assoc.my_module.project : nil
|
|
|
|
when Result
|
|
|
|
type_of = :result_file_added
|
|
|
|
message_items = { result: assoc }
|
|
|
|
project = assoc.my_module.project
|
|
|
|
end
|
|
|
|
|
|
|
|
Activities::CreateActivityService.call(
|
|
|
|
activity_type: type_of,
|
|
|
|
owner: current_user,
|
|
|
|
team: assoc.team,
|
|
|
|
subject: @asset,
|
|
|
|
project: project,
|
|
|
|
message_items: message_items
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def log_edit_activity
|
|
|
|
assoc ||= @asset.step
|
|
|
|
assoc ||= @asset.result
|
|
|
|
|
|
|
|
case assoc
|
|
|
|
when Step
|
|
|
|
if assoc.protocol.in_module?
|
|
|
|
log_step_edit_activity(
|
|
|
|
:edit_task_step_file_locally,
|
|
|
|
assoc,
|
|
|
|
assoc.my_module.project,
|
|
|
|
my_module: assoc.my_module.id,
|
|
|
|
file: @asset.file_name,
|
|
|
|
user: current_user.id,
|
|
|
|
step_position_original: @asset.step.position + 1,
|
|
|
|
step: assoc.id
|
|
|
|
)
|
|
|
|
else
|
|
|
|
log_step_edit_activity(
|
|
|
|
:edit_protocol_template_file_locally,
|
|
|
|
assoc,
|
|
|
|
nil,
|
|
|
|
{
|
|
|
|
file: @asset.file_name,
|
|
|
|
user: current_user.id,
|
|
|
|
step_position_original: @asset.step.position + 1,
|
|
|
|
step: assoc.id
|
|
|
|
}
|
|
|
|
)
|
|
|
|
end
|
|
|
|
when Result
|
|
|
|
log_result_edit_activity(
|
|
|
|
:edit_task_result_file_locally,
|
|
|
|
assoc,
|
|
|
|
file: @asset.file_name,
|
|
|
|
user: current_user.id,
|
|
|
|
result: Result.first.id
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def log_step_edit_activity(type_of, step, project = nil, message_items = {})
|
2023-11-23 08:12:38 +08:00
|
|
|
default_items = { step: step.id,
|
|
|
|
step_position: { id: step.id, value_for: 'position_plus_one' } }
|
|
|
|
message_items = default_items.merge(message_items)
|
|
|
|
|
|
|
|
Activities::CreateActivityService
|
|
|
|
.call(activity_type: type_of,
|
2024-01-16 17:39:11 +08:00
|
|
|
owner: current_user,
|
2023-11-23 08:12:38 +08:00
|
|
|
subject: step.protocol,
|
|
|
|
team: step.protocol.team,
|
|
|
|
project: project,
|
|
|
|
message_items: message_items)
|
|
|
|
end
|
|
|
|
|
2024-02-05 20:12:21 +08:00
|
|
|
def log_result_edit_activity(type_of, result, message_items)
|
2023-11-23 08:12:38 +08:00
|
|
|
Activities::CreateActivityService
|
|
|
|
.call(activity_type: type_of,
|
|
|
|
owner: current_user,
|
|
|
|
subject: result,
|
|
|
|
team: result.my_module.team,
|
|
|
|
project: result.my_module.project,
|
|
|
|
message_items: {
|
|
|
|
result: result.id
|
|
|
|
}.merge(message_items))
|
|
|
|
end
|
2024-01-03 22:19:32 +08:00
|
|
|
|
2023-11-17 14:41:12 +08:00
|
|
|
def check_asset_sync
|
|
|
|
render_404 if ENV['ASSET_SYNC_URL'].blank?
|
|
|
|
end
|
2023-10-17 17:36:08 +08:00
|
|
|
end
|