digestible_attributes 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1c596e6d31cb71e54906b8d6f8aa96bf319529f95eeb84facf867ed649b2bb37
4
+ data.tar.gz: 62b5ce599341143ac4c38484fab0fca9e2a5a3717d1b4d6251c5e257f5cf33be
5
+ SHA512:
6
+ metadata.gz: 7c9359ada793b67094adb6382bd7745e2d129f61c9904cb3225de3db931556b890a4638bdd14e78422a6eb95b695eacfccabc18fea9eacd7cb67a91c37d012c7
7
+ data.tar.gz: 434d463ffac20945b973d3ed948e7594f99c5ae11f1eb7130f3472913e63f309a88e42abb33ccb3b731845e272e1288ce05f142d778fd77ced1d3cfe1d6d6a81
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2018
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # DigestibleAttributes
2
+ This plugin lets you compute a hash digest based on the
3
+ values of a set of attributes, and store it on your model.
4
+
5
+ ## Usage
6
+
7
+ ### Options
8
+
9
+ * `fields` - list of attribute fields to be digested
10
+ * `algorithm` - which hash algorithm to use for digest (defaults to `:MD5`)
11
+ * `digest_column` - where to store the digest (defaults to `*ALGORITHM*_digest`; i.e. `md5_digest`)
12
+
13
+ ### Quick start
14
+ If you have a model with fields `foo`, `bar`, `baz`,
15
+ simply add the following to your model file:
16
+
17
+ ```rb
18
+ digestible_attributes fields: [:foo, :bar, :baz]
19
+ ```
20
+
21
+ ### Supported hash algorithms
22
+ This gem uses `OpenSSL::Digest` to compute digests. The currently supported
23
+ algorithms are:
24
+
25
+ * `:MD2`
26
+ * `:MD4`
27
+ * `:MD5`
28
+ * `:MDC2`
29
+ * `:RIPEMD160`
30
+ * `:SHA1`
31
+ * `:SHA224`
32
+ * `:SHA256`
33
+ * `:SHA384`
34
+ * `:SHA512`
35
+
36
+ ## Installation
37
+ Add this line to your application's Gemfile:
38
+
39
+ ```ruby
40
+ gem 'digestible_attributes'
41
+ ```
42
+
43
+ And then execute:
44
+ ```
45
+ $ bundle
46
+ ```
47
+
48
+ Or install it yourself as:
49
+ ```
50
+ $ gem install digestible_attributes
51
+ ```
52
+
53
+ ## Things to come
54
+ - Generators
55
+ - RSpec Matchers
56
+ - Any ideas you might have?
57
+
58
+ ## Contributing
59
+ For any suggested changes, you can fork the repo, make your changes, and then open up a PR.
60
+ Please be sure to include a helpful commit message / explanation for your changes.
61
+
62
+ ## License
63
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'DigestibleAttributes'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ require 'bundler/gem_tasks'
@@ -0,0 +1,9 @@
1
+ require 'active_support'
2
+ require 'digestible_attributes/configuration'
3
+ require 'digestible_attributes/railtie'
4
+
5
+ module DigestibleAttributes
6
+ ActiveSupport.on_load(:active_record) do
7
+ extend DigestibleAttributes::Configuration
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ require 'digestible_attributes/digester'
2
+
3
+ module DigestibleAttributes
4
+ module CallbackActions
5
+ extend ActiveSupport::Concern
6
+ include Digester
7
+
8
+ included do
9
+ before_save :set_digest_column
10
+ end
11
+
12
+ private
13
+
14
+ def set_digest_column
15
+ send("#{self.class.digest_column}=".to_sym, calculate_digest)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,58 @@
1
+ require 'digestible_attributes/callback_actions'
2
+ require 'digestible_attributes/errors'
3
+
4
+ module DigestibleAttributes
5
+ module Configuration
6
+ extend ActiveSupport::Concern
7
+
8
+ DIGEST_ALGORITHMS = %i(MD2 MD4 MD5 MDC2 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512)
9
+
10
+ cattr_accessor :digest_fields
11
+ cattr_accessor :digest_algorithm
12
+ cattr_accessor :digest_column
13
+
14
+ def digestible_attributes(options = {})
15
+ @@digest_fields = options.fetch(:fields, [])
16
+ @@digest_algorithm = options.fetch(:algorithm, :MD5)
17
+ @@digest_column = options.fetch(:digest_column, default_digest_column)
18
+
19
+ validate_configuration!
20
+
21
+ include CallbackActions
22
+ end
23
+
24
+ def default_digest_column
25
+ "#{@@digest_algorithm.downcase}_digest".to_sym
26
+ end
27
+
28
+ def validate_configuration!
29
+ validate_digest_fields!
30
+ validate_digest_algorithm!
31
+ validate_digest_column!
32
+ end
33
+
34
+ def validate_digest_fields!
35
+ if @@digest_fields & symbolized_columns != @@digest_fields
36
+ diff = @@digest_fields - symbolized_columns
37
+
38
+ raise Errors::DigestFieldError.new(diff)
39
+ end
40
+ end
41
+
42
+ def validate_digest_algorithm!
43
+ unless DIGEST_ALGORITHMS.include?(@@digest_algorithm)
44
+ raise Errors::DigestAlgorithmError.new(@@digest_algorithm)
45
+ end
46
+ end
47
+
48
+ def validate_digest_column!
49
+ unless symbolized_columns.include?(@@digest_column)
50
+ raise Errors::DigestColumnError.new(@@digest_column)
51
+ end
52
+ end
53
+
54
+ def symbolized_columns
55
+ self.column_names.map(&:to_sym)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,30 @@
1
+ module DigestibleAttributes
2
+ module Digester
3
+ extend ActiveSupport::Concern
4
+
5
+ NULL_ESCAPE = "\u0000".freeze
6
+ FIELD_ESCAPE = "\uffef".freeze
7
+ FIELD_SEPARATOR = "\uffff".freeze
8
+
9
+ def calculate_digest
10
+ OpenSSL::Digest(self.class.digest_algorithm).hexdigest(digestible_string)
11
+ end
12
+
13
+ private
14
+
15
+ def symbolized_digest_fields
16
+ attributes.symbolize_keys.slice(*self.class.digest_fields)
17
+ end
18
+
19
+ def digestible_string
20
+ symbolized_digest_fields.map do |field, value|
21
+ base_str = "#{field}#{FIELD_ESCAPE}"
22
+ if value.nil?
23
+ base_str += NULL_ESCAPE
24
+ else
25
+ base_str += value.to_s
26
+ end
27
+ end.join(FIELD_SEPARATOR)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ module DigestibleAttributes
2
+ module Errors
3
+ class DigestFieldError < StandardError
4
+ def initialize(fields)
5
+ @fields = fields
6
+
7
+ super("invalid digest field(s): #{fields}")
8
+ end
9
+
10
+ attr_reader :fields
11
+ end
12
+
13
+ class DigestColumnError < StandardError
14
+ def initialize(column)
15
+ @column = column
16
+
17
+ super("invalid digest column: '#{column}'")
18
+ end
19
+
20
+ attr_reader :column
21
+ end
22
+
23
+ class DigestAlgorithmError < StandardError
24
+ def initialize(algorithm)
25
+ @algorithm = algorithm
26
+
27
+ super("invalid digest algorithm: '#{algorithm}'")
28
+ end
29
+
30
+ attr_reader :algorithm
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,4 @@
1
+ module DigestibleAttributes
2
+ class Railtie < ::Rails::Railtie
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module DigestibleAttributes
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :digestible_attributes do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: digestible_attributes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Anthony Hernandez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-10-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.3.13
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.3.13
41
+ - !ruby/object:Gem::Dependency
42
+ name: postgresql
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.0.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 3.8.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 3.8.1
69
+ description:
70
+ email:
71
+ - ant@antfeedr.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - MIT-LICENSE
77
+ - README.md
78
+ - Rakefile
79
+ - lib/digestible_attributes.rb
80
+ - lib/digestible_attributes/callback_actions.rb
81
+ - lib/digestible_attributes/configuration.rb
82
+ - lib/digestible_attributes/digester.rb
83
+ - lib/digestible_attributes/errors.rb
84
+ - lib/digestible_attributes/railtie.rb
85
+ - lib/digestible_attributes/version.rb
86
+ - lib/tasks/digestible_attributes_tasks.rake
87
+ homepage: https://www.github.com/hernanat/digestible_attributes
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.7.6
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Rails plugin for generating and storing hash digests based on model attributes
111
+ test_files: []