effective_logging 3.0.13 → 3.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1fc5a45c2f4f2b72d25f2440ab60382a4e86455ac95176a4b8c927009aa1712b
4
- data.tar.gz: 75fb045296a8e2887ada0a2e637c3f0005b4ba7efaca433c2c7f49d29f0505b9
3
+ metadata.gz: 58a1c50df31d737cfd39e21a51ed64ab49bd9ec13ede06aaa16e047799abe431
4
+ data.tar.gz: 28d0db5308e8a8559d05951ac9ee325cdaf3ca3f24ee046ba975f403427ae4ba
5
5
  SHA512:
6
- metadata.gz: c17d99ed81e95846c101e19384c6be111147fec944ec6fe95ed2913cbec52344e4ac0ba6132e3dcdb66cf811b9d0336ca6af3fb80ac1253b53e0b1296b442b59
7
- data.tar.gz: 971f6803ddf2e57e2b66068a33bd7ce6bdac5b8cfa735290656df37f2a569234d2dd5b86b9710c846cca37b49abdb0db16b15c1f99f9ae817289f37c94b4ce7a
6
+ metadata.gz: 7cc96831bcbf17fd3307f0b5f66b5a3e17cee77a753b0dbe635184e2f678cbdb80f4fc5fd962d21ec0ca05c6ee98c353a6eddd7075ca2d3860f41ffbc7cb1445
7
+ data.tar.gz: ca38d82b8e4b814bc39087b52ebddb78d5e83ced0198799eda8e082b6180fe5ca9ed215f9299e2c02af4d11a227b925f17a5a58c91d69b07675b47a66589b5d6
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2019 Code and Effect Inc.
1
+ Copyright 2021 Code and Effect Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,32 +1,14 @@
1
1
  module Admin
2
2
  class LogsController < ApplicationController
3
- before_action :authenticate_user!
4
- skip_log_page_views
5
-
6
- layout (EffectiveLogging.layout.kind_of?(Hash) ? EffectiveLogging.layout[:admin_logs] : EffectiveLogging.layout)
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_logging) }
7
5
 
8
- def index
9
- @datatable = EffectiveLogsDatatable.new(self)
10
-
11
- @page_title = 'Logs'
6
+ include Effective::CrudController
7
+ skip_log_page_views
12
8
 
13
- EffectiveLogging.authorize!(self, :index, Effective::Log)
14
- EffectiveLogging.authorize!(self, :admin, :effective_logging)
9
+ if (config = EffectiveLogging.layout)
10
+ layout(config.kind_of?(Hash) ? config[:admin] : config)
15
11
  end
16
12
 
17
- def show
18
- @log = Effective::Log.includes(:logs).find(params[:id])
19
- @log.next_log = Effective::Log.order(:id).where(parent_id: @log.parent_id).where('id > ?', @log.id).first
20
- @log.prev_log = Effective::Log.order(:id).where(parent_id: @log.parent_id).where('id < ?', @log.id).last
21
-
22
- @page_title = "Log ##{@log.to_param}"
23
-
24
- if @log.logs.present?
25
- @log.datatable = EffectiveLogsDatatable.new(self, log_id: @log.id)
26
- end
27
-
28
- EffectiveLogging.authorize!(self, :show, @log)
29
- EffectiveLogging.authorize!(self, :admin, :effective_logging)
30
- end
31
13
  end
32
14
  end
@@ -1,11 +1,17 @@
1
1
  module Effective
2
2
  class LogsController < ApplicationController
3
+ before_action(:authenticate_user!, only: [:index, :show]) if defined?(Devise)
4
+
5
+ include Effective::CrudController
3
6
  skip_log_page_views
4
- before_action :authenticate_user!, only: [:index, :show]
7
+
8
+ if (config = EffectiveLogging.layout)
9
+ layout(config.kind_of?(Hash) ? config[:application] : config)
10
+ end
5
11
 
6
12
  # This is a post from our Javascript
7
13
  def create
8
- EffectiveLogging.authorize!(self, :create, Effective::Log.new)
14
+ EffectiveResources.authorize!(self, :create, Effective::Log.new)
9
15
 
10
16
  @log = Effective::Log.new.tap do |log|
11
17
  log.message = log_params[:message]
@@ -34,27 +40,10 @@ module Effective
34
40
 
35
41
  # This is the User index event
36
42
  def index
37
- EffectiveLogging.authorize!(self, :index, Effective::Log.new(user_id: current_user.id))
38
-
43
+ EffectiveResources.authorize!(self, :index, Effective::Log.new(user_id: current_user.id))
39
44
  @datatable = EffectiveLogsDatatable.new(self, user_id: current_user.id)
40
45
  end
41
46
 
42
- # This is the User show event
43
- def show
44
- @log = Effective::Log.includes(:logs).find(params[:id])
45
-
46
- EffectiveLogging.authorize!(self, :show, @log)
47
-
48
- @log.next_log = Effective::Log.unscoped.order(:id).where(parent_id: @log.parent_id).where('id > ?', @log.id).first
49
- @log.prev_log = Effective::Log.unscoped.order(:id).where(parent_id: @log.parent_id).where('id < ?', @log.id).last
50
-
51
- @page_title = "Log ##{@log.to_param}"
52
-
53
- if @log.logs.present?
54
- @log.datatable = EffectiveLogsDatatable.new(self, log_id: @log.id)
55
- end
56
- end
57
-
58
47
  def html_part
59
48
  @log = Effective::Log.find(params[:id])
60
49
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class EffectiveLogChangesDatatable < Effective::Datatable
2
4
  datatable do
3
5
  order :updated_at
@@ -5,19 +7,19 @@ class EffectiveLogChangesDatatable < Effective::Datatable
5
7
  col :updated_at, label: 'Date'
6
8
  col :id, visible: false
7
9
 
8
- col :user, sort: false
10
+ col :user, search: :string, sort: false
9
11
 
10
12
  col :associated_type, visible: false
11
- col :associated_id, visible: false
12
- col :associated_to_s, visible: false
13
+ col :associated_id, visible: false, label: 'Associated Id'
14
+ col :associated_to_s, visible: false, label: 'Associated'
13
15
 
14
16
  col :message, sort: false do |log|
15
- message = log.message.gsub("\n", '<br>')
17
+ (log.message || '').gsub!("\n", '<br>')
16
18
 
17
19
  if log.associated_id == attributes[:changes_to_id] && log.associated_type == attributes[:changes_to_type]
18
- message
20
+ log.message
19
21
  else
20
- "#{log.associated_type} #{log.associated_to_s} - #{message}"
22
+ "#{log.associated_type} #{log.associated_to_s} - #{log.message}"
21
23
  end
22
24
 
23
25
  end.search do |collection, term, column, sql_column|
@@ -29,9 +31,7 @@ class EffectiveLogChangesDatatable < Effective::Datatable
29
31
  tableize_hash(log.details)
30
32
  end
31
33
 
32
- unless attributes[:actions] == false
33
- actions_col partial: 'admin/logs/actions', partial_as: :log
34
- end
34
+ actions_col
35
35
  end
36
36
 
37
37
  # A nil attributes[:log_id] means give me all the top level log entries
@@ -7,19 +7,17 @@ class EffectiveLogsDatatable < Effective::Datatable
7
7
 
8
8
  if attributes[:user] == false
9
9
  # Do not include
10
- elsif attributes[:for]
11
- col :user, search: :string
12
10
  else
13
- col :user
11
+ col :user, search: :string, sort: false
14
12
  end
15
13
 
16
14
  unless attributes[:status] == false
17
15
  col :status, search: { collection: EffectiveLogging.statuses }
18
16
  end
19
17
 
20
- col :associated_type, search: { as: :string }
21
- col :associated_id, search: { as: :integer }, visible: false, label: 'Associated Id'
22
- col :associated_to_s, search: { as: :string }, label: 'Associated'
18
+ col :associated_type, visible: false
19
+ col :associated_id, visible: false, label: 'Associated Id'
20
+ col :associated_to_s, label: 'Associated'
23
21
 
24
22
  col :message do |log|
25
23
  log.message.gsub("\n", '<br>')
@@ -31,9 +29,7 @@ class EffectiveLogsDatatable < Effective::Datatable
31
29
  tableize_hash(log.details.except(:email))
32
30
  end
33
31
 
34
- unless attributes[:actions] == false
35
- actions_col partial: 'admin/logs/actions', partial_as: :log
36
- end
32
+ actions_col
37
33
  end
38
34
 
39
35
  # A nil attributes[:log_id] means give me all the top level log entries
@@ -27,8 +27,8 @@ module ActsAsLoggable
27
27
  except: Array(@acts_as_loggable_options[:except])
28
28
  }
29
29
 
30
- if name == 'User'
31
- log_changes_options[:except] += %i(sign_in_count current_sign_in_at current_sign_in_ip last_sign_in_at last_sign_in_ip encrypted_password remember_created_at reset_password_token invitation_sent_at invitation_created_at invitation_token)
30
+ if name.end_with?('User')
31
+ log_changes_options[:except] += %i(sign_in_count current_sign_in_at current_sign_in_ip last_sign_in_at last_sign_in_ip encrypted_password remember_created_at reset_password_token invitation_sent_at invitation_created_at invitation_token access_token refresh_token token_expires_at)
32
32
  end
33
33
 
34
34
  self.send(:define_method, :log_changes_options) { log_changes_options }
@@ -67,4 +67,3 @@ module ActsAsLoggable
67
67
  end
68
68
 
69
69
  end
70
-
@@ -2,42 +2,40 @@ module Effective
2
2
  class Log < ActiveRecord::Base
3
3
  self.table_name = EffectiveLogging.logs_table_name.to_s
4
4
 
5
- # These 3 attr_accessors are set on the controller #show actions
6
- attr_accessor :datatable
7
- attr_accessor :next_log
8
- attr_accessor :prev_log
9
-
10
5
  # Self-Referencing relationship
11
6
  belongs_to :parent, class_name: 'Effective::Log', counter_cache: true, optional: true
12
7
  has_many :logs, class_name: 'Effective::Log', foreign_key: :parent_id
13
8
 
14
- belongs_to :user, optional: true
9
+ belongs_to :user, polymorphic: true, optional: true
15
10
  belongs_to :changes_to, polymorphic: true, optional: true # This is the log_changes to: option
16
11
  belongs_to :associated, polymorphic: true, optional: true
17
12
 
18
- serialize :details, Hash
13
+ effective_resource do
14
+ logs_count :integer # Rails Counter Cache
19
15
 
20
- # Attributes
21
- # logs_count :integer # Rails Counter Cache
16
+ changes_to_type :string
17
+ changes_to_id :string
22
18
 
23
- # changes_to_type :string
24
- # changes_to_id :string
19
+ associated_type :string
20
+ associated_id :integer
21
+ associated_to_s :string
25
22
 
26
- # associated_type :string
27
- # associated_id :integer
28
- # associated_to_s :string
29
- # message :text
30
- # details :text
31
- # status :string
32
- # timestamps
23
+ status :string
24
+ message :text
25
+ details :text
26
+
27
+ timestamps
28
+ end
29
+
30
+ serialize :details, Hash
33
31
 
34
32
  validates :message, presence: true
35
33
  validates :status, presence: true, inclusion: { in: EffectiveLogging.statuses }
36
34
 
37
35
  scope :deep, -> { includes(:user, :associated) }
38
36
  scope :sorted, -> { order(:id) }
39
- scope :logged_changes, -> { where(status: EffectiveLogging.log_changes_status)}
40
- scope :changes, -> { where(status: EffectiveLogging.log_changes_status)}
37
+ scope :logged_changes, -> { where(status: EffectiveLogging.log_changes_status) }
38
+ scope :changes, -> { where(status: EffectiveLogging.log_changes_status) }
41
39
 
42
40
  def to_s
43
41
  "Log #{id}"
@@ -55,6 +53,18 @@ module Effective
55
53
  self[:details] || {}
56
54
  end
57
55
 
56
+ def next_log
57
+ Log.order(id: :asc).where(parent_id: parent_id).where('id > ?', id).first
58
+ end
59
+
60
+ def prev_log
61
+ Log.order(id: :desc).where(parent_id: parent_id).where('id < ?', id).first
62
+ end
63
+
64
+ def child_logs_datatable
65
+ EffectiveLogsDatatable.new(log_id: id)
66
+ end
67
+
58
68
  # Dynamically add logging methods based on the defined statuses
59
69
  # EffectiveLogging.info 'my message'
60
70
  (EffectiveLogging.statuses || []).each do |status|
@@ -63,5 +73,3 @@ module Effective
63
73
 
64
74
  end
65
75
  end
66
-
67
-
@@ -6,7 +6,7 @@ class EffectiveLogger
6
6
 
7
7
  options = Hash(options).delete_if { |k, v| v.blank? }
8
8
 
9
- if options[:user].present? && !options[:user].kind_of?(User)
9
+ if options[:user].present? && !options[:user].class.name.end_with?('User')
10
10
  raise ArgumentError.new('Log.log :user => ... argument must be a User object')
11
11
  end
12
12
 
@@ -30,6 +30,7 @@ class EffectiveLogger
30
30
  message: message,
31
31
  status: status,
32
32
  user_id: options.delete(:user_id),
33
+ user_type: options.delete(:user_type),
33
34
  user: options.delete(:user),
34
35
  parent: options.delete(:parent),
35
36
  associated: options.delete(:associated),
@@ -8,18 +8,22 @@
8
8
  %p= log.message.to_s.gsub("\n", '<br>').html_safe
9
9
 
10
10
  .col-md-4.text-right
11
- - if log.prev_log
12
- = link_to 'Prev', request.fullpath.sub('/' + log.to_param, '/' + log.prev_log.to_param), class: 'btn btn-primary'
11
+ - prev_log = log.prev_log
12
+ - next_log = log.next_log
13
13
 
14
- - if log.next_log
15
- = link_to 'Next', request.fullpath.sub('/' + log.to_param, '/' + log.next_log.to_param), class: 'btn btn-primary'
14
+ - if prev_log.present?
15
+ = link_to 'Prev', request.fullpath.sub('/' + log.to_param, '/' + prev_log.to_param), class: 'btn btn-primary'
16
+
17
+ - if next_log.present?
18
+ = link_to 'Next', request.fullpath.sub('/' + log.to_param, '/' + next_log.to_param), class: 'btn btn-primary'
16
19
 
17
20
  .panel-body.card-body
18
21
  .row
19
22
  .col-md-6
20
23
  %p
21
24
  - status_class = bootstrap_class_for_status(log.status)
22
- %span{:class => (defined?(EffectiveBootstrap) ? "badge badge-#{status_class}" : "label label-#{status_class}")}= log.status
25
+ %span{class: (defined?(EffectiveBootstrap) ? "badge badge-#{status_class}" : "label label-#{status_class}")}= log.status
26
+
23
27
  = log.created_at.strftime("%F %H:%M:%S")
24
28
  = '(' + time_ago_in_words(log.created_at) + ' ago)'
25
29
 
@@ -28,7 +32,8 @@
28
32
  %p
29
33
  %strong User:
30
34
  = (log.user.to_s.starts_with?('#<User:0x') ? (log.user.email rescue log.user) : log.user)
31
- - if (log.associated.present? rescue false)
35
+
36
+ - if log.associated_id.present? && log.associated_type.present? && (log.associated.present? rescue false)
32
37
  %p
33
38
  %strong Associated:
34
39
  - if log.associated.to_s.starts_with?('#<')
@@ -47,6 +52,4 @@
47
52
  - if log.logs.present?
48
53
  %hr
49
54
  %p This log contains #{log.logs_count} additional sub entries:
50
-
51
- - unless log.datatable.nil?
52
- = render_datatable(log.datatable)
55
+ = render_datatable(log.child_logs_datatable)
@@ -2,37 +2,11 @@ EffectiveLogging.setup do |config|
2
2
  # Configure Database Tables
3
3
  config.logs_table_name = :logs
4
4
 
5
- # Authorization Method
6
- #
7
- # This method is called by all controller actions with the appropriate action and resource
8
- # If the method returns false, an Effective::AccessDenied Error will be raised (see README.md for complete info)
9
- #
10
- # Use via Proc (and with CanCan):
11
- # config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) }
12
- #
13
- # Use via custom method:
14
- # config.authorization_method = :my_authorization_method
15
- #
16
- # And then in your application_controller.rb:
17
- #
18
- # def my_authorization_method(action, resource)
19
- # current_user.is?(:admin)
20
- # end
21
- #
22
- # Or disable the check completely:
23
- # config.authorization_method = false
24
- config.authorization_method = Proc.new { |controller, action, resource| authorize!(action, resource) } # CanCanCan
25
-
26
5
  # Admin Screens Layout Settings
27
- config.layout = 'application' # All EffectiveLogging controllers will use this layout
28
-
29
- # config.layout = {
30
- # logs: 'application',
31
- # admin_logs: 'admin',
32
- # }
6
+ # config.layout = { application: 'application', admin: 'admin' }
33
7
 
34
8
  # EffectiveLogger.info('my message') macros
35
- # The following statuses are already present: info, success, error, view, change, email, sign_in, sign_out
9
+ # The following exist: info, success, error, view, change, download, email, sign_in, sign_out
36
10
  # Add more here
37
11
  config.additional_statuses = []
38
12
 
data/config/routes.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  EffectiveLogging::Engine.routes.draw do
2
- scope :module => 'effective' do
2
+ scope module: 'effective' do
3
3
  # Create is our javascript POST event for EffectiveLogging from JS side
4
4
  # The show and index routes are for user specific logs
5
5
  resources :logs, only: [:create, :index, :show] do
@@ -3,6 +3,7 @@ class CreateEffectiveLogging < ActiveRecord::Migration[4.2]
3
3
  create_table <%= @logs_table_name %> do |t|
4
4
  t.integer :parent_id
5
5
 
6
+ t.string :user_type
6
7
  t.integer :user_id
7
8
 
8
9
  t.string :changes_to_type
@@ -3,49 +3,16 @@ require 'effective_logging/engine'
3
3
  require 'effective_logging/version'
4
4
 
5
5
  module EffectiveLogging
6
-
7
- # The following are all valid config keys
8
- mattr_accessor :logs_table_name
9
-
10
- mattr_accessor :authorization_method
11
- mattr_accessor :layout
12
- mattr_accessor :additional_statuses
13
-
14
- mattr_accessor :active_storage_enabled
15
- mattr_accessor :email_enabled
16
- mattr_accessor :sign_in_enabled
17
- mattr_accessor :sign_out_enabled
18
-
19
6
  mattr_accessor :supressed
20
7
 
21
- def self.setup
22
- yield self
8
+ def self.config_keys
9
+ [
10
+ :logs_table_name, :layout, :additional_statuses,
11
+ :active_storage_enabled, :email_enabled, :sign_in_enabled, :sign_out_enabled
12
+ ]
23
13
  end
24
14
 
25
- def self.authorized?(controller, action, resource)
26
- @_exceptions ||= [Effective::AccessDenied, (CanCan::AccessDenied if defined?(CanCan)), (Pundit::NotAuthorizedError if defined?(Pundit))].compact
27
-
28
- return !!authorization_method unless authorization_method.respond_to?(:call)
29
- controller = controller.controller if controller.respond_to?(:controller)
30
-
31
- begin
32
- !!(controller || self).instance_exec((controller || self), action, resource, &authorization_method)
33
- rescue *@_exceptions
34
- false
35
- end
36
- end
37
-
38
- def self.authorize!(controller, action, resource)
39
- raise Effective::AccessDenied unless authorized?(controller, action, resource)
40
- end
41
-
42
- def self.supressed(&block)
43
- @@supressed = true; yield; @@supressed = false
44
- end
45
-
46
- def self.supressed?
47
- @@supressed == true
48
- end
15
+ include EffectiveGem
49
16
 
50
17
  def self.statuses
51
18
  @statuses ||= (
@@ -61,7 +28,7 @@ module EffectiveLogging
61
28
  ('sign_out' if sign_out_enabled)
62
29
  ].compact
63
30
 
64
- additional = Array(@@additional_statuses).map { |status| status.to_s.downcase }
31
+ additional = Array(additional_statuses).map { |status| status.to_s.downcase }
65
32
 
66
33
  base | additional # union
67
34
  )
@@ -73,11 +40,21 @@ module EffectiveLogging
73
40
 
74
41
  # This is set by the "set_effective_logging_current_user" before_filter.
75
42
  def self.current_user=(user)
76
- @effective_logging_current_user = user
43
+ Thread.current[:effective_logging_current_user] = user
77
44
  end
78
45
 
79
46
  def self.current_user
80
- @effective_logging_current_user
47
+ Thread.current[:effective_logging_current_user]
48
+ end
49
+
50
+ def self.supressed(&block)
51
+ Thread.current[:effective_logging_supressed] = true
52
+ yield
53
+ Thread.current[:effective_logging_supressed] = nil
54
+ end
55
+
56
+ def self.supressed?
57
+ Thread.current[:effective_logging_supressed] == true
81
58
  end
82
59
 
83
60
  end
@@ -33,6 +33,9 @@ module EffectiveLogging
33
33
  return true if changes.blank? # If you just click save and change nothing, don't log it.
34
34
 
35
35
  message = (['Updated'] + changes.map do |attribute, (before, after)|
36
+ before = "HTML content (#{before.length})" if before.kind_of?(String) && before.include?('<div')
37
+ after = "HTML content (#{after.length})" if after.kind_of?(String) && after.include?('<div')
38
+
36
39
  "#{attribute}: #{before.presence || BLANK} &rarr; #{after.presence || BLANK}"
37
40
  end).join("\n")
38
41
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module EffectiveLogging
2
4
  module ActiveStorageLogger
3
5
 
@@ -6,16 +8,20 @@ module EffectiveLogging
6
8
 
7
9
  key = decode_verified_key()
8
10
  return unless key.present?
11
+ return if (key[:content_type] || '').starts_with?('image')
9
12
 
10
13
  blob = ActiveStorage::Blob.where(key: key[:key]).first
11
14
  return unless blob.present?
12
15
 
13
16
  blob.attachments.each do |attachment|
17
+ next if attachment.name == 'embeds'
18
+ next if attachment.record_type == 'ActionText::RichText'
19
+
14
20
  associated = attachment.record
15
21
  filename = blob.filename.to_s
16
22
  message = [associated.to_s, filename.to_s].uniq.join(' ')
17
23
 
18
- EffectiveLogger.download(message, associated: associated, filename: filename, user: user)
24
+ EffectiveLogger.download(message, associated: associated, associated_to_s: filename, filename: filename, user: user)
19
25
  end
20
26
  end
21
27
 
@@ -5,37 +5,57 @@ module EffectiveLogging
5
5
  return unless message.present?
6
6
 
7
7
  # collect a Hash of arguments used to invoke EffectiveLogger.success
8
- logged_fields = { from: message.from.join(','), to: message.to, subject: message.subject, cc: message.cc, bcc: message.bcc }
8
+ fields = { from: message.from.join(','), to: message.to, subject: message.subject, cc: message.cc, bcc: message.bcc }
9
9
 
10
10
  # Add a log header to your mailer to pass some objects or additional things to EffectiveLogger
11
11
  # mail(to: 'admin@example.com', subject: @post.title, log: { post: @post })
12
12
  if message.header['log'].present?
13
13
  # This is a bit sketchy, but gives access to the object in Rails 4.2 anyway
14
- logged_fields.merge!(message.header['log'].instance_variable_get(:@value) || {})
14
+ fields.merge!(message.header['log'].instance_variable_get(:@value) || {})
15
15
 
16
16
  # Get rid of the extra header, as it should not be set in the real mail message.
17
17
  message.header['log'] = nil
18
18
  end
19
19
 
20
- body = (message.body.try(:parts) || []).find { |part| part.content_type.to_s.downcase.include?('text/html') }
21
- to = Array(message.to) - [nil, '']
20
+ # Pass a tenant to your mailer
21
+ # mail(to: 'admin@example.com', subject: @post.title, tenant: Tenant.current)
22
+ tenant = if message.header['tenant'].present?
23
+ value = message.header['tenant'].to_s.to_sym # OptionalField, not a String here
24
+ message.header['tenant'] = nil
25
+ value
26
+ end || (Tenant.current if defined?(Tenant))
22
27
 
23
- logged_fields[:email] = "#{message.header}<hr>#{(body.presence || message.body)}"
28
+ user_klass = "#{tenant.to_s.classify}::User".safe_constantize
24
29
 
25
- to.each do |to|
26
- user = (User.where(email: to).first rescue nil)
30
+ body = (message.body.try(:parts) || []).find { |part| part.content_type.to_s.downcase.include?('text/html') }
31
+ body ||= message.body
27
32
 
28
- logged_fields[:to] = to
29
- logged_fields[:associated] ||= user
30
- logged_fields[:user] ||= user
33
+ fields[:email] = "#{message.header}<hr>#{body}"
31
34
 
32
- ::EffectiveLogger.email("#{message.subject} - #{message.to.join(', ')}", logged_fields)
35
+ if tenant.present?
36
+ Tenant.as(tenant) { log_email(message, fields, user_klass) }
37
+ else
38
+ log_email(message, fields, user_klass)
33
39
  end
34
40
 
35
- if to.blank? && (message.cc.present? || message.bcc.present?)
36
- ::EffectiveLogger.email("#{message.subject} - multiple recipients", logged_fields)
41
+ true
42
+ end
43
+
44
+ private
45
+
46
+ def self.log_email(message, fields, user_klass)
47
+ tos = Array(message.to) - [nil, '']
48
+
49
+ tos.each do |to|
50
+ user = (user_klass.where(email: to.downcase).first if user_klass.present?)
51
+
52
+ user_fields = fields.merge(to: to, user: user, associated: user)
53
+ ::EffectiveLogger.email("#{message.subject} - #{tos.join(', ')}", user_fields)
37
54
  end
38
55
 
56
+ if tos.blank? && (message.cc.present? || message.bcc.present?)
57
+ ::EffectiveLogger.email("#{message.subject} - multiple recipients", fields)
58
+ end
39
59
  end
40
60
 
41
61
  end
@@ -39,7 +39,7 @@ module EffectiveLogging
39
39
  return if @_effective_logging_skip_log_page_view == true
40
40
  return if (self.class.log_page_views_opts[:skip_namespace] || []).include?(self.class.parent)
41
41
 
42
- user = EffectiveLogging.current_user || current_user
42
+ user = EffectiveLogging.current_user || (current_user if respond_to?(:current_user))
43
43
 
44
44
  if self.class.log_page_views_opts[:details] == false
45
45
  ::EffectiveLogger.view("#{request.request_method} #{request.path}", user: user)
@@ -66,4 +66,3 @@ module EffectiveLogging
66
66
 
67
67
  end
68
68
  end
69
-
@@ -9,8 +9,9 @@ module EffectiveLogging
9
9
  EffectiveLogging.current_user = current_user
10
10
 
11
11
  if block_given?
12
- yield
12
+ retval = yield
13
13
  EffectiveLogging.current_user = nil
14
+ retval
14
15
  end
15
16
  end
16
17
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveLogging
2
- VERSION = '3.0.13'.freeze
2
+ VERSION = '3.1.4'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_logging
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.13
4
+ version: 3.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-02 00:00:00.000000000 Z
11
+ date: 2021-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -98,10 +98,8 @@ files:
98
98
  - app/datatables/effective_logs_datatable.rb
99
99
  - app/helpers/effective_logging_helper.rb
100
100
  - app/models/concerns/acts_as_loggable.rb
101
- - app/models/effective/access_denied.rb
102
101
  - app/models/effective/log.rb
103
102
  - app/models/effective_logger.rb
104
- - app/views/admin/logs/_actions.html.haml
105
103
  - app/views/admin/logs/index.html.haml
106
104
  - app/views/admin/logs/show.html.haml
107
105
  - app/views/effective/logs/_log.html.haml
@@ -1,17 +0,0 @@
1
- unless defined?(Effective::AccessDenied)
2
- module Effective
3
- class AccessDenied < StandardError
4
- attr_reader :action, :subject
5
-
6
- def initialize(message = nil, action = nil, subject = nil)
7
- @message = message
8
- @action = action
9
- @subject = subject
10
- end
11
-
12
- def to_s
13
- @message || I18n.t(:'unauthorized.default', :default => 'Access Denied')
14
- end
15
- end
16
- end
17
- end
@@ -1,8 +0,0 @@
1
- - show_path = (datatable.admin_namespace? ? effective_logging.admin_log_path(log) : effective_logging.log_path(log))
2
-
3
- - if defined?(EffectiveBootstrap)
4
- = dropdown(variation: :dropleft) do
5
- = dropdown_link_to 'View', show_path
6
- - else
7
- = link_to show_path, title: 'View' do
8
- %span.glyphicon.glyphicon-eye-open