loggable_activity 0.1.39 → 0.1.42
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.document +1 -0
- data/.nojekyll +1 -0
- data/.rubocop.yml +1 -1
- data/doc/.nojekyll +1 -0
- data/doc/CHANGELOG_md.html +125 -0
- data/doc/CODE_OF_CONDUCT_md.html +220 -0
- data/doc/CONSIDERTIONS_md.html +227 -0
- data/doc/CreateLoggableActivities.html +144 -0
- data/doc/CreateLoggableEncryptionKeys.html +140 -0
- data/doc/CreateLoggablePayloads.html +144 -0
- data/doc/GETTING-STARTED_md.html +186 -0
- data/doc/Gemfile.html +104 -0
- data/doc/Gemfile_lock.html +152 -0
- data/doc/LICENSE_txt.html +104 -0
- data/doc/LoggableActivity/CurrentUser.html +99 -0
- data/doc/LoggableActivity/Generators/InstallGenerator.html +178 -0
- data/doc/LoggableActivity/Generators.html +91 -0
- data/doc/README_md.html +138 -0
- data/doc/ROADMAP_md.html +151 -0
- data/doc/Rakefile.html +102 -0
- data/doc/bin/setup.html +100 -0
- data/doc/notes/CHEAT_SHEET_md.html +130 -0
- data/doc/sig/loggable_activity_rbs.html +101 -0
- data/docs/LoggableActivity/Activity.html +494 -0
- data/docs/LoggableActivity/Configuration.html +183 -0
- data/docs/LoggableActivity/Encryption.html +220 -0
- data/docs/LoggableActivity/EncryptionError.html +99 -0
- data/docs/LoggableActivity/EncryptionKey.html +327 -0
- data/docs/LoggableActivity/Error.html +97 -0
- data/docs/LoggableActivity/Hooks.html +172 -0
- data/docs/LoggableActivity/Payload.html +159 -0
- data/docs/LoggableActivity/PayloadsBuilder.html +154 -0
- data/docs/LoggableActivity/UpdatePayloadsBuilder.html +199 -0
- data/docs/LoggableActivity.html +100 -0
- data/docs/created.rid +10 -0
- data/docs/css/fonts.css +167 -0
- data/docs/css/rdoc.css +687 -0
- data/docs/fonts/Lato-Light.ttf +0 -0
- data/docs/fonts/Lato-LightItalic.ttf +0 -0
- data/docs/fonts/Lato-Regular.ttf +0 -0
- data/docs/fonts/Lato-RegularItalic.ttf +0 -0
- data/docs/fonts/SourceCodePro-Bold.ttf +0 -0
- data/docs/fonts/SourceCodePro-Regular.ttf +0 -0
- data/docs/images/add.png +0 -0
- data/docs/images/arrow_up.png +0 -0
- data/docs/images/brick.png +0 -0
- data/docs/images/brick_link.png +0 -0
- data/docs/images/bug.png +0 -0
- data/docs/images/bullet_black.png +0 -0
- data/docs/images/bullet_toggle_minus.png +0 -0
- data/docs/images/bullet_toggle_plus.png +0 -0
- data/docs/images/date.png +0 -0
- data/docs/images/delete.png +0 -0
- data/docs/images/find.png +0 -0
- data/docs/images/loadingAnimation.gif +0 -0
- data/docs/images/macFFBgHack.png +0 -0
- data/docs/images/package.png +0 -0
- data/docs/images/page_green.png +0 -0
- data/docs/images/page_white_text.png +0 -0
- data/docs/images/page_white_width.png +0 -0
- data/docs/images/plugin.png +0 -0
- data/docs/images/ruby.png +0 -0
- data/docs/images/tag_blue.png +0 -0
- data/docs/images/tag_green.png +0 -0
- data/docs/images/transparent.png +0 -0
- data/docs/images/wrench.png +0 -0
- data/docs/images/wrench_orange.png +0 -0
- data/docs/images/zoom.png +0 -0
- data/docs/index.html +91 -0
- data/docs/js/darkfish.js +97 -0
- data/docs/js/navigation.js +105 -0
- data/docs/js/navigation.js.gz +0 -0
- data/docs/js/search.js +110 -0
- data/docs/js/search_index.js +1 -0
- data/docs/js/search_index.js.gz +0 -0
- data/docs/js/searcher.js +229 -0
- data/docs/js/searcher.js.gz +0 -0
- data/docs/table_of_contents.html +184 -0
- data/lib/generators/loggable_activity/install_generator.rb +2 -1
- data/lib/generators/loggable_activity/templates/current_user.rb +1 -1
- data/lib/generators/loggable_activity/templates/loggable_activity.yml +29 -0
- data/lib/loggable_activity/activity.rb +208 -59
- data/lib/loggable_activity/configuration.rb +18 -0
- data/lib/loggable_activity/encryption.rb +20 -1
- data/lib/loggable_activity/encryption_key.rb +81 -14
- data/lib/loggable_activity/hooks.rb +10 -7
- data/lib/loggable_activity/payload.rb +45 -11
- data/lib/loggable_activity/payloads_builder.rb +50 -4
- data/lib/loggable_activity/update_payloads_builder.rb +64 -2
- data/lib/loggable_activity/version.rb +1 -1
- metadata +81 -9
- data/.DS_Store +0 -0
- data/loggable_activity-0.1.32.gem +0 -0
- data/loggable_activity-0.1.33.gem +0 -0
- data/loggable_activity-0.1.34.gem +0 -0
Binary file
|
@@ -0,0 +1,184 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<meta charset="UTF-8">
|
6
|
+
|
7
|
+
<title>Table of Contents - RDoc Documentation</title>
|
8
|
+
|
9
|
+
<script type="text/javascript">
|
10
|
+
var rdoc_rel_prefix = "./";
|
11
|
+
var index_rel_prefix = "./";
|
12
|
+
</script>
|
13
|
+
|
14
|
+
<script src="./js/navigation.js" defer></script>
|
15
|
+
<script src="./js/search.js" defer></script>
|
16
|
+
<script src="./js/search_index.js" defer></script>
|
17
|
+
<script src="./js/searcher.js" defer></script>
|
18
|
+
<script src="./js/darkfish.js" defer></script>
|
19
|
+
|
20
|
+
<link href="./css/fonts.css" rel="stylesheet">
|
21
|
+
<link href="./css/rdoc.css" rel="stylesheet">
|
22
|
+
|
23
|
+
|
24
|
+
<body id="top" class="table-of-contents">
|
25
|
+
<main role="main">
|
26
|
+
<h1 class="class">Table of Contents - RDoc Documentation</h1>
|
27
|
+
|
28
|
+
|
29
|
+
<h2 id="classes">Classes and Modules</h2>
|
30
|
+
<ul>
|
31
|
+
<li class="module">
|
32
|
+
<a href="LoggableActivity.html">LoggableActivity</a>
|
33
|
+
</li>
|
34
|
+
<li class="class">
|
35
|
+
<a href="LoggableActivity/Activity.html">LoggableActivity::Activity</a>
|
36
|
+
</li>
|
37
|
+
<li class="class">
|
38
|
+
<a href="LoggableActivity/Configuration.html">LoggableActivity::Configuration</a>
|
39
|
+
</li>
|
40
|
+
<li class="module">
|
41
|
+
<a href="LoggableActivity/Encryption.html">LoggableActivity::Encryption</a>
|
42
|
+
</li>
|
43
|
+
<li class="class">
|
44
|
+
<a href="LoggableActivity/EncryptionError.html">LoggableActivity::EncryptionError</a>
|
45
|
+
</li>
|
46
|
+
<li class="class">
|
47
|
+
<a href="LoggableActivity/EncryptionKey.html">LoggableActivity::EncryptionKey</a>
|
48
|
+
</li>
|
49
|
+
<li class="module">
|
50
|
+
<a href="LoggableActivity/Hooks.html">LoggableActivity::Hooks</a>
|
51
|
+
</li>
|
52
|
+
<li class="class">
|
53
|
+
<a href="LoggableActivity/Payload.html">LoggableActivity::Payload</a>
|
54
|
+
</li>
|
55
|
+
<li class="module">
|
56
|
+
<a href="LoggableActivity/PayloadsBuilder.html">LoggableActivity::PayloadsBuilder</a>
|
57
|
+
</li>
|
58
|
+
<li class="module">
|
59
|
+
<a href="LoggableActivity/UpdatePayloadsBuilder.html">LoggableActivity::UpdatePayloadsBuilder</a>
|
60
|
+
</li>
|
61
|
+
</ul>
|
62
|
+
|
63
|
+
<h2 id="methods">Methods</h2>
|
64
|
+
<ul>
|
65
|
+
|
66
|
+
<li class="method">
|
67
|
+
<a href="LoggableActivity/Activity.html#method-c-activities_for_actor">::activities_for_actor</a>
|
68
|
+
—
|
69
|
+
<span class="container">LoggableActivity::Activity</span>
|
70
|
+
|
71
|
+
<li class="method">
|
72
|
+
<a href="LoggableActivity/Encryption.html#method-c-blank-3F">::blank?</a>
|
73
|
+
—
|
74
|
+
<span class="container">LoggableActivity::Encryption</span>
|
75
|
+
|
76
|
+
<li class="method">
|
77
|
+
<a href="LoggableActivity/EncryptionKey.html#method-c-create_encryption_key">::create_encryption_key</a>
|
78
|
+
—
|
79
|
+
<span class="container">LoggableActivity::EncryptionKey</span>
|
80
|
+
|
81
|
+
<li class="method">
|
82
|
+
<a href="LoggableActivity/Encryption.html#method-c-decrypt">::decrypt</a>
|
83
|
+
—
|
84
|
+
<span class="container">LoggableActivity::Encryption</span>
|
85
|
+
|
86
|
+
<li class="method">
|
87
|
+
<a href="LoggableActivity/Encryption.html#method-c-encrypt">::encrypt</a>
|
88
|
+
—
|
89
|
+
<span class="container">LoggableActivity::Encryption</span>
|
90
|
+
|
91
|
+
<li class="method">
|
92
|
+
<a href="LoggableActivity/Configuration.html#method-c-for_class">::for_class</a>
|
93
|
+
—
|
94
|
+
<span class="container">LoggableActivity::Configuration</span>
|
95
|
+
|
96
|
+
<li class="method">
|
97
|
+
<a href="LoggableActivity/EncryptionKey.html#method-c-for_record">::for_record</a>
|
98
|
+
—
|
99
|
+
<span class="container">LoggableActivity::EncryptionKey</span>
|
100
|
+
|
101
|
+
<li class="method">
|
102
|
+
<a href="LoggableActivity/EncryptionKey.html#method-c-for_record_by_type_and_id">::for_record_by_type_and_id</a>
|
103
|
+
—
|
104
|
+
<span class="container">LoggableActivity::EncryptionKey</span>
|
105
|
+
|
106
|
+
<li class="method">
|
107
|
+
<a href="LoggableActivity/Activity.html#method-c-latest">::latest</a>
|
108
|
+
—
|
109
|
+
<span class="container">LoggableActivity::Activity</span>
|
110
|
+
|
111
|
+
<li class="method">
|
112
|
+
<a href="LoggableActivity/Configuration.html#method-c-load_config_file">::load_config_file</a>
|
113
|
+
—
|
114
|
+
<span class="container">LoggableActivity::Configuration</span>
|
115
|
+
|
116
|
+
<li class="method">
|
117
|
+
<a href="LoggableActivity/EncryptionKey.html#method-c-random_key">::random_key</a>
|
118
|
+
—
|
119
|
+
<span class="container">LoggableActivity::EncryptionKey</span>
|
120
|
+
|
121
|
+
<li class="method">
|
122
|
+
<a href="LoggableActivity/Activity.html#method-i-actor_display_name">#actor_display_name</a>
|
123
|
+
—
|
124
|
+
<span class="container">LoggableActivity::Activity</span>
|
125
|
+
|
126
|
+
<li class="method">
|
127
|
+
<a href="LoggableActivity/Activity.html#method-i-attrs">#attrs</a>
|
128
|
+
—
|
129
|
+
<span class="container">LoggableActivity::Activity</span>
|
130
|
+
|
131
|
+
<li class="method">
|
132
|
+
<a href="LoggableActivity/Payload.html#method-i-attrs">#attrs</a>
|
133
|
+
—
|
134
|
+
<span class="container">LoggableActivity::Payload</span>
|
135
|
+
|
136
|
+
<li class="method">
|
137
|
+
<a href="LoggableActivity/PayloadsBuilder.html#method-i-build_payloads">#build_payloads</a>
|
138
|
+
—
|
139
|
+
<span class="container">LoggableActivity::PayloadsBuilder</span>
|
140
|
+
|
141
|
+
<li class="method">
|
142
|
+
<a href="LoggableActivity/UpdatePayloadsBuilder.html#method-i-build_update_payloads">#build_update_payloads</a>
|
143
|
+
—
|
144
|
+
<span class="container">LoggableActivity::UpdatePayloadsBuilder</span>
|
145
|
+
|
146
|
+
<li class="method">
|
147
|
+
<a href="LoggableActivity/Hooks.html#method-i-log">#log</a>
|
148
|
+
—
|
149
|
+
<span class="container">LoggableActivity::Hooks</span>
|
150
|
+
|
151
|
+
<li class="method">
|
152
|
+
<a href="LoggableActivity/EncryptionKey.html#method-i-mark_as_deleted">#mark_as_deleted</a>
|
153
|
+
—
|
154
|
+
<span class="container">LoggableActivity::EncryptionKey</span>
|
155
|
+
|
156
|
+
<li class="method">
|
157
|
+
<a href="LoggableActivity/Activity.html#method-i-primary_payload_attrs">#primary_payload_attrs</a>
|
158
|
+
—
|
159
|
+
<span class="container">LoggableActivity::Activity</span>
|
160
|
+
|
161
|
+
<li class="method">
|
162
|
+
<a href="LoggableActivity/Activity.html#method-i-record_display_name">#record_display_name</a>
|
163
|
+
—
|
164
|
+
<span class="container">LoggableActivity::Activity</span>
|
165
|
+
|
166
|
+
<li class="method">
|
167
|
+
<a href="LoggableActivity/Activity.html#method-i-relations_attrs">#relations_attrs</a>
|
168
|
+
—
|
169
|
+
<span class="container">LoggableActivity::Activity</span>
|
170
|
+
|
171
|
+
<li class="method">
|
172
|
+
<a href="LoggableActivity/Activity.html#method-i-update_activity_attrs">#update_activity_attrs</a>
|
173
|
+
—
|
174
|
+
<span class="container">LoggableActivity::Activity</span>
|
175
|
+
</ul>
|
176
|
+
</main>
|
177
|
+
|
178
|
+
|
179
|
+
<footer id="validator-badges" role="contentinfo">
|
180
|
+
<p><a href="https://validator.w3.org/check/referer">Validate</a>
|
181
|
+
<p>Generated by <a href="https://ruby.github.io/rdoc/">RDoc</a> 6.6.2.
|
182
|
+
<p>Based on <a href="http://deveiate.org/projects/Darkfish-RDoc/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.
|
183
|
+
</footer>
|
184
|
+
|
@@ -23,7 +23,8 @@ module LoggableActivity
|
|
23
23
|
|
24
24
|
def create_model_file
|
25
25
|
template 'loggable_activity.en.yml', 'config/locales/loggable_activity.en.yml'
|
26
|
-
template
|
26
|
+
template 'loggable_activity.yml', 'config/loggable_activity.yml'
|
27
|
+
template 'current_user.rb', 'app/controllers/concerns/loggable_activity/current_user.rb'
|
27
28
|
end
|
28
29
|
end
|
29
30
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Stores current user in a thread variable so that is can be accessed from the 'models/conserns/loggable/activities.rb' file.
|
4
3
|
module LoggableActivity
|
4
|
+
# Stores current user in a thread variable so is can be accessed from the LoggableActivity::Hook model
|
5
5
|
module CurrentUser
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# User:
|
2
|
+
# record_display_name: full_name
|
3
|
+
# loggable_attrs:
|
4
|
+
# - first_name
|
5
|
+
# - last_name
|
6
|
+
# - age
|
7
|
+
# - email
|
8
|
+
# - user_type
|
9
|
+
# auto_log:
|
10
|
+
# - create
|
11
|
+
# - update
|
12
|
+
# - destroy
|
13
|
+
# relations:
|
14
|
+
# - has_one: :demo_user_profile
|
15
|
+
# model: Demo::UserProfile
|
16
|
+
# loggable_attrs:
|
17
|
+
# - sex
|
18
|
+
# - religion
|
19
|
+
# - belongs_to: :demo_address
|
20
|
+
# model: Demo::Address
|
21
|
+
# loggable_attrs:
|
22
|
+
# - street
|
23
|
+
# - city
|
24
|
+
# - country
|
25
|
+
# - postal_code
|
26
|
+
# - belongs_to: :demo_club
|
27
|
+
# model: Demo::Club
|
28
|
+
# loggable_attrs:
|
29
|
+
# - name
|
@@ -1,29 +1,132 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# This is the activity log. It contains an agregation of payloads.
|
4
|
-
# It reprecent one activity for the log
|
5
|
-
|
6
3
|
module LoggableActivity
|
4
|
+
# Represents one action in the activity log.
|
7
5
|
class Activity < ActiveRecord::Base
|
8
6
|
self.table_name = 'loggable_activities'
|
7
|
+
# Associations
|
9
8
|
has_many :payloads, class_name: 'LoggableActivity::Payload', dependent: :destroy
|
9
|
+
belongs_to :record, polymorphic: true, optional: true
|
10
|
+
belongs_to :actor, polymorphic: true, optional: true
|
11
|
+
|
10
12
|
accepts_nested_attributes_for :payloads
|
11
13
|
|
14
|
+
# Validations
|
12
15
|
validates :actor, presence: true
|
13
16
|
validates :action, presence: true
|
14
|
-
# validates :encrypted_record_display_name, presence: true
|
15
|
-
# validates :encrypted_actor_display_name, presence: true
|
16
|
-
|
17
17
|
validate :must_have_at_least_one_payload
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
# Returns a list of attributes of the activity includig the indliced relations.
|
20
|
+
# The included relations are devined in the 'config/loggable_activity.yaml' file.
|
21
|
+
# The attributes are packed in a way that they can be used to display the activity in the UI.
|
22
|
+
#
|
23
|
+
# Example:
|
24
|
+
# @activity.attrs
|
25
|
+
#
|
26
|
+
# Returns:
|
27
|
+
# [
|
28
|
+
# {
|
29
|
+
# record_class: "User",
|
30
|
+
# payload_type: "primary_payload",
|
31
|
+
# attrs: {
|
32
|
+
# "first_name" => "David",
|
33
|
+
# "last_name" => "Bowie",
|
34
|
+
# "age" => "69",
|
35
|
+
# "email" => "david@example.com",
|
36
|
+
# "user_type" => "Patient"
|
37
|
+
# }
|
38
|
+
# },
|
39
|
+
# {
|
40
|
+
# record_class: "Demo::UserProfile",
|
41
|
+
# payload_type: "current_association",
|
42
|
+
# attrs: {
|
43
|
+
# "sex" => "Male",
|
44
|
+
# "religion" => "Agnostic"
|
45
|
+
# }
|
46
|
+
# },
|
47
|
+
# {
|
48
|
+
# record_class: "Demo::Address",
|
49
|
+
# payload_type: "current_association",
|
50
|
+
# attrs: {
|
51
|
+
# "street" => "Eiffel Tower",
|
52
|
+
# "city" => "Paris",
|
53
|
+
# "country" => "France",
|
54
|
+
# "postal_code" => "75007"
|
55
|
+
# }
|
56
|
+
# },
|
57
|
+
# {
|
58
|
+
# record_class: "Demo::Club",
|
59
|
+
# payload_type: "current_association",
|
60
|
+
# attrs: {
|
61
|
+
# "name" => "Mystic Fusion Lounge"
|
62
|
+
# }
|
63
|
+
# }
|
64
|
+
# ]
|
65
|
+
#
|
22
66
|
def attrs
|
23
|
-
|
24
|
-
|
67
|
+
ordered_payloads.map do |payload|
|
68
|
+
{
|
69
|
+
record_class: payload.record_type,
|
70
|
+
payload_type: payload.payload_type,
|
71
|
+
attrs: payload.attrs
|
72
|
+
}
|
73
|
+
end
|
25
74
|
end
|
26
75
|
|
76
|
+
# Returns the attributes of an upddate activity.
|
77
|
+
#
|
78
|
+
# Example:
|
79
|
+
# @activity.update_activity_attrs
|
80
|
+
#
|
81
|
+
# Returns:
|
82
|
+
# {
|
83
|
+
# # Update attributes for Demo::Club
|
84
|
+
# update_attrs: {
|
85
|
+
# record_class: "Demo::Club",
|
86
|
+
# attrs: [
|
87
|
+
# {
|
88
|
+
# "name" => {
|
89
|
+
# # Previous name
|
90
|
+
# from: "Electric Oasis Club",
|
91
|
+
# # New name
|
92
|
+
# to: "Electric Oasis Club nr 5"
|
93
|
+
# }
|
94
|
+
# }
|
95
|
+
# ]
|
96
|
+
# },
|
97
|
+
# # Updated relations attributes
|
98
|
+
# updated_relations_attrs: [
|
99
|
+
# {
|
100
|
+
# record_class: "Demo::Address",
|
101
|
+
# previous_attrs: {
|
102
|
+
# # Record class
|
103
|
+
# record_class: "Demo::Address",
|
104
|
+
# # Previous association payload type
|
105
|
+
# payload_type: "previous_association",
|
106
|
+
# # Previous attributes for Demo::Address
|
107
|
+
# attrs: {
|
108
|
+
# "street" => "Ice Hotel, Marknadsvägen 63",
|
109
|
+
# "city" => "Jukkasjärvi",
|
110
|
+
# "country" => "Sweden",
|
111
|
+
# "postal_code" => "981 91"
|
112
|
+
# }
|
113
|
+
# },
|
114
|
+
# current_attrs: {
|
115
|
+
# record_class: "Demo::Address",
|
116
|
+
# # Current association payload type
|
117
|
+
# payload_type: "current_association",
|
118
|
+
# # Current attributes for Demo::Address
|
119
|
+
# attrs: {
|
120
|
+
# "street" => "The Palace of Versailles",
|
121
|
+
# "city" => "Versailles",
|
122
|
+
# "country" => "France",
|
123
|
+
# "postal_code" => "78000"
|
124
|
+
# }
|
125
|
+
# }
|
126
|
+
# }
|
127
|
+
# ]
|
128
|
+
# }
|
129
|
+
#
|
27
130
|
def update_activity_attrs
|
28
131
|
{
|
29
132
|
update_attrs:,
|
@@ -31,46 +134,98 @@ module LoggableActivity
|
|
31
134
|
}
|
32
135
|
end
|
33
136
|
|
137
|
+
# Returns the attributes for the primary payload, without the relations.
|
138
|
+
#
|
139
|
+
# Example:
|
140
|
+
#
|
141
|
+
# @activity.primary_payload_attrs
|
142
|
+
#
|
143
|
+
# Returns:
|
144
|
+
# {
|
145
|
+
# "first_name" => "David",
|
146
|
+
# "last_name" => "Bowie",
|
147
|
+
# "age" => "69",
|
148
|
+
# "email" => "david@example.com",
|
149
|
+
# "user_type" => "Patient"
|
150
|
+
# }
|
151
|
+
#
|
34
152
|
def primary_payload_attrs
|
35
153
|
primary_payload ? primary_payload.attrs : {}
|
36
154
|
end
|
37
155
|
|
38
|
-
|
39
|
-
|
40
|
-
|
156
|
+
# Returns the attributes for the relations.
|
157
|
+
#
|
158
|
+
# Example:
|
159
|
+
#
|
160
|
+
# @activity.relations_attrs
|
161
|
+
#
|
162
|
+
# Returns:
|
163
|
+
# [
|
164
|
+
# {
|
165
|
+
# record_class: "Demo::Address",
|
166
|
+
# # Current association payload type
|
167
|
+
# payload_type: "current_association",
|
168
|
+
# # Current attributes for Demo::Address
|
169
|
+
# attrs: {
|
170
|
+
# "street" => "The Palace of Versailles",
|
171
|
+
# "city" => "Versailles",
|
172
|
+
# "country" => "France",
|
173
|
+
# "postal_code" => "78000"
|
174
|
+
# }
|
175
|
+
# }
|
176
|
+
# ]
|
177
|
+
def relations_attrs
|
178
|
+
attrs.filter { |p| p[:payload_type] == 'current_association' }
|
41
179
|
end
|
42
180
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
181
|
+
# Returns the display name for a record. what method to use if defined in '/config/loggable_activity.yaml'
|
182
|
+
#
|
183
|
+
# Example:
|
184
|
+
#
|
185
|
+
# @activity.record_display_name
|
186
|
+
#
|
187
|
+
# Returns:
|
188
|
+
# "David Bowie"
|
189
|
+
#
|
190
|
+
def record_display_name
|
191
|
+
return I18n.t('loggable.activity.deleted') if encrypted_record_display_name.nil?
|
47
192
|
|
48
|
-
|
49
|
-
attrs.filter { |p| p[:payload_type] == 'current_association' }
|
193
|
+
LoggableActivity::Encryption.decrypt(encrypted_record_display_name, record_key)
|
50
194
|
end
|
51
195
|
|
52
|
-
|
53
|
-
|
196
|
+
# Returns the display name for a actor. what method to use if defined in '/config/loggable_activity.yaml'
|
197
|
+
#
|
198
|
+
# Example:
|
199
|
+
#
|
200
|
+
# @activity.actor_display_name
|
201
|
+
#
|
202
|
+
# Returns:
|
203
|
+
# "Elvis Presley"
|
204
|
+
#
|
205
|
+
def actor_display_name
|
206
|
+
return I18n.t('loggable.activity.deleted') if encrypted_actor_display_name.nil?
|
54
207
|
|
55
|
-
|
56
|
-
|
57
|
-
current_attrs = payloads.find { |p| p[:payload_type] == 'current_association' }
|
58
|
-
next if previous_attrs.nil? && current_attrs.nil?
|
208
|
+
LoggableActivity::Encryption.decrypt(encrypted_actor_display_name, actor_key)
|
209
|
+
end
|
59
210
|
|
60
|
-
|
61
|
-
|
211
|
+
# Returns a list of activities for a given actor.
|
212
|
+
def self.activities_for_actor(actor, limit = 20, params = { offset: 0 })
|
213
|
+
LoggableActivity::Activity.latest(limit, params).where(actor:)
|
62
214
|
end
|
63
215
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
216
|
+
# Returns a list of activities ordered by creation date.
|
217
|
+
def self.latest(limit = 20, params = { offset: 0 })
|
218
|
+
offset = params[:offset] || 0
|
219
|
+
LoggableActivity::Activity
|
220
|
+
.all
|
221
|
+
.order(created_at: :desc)
|
222
|
+
.includes(:payloads)
|
223
|
+
.offset(offset)
|
224
|
+
.limit(limit)
|
72
225
|
end
|
73
226
|
|
227
|
+
private
|
228
|
+
|
74
229
|
def update_attrs
|
75
230
|
update_payload_attrs = attrs.find { |p| p[:payload_type] == 'update_payload' }
|
76
231
|
return nil unless update_payload_attrs
|
@@ -79,42 +234,36 @@ module LoggableActivity
|
|
79
234
|
update_payload_attrs
|
80
235
|
end
|
81
236
|
|
82
|
-
def
|
83
|
-
|
237
|
+
def primary_payload
|
238
|
+
ordered_payloads.find { |p| p.payload_type == 'primary_payload' }
|
84
239
|
end
|
85
240
|
|
86
|
-
def
|
87
|
-
|
241
|
+
def updated_relations_attrs
|
242
|
+
grouped_associations = attrs.group_by { |p| p[:record_class] }
|
88
243
|
|
89
|
-
|
90
|
-
|
244
|
+
grouped_associations.map do |record_class, payloads|
|
245
|
+
previous_attrs = payloads.find { |p| p[:payload_type] == 'previous_association' }
|
246
|
+
current_attrs = payloads.find { |p| p[:payload_type] == 'current_association' }
|
247
|
+
next if previous_attrs.nil? && current_attrs.nil?
|
91
248
|
|
92
|
-
|
93
|
-
|
249
|
+
{ record_class:, previous_attrs:, current_attrs: }
|
250
|
+
end.compact
|
251
|
+
end
|
94
252
|
|
95
|
-
|
253
|
+
def previous_associations_attrs
|
254
|
+
attrs.select { |p| p[:payload_type] == 'previous_association' }
|
96
255
|
end
|
97
256
|
|
98
|
-
def
|
99
|
-
|
257
|
+
def ordered_payloads
|
258
|
+
payloads.order(:payload_type)
|
100
259
|
end
|
101
260
|
|
102
261
|
def record_key
|
103
262
|
LoggableActivity::EncryptionKey.for_record(record)&.key
|
104
263
|
end
|
105
264
|
|
106
|
-
def
|
107
|
-
LoggableActivity::
|
108
|
-
end
|
109
|
-
|
110
|
-
def self.latest(limit = 20, params = { offset: 0 })
|
111
|
-
offset = params[:offset] || 0
|
112
|
-
LoggableActivity::Activity
|
113
|
-
.all
|
114
|
-
.order(created_at: :desc)
|
115
|
-
.includes(:payloads)
|
116
|
-
.offset(offset)
|
117
|
-
.limit(limit)
|
265
|
+
def actor_key
|
266
|
+
LoggableActivity::EncryptionKey.for_record(actor)&.key
|
118
267
|
end
|
119
268
|
|
120
269
|
def must_have_at_least_one_payload
|
@@ -1,11 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module LoggableActivity
|
4
|
+
# This class is used to load the configuration file located at config/loggable_activity.yml
|
4
5
|
class Configuration
|
5
6
|
def self.load_config_file(config_file_path)
|
6
7
|
@config_data = YAML.load_file(config_file_path)
|
7
8
|
end
|
8
9
|
|
10
|
+
# Returns the configuration data for the given class
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# LoggableActivity::Configuration.for_class('User')
|
14
|
+
# Returns:
|
15
|
+
# {
|
16
|
+
# "record_display_name": "full_name",
|
17
|
+
# "loggable_attrs": [
|
18
|
+
# "first_name",
|
19
|
+
# "last_name",
|
20
|
+
# ],
|
21
|
+
# "auto_log": [
|
22
|
+
# "create",
|
23
|
+
# "update",
|
24
|
+
# "destroy"
|
25
|
+
# ]
|
26
|
+
# }
|
9
27
|
def self.for_class(class_name)
|
10
28
|
@config_data[class_name]
|
11
29
|
end
|
@@ -5,10 +5,20 @@ require 'openssl'
|
|
5
5
|
require 'base64'
|
6
6
|
|
7
7
|
module LoggableActivity
|
8
|
+
# This error is raised when encryption or decryption fails
|
8
9
|
class EncryptionError < StandardError
|
9
10
|
end
|
10
11
|
|
12
|
+
# This module is used to encrypt and decrypt attributes
|
11
13
|
module Encryption
|
14
|
+
# Encrypts the given data using the given encryption key
|
15
|
+
#
|
16
|
+
# Example:
|
17
|
+
# LoggableActivity::Encryption.encrypt('my secret data', 'my secret key')
|
18
|
+
#
|
19
|
+
# Returns:
|
20
|
+
# "SOME_ENCRYPTED_STRING"
|
21
|
+
#
|
12
22
|
def self.encrypt(data, encryption_key)
|
13
23
|
return nil if data.nil?
|
14
24
|
return nil if encryption_key.nil?
|
@@ -22,8 +32,17 @@ module LoggableActivity
|
|
22
32
|
raise EncryptionError, "Encryption failed: #{e.message} ***"
|
23
33
|
end
|
24
34
|
|
35
|
+
# Decrypts the given data using the given encryption key
|
36
|
+
#
|
37
|
+
# Example:
|
38
|
+
# LoggableActivity::Encryption.decrypt('SOME_ENCRYPTED_STRING', 'SECRET_KEY')
|
39
|
+
#
|
40
|
+
# Returns:
|
41
|
+
# "my secret data"
|
42
|
+
#
|
25
43
|
def self.decrypt(data, encryption_key)
|
26
|
-
return
|
44
|
+
return nil if data.nil?
|
45
|
+
return I18n.t('loggable.activity.deleted') if encryption_key.nil?
|
27
46
|
|
28
47
|
cipher = OpenSSL::Cipher.new('AES-128-CBC').decrypt
|
29
48
|
cipher.key = Digest::SHA1.hexdigest(encryption_key)[0..15]
|