loggable_activity 0.2.1 → 0.5.0

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 (150) 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/CHEAT_SHEET.md +31 -0
  6. data/MIT-LICENSE +21 -0
  7. data/README.md +31 -45
  8. data/Rakefile +6 -4
  9. data/app/assets/config/loggable_activity_manifest.js +4 -0
  10. data/app/assets/javascripts/loggable_activity/application.js +2 -0
  11. data/app/assets/stylesheets/loggable_activity/application.scss +20 -0
  12. data/app/controllers/concerns/.keep +0 -0
  13. data/app/controllers/loggable_activity/activities_controller.rb +12 -0
  14. data/app/controllers/loggable_activity/application_controller.rb +6 -0
  15. data/app/helpers/loggable_activity/activities_helper.rb +17 -0
  16. data/app/helpers/loggable_activity/application_helper.rb +6 -0
  17. data/app/jobs/loggable_activity/application_job.rb +6 -0
  18. data/app/mailers/loggable_activity/application_mailer.rb +8 -0
  19. data/app/models/loggable_activity/application_record.rb +7 -0
  20. data/app/views/kaminari/kaminari-turbo-bootstrap/_first_page.html.erb +14 -0
  21. data/app/views/kaminari/kaminari-turbo-bootstrap/_gap.html.erb +8 -0
  22. data/app/views/kaminari/kaminari-turbo-bootstrap/_last_page.html.erb +13 -0
  23. data/app/views/kaminari/kaminari-turbo-bootstrap/_next_page.html.erb +13 -0
  24. data/app/views/kaminari/kaminari-turbo-bootstrap/_page.html.erb +14 -0
  25. data/app/views/kaminari/kaminari-turbo-bootstrap/_paginator.html.erb +27 -0
  26. data/app/views/kaminari/kaminari-turbo-bootstrap/_prev_page.html.erb +14 -0
  27. data/app/views/layouts/loggable_activity/application.html.erb +19 -0
  28. data/app/views/loggable_activity/activities/_activities.html.erb +56 -0
  29. data/app/views/loggable_activity/activities/index.html.erb +7 -0
  30. data/app/views/loggable_activity/activities/show.html.erb +2 -0
  31. data/config/initializers/kaminari_config.rb +14 -0
  32. data/config/routes.rb +7 -0
  33. data/{lib/generators/loggable_activity/templates/create_loggable_activities.rb → db/migrate/20240702092648_create_loggable_activity_tables.rb} +18 -10
  34. data/git-org/HEAD +1 -0
  35. data/git-org/config +7 -0
  36. data/git-org/description +1 -0
  37. data/git-org/hooks/applypatch-msg.sample +15 -0
  38. data/git-org/hooks/commit-msg.sample +24 -0
  39. data/git-org/hooks/fsmonitor-watchman.sample +174 -0
  40. data/git-org/hooks/post-update.sample +8 -0
  41. data/git-org/hooks/pre-applypatch.sample +14 -0
  42. data/git-org/hooks/pre-commit.sample +49 -0
  43. data/git-org/hooks/pre-merge-commit.sample +13 -0
  44. data/git-org/hooks/pre-push.sample +53 -0
  45. data/git-org/hooks/pre-rebase.sample +169 -0
  46. data/git-org/hooks/pre-receive.sample +24 -0
  47. data/git-org/hooks/prepare-commit-msg.sample +42 -0
  48. data/git-org/hooks/push-to-checkout.sample +78 -0
  49. data/git-org/hooks/update.sample +128 -0
  50. data/git-org/info/exclude +6 -0
  51. data/lib/loggable_activity/activity.rb +3 -3
  52. data/lib/{schemas → loggable_activity}/config_schema.json +3 -3
  53. data/lib/loggable_activity/configuration.rb +51 -75
  54. data/lib/loggable_activity/data_owner.rb +0 -1
  55. data/lib/loggable_activity/encryption.rb +16 -7
  56. data/lib/loggable_activity/encryption_key.rb +4 -7
  57. data/lib/loggable_activity/engine.rb +27 -0
  58. data/lib/loggable_activity/error.rb +0 -10
  59. data/lib/loggable_activity/hooks.rb +10 -5
  60. data/lib/loggable_activity/payload.rb +8 -11
  61. data/lib/loggable_activity/sanitizer.rb +6 -2
  62. data/lib/loggable_activity/services/base_payloads_builder.rb +14 -5
  63. data/lib/loggable_activity/services/destroy_payloads_builder.rb +2 -1
  64. data/lib/loggable_activity/services/payloads_builder.rb +9 -2
  65. data/lib/loggable_activity/services/update_payloads_builder.rb +30 -2
  66. data/lib/loggable_activity/version.rb +1 -1
  67. data/lib/loggable_activity.rb +51 -14
  68. data/lib/tasks/loggable_activity_tasks.rake +6 -0
  69. metadata +129 -117
  70. data/.document +0 -1
  71. data/.nojekyll +0 -1
  72. data/.rspec +0 -3
  73. data/CONSIDERTIONS.md +0 -129
  74. data/GETTING-STARTED.md +0 -119
  75. data/LICENSE.txt +0 -21
  76. data/PAYLOAD_EXAMPLE.md +0 -63
  77. data/ROADMAP.md +0 -23
  78. data/docs/LoggableActivity/Activity.html +0 -555
  79. data/docs/LoggableActivity/Configuration.html +0 -330
  80. data/docs/LoggableActivity/ConfigurationError.html +0 -148
  81. data/docs/LoggableActivity/DataOwner.html +0 -138
  82. data/docs/LoggableActivity/Encryption.html +0 -234
  83. data/docs/LoggableActivity/EncryptionError.html +0 -145
  84. data/docs/LoggableActivity/EncryptionKey.html +0 -351
  85. data/docs/LoggableActivity/Error.html +0 -145
  86. data/docs/LoggableActivity/Hooks.html +0 -759
  87. data/docs/LoggableActivity/Payload.html +0 -432
  88. data/docs/LoggableActivity/Services/BasePayloadsBuilder.html +0 -442
  89. data/docs/LoggableActivity/Services/DestroyPayloadsBuilder.html +0 -395
  90. data/docs/LoggableActivity/Services/PayloadsBuilder.html +0 -342
  91. data/docs/LoggableActivity/Services/UpdatePayloadsBuilder.html +0 -490
  92. data/docs/LoggableActivity/Services.html +0 -93
  93. data/docs/LoggableActivity.html +0 -102
  94. data/docs/created.rid +0 -14
  95. data/docs/css/fonts.css +0 -167
  96. data/docs/css/rdoc.css +0 -687
  97. data/docs/fonts/Lato-Light.ttf +0 -0
  98. data/docs/fonts/Lato-LightItalic.ttf +0 -0
  99. data/docs/fonts/Lato-Regular.ttf +0 -0
  100. data/docs/fonts/Lato-RegularItalic.ttf +0 -0
  101. data/docs/fonts/SourceCodePro-Bold.ttf +0 -0
  102. data/docs/fonts/SourceCodePro-Regular.ttf +0 -0
  103. data/docs/images/add.png +0 -0
  104. data/docs/images/arrow_up.png +0 -0
  105. data/docs/images/brick.png +0 -0
  106. data/docs/images/brick_link.png +0 -0
  107. data/docs/images/bug.png +0 -0
  108. data/docs/images/bullet_black.png +0 -0
  109. data/docs/images/bullet_toggle_minus.png +0 -0
  110. data/docs/images/bullet_toggle_plus.png +0 -0
  111. data/docs/images/date.png +0 -0
  112. data/docs/images/delete.png +0 -0
  113. data/docs/images/find.png +0 -0
  114. data/docs/images/loadingAnimation.gif +0 -0
  115. data/docs/images/macFFBgHack.png +0 -0
  116. data/docs/images/package.png +0 -0
  117. data/docs/images/page_green.png +0 -0
  118. data/docs/images/page_white_text.png +0 -0
  119. data/docs/images/page_white_width.png +0 -0
  120. data/docs/images/plugin.png +0 -0
  121. data/docs/images/ruby.png +0 -0
  122. data/docs/images/tag_blue.png +0 -0
  123. data/docs/images/tag_green.png +0 -0
  124. data/docs/images/transparent.png +0 -0
  125. data/docs/images/wrench.png +0 -0
  126. data/docs/images/wrench_orange.png +0 -0
  127. data/docs/images/zoom.png +0 -0
  128. data/docs/index.html +0 -99
  129. data/docs/js/darkfish.js +0 -97
  130. data/docs/js/navigation.js +0 -105
  131. data/docs/js/navigation.js.gz +0 -0
  132. data/docs/js/search.js +0 -110
  133. data/docs/js/search_index.js +0 -1
  134. data/docs/js/search_index.js.gz +0 -0
  135. data/docs/js/searcher.js +0 -229
  136. data/docs/js/searcher.js.gz +0 -0
  137. data/docs/table_of_contents.html +0 -617
  138. data/help/loggable_activity_help.txt +0 -19
  139. data/lib/generators/.DS_Store +0 -0
  140. data/lib/generators/loggable_activity/.DS_Store +0 -0
  141. data/lib/generators/loggable_activity/install_generator.rb +0 -109
  142. data/lib/generators/loggable_activity/templates/.DS_Store +0 -0
  143. data/lib/generators/loggable_activity/templates/binary_ids/create_loggable_activities.rb +0 -30
  144. data/lib/generators/loggable_activity/templates/config/locales/loggable_activity.en.yml +0 -36
  145. data/lib/generators/loggable_activity/templates/config/loggable_activity.yaml +0 -29
  146. data/lib/generators/loggable_activity/templates/loggable_activity.en.yaml +0 -36
  147. data/pkg/loggable_activity-0.1.35.gem +0 -0
  148. data/sig/loggable_activity.rbs +0 -4
  149. /data/{.rspec_status → app/assets/images/loggable_activity/.keep} +0 -0
  150. /data/lib/{generators/loggable_activity/templates → loggable_activity/concerns}/current_user.rb +0 -0
@@ -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
@@ -5,7 +5,7 @@
5
5
  "current_user_model_name": {
6
6
  "type": "string"
7
7
  },
8
- "fetch_current_user_name_from": {
8
+ "current_user_name": {
9
9
  "type": "string"
10
10
  },
11
11
  "task_for_sanitization": {
@@ -13,7 +13,7 @@
13
13
  }
14
14
  },
15
15
  "patternProperties": {
16
- "^(?!current_user_model_name$|fetch_current_user_name_from$|task_for_sanitization)[A-Za-z0-9_:]+$": {
16
+ "^(?!current_user_model_name$|current_user_name$|task_for_sanitization)[A-Za-z0-9_:]+$": {
17
17
  "type": "object",
18
18
  "properties": {
19
19
  "data_owner": {
@@ -91,6 +91,6 @@
91
91
  "additionalProperties": false,
92
92
  "required": [
93
93
  "current_user_model_name",
94
- "fetch_current_user_name_from"
94
+ "current_user_name"
95
95
  ]
96
96
  }
@@ -2,94 +2,70 @@
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?
11
+ class << self
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
42
17
 
43
- raise ConfigurationError,
44
- "config/loggable_activity.yaml is invalid: #{errors.join(', ')}"
45
- 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
46
22
 
47
- # Returns true if the configuration file has been loaded
48
- def self.loaded?
49
- !@config_data.nil?
50
- 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?
51
28
 
52
- # Returns the configuration data
53
- class << self
54
- # @return [Hash]
55
- attr_reader :config_data
56
- end
29
+ raise ConfigurationError,
30
+ "config/loggable_activity.yaml is invalid: #{errors.join(', ')}"
31
+ end
57
32
 
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
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
79
54
 
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
55
+ # Returns the name of the field or method to use for the actor's display name.
56
+ def current_user_name
57
+ config_data['current_user_name']
58
+ end
84
59
 
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
60
+ # Returns the name of the model to use for the current user.
61
+ def current_user_model_name
62
+ config_data['current_user_model_name']
63
+ end
89
64
 
90
- # Returns whatever models should be sanitized on delete.
91
- def self.task_for_sanitization
92
- @config_data['task_for_sanitization']
65
+ # Returns whatever models should be sanitized on delete.
66
+ def task_for_sanitization
67
+ config_data['task_for_sanitization']
68
+ end
93
69
  end
94
70
  end
95
71
  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,27 @@
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
+
22
+ # initializer 'loggable_activity.assets.precompile' do |app|
23
+ # app.config.assets.precompile += %w( loggable_activity/application.css )
24
+ # app.config.assets.precompile += %w( loggable_activity/bootstrap.css )
25
+ # end
26
+ end
27
+ 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
@@ -24,6 +24,7 @@ module LoggableActivity
24
24
 
25
25
  # Initializes attributes based on configuration.
26
26
  self.loggable_attrs = config&.fetch('loggable_attrs', []) || []
27
+ self.public_attrs = config&.fetch('public_attrs', []) || []
27
28
  self.relations = config&.fetch('relations', []) || []
28
29
  self.auto_log = config&.fetch('auto_log', []) || []
29
30
  self.fetch_record_name_from = config&.fetch('fetch_record_name_from', nil)
@@ -60,6 +61,10 @@ module LoggableActivity
60
61
  end
61
62
  end
62
63
 
64
+ def disable_hooks!
65
+ self.disable_hooks = true
66
+ end
67
+
63
68
  private
64
69
 
65
70
  # Logs an activity for the current action.
@@ -134,6 +139,7 @@ module LoggableActivity
134
139
  # Logs a create activity automatically if configured.
135
140
  def log_create_activity
136
141
  return unless hooks_enabled?
142
+ return if id.nil?
137
143
 
138
144
  log(:create) if self.class.auto_log.include?('create')
139
145
  end
@@ -159,13 +165,13 @@ module LoggableActivity
159
165
 
160
166
  # Returns the encrypted name of the actor.
161
167
  def encrypted_actor_name
162
- name = @actor.send(fetch_current_user_name_from)
168
+ name = @actor.send(current_user_name)
163
169
  ::LoggableActivity::Encryption.encrypt(name, actor_secret_key)
164
170
  end
165
171
 
166
172
  # Reads the field to feetch the record name from.
167
- def fetch_current_user_name_from
168
- ::LoggableActivity::Configuration.fetch_current_user_name_from
173
+ def current_user_name
174
+ ::LoggableActivity::Configuration.current_user_name
169
175
  end
170
176
 
171
177
  # Returns the action key for the current action.
@@ -200,13 +206,12 @@ module LoggableActivity
200
206
 
201
207
  class_methods do
202
208
  # The loggable_attrs attribute is used read the configuration for the model that included LoggableActivity::Hooks.
203
- attr_accessor :loggable_attrs, :relations, :auto_log, :fetch_record_name_from, :route
209
+ attr_accessor :loggable_attrs, :relations, :auto_log, :fetch_record_name_from, :route, :public_attrs
204
210
 
205
211
  # Convert the model name and name space in to 'base_action'.
206
212
  def base_action
207
213
  name.downcase.gsub('::', '/')
208
214
  end
209
-
210
215
  end
211
216
  end
212
217
  end