loggable_activity 0.2.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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