Gemfile Changes
| @@ -6,3 +6,4 @@ git_source(:github) do | |
| 6 | +gem 'carrierwave' |
Gemfile.lock Changes
| @@ -112,6 +112,7 @@ GEM | |
| 112 | + carrierwave (3.1.2) |
| @@ -288,6 +289,7 @@ DEPENDENCIES | |
| 289 | + carrierwave |
app/controllers/log_redaction_controller.rb Added
| @@ -0,0 +1,30 @@ | |
| 1 | +class LogRedactionController < AdminController |
| 2 | +def redact |
| 3 | + selected_log = TransformationLog.find(params[:id]) |
| 4 | + current_text = selected_log.log.to_s |
| 5 | + |
| 6 | +# Remove any emails from the log by splitting into chunks and redacting |
| 7 | +# any suspicious-looking chunks |
| 8 | + chunks = current_text.split(' ') |
| 9 | + redacted_chunks = [] |
| 10 | + emailish = %r{ |
| 11 | + [a-z0-9._%+-]+ # username |
| 12 | + @ |
| 13 | + [a-z0-9.-]+.[a-z]{2,} # domain |
| 14 | + }ix |
| 15 | + chunks.each do |
| 16 | + redacted_chunks << chunk.gsub(emailish, '[REDACTED]') |
| 17 | +end |
| 18 | + updated_text = redacted_chunks.join(' ') |
| 19 | + |
| 20 | +# NOTE: Need to escape single quotes with "''" to avoid SQL syntax error |
| 21 | +RawLog.where(transformation_log_id: params[:id]).update_all("log = '#{updated_text.gsub("'", "''")}'") |
| 22 | + |
| 23 | + flash[:notice] = "Redacted log #{params[:id]}" |
| 24 | + redirect_to log_path(params[:id]) |
| 25 | +rescue => e |
| 26 | +Rails.logger.error("Log redaction failed for #{params[:id]} because #{e.message}") |
| 27 | + flash[:notice] = "Redacted log #{params[:id]}" |
| 28 | + redirect_to logs_path |
| 29 | +end |
| 30 | +end |
app/views/logs/show.html.haml Changed
| @@ -35,6 +35,8 @@ | |
| 35 | + .m-b-xs |
| 36 | + = link_to 'Redact Log', redact_log_path(@log), class:'btn-fw btn btn-outline b-warning text-warning btn-sm' |
config/routes.rb Changed
| @@ -47,6 +47,8 @@ Rails.application.routes.draw do | |
| 47 | + get 'logs/:id/redact', to: 'log_redaction#redact', as: :redact_log |
| 48 | + |
spec/controllers/log_redaction_controller_spec.rb Added
| @@ -0,0 +1,21 @@ | |
| 1 | +require 'rails_helper' |
| 2 | + |
| 3 | +RSpec.describe LogRedactionController do |
| 4 | + login_user |
| 5 | + |
| 6 | + let!(:transformation_log) do |
| 7 | +FactoryGirl.create( |
| 8 | +:log, |
| 9 | +log: 'Customer jane@example.com triggered token TOKENVALUE999 for export' |
| 10 | + ) |
| 11 | +end |
| 12 | + |
| 13 | + it 'redacts log content', aggregate_failures: true do |
| 14 | + get :redact, params: { id: transformation_log.id } |
| 15 | + transformation_log.reload |
| 16 | + |
| 17 | + expect(response).to redirect_to(log_path(transformation_log)) |
| 18 | + expect(transformation_log.log).to include('[REDACTED]') |
| 19 | + expect(transformation_log.log).not_to include('jane@example.com') |
| 20 | +end |
| 21 | +end |
| 22 | + |