loggable_activity 0.1.56 → 0.1.58
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 +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
|