loggable_activity 0.1.56 → 0.1.58
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -1
- data/CHANGELOG.md +9 -0
- data/GETTING-STARTED.md +8 -47
- data/PAYLOAD_EXAMPLE.md +63 -0
- data/docs/LoggableActivity/Activity.html +92 -241
- data/docs/LoggableActivity/Configuration.html +162 -15
- data/docs/LoggableActivity/ConfigurationError.html +148 -0
- data/docs/LoggableActivity/DataOwner.html +138 -0
- data/docs/LoggableActivity/Encryption.html +18 -14
- data/docs/LoggableActivity/EncryptionError.html +47 -1
- data/docs/LoggableActivity/EncryptionKey.html +54 -35
- data/docs/LoggableActivity/Error.html +48 -0
- data/docs/LoggableActivity/Hooks.html +221 -89
- data/docs/LoggableActivity/Payload.html +103 -27
- data/docs/LoggableActivity/Services/BasePayloadsBuilder.html +442 -0
- data/docs/LoggableActivity/Services/DestroyPayloadsBuilder.html +395 -0
- data/docs/LoggableActivity/Services/PayloadsBuilder.html +342 -0
- data/docs/LoggableActivity/Services/UpdatePayloadsBuilder.html +490 -0
- data/docs/LoggableActivity/Services.html +93 -0
- data/docs/created.rid +14 -10
- data/docs/index.html +10 -2
- data/docs/js/navigation.js.gz +0 -0
- data/docs/js/search_index.js +1 -1
- data/docs/js/search_index.js.gz +0 -0
- data/docs/js/searcher.js.gz +0 -0
- data/docs/table_of_contents.html +253 -85
- data/lib/generators/loggable_activity/install_generator.rb +2 -18
- data/lib/generators/loggable_activity/templates/binary_ids/create_loggable_activities.rb +9 -10
- data/lib/generators/loggable_activity/templates/create_loggable_activities.rb +16 -13
- data/lib/loggable_activity/activity.rb +53 -102
- data/lib/loggable_activity/configuration.rb +60 -3
- data/lib/loggable_activity/data_owner.rb +18 -0
- data/lib/loggable_activity/encryption.rb +14 -14
- data/lib/loggable_activity/encryption_key.rb +26 -25
- data/lib/loggable_activity/error.rb +34 -0
- data/lib/loggable_activity/hooks.rb +78 -43
- data/lib/loggable_activity/payload.rb +70 -20
- data/lib/loggable_activity/services/base_payloads_builder.rb +127 -0
- data/lib/loggable_activity/services/destroy_payloads_builder.rb +127 -0
- data/lib/loggable_activity/services/payloads_builder.rb +98 -0
- data/lib/loggable_activity/services/update_payloads_builder.rb +168 -0
- data/lib/loggable_activity/version.rb +1 -1
- data/lib/loggable_activity.rb +6 -6
- data/lib/schemas/config_schema.json +90 -0
- metadata +37 -26
- data/docs/LoggableActivity/PayloadsBuilder.html +0 -441
- data/docs/LoggableActivity/UpdatePayloadsBuilder.html +0 -424
- data/lib/generators/loggable_activity/install_templates_generator.rb +0 -105
- data/lib/generators/loggable_activity/templates/helpers/activity_helper.rb +0 -37
- data/lib/generators/loggable_activity/templates/helpers/router.rb +0 -52
- data/lib/generators/loggable_activity/templates/helpers/routes_helper.rb +0 -20
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_create.html.erb +0 -23
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_create.html.slim +0 -18
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_destroy.html.erb +0 -18
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_destroy.html.slim +0 -17
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_show.html.erb +0 -18
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_show.html.slim +0 -17
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_update.html.erb +0 -18
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_update.html.slim +0 -12
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_activity_info.html.erb +0 -12
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_activity_info.html.slim +0 -11
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_list_attrs.html.erb +0 -8
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_list_attrs.html.slim +0 -6
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_update_attrs.html.erb +0 -17
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_update_attrs.html.slim +0 -14
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_updated_relations.html.erb +0 -23
- data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_updated_relations.html.slim +0 -21
- data/lib/loggable_activity/payloads_builder.rb +0 -153
- data/lib/loggable_activity/update_payloads_builder.rb +0 -127
@@ -1,23 +0,0 @@
|
|
1
|
-
<tr>
|
2
|
-
<td>
|
3
|
-
<%= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity } %>
|
4
|
-
</td>
|
5
|
-
<td>
|
6
|
-
<b class="text-secondary"><%= primary_type(activity) %></b>
|
7
|
-
<br>
|
8
|
-
<% activity.primary_payload_attrs.each do |k, v| %>
|
9
|
-
<%= "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe %>
|
10
|
-
<br>
|
11
|
-
<% end %>
|
12
|
-
<br>
|
13
|
-
<% activity.relations_attrs.each do |relation_attrs| %>
|
14
|
-
<b class="text-secondary"><%= relation_type(relation_attrs) %></b>
|
15
|
-
<br>
|
16
|
-
<%= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation_attrs[:attrs] } %>
|
17
|
-
<br>
|
18
|
-
<% end %>
|
19
|
-
</td>
|
20
|
-
<td>
|
21
|
-
<%= link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm' %>
|
22
|
-
</td>
|
23
|
-
</tr>
|
@@ -1,18 +0,0 @@
|
|
1
|
-
tr
|
2
|
-
td
|
3
|
-
= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity }
|
4
|
-
td
|
5
|
-
b.text-secondary = primary_type(activity)
|
6
|
-
br
|
7
|
-
- activity.primary_payload_attrs.each do |k, v|
|
8
|
-
= "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe
|
9
|
-
br/
|
10
|
-
br
|
11
|
-
- activity.relations_attrs.each do |relation_attrs|
|
12
|
-
b.text-secondary = relation_type(relation_attrs)
|
13
|
-
br/
|
14
|
-
=
|
15
|
-
= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation_attrs[:attrs] }
|
16
|
-
br/
|
17
|
-
td
|
18
|
-
=< link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm'
|
@@ -1,18 +0,0 @@
|
|
1
|
-
<tr>
|
2
|
-
<td>
|
3
|
-
<%= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity } %>
|
4
|
-
</td>
|
5
|
-
<td>
|
6
|
-
<% update_activity_attrs = activity.update_activity_attrs %>
|
7
|
-
<% if update_attrs = update_activity_attrs[:update_attrs] %>
|
8
|
-
<%= render partial: 'loggable_activity/templates/shared/update_attrs', locals: { update_attrs: update_attrs } %>
|
9
|
-
<% end %>
|
10
|
-
<% if updated_relations = update_activity_attrs[:updated_relations_attrs] %>
|
11
|
-
<br>
|
12
|
-
<%= render partial: 'loggable_activity/templates/shared/updated_relations', locals: { updated_relations: updated_relations } %>
|
13
|
-
<% end %>
|
14
|
-
</td>
|
15
|
-
<td>
|
16
|
-
<%= link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm' %>
|
17
|
-
</td>
|
18
|
-
</tr>
|
@@ -1,17 +0,0 @@
|
|
1
|
-
tr
|
2
|
-
td
|
3
|
-
= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity }
|
4
|
-
td
|
5
|
-
b.text-secondary = primary_type(activity)
|
6
|
-
br/
|
7
|
-
- activity.primary_payload_attrs.each do |k, v|
|
8
|
-
= "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe
|
9
|
-
br/
|
10
|
-
br/
|
11
|
-
- activity.relations_attrs.each do |relation_attrs|
|
12
|
-
b.text-secondary = relation_type(relation_attrs)
|
13
|
-
br/
|
14
|
-
= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation_attrs[:attrs] }
|
15
|
-
br/
|
16
|
-
td
|
17
|
-
=< link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm'
|
@@ -1,18 +0,0 @@
|
|
1
|
-
<tr>
|
2
|
-
<td>
|
3
|
-
<%= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity } %>
|
4
|
-
</td>
|
5
|
-
<td>
|
6
|
-
<b class="text-secondary"><%= primary_type(activity) %></b><br/>
|
7
|
-
<% activity.primary_payload_attrs.each do |k, v| %>
|
8
|
-
<%= "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe %><br/>
|
9
|
-
<% end %><br/>
|
10
|
-
<% activity.relations_attrs.each do |relation_attrs| %>
|
11
|
-
<b class="text-secondary"><%= relation_type(relation_attrs) %></b><br/>
|
12
|
-
<%= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation_attrs[:attrs] } %><br/>
|
13
|
-
<% end %>
|
14
|
-
</td>
|
15
|
-
<td>
|
16
|
-
<%= link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm' %>
|
17
|
-
</td>
|
18
|
-
</tr>
|
@@ -1,17 +0,0 @@
|
|
1
|
-
tr
|
2
|
-
td
|
3
|
-
= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity }
|
4
|
-
td
|
5
|
-
b.text-secondary = primary_type(activity)
|
6
|
-
br/
|
7
|
-
- activity.primary_payload_attrs.each do |k, v|
|
8
|
-
= "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe
|
9
|
-
br/
|
10
|
-
br/
|
11
|
-
- activity.relations_attrs.each do |relation_attrs|
|
12
|
-
b.text-secondary = relation_type(relation_attrs)
|
13
|
-
br/
|
14
|
-
= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation_attrs[:attrs] }
|
15
|
-
br/
|
16
|
-
td
|
17
|
-
=< link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm'
|
@@ -1,18 +0,0 @@
|
|
1
|
-
<tr>
|
2
|
-
<td>
|
3
|
-
<%= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity } %>
|
4
|
-
</td>
|
5
|
-
<td>
|
6
|
-
<% update_activity_attrs = activity.update_activity_attrs %>
|
7
|
-
<% if update_attrs = update_activity_attrs[:update_attrs] %>
|
8
|
-
<%= render partial: 'loggable_activity/templates/shared/update_attrs', locals: { update_attrs: update_attrs } %>
|
9
|
-
<% end %>
|
10
|
-
<% if updated_relations = update_activity_attrs[:updated_relations_attrs] %>
|
11
|
-
<br>
|
12
|
-
<%= render partial: 'loggable_activity/templates/shared/updated_relations', locals: { updated_relations: updated_relations } %>
|
13
|
-
<% end %>
|
14
|
-
</td>
|
15
|
-
<td>
|
16
|
-
<%= link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm' %>
|
17
|
-
</td>
|
18
|
-
</tr>
|
@@ -1,12 +0,0 @@
|
|
1
|
-
tr
|
2
|
-
td
|
3
|
-
= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity }
|
4
|
-
td
|
5
|
-
- update_activity_attrs = activity.update_activity_attrs
|
6
|
-
- if update_attrs = update_activity_attrs[:update_attrs]
|
7
|
-
= render partial: 'loggable_activity/templates/shared/update_attrs', locals: { update_attrs: update_attrs }
|
8
|
-
- if updated_relations = update_activity_attrs[:updated_relations_attrs]
|
9
|
-
br/
|
10
|
-
= render partial: 'loggable_activity/templates/shared/updated_relations', locals: { updated_relations: updated_relations }
|
11
|
-
td
|
12
|
-
=< link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm'
|
@@ -1,12 +0,0 @@
|
|
1
|
-
<div class="px-4">
|
2
|
-
<h5><%= t("loggable.activity.#{activity.action}", name: "") %></h5>
|
3
|
-
<b><%= activity.record_display_name %></b>
|
4
|
-
<br>
|
5
|
-
<i>Actor: </i>
|
6
|
-
<br>
|
7
|
-
<%= activity.actor_display_name %>
|
8
|
-
<br>
|
9
|
-
<i>When: </i>
|
10
|
-
<br>
|
11
|
-
<%= I18n.l(activity.created_at, format: :long) %>
|
12
|
-
</div>
|
@@ -1,17 +0,0 @@
|
|
1
|
-
<b class="text-secondary"><%= update_relation_class(update_attrs) %></b>
|
2
|
-
<br>
|
3
|
-
<% if update_attrs[:attrs] == :deleted %>
|
4
|
-
<%= t('loggable.activity.deleted') %>
|
5
|
-
<% else %>
|
6
|
-
<% update_attrs[:attrs].each do |attr| %>
|
7
|
-
<% attr.each do |key, from_to| %>
|
8
|
-
<% next if from_to.nil? %>
|
9
|
-
<i><%= key %></i>
|
10
|
-
<br>
|
11
|
-
<%= "from: #{from_to[:from].nil? ? 'Empty' : from_to[:from]}" %>
|
12
|
-
<br>
|
13
|
-
<%= "to: #{from_to[:to].nil? ? 'Empty' : from_to[:to]}" %>
|
14
|
-
<br>
|
15
|
-
<% end %>
|
16
|
-
<% end %>
|
17
|
-
<% end %>
|
@@ -1,14 +0,0 @@
|
|
1
|
-
b.text-secondary = update_relation_class(update_attrs)
|
2
|
-
br/
|
3
|
-
- if update_attrs[:attrs] == :deleted
|
4
|
-
= t('loggable.activity.deleted')
|
5
|
-
- else
|
6
|
-
- update_attrs[:attrs].each do |attr|
|
7
|
-
- attr.each do |key, from_to|
|
8
|
-
- next if from_to.nil?
|
9
|
-
i = key
|
10
|
-
br/
|
11
|
-
= "from: #{from_to[:from].nil? ? "Empty" : from_to[:from]}"
|
12
|
-
br/
|
13
|
-
= "to: #{from_to[:to].nil? ? "Empty" : from_to[:to]}"
|
14
|
-
br/
|
@@ -1,23 +0,0 @@
|
|
1
|
-
<% updated_relations.each do |relation| %>
|
2
|
-
<b class="text-secondary"><%= update_relation_class(relation) %></b>
|
3
|
-
<br>
|
4
|
-
<% if relation[:previous_attrs].present? %>
|
5
|
-
<i>From:</i>
|
6
|
-
<br>
|
7
|
-
<%= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation[:previous_attrs][:attrs] } %>
|
8
|
-
<% else %>
|
9
|
-
<i>From:</i>
|
10
|
-
<br>
|
11
|
-
Empty
|
12
|
-
<br>
|
13
|
-
<% end %>
|
14
|
-
<% if relation[:current_attrs].present? %>
|
15
|
-
<i>To:</i>
|
16
|
-
<br>
|
17
|
-
<%= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation[:current_attrs][:attrs] } %>
|
18
|
-
<% else %>
|
19
|
-
<i>To:</i>
|
20
|
-
<br>
|
21
|
-
Empty
|
22
|
-
<% end %>
|
23
|
-
<% end %>
|
@@ -1,21 +0,0 @@
|
|
1
|
-
- updated_relations.each do |relation|
|
2
|
-
b.text-secondary = update_relation_class(relation)
|
3
|
-
br/
|
4
|
-
- if relation[:previous_attrs].present?
|
5
|
-
i From:
|
6
|
-
br/
|
7
|
-
= render partial:'loggable_activity/templates/shared/list_attrs', locals: {attrs: relation[:previous_attrs][:attrs] }
|
8
|
-
- else
|
9
|
-
i From:
|
10
|
-
br/
|
11
|
-
|Empty
|
12
|
-
br
|
13
|
-
- if relation[:current_attrs].present?
|
14
|
-
i To:
|
15
|
-
br/
|
16
|
-
= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation[:current_attrs][:attrs] }
|
17
|
-
- else
|
18
|
-
i To:
|
19
|
-
br/
|
20
|
-
|Empty
|
21
|
-
|
@@ -1,153 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module LoggableActivity
|
4
|
-
# This module is responsible for building payloads used in loggable activities.
|
5
|
-
module PayloadsBuilder
|
6
|
-
# Builds payloads for the loggable activity.
|
7
|
-
#
|
8
|
-
# Example:
|
9
|
-
# build_payloads
|
10
|
-
#
|
11
|
-
# Returns:
|
12
|
-
# #<LoggableActivity::Payload:0x0000000109658718> {
|
13
|
-
# :id => 129,
|
14
|
-
# :record_type => "Demo::Club",
|
15
|
-
# :record_id => 4,
|
16
|
-
# :encrypted_attrs => {
|
17
|
-
# "name" => "z/jigjcm3Fb89L7QT8XiNhvVgjtRXKkmg/xohR6wIc0=\n"
|
18
|
-
# },
|
19
|
-
# :payload_type => "current_association",
|
20
|
-
# :data_owner => nil,
|
21
|
-
# :activity_id => 50,
|
22
|
-
# :created_at => Wed, 14 Feb 2024 13:21:13.964339000 UTC +00:00,
|
23
|
-
# :updated_at => Wed, 14 Feb 2024 13:21:13.964339000 UTC +00:00
|
24
|
-
# }
|
25
|
-
#
|
26
|
-
def build_payloads
|
27
|
-
build_primary_payload
|
28
|
-
self.class.relations.each do |relation_config|
|
29
|
-
build_relation_payload(relation_config)
|
30
|
-
end
|
31
|
-
@payloads
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
# Builds the primary payload.
|
37
|
-
def build_primary_payload
|
38
|
-
encrypted_attrs = encrypt_attrs(attributes, self.class.loggable_attrs, primary_encryption_key)
|
39
|
-
@payloads << LoggableActivity::Payload.new(
|
40
|
-
record: @record,
|
41
|
-
payload_type: 'primary_payload',
|
42
|
-
encrypted_attrs:,
|
43
|
-
data_owner: true,
|
44
|
-
route: self.class.route
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
|
-
# Builds the payload for destroyed records.
|
49
|
-
def build_destroy_payload
|
50
|
-
encrypted_attrs = encrypt_attrs(attributes, self.class.loggable_attrs, primary_encryption_key)
|
51
|
-
encrypted_attrs.transform_values! { '*** DELETED ***' }
|
52
|
-
@payloads << LoggableActivity::Payload.new(
|
53
|
-
record: @record,
|
54
|
-
payload_type: 'primary_payload',
|
55
|
-
encrypted_attrs:,
|
56
|
-
data_owner: true,
|
57
|
-
route: nil
|
58
|
-
)
|
59
|
-
end
|
60
|
-
|
61
|
-
# Builds payloads for relations
|
62
|
-
#
|
63
|
-
# @param relation_config [Hash] The configuration of the relation.
|
64
|
-
def build_relation_payload(relation_config)
|
65
|
-
relation_config.each_key do |key|
|
66
|
-
case key
|
67
|
-
when 'belongs_to'
|
68
|
-
build_payload(relation_config, 'belongs_to')
|
69
|
-
when 'has_one'
|
70
|
-
build_payload(relation_config, 'has_one')
|
71
|
-
when 'has_many'
|
72
|
-
build_has_many_payloads(relation_config, 'has_many')
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Builds the payload for a specific relation.
|
78
|
-
#
|
79
|
-
# @param relation_config [Hash] The configuration of the relation.
|
80
|
-
# @param relation_type [String] The type of the relation.
|
81
|
-
def build_payload(relation_config, relation_type)
|
82
|
-
associated_record = send(relation_config[relation_type])
|
83
|
-
return nil if associated_record.nil?
|
84
|
-
|
85
|
-
build_associated_payload(associated_record, relation_config)
|
86
|
-
end
|
87
|
-
|
88
|
-
# Builds payloads for has_many relations.
|
89
|
-
def build_has_many_payloads(relation_config, relation_type)
|
90
|
-
associated_records = send(relation_config[relation_type])
|
91
|
-
return nil if associated_records.empty?
|
92
|
-
|
93
|
-
associated_records.each do |associated_record|
|
94
|
-
build_associated_payload(associated_record, relation_config)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
# Builds the payload for an associated record.
|
99
|
-
def build_associated_payload(associated_record, relation_config)
|
100
|
-
associated_loggable_attrs = relation_config['loggable_attrs']
|
101
|
-
encryption_key = associated_record_encryption_key(associated_record, relation_config['data_owner'])
|
102
|
-
encrypted_attrs =
|
103
|
-
encrypt_attrs(
|
104
|
-
associated_record.attributes,
|
105
|
-
associated_loggable_attrs,
|
106
|
-
encryption_key.key
|
107
|
-
)
|
108
|
-
|
109
|
-
@payloads << LoggableActivity::Payload.new(
|
110
|
-
record: associated_record,
|
111
|
-
encrypted_attrs:,
|
112
|
-
payload_type: 'current_association',
|
113
|
-
data_owner: relation_config['data_owner'],
|
114
|
-
route: relation_config['route']
|
115
|
-
)
|
116
|
-
end
|
117
|
-
|
118
|
-
# Retrieves the encryption key for the associated record.
|
119
|
-
#
|
120
|
-
# @param associated_record [ActiveRecord::Base] The associated record.
|
121
|
-
# @param data_owner [Boolean] Whether the associated record is the owner of the data.
|
122
|
-
# @return [LoggableActivity::EncryptionKey] The encryption key for the associated record.
|
123
|
-
def associated_record_encryption_key(associated_record, data_owner)
|
124
|
-
if data_owner
|
125
|
-
LoggableActivity::EncryptionKey.for_record(associated_record, LoggableActivity::EncryptionKey.for_record(self))
|
126
|
-
else
|
127
|
-
LoggableActivity::EncryptionKey.for_record(associated_record)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
# Encrypts attributes.
|
132
|
-
#
|
133
|
-
# @param attrs [Hash] The attributes to be encrypted.
|
134
|
-
# @param loggable_attrs [Array<String>] The loggable attributes.
|
135
|
-
# @param encryption_key [String] The encryption key.
|
136
|
-
# @return [Hash] The encrypted attributes.
|
137
|
-
def encrypt_attrs(attrs, loggable_attrs, encryption_key)
|
138
|
-
attrs = attrs.slice(*loggable_attrs)
|
139
|
-
encrypt_attr(attrs, encryption_key)
|
140
|
-
end
|
141
|
-
|
142
|
-
# Encrypts a single attribute.
|
143
|
-
#
|
144
|
-
# @param attrs [Hash] The attributes to be encrypted.
|
145
|
-
# @param encryption_key [String] The encryption key.
|
146
|
-
# @return [Hash] The encrypted attributes.
|
147
|
-
def encrypt_attr(attrs, encryption_key)
|
148
|
-
attrs.each do |key, value|
|
149
|
-
attrs[key] = LoggableActivity::Encryption.encrypt(value, encryption_key)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
@@ -1,127 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module LoggableActivity
|
4
|
-
# This module is responsible for building update payloads used in loggable activities.
|
5
|
-
module UpdatePayloadsBuilder
|
6
|
-
# Builds payloads for an activity update event.
|
7
|
-
def build_update_payloads
|
8
|
-
@update_payloads = []
|
9
|
-
|
10
|
-
previous_values, current_values = primary_update_attrs
|
11
|
-
build_primary_update_payload(previous_values, current_values)
|
12
|
-
|
13
|
-
self.class.relations.each do |relation_config|
|
14
|
-
build_update_relation_payloads(relation_config)
|
15
|
-
end
|
16
|
-
@update_payloads
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
# Fetch the previous and current values of the primary record.
|
22
|
-
def primary_update_attrs
|
23
|
-
previous_values = saved_changes.transform_values(&:first)
|
24
|
-
current_values = saved_changes.transform_values(&:last)
|
25
|
-
|
26
|
-
[previous_values, current_values]
|
27
|
-
end
|
28
|
-
|
29
|
-
# Builds the primary update payload.
|
30
|
-
def build_primary_update_payload(previous_values, current_values)
|
31
|
-
return if previous_values == current_values
|
32
|
-
|
33
|
-
encrypted_update_attrs = encrypted_update_attrs(previous_values, current_values)
|
34
|
-
@update_payloads << LoggableActivity::Payload.new(
|
35
|
-
record: @record,
|
36
|
-
payload_type: 'update_payload',
|
37
|
-
encrypted_attrs: encrypted_update_attrs,
|
38
|
-
route: self.class.route
|
39
|
-
)
|
40
|
-
end
|
41
|
-
|
42
|
-
# Returns the encrypted attributes for the update payload.
|
43
|
-
def encrypted_update_attrs(previous_values, current_values)
|
44
|
-
changes = []
|
45
|
-
changed_attrs = previous_values.slice(*self.class.loggable_attrs)
|
46
|
-
changed_attrs.each do |key, from_value|
|
47
|
-
from = LoggableActivity::Encryption.encrypt(from_value, primary_encryption_key)
|
48
|
-
to_value = current_values[key]
|
49
|
-
to = LoggableActivity::Encryption.encrypt(to_value, primary_encryption_key)
|
50
|
-
changes << { key => { from:, to: } }
|
51
|
-
end
|
52
|
-
{ changes: }
|
53
|
-
end
|
54
|
-
|
55
|
-
# Builds update payloads for relations.
|
56
|
-
def build_update_relation_payloads(relation_config)
|
57
|
-
relation_config.each_key do |key|
|
58
|
-
case key
|
59
|
-
when 'belongs_to'
|
60
|
-
build_relation_update_for_belongs_to(relation_config)
|
61
|
-
when 'has_one'
|
62
|
-
build_relation_update_for_has_one(relation_config)
|
63
|
-
when 'has_many'
|
64
|
-
build_relation_update_for_has_many(relation_config)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# Builds the update payload for a has_many relation.
|
70
|
-
def build_relation_update_for_has_many(relation_config)
|
71
|
-
# NOTE: This method is not implemented yet.
|
72
|
-
# It requires that there is a form where it is possible to change
|
73
|
-
# the related records. This is not implemented yet. in the Demo app
|
74
|
-
# puts relation_config['has_many']
|
75
|
-
end
|
76
|
-
|
77
|
-
# Builds the update payload for a has_one relation.
|
78
|
-
def build_relation_update_for_has_one(relation_config)
|
79
|
-
# NOTE: This method is not implemented yet.
|
80
|
-
# It requires that there is a form where it is possible to change
|
81
|
-
# the related records. This is not implemented yet. in the Demo app
|
82
|
-
# puts relation_config['has_one']
|
83
|
-
end
|
84
|
-
|
85
|
-
# Builds the update payload for a belongs_to relation.
|
86
|
-
def build_relation_update_for_belongs_to(relation_config)
|
87
|
-
relation_id = "#{relation_config['belongs_to']}_id"
|
88
|
-
model_class_name = relation_config['model']
|
89
|
-
model_class = model_class_name.constantize
|
90
|
-
|
91
|
-
return unless saved_changes.include?(relation_id)
|
92
|
-
|
93
|
-
relation_id_changes = saved_changes[relation_id]
|
94
|
-
previous_relation_id, current_relation_id = relation_id_changes
|
95
|
-
|
96
|
-
[previous_relation_id, current_relation_id].each_with_index do |id, index|
|
97
|
-
relation_record = id ? model_class.find_by(id:) : nil
|
98
|
-
next unless relation_record
|
99
|
-
|
100
|
-
payload_type = index.zero? ? 'previous_association' : 'current_association'
|
101
|
-
build_relation_update_payload(
|
102
|
-
relation_config,
|
103
|
-
relation_record,
|
104
|
-
payload_type
|
105
|
-
)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# Builds the update payload for a relation.
|
110
|
-
def build_relation_update_payload(relation_config, record, payload_type)
|
111
|
-
encryption_key = LoggableActivity::EncryptionKey.for_record(record)&.key
|
112
|
-
encrypted_attrs = relation_encrypted_attrs(record.attributes, relation_config['loggable_attrs'], encryption_key)
|
113
|
-
|
114
|
-
@update_payloads << LoggableActivity::Payload.new(
|
115
|
-
record:,
|
116
|
-
encrypted_attrs:,
|
117
|
-
payload_type:,
|
118
|
-
route: relation_config['route']
|
119
|
-
)
|
120
|
-
end
|
121
|
-
|
122
|
-
# Returns the encrypted attributes for a relation.
|
123
|
-
def relation_encrypted_attrs(attrs, loggable_attrs, encryption_key)
|
124
|
-
encrypt_attrs(attrs, loggable_attrs, encryption_key)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|