effective_logging 3.0.10 → 3.1.1

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: ced9c07cb086b859429b90b1ccbac95ae8e201b775bcd583b3d289004289094d
4
- data.tar.gz: 7411b720f373bc75ad92be98649481daefc15755d972835909e65d272d243b40
3
+ metadata.gz: e1dc7b7f4024ac664b211eba56892cd43828ec911f37361b91f1ac6496f87fb7
4
+ data.tar.gz: 512c990d5a8dddfcc665e28ff7dd6ef66302ce4f855d68d87fa89af44ef79ed4
5
5
  SHA512:
6
- metadata.gz: caef27d98294627b0a21fa7d6dee8ab0d08d86e8297eddcbfcc403724bbfb75ca79b317192ee96ef744704e88fd03a04b41a913289c7a6e1c92753a140640a38
7
- data.tar.gz: 579cabf40e8107f4a44c23da05e87c7d6887c4e7604b265475a8a4ae6769f99ce421e3e358df70f1d56935e06724254ceebec651cf8a41f5935811d44ad5cff2
6
+ metadata.gz: 612a1bed2cc27c80ee726a023a079e0a5a2dcf80b7d390e07bb9a692bf60da43c974d754bc29f99a17bc95d589e18457aa52261564da19e509947b47046a8f3c
7
+ data.tar.gz: 798375484126e11a779eaffbdf1c53e26a5530f701440b4190660948b52ee9c728e1e7f300684b088a636d4b9df1d08087b71dc3477a434a23c2422b576b27c7
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
data/README.md CHANGED
@@ -211,14 +211,6 @@ class Post < ActiveRecord::Base
211
211
  end
212
212
  ```
213
213
 
214
- and to your controller:
215
-
216
- ```ruby
217
- class ApplicationController < ActionController::Base
218
- before_action :set_effective_logging_current_user
219
- end
220
- ```
221
-
222
214
  Then to see the log for this resource, on any view:
223
215
 
224
216
  ```erb
@@ -1,32 +1,20 @@
1
1
  module Admin
2
2
  class LogsController < ApplicationController
3
- before_action :authenticate_user!
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_logging) }
5
+
6
+ include Effective::CrudController
4
7
  skip_log_page_views
5
8
 
6
- layout (EffectiveLogging.layout.kind_of?(Hash) ? EffectiveLogging.layout[:admin_logs] : EffectiveLogging.layout)
9
+ if (config = EffectiveLogging.layout)
10
+ layout(config.kind_of?(Hash) ? config[:admin] : config)
11
+ end
7
12
 
8
13
  def index
14
+ EffectiveResources.authorize!(self, :index, Effective::Log)
9
15
  @datatable = EffectiveLogsDatatable.new(self)
10
-
11
16
  @page_title = 'Logs'
12
-
13
- EffectiveLogging.authorize!(self, :index, Effective::Log)
14
- EffectiveLogging.authorize!(self, :admin, :effective_logging)
15
17
  end
16
18
 
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
19
  end
32
20
  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?('#<')
@@ -40,14 +45,11 @@
40
45
  - next unless value.present?
41
46
  .row
42
47
  .col-md-12
43
- %p
48
+ .mt-3
44
49
  %strong= "#{key.to_s.titleize}:"
45
50
  = format_log_details_value(log, key)
46
51
 
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)
53
-
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
 
@@ -40,6 +14,9 @@ EffectiveLogging.setup do |config|
40
14
  #### Automatic Logging Functionality ####
41
15
  #########################################
42
16
 
17
+ # Log all active storage downloads
18
+ config.active_storage_enabled = true
19
+
43
20
  # Log all sent emails
44
21
  config.email_enabled = true
45
22
 
@@ -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,53 +3,34 @@ 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 :email_enabled
15
- mattr_accessor :sign_in_enabled
16
- mattr_accessor :sign_out_enabled
17
-
18
6
  mattr_accessor :supressed
19
7
 
20
- def self.setup
21
- 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
+ ]
22
13
  end
23
14
 
24
- def self.authorized?(controller, action, resource)
25
- @_exceptions ||= [Effective::AccessDenied, (CanCan::AccessDenied if defined?(CanCan)), (Pundit::NotAuthorizedError if defined?(Pundit))].compact
26
-
27
- return !!authorization_method unless authorization_method.respond_to?(:call)
28
- controller = controller.controller if controller.respond_to?(:controller)
29
-
30
- begin
31
- !!(controller || self).instance_exec((controller || self), action, resource, &authorization_method)
32
- rescue *@_exceptions
33
- false
34
- end
35
- end
36
-
37
- def self.authorize!(controller, action, resource)
38
- raise Effective::AccessDenied unless authorized?(controller, action, resource)
39
- end
40
-
41
- def self.supressed(&block)
42
- @@supressed = true; yield; @@supressed = false
43
- end
44
-
45
- def self.supressed?
46
- @@supressed == true
47
- end
15
+ include EffectiveGem
48
16
 
49
17
  def self.statuses
50
18
  @statuses ||= (
51
- Array(@@additional_statuses).map { |status| status.to_s.downcase } | # union
52
- ['info', 'success', 'error', 'view', log_changes_status, ('email' if email_enabled), ('sign_in' if sign_in_enabled), ('sign_out' if sign_out_enabled)].compact
19
+ base = [
20
+ 'info',
21
+ 'success',
22
+ 'error',
23
+ 'view',
24
+ log_changes_status, # 'change'
25
+ ('download' if active_storage_enabled),
26
+ ('email' if email_enabled),
27
+ ('sign_in' if sign_in_enabled),
28
+ ('sign_out' if sign_out_enabled)
29
+ ].compact
30
+
31
+ additional = Array(additional_statuses).map { |status| status.to_s.downcase }
32
+
33
+ base | additional # union
53
34
  )
54
35
  end
55
36
 
@@ -59,11 +40,21 @@ module EffectiveLogging
59
40
 
60
41
  # This is set by the "set_effective_logging_current_user" before_filter.
61
42
  def self.current_user=(user)
62
- @effective_logging_current_user = user
43
+ Thread.current[:effective_logging_current_user] = user
63
44
  end
64
45
 
65
46
  def self.current_user
66
- @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
67
58
  end
68
59
 
69
60
  end
@@ -0,0 +1,23 @@
1
+ module EffectiveLogging
2
+ module ActiveStorageLogger
3
+
4
+ def track_downloads
5
+ user = current_user if respond_to?(:current_user)
6
+
7
+ key = decode_verified_key()
8
+ return unless key.present?
9
+
10
+ blob = ActiveStorage::Blob.where(key: key[:key]).first
11
+ return unless blob.present?
12
+
13
+ blob.attachments.each do |attachment|
14
+ associated = attachment.record
15
+ filename = blob.filename.to_s
16
+ message = [associated.to_s, filename.to_s].uniq.join(' ')
17
+
18
+ EffectiveLogger.download(message, associated: associated, filename: filename, user: user)
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -5,30 +5,56 @@ 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 }
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
+ # 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))
27
+
28
+ user_klass = "#{tenant.to_s.classify}::User".safe_constantize
29
+
20
30
  body = (message.body.try(:parts) || []).find { |part| part.content_type.to_s.downcase.include?('text/html') }
31
+ body ||= message.body
21
32
 
22
- logged_fields[:email] = "#{message.header}<hr>#{(body.presence || message.body)}"
33
+ fields[:email] = "#{message.header}<hr>#{body}"
23
34
 
24
- (message.to || []).each do |to|
25
- user = (User.where(email: to).first rescue nil)
35
+ if tenant.present?
36
+ Tenant.as(tenant) { log_email(message, fields, user_klass) }
37
+ else
38
+ log_email(message, fields, user_klass)
39
+ end
40
+
41
+ true
42
+ end
26
43
 
27
- logged_fields[:to] = to
28
- logged_fields[:associated] ||= user
29
- logged_fields[:user] ||= user
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)
54
+ end
30
55
 
31
- ::EffectiveLogger.email("#{message.subject} - #{message.to.join(', ')}", logged_fields)
56
+ if tos.blank? && (message.cc.present? || message.bcc.present?)
57
+ ::EffectiveLogger.email("#{message.subject} - multiple recipients", fields)
32
58
  end
33
59
  end
34
60
 
@@ -1,4 +1,5 @@
1
1
  require 'effective_logging/active_record_logger'
2
+ require 'effective_logging/active_storage_logger'
2
3
  require 'effective_logging/email_logger'
3
4
  require 'effective_logging/log_page_views'
4
5
  require 'effective_logging/set_current_user'
@@ -27,6 +28,16 @@ module EffectiveLogging
27
28
  end
28
29
  end
29
30
 
31
+ # Log all ActiveStorage downloads
32
+ initializer 'effective_logging.active_storage' do |app|
33
+ if EffectiveLogging.active_storage_enabled == true && defined?(ActiveStorage)
34
+ Rails.application.config.to_prepare do
35
+ ActiveStorage::DiskController.include(EffectiveLogging::ActiveStorageLogger)
36
+ ActiveStorage::DiskController.class_eval { after_action(:track_downloads, only: :show) }
37
+ end
38
+ end
39
+ end
40
+
30
41
  # Register the log_page_views concern so that it can be called in ActionController or elsewhere
31
42
  initializer 'effective_logging.log_changes_action_controller' do |app|
32
43
  Rails.application.config.to_prepare do
@@ -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
-
@@ -3,11 +3,16 @@ module EffectiveLogging
3
3
  module ActionController
4
4
 
5
5
  # Add me to your ApplicationController
6
- # before_action :set_effective_logging_current_user
6
+ # around_action :set_effective_logging_current_user
7
7
 
8
8
  def set_effective_logging_current_user
9
9
  EffectiveLogging.current_user = current_user
10
- yield if block_given?
10
+
11
+ if block_given?
12
+ retval = yield
13
+ EffectiveLogging.current_user = nil
14
+ retval
15
+ end
11
16
  end
12
17
 
13
18
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveLogging
2
- VERSION = '3.0.10'.freeze
2
+ VERSION = '3.1.1'.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.10
4
+ version: 3.1.1
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: 2020-09-08 00:00:00.000000000 Z
11
+ date: 2021-02-22 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
@@ -112,6 +110,7 @@ files:
112
110
  - db/migrate/01_create_effective_logging.rb.erb
113
111
  - lib/effective_logging.rb
114
112
  - lib/effective_logging/active_record_logger.rb
113
+ - lib/effective_logging/active_storage_logger.rb
115
114
  - lib/effective_logging/email_logger.rb
116
115
  - lib/effective_logging/engine.rb
117
116
  - lib/effective_logging/log_page_views.rb
@@ -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