dawarich/app/controllers/settings/users_controller.rb

145 lines
4.1 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
class Settings::UsersController < ApplicationController
2025-07-23 14:21:33 -04:00
before_action :authenticate_self_hosted!, except: [:export, :import]
2025-06-28 06:22:56 -04:00
before_action :authenticate_admin!, except: [:export, :import]
2025-07-23 14:21:33 -04:00
before_action :authenticate_user!
2024-11-08 11:56:14 -05:00
def index
@users = User.order(created_at: :desc)
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update(user_params)
redirect_to settings_users_url, notice: 'User was successfully updated.'
else
redirect_to settings_users_url, notice: 'User could not be updated.', status: :unprocessable_entity
end
end
def create
@user = User.new(
email: user_params[:email],
password: user_params[:password],
password_confirmation: user_params[:password]
)
if @user.save
redirect_to settings_users_url, notice: 'User was successfully created'
else
2024-11-08 11:56:14 -05:00
redirect_to settings_users_url, notice: 'User could not be created.', status: :unprocessable_entity
end
end
def destroy
@user = User.find(params[:id])
if @user.destroy
redirect_to settings_url, notice: 'User was successfully deleted.'
else
redirect_to settings_url, notice: 'User could not be deleted.', status: :unprocessable_entity
end
end
def export
current_user.export_data
redirect_to exports_path, notice: 'Your data is being exported. You will receive a notification when it is ready.'
end
def import
2025-07-28 17:09:33 -04:00
files_params = params.dig(:import, :files)
2025-07-28 16:49:39 -04:00
raw_files = Array(files_params).reject(&:blank?)
if raw_files.empty?
2025-06-28 06:22:56 -04:00
redirect_to edit_user_registration_path, alert: 'Please select a ZIP archive to import.'
return
end
2025-07-28 16:49:39 -04:00
created_imports = []
2025-06-28 06:22:56 -04:00
2025-07-28 16:49:39 -04:00
raw_files.each do |item|
next if item.is_a?(ActionDispatch::Http::UploadedFile)
2025-06-28 06:22:56 -04:00
2025-07-28 16:49:39 -04:00
import = create_import_from_signed_id(item)
created_imports << import if import.present?
end
2025-06-28 06:22:56 -04:00
2025-07-28 16:49:39 -04:00
if created_imports.any?
2025-06-28 06:22:56 -04:00
redirect_to edit_user_registration_path,
notice: 'Your data import has been started. You will receive a notification when it completes.'
else
redirect_to edit_user_registration_path,
2025-07-28 16:49:39 -04:00
alert: 'No valid file references were found. Please upload files using the file selector.'
2025-06-28 06:22:56 -04:00
end
rescue StandardError => e
2025-07-28 16:49:39 -04:00
if created_imports.present?
import_ids = created_imports.map(&:id).compact
Import.where(id: import_ids).destroy_all if import_ids.any?
end
2025-06-28 06:22:56 -04:00
ExceptionReporter.call(e, 'User data import failed to start')
redirect_to edit_user_registration_path,
alert: 'An error occurred while starting the import. Please try again.'
2025-06-26 13:24:40 -04:00
end
private
def user_params
params.require(:user).permit(:email, :password)
end
2025-06-30 16:29:28 -04:00
2025-07-28 16:49:39 -04:00
def create_import_from_signed_id(signed_id)
Rails.logger.debug "Creating user data import from signed ID: #{signed_id[0..20]}..."
blob = ActiveStorage::Blob.find_signed(signed_id)
validate_archive_blob(blob)
2025-07-28 17:09:33 -04:00
# Generate unique name if duplicate exists
base_name = blob.filename.to_s
unique_name = generate_unique_import_name(base_name)
2025-07-28 16:49:39 -04:00
import = current_user.imports.build(
2025-07-28 17:09:33 -04:00
name: unique_name,
2025-07-28 16:49:39 -04:00
source: :user_data_archive
)
import.file.attach(blob)
import.save!
import
end
2025-07-28 17:09:33 -04:00
def generate_unique_import_name(base_name)
return base_name unless current_user.imports.exists?(name: base_name)
# Extract extension
name_without_ext = File.basename(base_name, File.extname(base_name))
extension = File.extname(base_name)
counter = 1
loop do
candidate_name = "#{name_without_ext}_#{counter}#{extension}"
break candidate_name unless current_user.imports.exists?(name: candidate_name)
counter += 1
end
end
2025-07-28 16:49:39 -04:00
def validate_archive_blob(blob)
unless blob.content_type == 'application/zip' ||
blob.content_type == 'application/x-zip-compressed' ||
File.extname(blob.filename.to_s).downcase == '.zip'
2025-06-30 16:29:28 -04:00
2025-07-02 14:29:12 -04:00
redirect_to edit_user_registration_path, alert: 'Please upload a valid ZIP file.' and return
2025-06-30 16:29:28 -04:00
end
end
end