loggable_activity 0.2.1 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +29 -42
  3. data/.vscode/commands.json +2 -2
  4. data/.vscode/terminals.json +8 -8
  5. data/CHANGELOG.md +9 -0
  6. data/CHEAT_SHEET.md +31 -0
  7. data/MIT-LICENSE +21 -0
  8. data/README.md +1 -1
  9. data/Rakefile +6 -4
  10. data/app/assets/config/loggable_activity_manifest.js +2 -0
  11. data/app/assets/javascripts/loggable_activity/application.js +1 -0
  12. data/app/assets/stylesheets/loggable_activity/activities.scss +25 -0
  13. data/app/assets/stylesheets/loggable_activity/application.scss +16 -0
  14. data/app/controllers/concerns/.keep +0 -0
  15. data/app/controllers/loggable_activity/activities_controller.rb +12 -0
  16. data/app/controllers/loggable_activity/application_controller.rb +6 -0
  17. data/app/helpers/loggable_activity/activities_helper.rb +17 -0
  18. data/app/helpers/loggable_activity/application_helper.rb +6 -0
  19. data/app/jobs/loggable_activity/application_job.rb +6 -0
  20. data/app/mailers/loggable_activity/application_mailer.rb +8 -0
  21. data/app/models/loggable_activity/application_record.rb +7 -0
  22. data/app/views/kaminari/pico/_first_page.html.erb +13 -0
  23. data/app/views/kaminari/pico/_gap.html.erb +8 -0
  24. data/app/views/kaminari/pico/_last_page.html.erb +12 -0
  25. data/app/views/kaminari/pico/_next_page.html.erb +13 -0
  26. data/app/views/kaminari/pico/_page.html.erb +14 -0
  27. data/app/views/kaminari/pico/_paginator.html.erb +27 -0
  28. data/app/views/kaminari/pico/_prev_page.html.erb +14 -0
  29. data/app/views/layouts/loggable_activity/application.html.slim +20 -0
  30. data/app/views/loggable_activity/activities/_activities.html.slim +28 -0
  31. data/app/views/loggable_activity/activities/index.html.erb +6 -0
  32. data/app/views/loggable_activity/bootstrap/kaminari/_first_page.html.erb +13 -0
  33. data/app/views/loggable_activity/bootstrap/kaminari/_gap.html.erb +8 -0
  34. data/app/views/loggable_activity/bootstrap/kaminari/_last_page.html.erb +13 -0
  35. data/app/views/loggable_activity/bootstrap/kaminari/_next_page.html.erb +13 -0
  36. data/app/views/loggable_activity/bootstrap/kaminari/_page.html.erb +14 -0
  37. data/app/views/loggable_activity/bootstrap/kaminari/_paginator.html.erb +27 -0
  38. data/app/views/loggable_activity/bootstrap/kaminari/_prev_page.html.erb +13 -0
  39. data/config/initializers/kaminari_config.rb +14 -0
  40. data/config/routes.rb +7 -0
  41. data/{lib/generators/loggable_activity/templates/create_loggable_activities.rb → db/migrate/20240702092648_create_loggable_activity_tables.rb} +18 -10
  42. data/git-org/HEAD +1 -0
  43. data/git-org/config +7 -0
  44. data/git-org/description +1 -0
  45. data/git-org/hooks/applypatch-msg.sample +15 -0
  46. data/git-org/hooks/commit-msg.sample +24 -0
  47. data/git-org/hooks/fsmonitor-watchman.sample +174 -0
  48. data/git-org/hooks/post-update.sample +8 -0
  49. data/git-org/hooks/pre-applypatch.sample +14 -0
  50. data/git-org/hooks/pre-commit.sample +49 -0
  51. data/git-org/hooks/pre-merge-commit.sample +13 -0
  52. data/git-org/hooks/pre-push.sample +53 -0
  53. data/git-org/hooks/pre-rebase.sample +169 -0
  54. data/git-org/hooks/pre-receive.sample +24 -0
  55. data/git-org/hooks/prepare-commit-msg.sample +42 -0
  56. data/git-org/hooks/push-to-checkout.sample +78 -0
  57. data/git-org/hooks/update.sample +128 -0
  58. data/git-org/info/exclude +6 -0
  59. data/lib/loggable_activity/activity.rb +4 -3
  60. data/lib/{schemas → loggable_activity}/config_schema.json +3 -10
  61. data/lib/loggable_activity/configuration.rb +48 -77
  62. data/lib/loggable_activity/data_owner.rb +0 -1
  63. data/lib/loggable_activity/encryption.rb +16 -7
  64. data/lib/loggable_activity/encryption_key.rb +4 -7
  65. data/lib/loggable_activity/engine.rb +22 -0
  66. data/lib/loggable_activity/error.rb +0 -10
  67. data/lib/loggable_activity/hooks.rb +10 -15
  68. data/lib/loggable_activity/payload.rb +8 -11
  69. data/lib/loggable_activity/sanitizer.rb +6 -2
  70. data/lib/loggable_activity/services/base_payloads_builder.rb +14 -5
  71. data/lib/loggable_activity/services/destroy_payloads_builder.rb +2 -1
  72. data/lib/loggable_activity/services/payloads_builder.rb +12 -5
  73. data/lib/loggable_activity/services/update_payloads_builder.rb +34 -6
  74. data/lib/loggable_activity/version.rb +1 -1
  75. data/lib/loggable_activity.rb +51 -14
  76. data/lib/tasks/loggable_activity_tasks.rake +6 -0
  77. data/loggable_activity-0.5.0.gem +0 -0
  78. metadata +129 -109
  79. data/.document +0 -1
  80. data/.nojekyll +0 -1
  81. data/.rspec +0 -3
  82. data/CONSIDERTIONS.md +0 -129
  83. data/GETTING-STARTED.md +0 -119
  84. data/LICENSE.txt +0 -21
  85. data/PAYLOAD_EXAMPLE.md +0 -63
  86. data/ROADMAP.md +0 -23
  87. data/docs/LoggableActivity/Activity.html +0 -555
  88. data/docs/LoggableActivity/Configuration.html +0 -330
  89. data/docs/LoggableActivity/ConfigurationError.html +0 -148
  90. data/docs/LoggableActivity/DataOwner.html +0 -138
  91. data/docs/LoggableActivity/Encryption.html +0 -234
  92. data/docs/LoggableActivity/EncryptionError.html +0 -145
  93. data/docs/LoggableActivity/EncryptionKey.html +0 -351
  94. data/docs/LoggableActivity/Error.html +0 -145
  95. data/docs/LoggableActivity/Hooks.html +0 -759
  96. data/docs/LoggableActivity/Payload.html +0 -432
  97. data/docs/LoggableActivity/Services/BasePayloadsBuilder.html +0 -442
  98. data/docs/LoggableActivity/Services/DestroyPayloadsBuilder.html +0 -395
  99. data/docs/LoggableActivity/Services/PayloadsBuilder.html +0 -342
  100. data/docs/LoggableActivity/Services/UpdatePayloadsBuilder.html +0 -490
  101. data/docs/LoggableActivity/Services.html +0 -93
  102. data/docs/LoggableActivity.html +0 -102
  103. data/docs/created.rid +0 -14
  104. data/docs/css/fonts.css +0 -167
  105. data/docs/css/rdoc.css +0 -687
  106. data/docs/fonts/Lato-Light.ttf +0 -0
  107. data/docs/fonts/Lato-LightItalic.ttf +0 -0
  108. data/docs/fonts/Lato-Regular.ttf +0 -0
  109. data/docs/fonts/Lato-RegularItalic.ttf +0 -0
  110. data/docs/fonts/SourceCodePro-Bold.ttf +0 -0
  111. data/docs/fonts/SourceCodePro-Regular.ttf +0 -0
  112. data/docs/images/add.png +0 -0
  113. data/docs/images/arrow_up.png +0 -0
  114. data/docs/images/brick.png +0 -0
  115. data/docs/images/brick_link.png +0 -0
  116. data/docs/images/bug.png +0 -0
  117. data/docs/images/bullet_black.png +0 -0
  118. data/docs/images/bullet_toggle_minus.png +0 -0
  119. data/docs/images/bullet_toggle_plus.png +0 -0
  120. data/docs/images/date.png +0 -0
  121. data/docs/images/delete.png +0 -0
  122. data/docs/images/find.png +0 -0
  123. data/docs/images/loadingAnimation.gif +0 -0
  124. data/docs/images/macFFBgHack.png +0 -0
  125. data/docs/images/package.png +0 -0
  126. data/docs/images/page_green.png +0 -0
  127. data/docs/images/page_white_text.png +0 -0
  128. data/docs/images/page_white_width.png +0 -0
  129. data/docs/images/plugin.png +0 -0
  130. data/docs/images/ruby.png +0 -0
  131. data/docs/images/tag_blue.png +0 -0
  132. data/docs/images/tag_green.png +0 -0
  133. data/docs/images/transparent.png +0 -0
  134. data/docs/images/wrench.png +0 -0
  135. data/docs/images/wrench_orange.png +0 -0
  136. data/docs/images/zoom.png +0 -0
  137. data/docs/index.html +0 -99
  138. data/docs/js/darkfish.js +0 -97
  139. data/docs/js/navigation.js +0 -105
  140. data/docs/js/navigation.js.gz +0 -0
  141. data/docs/js/search.js +0 -110
  142. data/docs/js/search_index.js +0 -1
  143. data/docs/js/search_index.js.gz +0 -0
  144. data/docs/js/searcher.js +0 -229
  145. data/docs/js/searcher.js.gz +0 -0
  146. data/docs/table_of_contents.html +0 -617
  147. data/help/loggable_activity_help.txt +0 -19
  148. data/lib/generators/.DS_Store +0 -0
  149. data/lib/generators/loggable_activity/.DS_Store +0 -0
  150. data/lib/generators/loggable_activity/install_generator.rb +0 -109
  151. data/lib/generators/loggable_activity/templates/.DS_Store +0 -0
  152. data/lib/generators/loggable_activity/templates/binary_ids/create_loggable_activities.rb +0 -30
  153. data/lib/generators/loggable_activity/templates/config/locales/loggable_activity.en.yml +0 -36
  154. data/lib/generators/loggable_activity/templates/config/loggable_activity.yaml +0 -29
  155. data/lib/generators/loggable_activity/templates/loggable_activity.en.yaml +0 -36
  156. data/pkg/loggable_activity-0.1.35.gem +0 -0
  157. data/sig/loggable_activity.rbs +0 -4
  158. /data/{.rspec_status → app/assets/images/loggable_activity/.keep} +0 -0
  159. /data/lib/{generators/loggable_activity/templates → loggable_activity/concerns}/current_user.rb +0 -0
@@ -0,0 +1,42 @@
1
+ #!/bin/sh
2
+ #
3
+ # An example hook script to prepare the commit log message.
4
+ # Called by "git commit" with the name of the file that has the
5
+ # commit message, followed by the description of the commit
6
+ # message's source. The hook's purpose is to edit the commit
7
+ # message file. If the hook fails with a non-zero status,
8
+ # the commit is aborted.
9
+ #
10
+ # To enable this hook, rename this file to "prepare-commit-msg".
11
+
12
+ # This hook includes three examples. The first one removes the
13
+ # "# Please enter the commit message..." help message.
14
+ #
15
+ # The second includes the output of "git diff --name-status -r"
16
+ # into the message, just before the "git status" output. It is
17
+ # commented because it doesn't cope with --amend or with squashed
18
+ # commits.
19
+ #
20
+ # The third example adds a Signed-off-by line to the message, that can
21
+ # still be edited. This is rarely a good idea.
22
+
23
+ COMMIT_MSG_FILE=$1
24
+ COMMIT_SOURCE=$2
25
+ SHA1=$3
26
+
27
+ /usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE"
28
+
29
+ # case "$COMMIT_SOURCE,$SHA1" in
30
+ # ,|template,)
31
+ # /usr/bin/perl -i.bak -pe '
32
+ # print "\n" . `git diff --cached --name-status -r`
33
+ # if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;;
34
+ # *) ;;
35
+ # esac
36
+
37
+ # SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
38
+ # git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE"
39
+ # if test -z "$COMMIT_SOURCE"
40
+ # then
41
+ # /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE"
42
+ # fi
@@ -0,0 +1,78 @@
1
+ #!/bin/sh
2
+
3
+ # An example hook script to update a checked-out tree on a git push.
4
+ #
5
+ # This hook is invoked by git-receive-pack(1) when it reacts to git
6
+ # push and updates reference(s) in its repository, and when the push
7
+ # tries to update the branch that is currently checked out and the
8
+ # receive.denyCurrentBranch configuration variable is set to
9
+ # updateInstead.
10
+ #
11
+ # By default, such a push is refused if the working tree and the index
12
+ # of the remote repository has any difference from the currently
13
+ # checked out commit; when both the working tree and the index match
14
+ # the current commit, they are updated to match the newly pushed tip
15
+ # of the branch. This hook is to be used to override the default
16
+ # behaviour; however the code below reimplements the default behaviour
17
+ # as a starting point for convenient modification.
18
+ #
19
+ # The hook receives the commit with which the tip of the current
20
+ # branch is going to be updated:
21
+ commit=$1
22
+
23
+ # It can exit with a non-zero status to refuse the push (when it does
24
+ # so, it must not modify the index or the working tree).
25
+ die () {
26
+ echo >&2 "$*"
27
+ exit 1
28
+ }
29
+
30
+ # Or it can make any necessary changes to the working tree and to the
31
+ # index to bring them to the desired state when the tip of the current
32
+ # branch is updated to the new commit, and exit with a zero status.
33
+ #
34
+ # For example, the hook can simply run git read-tree -u -m HEAD "$1"
35
+ # in order to emulate git fetch that is run in the reverse direction
36
+ # with git push, as the two-tree form of git read-tree -u -m is
37
+ # essentially the same as git switch or git checkout that switches
38
+ # branches while keeping the local changes in the working tree that do
39
+ # not interfere with the difference between the branches.
40
+
41
+ # The below is a more-or-less exact translation to shell of the C code
42
+ # for the default behaviour for git's push-to-checkout hook defined in
43
+ # the push_to_deploy() function in builtin/receive-pack.c.
44
+ #
45
+ # Note that the hook will be executed from the repository directory,
46
+ # not from the working tree, so if you want to perform operations on
47
+ # the working tree, you will have to adapt your code accordingly, e.g.
48
+ # by adding "cd .." or using relative paths.
49
+
50
+ if ! git update-index -q --ignore-submodules --refresh
51
+ then
52
+ die "Up-to-date check failed"
53
+ fi
54
+
55
+ if ! git diff-files --quiet --ignore-submodules --
56
+ then
57
+ die "Working directory has unstaged changes"
58
+ fi
59
+
60
+ # This is a rough translation of:
61
+ #
62
+ # head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX
63
+ if git cat-file -e HEAD 2>/dev/null
64
+ then
65
+ head=HEAD
66
+ else
67
+ head=$(git hash-object -t tree --stdin </dev/null)
68
+ fi
69
+
70
+ if ! git diff-index --quiet --cached --ignore-submodules $head --
71
+ then
72
+ die "Working directory has staged changes"
73
+ fi
74
+
75
+ if ! git read-tree -u -m "$commit"
76
+ then
77
+ die "Could not update working tree to new HEAD"
78
+ fi
@@ -0,0 +1,128 @@
1
+ #!/bin/sh
2
+ #
3
+ # An example hook script to block unannotated tags from entering.
4
+ # Called by "git receive-pack" with arguments: refname sha1-old sha1-new
5
+ #
6
+ # To enable this hook, rename this file to "update".
7
+ #
8
+ # Config
9
+ # ------
10
+ # hooks.allowunannotated
11
+ # This boolean sets whether unannotated tags will be allowed into the
12
+ # repository. By default they won't be.
13
+ # hooks.allowdeletetag
14
+ # This boolean sets whether deleting tags will be allowed in the
15
+ # repository. By default they won't be.
16
+ # hooks.allowmodifytag
17
+ # This boolean sets whether a tag may be modified after creation. By default
18
+ # it won't be.
19
+ # hooks.allowdeletebranch
20
+ # This boolean sets whether deleting branches will be allowed in the
21
+ # repository. By default they won't be.
22
+ # hooks.denycreatebranch
23
+ # This boolean sets whether remotely creating branches will be denied
24
+ # in the repository. By default this is allowed.
25
+ #
26
+
27
+ # --- Command line
28
+ refname="$1"
29
+ oldrev="$2"
30
+ newrev="$3"
31
+
32
+ # --- Safety check
33
+ if [ -z "$GIT_DIR" ]; then
34
+ echo "Don't run this script from the command line." >&2
35
+ echo " (if you want, you could supply GIT_DIR then run" >&2
36
+ echo " $0 <ref> <oldrev> <newrev>)" >&2
37
+ exit 1
38
+ fi
39
+
40
+ if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
41
+ echo "usage: $0 <ref> <oldrev> <newrev>" >&2
42
+ exit 1
43
+ fi
44
+
45
+ # --- Config
46
+ allowunannotated=$(git config --type=bool hooks.allowunannotated)
47
+ allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch)
48
+ denycreatebranch=$(git config --type=bool hooks.denycreatebranch)
49
+ allowdeletetag=$(git config --type=bool hooks.allowdeletetag)
50
+ allowmodifytag=$(git config --type=bool hooks.allowmodifytag)
51
+
52
+ # check for no description
53
+ projectdesc=$(sed -e '1q' "$GIT_DIR/description")
54
+ case "$projectdesc" in
55
+ "Unnamed repository"* | "")
56
+ echo "*** Project description file hasn't been set" >&2
57
+ exit 1
58
+ ;;
59
+ esac
60
+
61
+ # --- Check types
62
+ # if $newrev is 0000...0000, it's a commit to delete a ref.
63
+ zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
64
+ if [ "$newrev" = "$zero" ]; then
65
+ newrev_type=delete
66
+ else
67
+ newrev_type=$(git cat-file -t $newrev)
68
+ fi
69
+
70
+ case "$refname","$newrev_type" in
71
+ refs/tags/*,commit)
72
+ # un-annotated tag
73
+ short_refname=${refname##refs/tags/}
74
+ if [ "$allowunannotated" != "true" ]; then
75
+ echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
76
+ echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
77
+ exit 1
78
+ fi
79
+ ;;
80
+ refs/tags/*,delete)
81
+ # delete tag
82
+ if [ "$allowdeletetag" != "true" ]; then
83
+ echo "*** Deleting a tag is not allowed in this repository" >&2
84
+ exit 1
85
+ fi
86
+ ;;
87
+ refs/tags/*,tag)
88
+ # annotated tag
89
+ if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
90
+ then
91
+ echo "*** Tag '$refname' already exists." >&2
92
+ echo "*** Modifying a tag is not allowed in this repository." >&2
93
+ exit 1
94
+ fi
95
+ ;;
96
+ refs/heads/*,commit)
97
+ # branch
98
+ if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
99
+ echo "*** Creating a branch is not allowed in this repository" >&2
100
+ exit 1
101
+ fi
102
+ ;;
103
+ refs/heads/*,delete)
104
+ # delete branch
105
+ if [ "$allowdeletebranch" != "true" ]; then
106
+ echo "*** Deleting a branch is not allowed in this repository" >&2
107
+ exit 1
108
+ fi
109
+ ;;
110
+ refs/remotes/*,commit)
111
+ # tracking branch
112
+ ;;
113
+ refs/remotes/*,delete)
114
+ # delete tracking branch
115
+ if [ "$allowdeletebranch" != "true" ]; then
116
+ echo "*** Deleting a tracking branch is not allowed in this repository" >&2
117
+ exit 1
118
+ fi
119
+ ;;
120
+ *)
121
+ # Anything else (is there anything else?)
122
+ echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
123
+ exit 1
124
+ ;;
125
+ esac
126
+
127
+ # --- Finished
128
+ exit 0
@@ -0,0 +1,6 @@
1
+ # git ls-files --others --exclude-from=.git/info/exclude
2
+ # Lines that start with '#' are comments.
3
+ # For a project mostly in C, the following would be a good set of
4
+ # exclude patterns (uncomment them if you want to use them):
5
+ # *.[oa]
6
+ # *~
@@ -5,7 +5,6 @@ require 'active_record'
5
5
  module LoggableActivity
6
6
  # Represents one action in the activity log.
7
7
  class Activity < ActiveRecord::Base
8
- self.table_name = 'loggable_activities'
9
8
  # Associations
10
9
  has_many :payloads, class_name: '::LoggableActivity::Payload', dependent: :destroy
11
10
  belongs_to :actor, polymorphic: true, optional: true
@@ -33,7 +32,7 @@ module LoggableActivity
33
32
  'belongs_to_payload' => 'belongs_to',
34
33
  'belongs_to_destroy_payload' => 'belongs_to',
35
34
  'belongs_to_update_payload' => 'belongs_to'
36
- }
35
+ }.freeze
37
36
 
38
37
  # Returns an array of hashes, each representing an activity's attributes and its associated relations. The structure and relations to include are specified in 'config/loggable_activity.yaml'. This format is designed for UI display purposes.
39
38
  #
@@ -72,7 +71,8 @@ module LoggableActivity
72
71
  route: payload.payload_route,
73
72
  record_display_name: payload.record_display_name,
74
73
  current_payload: payload.current_payload,
75
- data_owner: payload.data_owner
74
+ data_owner: payload.data_owner,
75
+ public_attrs: payload.public_attrs
76
76
  }
77
77
  end
78
78
  end
@@ -135,6 +135,7 @@ module LoggableActivity
135
135
  return I18n.t('loggable.activity.deleted') if actor_deleted?
136
136
 
137
137
  ::LoggableActivity::Encryption.decrypt(encrypted_actor_name, actor_secret_key)
138
+
138
139
  end
139
140
 
140
141
  # Returns a list of activities for a given actor.
@@ -2,10 +2,7 @@
2
2
  "$schema": "http://json-schema.org/draft-06/schema#",
3
3
  "type": "object",
4
4
  "properties": {
5
- "current_user_model_name": {
6
- "type": "string"
7
- },
8
- "fetch_current_user_name_from": {
5
+ "fetch_actor_name_from": {
9
6
  "type": "string"
10
7
  },
11
8
  "task_for_sanitization": {
@@ -13,7 +10,7 @@
13
10
  }
14
11
  },
15
12
  "patternProperties": {
16
- "^(?!current_user_model_name$|fetch_current_user_name_from$|task_for_sanitization)[A-Za-z0-9_:]+$": {
13
+ "^(?!fetch_actor_name_from$|task_for_sanitization)[A-Za-z0-9_:]+$": {
17
14
  "type": "object",
18
15
  "properties": {
19
16
  "data_owner": {
@@ -72,9 +69,6 @@
72
69
  "route": {
73
70
  "type": "string",
74
71
  "minLength": 1
75
- },
76
- "fetch_record_name_from": {
77
- "type": "string"
78
72
  }
79
73
  },
80
74
  "required": [
@@ -90,7 +84,6 @@
90
84
  },
91
85
  "additionalProperties": false,
92
86
  "required": [
93
- "current_user_model_name",
94
- "fetch_current_user_name_from"
87
+ "fetch_actor_name_from"
95
88
  ]
96
89
  }
@@ -2,94 +2,65 @@
2
2
 
3
3
  require 'json-schema'
4
4
  require 'json'
5
- require 'awesome_print'
6
5
 
7
6
  module LoggableActivity
8
- # This class is used to load the configuration file located at config/loggable_activity.yml
9
- class ConfigurationError < StandardError
10
- def initialize(msg = '')
11
- # https://api.loggable_activity.com/msg
12
- puts '---------------- LOGGABLE ACTIVITY -----------------'
13
- puts msg
14
- puts '----------------------------------------------------'
15
- super(msg)
16
- end
17
- end
18
-
19
7
  # This class is used to load the configuration file located at config/loggable_activity.yml
20
8
  # When the LoggableActivity::Hook is included in a model
21
9
  # it takes the model's name and find the configuration for that model in the configuration file.
22
10
  class Configuration
23
- # Loads the configuration file
24
- def self.load_config_file(config_file_path)
25
- @config_data = YAML.load_file(config_file_path)
26
- validate_config_file
27
- rescue Errno::ENOENT
28
- raise ConfigurationError, 'config/loggable_activity.yaml not found'
29
- end
30
-
31
- # Loads the schema file for the configuration file
32
- def self.load_schema
33
- schema_path = File.join(__dir__, '..', 'schemas', 'config_schema.json')
34
- JSON.parse(File.read(schema_path))
35
- end
36
-
37
- # Validates the configuration file againss the schema
38
- def self.validate_config_file
39
- schema = load_schema
40
- errors = JSON::Validator.fully_validate(schema, @config_data)
41
- return unless errors.any?
42
-
43
- raise ConfigurationError,
44
- "config/loggable_activity.yaml is invalid: #{errors.join(', ')}"
45
- end
46
-
47
- # Returns true if the configuration file has been loaded
48
- def self.loaded?
49
- !@config_data.nil?
50
- end
51
-
52
- # Returns the configuration data
53
11
  class << self
54
- # @return [Hash]
55
- attr_reader :config_data
56
- end
12
+ # Loads the schema file for the configuration file
13
+ def load_schema
14
+ schema_path = File.join(__dir__, 'config_schema.json')
15
+ JSON.parse(File.read(schema_path))
16
+ end
57
17
 
58
- # Returns the configuration data for the given class
59
- #
60
- # Example:
61
- # ::LoggableActivity::Configuration.for_class('User')
62
- # Returns:
63
- # {
64
- # "fetch_record_name_from": "full_name",
65
- # "loggable_attrs": [
66
- # "first_name",
67
- # "last_name",
68
- # ],
69
- # "auto_log": [
70
- # "create",
71
- # "update",
72
- # "destroy"
73
- # ],
74
- # ....
75
- # }
76
- def self.for_class(class_name)
77
- @config_data[class_name]
78
- end
18
+ # Loads the configuration file, and store it as a hash
19
+ def config_data
20
+ @config_data ||= YAML.load_file(LoggableActivity.config_file_path)
21
+ end
79
22
 
80
- # Returns the name of the field or method to use for the actor's display name.
81
- def self.fetch_current_user_name_from
82
- @config_data['fetch_current_user_name_from']
83
- end
23
+ # Validates the configuration file againss the schema
24
+ def validate_config_file
25
+ schema = load_schema
26
+ errors = JSON::Validator.fully_validate(schema, config_data)
27
+ return true unless errors.any?
84
28
 
85
- # Returns the name of the model to use for the current user.
86
- def self.current_user_model_name
87
- @config_data['current_user_model_name']
88
- end
29
+ raise ConfigurationError,
30
+ "config/loggable_activity.yaml is invalid: #{errors.join(', ')}"
31
+ end
32
+
33
+ # Returns the configuration data for the given class
34
+ #
35
+ # Example:
36
+ # ::LoggableActivity::Configuration.for_class('User')
37
+ # Returns:
38
+ # {
39
+ # "fetch_record_name_from": "full_name",
40
+ # "loggable_attrs": [
41
+ # "first_name",
42
+ # "last_name",
43
+ # ],
44
+ # "auto_log": [
45
+ # "create",
46
+ # "update",
47
+ # "destroy"
48
+ # ],
49
+ # ....
50
+ # }
51
+ def for_class(class_name)
52
+ config_data[class_name]
53
+ end
89
54
 
90
- # Returns whatever models should be sanitized on delete.
91
- def self.task_for_sanitization
92
- @config_data['task_for_sanitization']
55
+ # Returns the name of the field or method to use for the actor's display name.
56
+ def fetch_actor_name_from
57
+ config_data['fetch_actor_name_from']
58
+ end
59
+
60
+ # Returns whatever models should be sanitized on delete.
61
+ def task_for_sanitization
62
+ config_data['task_for_sanitization']
63
+ end
93
64
  end
94
65
  end
95
66
  end
@@ -6,7 +6,6 @@ module LoggableActivity
6
6
  # This class represends an additional data owner for a record.
7
7
  # For it to kick in, the data_owner configuration has to be set to true in the loggable_activity.yaml file.
8
8
  class DataOwner < ActiveRecord::Base
9
- self.table_name = 'loggable_data_owners'
10
9
  belongs_to :record, polymorphic: true, optional: true
11
10
  belongs_to :encryption_key, class_name: '::LoggableActivity::EncryptionKey'
12
11
 
@@ -20,7 +20,10 @@ module LoggableActivity
20
20
  return nil if data.nil?
21
21
 
22
22
  encryption_key = Base64.decode64(secret_key)
23
- raise EncryptionError, "Encryption failed: Invalid encoded_key length #{encryption_key.bytesize}" unless encryption_key.bytesize == 32
23
+ unless encryption_key.bytesize == 32
24
+ raise EncryptionError,
25
+ "Encryption failed: Invalid encoded_key length #{encryption_key.bytesize}"
26
+ end
24
27
 
25
28
  cipher = OpenSSL::Cipher.new('AES-256-CBC').encrypt
26
29
  cipher.key = encryption_key
@@ -42,11 +45,14 @@ module LoggableActivity
42
45
  # "my secret data"
43
46
  #
44
47
  def self.decrypt(data, secret_key)
45
- return I18n.t('loggable.activity.deleted') if secret_key.nil?
48
+ return I18n.t('loggable_activity.activity.deleted') if secret_key.nil?
46
49
  return '' if data.blank?
47
50
 
48
51
  encryption_key = Base64.decode64(secret_key)
49
- raise EncryptionError, "Decryption failed: Invalid encoded_key length: #{encryption_key.bytesize}" unless encryption_key.bytesize == 32
52
+ unless encryption_key.bytesize == 32
53
+ raise EncryptionError,
54
+ "Decryption failed: Invalid encoded_key length: #{encryption_key.bytesize}"
55
+ end
50
56
 
51
57
  cipher = OpenSSL::Cipher.new('AES-256-CBC').decrypt
52
58
  cipher.key = encryption_key
@@ -58,11 +64,14 @@ module LoggableActivity
58
64
 
59
65
  decrypted_data.force_encoding('UTF-8')
60
66
  rescue OpenSSL::Cipher::CipherError => e
61
- puts "CipherError Decryption failed: #{e.message}"
62
- '*** DECRYPTION FAILED ***'
67
+ Rails.logger.error "CipherError Decryption failed: #{e.message}"
68
+ I18n.t('loggable_activity.decryption.failed')
63
69
  rescue EncryptionError => e
64
- puts "EncryptionError failed: #{e.message}"
65
- '*** DECRYPTION FAILED ***'
70
+ Rails.logger.error "EncryptionError: #{e.message}"
71
+ I18n.t('loggable_activity.decryption.failed')
72
+ rescue ArgumentError => e
73
+ Rails.logger.error "ArgumentError Decryption failed: #{e.message}"
74
+ I18n.t('loggable_activity.decryption.failed')
66
75
  end
67
76
 
68
77
  # Returns true if the given value is blank
@@ -6,15 +6,13 @@ module LoggableActivity
6
6
  # This class represents the encryption key used to unlock the data for one payload.
7
7
  # When deleted, only the encryption_key field is deleted.
8
8
  class EncryptionKey < ActiveRecord::Base
9
- self.table_name = 'loggable_encryption_keys'
10
-
11
9
  # Associations
12
10
  belongs_to :record, polymorphic: true, optional: true
13
11
  # belongs_to :payload, class_name: '::LoggableActivity::Payload', optional: true
14
12
  # belongs_to :parent_key, class_name: '::LoggableActivity::EncryptionKey', optional: true,
15
13
  # foreign_key: 'parent_key_id'
16
14
 
17
- # Prepare the record for deletion
15
+ # Prepare the record for deletion
18
16
  def mark_as_deleted!
19
17
  LoggableActivity::Configuration.task_for_sanitization ? update(delete_at: DateTime.now + 1.month) : delete
20
18
  end
@@ -25,17 +23,16 @@ module LoggableActivity
25
23
  end
26
24
 
27
25
  # Delete the encryption key by updating the key to nil.
26
+ # Nullify the delete_at field, so the key is not deleted when the sanitization task runs.
28
27
  def delete
29
- update(secret_key: nil, delete_at: nil)
28
+ update(secret_key: nil, delete_at: nil)
30
29
  end
31
30
 
32
31
  # Restores the encryption key by updating the delete_at field to nil.
33
32
  def restore!
34
- update(delete_at: nil) if delete_at && DateTime.now < delete_at
33
+ update(delete_at: nil) if delete_at && DateTime.now < delete_at
35
34
  end
36
35
 
37
-
38
-
39
36
  # Returns an encryption key for a record by its type and ID, optionally using a parent key.
40
37
  #
41
38
  # @param record_type [String] The type of the record.
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LoggableActivity
4
+ # Engine
5
+ #
6
+ # This module defines the LoggableActivity engine for use within a Rails application.
7
+ # It leverages Rails::Engine to create an isolated namespace, ensuring that the components
8
+ # of the LoggableActivity engine (such as models, controllers, and views) do not interfere
9
+ # with those of the host application or other engines.
10
+ #
11
+ # Example Usage:
12
+ # In a Rails application, you can mount this engine to make its functionality available:
13
+ #
14
+ # mount LoggableActivity::Engine, at: "/loggable_activity"
15
+ #
16
+ # This will allow the application to utilize the features provided by the LoggableActivity engine
17
+ # under the specified mount path.
18
+ #
19
+ class Engine < ::Rails::Engine
20
+ isolate_namespace LoggableActivity
21
+ end
22
+ end
@@ -4,9 +4,6 @@ module LoggableActivity
4
4
  # Error class for loggable activity.
5
5
  class Error < StandardError
6
6
  def initialize(msg = '')
7
- puts '---------------- LOGGABLE ACTIVITY -----------------'
8
- puts msg
9
- puts '----------------------------------------------------'
10
7
  super(msg)
11
8
  end
12
9
  end
@@ -14,9 +11,6 @@ module LoggableActivity
14
11
  # Error class for encryption.
15
12
  class EncryptionError < StandardError
16
13
  def initialize(msg = '')
17
- puts '---------------- LOGGABLE ACTIVITY -----------------'
18
- puts msg
19
- puts '----------------------------------------------------'
20
14
  super(msg)
21
15
  end
22
16
  end
@@ -24,10 +18,6 @@ module LoggableActivity
24
18
  # This class is used to load the configuration file located at config/loggable_activity.yml
25
19
  class ConfigurationError < StandardError
26
20
  def initialize(msg = '')
27
- # https://api.loggable_activity.com/msg
28
- puts '---------------- LOGGABLE ACTIVITY -----------------'
29
- puts msg
30
- puts '----------------------------------------------------'
31
21
  super(msg)
32
22
  end
33
23
  end