# frozen_string_literal: true class Settings::UsersController < ApplicationController before_action :authenticate_self_hosted!, except: %i[export import] before_action :authenticate_user! before_action :authenticate_admin!, except: %i[export import] 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_content 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 redirect_to settings_users_url, notice: 'User could not be created.', status: :unprocessable_content 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_content 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 if params[:archive].blank? redirect_to edit_user_registration_path, alert: 'Please select a ZIP archive to import.' return end import = create_import_from_signed_archive_id(params[:archive]) if import.save 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, alert: 'Failed to start import. Please try again.' end rescue StandardError => e 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.' end private def user_params params.require(:user).permit(:email, :password) end def create_import_from_signed_archive_id(signed_id) Rails.logger.debug "Creating archive import from signed ID: #{signed_id[0..20]}..." blob = ActiveStorage::Blob.find_signed(signed_id) # Validate that it's a ZIP file validate_blob_file_type(blob) import_name = generate_unique_import_name(blob.filename.to_s) import = current_user.imports.build( name: import_name, source: :user_data_archive ) import.file.attach(blob) import end def generate_unique_import_name(original_name) return original_name unless current_user.imports.exists?(name: original_name) # Extract filename and extension basename = File.basename(original_name, File.extname(original_name)) extension = File.extname(original_name) # Add current datetime timestamp = Time.current.strftime('%Y%m%d_%H%M%S') "#{basename}_#{timestamp}#{extension}" end def validate_archive_file(archive_file) unless ['application/zip', 'application/x-zip-compressed'].include?(archive_file.content_type) || File.extname(archive_file.original_filename).downcase == '.zip' redirect_to edit_user_registration_path, alert: 'Please upload a valid ZIP file.' and return end end def validate_blob_file_type(blob) unless ['application/zip', 'application/x-zip-compressed'].include?(blob.content_type) || File.extname(blob.filename.to_s).downcase == '.zip' raise StandardError, 'Please upload a valid ZIP file.' end end end