simple_encryptable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e71d844778dbffd0c1dfbceae91340e319ff558576730972d1a8050e48ca55a2
4
+ data.tar.gz: 7d176835432850b263061f6e358bb9560601de28ca8247defefd0222e975f2bf
5
+ SHA512:
6
+ metadata.gz: 2c86f5a72c73f580be17e4f8050749ec30f563869a650aab3d2eabc57aa5f54ca28911be9f9a6c2775362734e1f1d1f00e7f8243648bc4e70897d3bde8dba9b8
7
+ data.tar.gz: 12e93d6966fd12d3eadf9e5bbd5b6c10f2e47a7814fe43c64645dcdfefc33551cf5c3be842b00c1db96a9da9a469f6d55f61b4838d9dab8756e9003ca5c4e509
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ # OS files
14
+ .DS_Store
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.4.5
7
+ before_install: gem install bundler -v 1.17.3
data/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file. This
4
+ project adheres to [Semantic Versioning](http://semver.org).
5
+
6
+
7
+ ## [0.1.0] - 2019-08-24
8
+
9
+ ### Changed
10
+
11
+ - Gem in is 0.1.0 release, basic functionality implemented
12
+
13
+ [0.1.0]: https://github.com/rkorzeniec/simple_encryptable/compare/...v0.1.0
14
+
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in simple_encryptable.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 rkorzeniec
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # SimpleEncryptable
2
+
3
+ SimpleEncryptable is based on Rails encryption mechanisms, it is streamline without all the bells and whistles, only the esentials. Heavilly inspired by [Pawel Urbanek](https://pawelurbanek.com/rails-secure-encrypt-decrypt).
4
+
5
+ ## Installation
6
+
7
+ Add SimpleEncryptable application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'simple_encryptable'
11
+ ```
12
+ or
13
+ ```ruby
14
+ gem 'simple_encryptable', '~> 0.1.0'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install simple_encryptable
24
+
25
+ ## Usage
26
+ With `ActiveRecord` objects, the database must have `encrypted_[attribute]` column(s). With `PORO` objects, `attr_accessor [attribute]` must be provided.
27
+
28
+ You must include `SimpleEncryptable`, it is not dynamically loaded into all `ActiveRecord` objects. Providing `secret` and `salt` tokens is crutial. Ideally store them in an .env file or using Rails credentials mechanism.
29
+
30
+ ```ruby
31
+ class User
32
+ include SimpleEncryptable
33
+
34
+ attr_encryptor :secret_attribute, :another_secret_attribute, secret: 'foo', salt: 'bar'
35
+ end
36
+ ```
37
+
38
+ ## Contributing
39
+
40
+ 1. [Fork it](https://help.github.com/articles/about-forks/)
41
+ 2. Clone the project `git clone git@github.com:[YOUR GITHUB USERNAME]/simple_encryptable.git`
42
+ 3. `cd simple_encryptable`
43
+ 4. Install dependencies, `bundle install`
44
+ 5. Create your feature branch `git checkout -b my-new-feature`
45
+ 6. Write your feature, along with tests for your changes
46
+ 7. Run the tests `rake test`, all must be green
47
+ 8. Commit your changes `git commit -am 'Added some feature'`
48
+ 9. Push to the branch `git push origin my-new-feature`
49
+ 10. Create new [Pull Request](https://help.github.com/articles/creating-a-pull-request/)
50
+
51
+
52
+ ## License
53
+
54
+ 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,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << 'test'
6
+ t.libs << 'lib'
7
+ t.test_files = FileList['test/**/test_*.rb']
8
+ end
9
+
10
+ task default: :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "simple_encryptable"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/key_generator'
4
+ require 'active_support/message_encryptor'
5
+
6
+ module SimpleEncryptable
7
+ class Encryptor
8
+ class << self
9
+ def encrypt(value, options)
10
+ key = key(options)
11
+ ActiveSupport::MessageEncryptor.new(key).encrypt_and_sign(value)
12
+ end
13
+
14
+ def decrypt(value, options)
15
+ key = key(options)
16
+ ActiveSupport::MessageEncryptor.new(key).decrypt_and_verify(value)
17
+ end
18
+
19
+ private
20
+
21
+ def key(arguments = {})
22
+ raise Error, 'Secret option is missing.' if arguments[:secret].to_s.empty?
23
+ raise Error, 'Salt option is missing' if arguments[:salt].to_s.empty?
24
+
25
+ ::ActiveSupport::KeyGenerator
26
+ .new(arguments[:secret])
27
+ .generate_key(arguments[:salt], ActiveSupport::MessageEncryptor.key_len).freeze
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleEncryptable
4
+ class Error < StandardError; end
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleEncryptable
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+ require 'simple_encryptable/error'
5
+ require 'simple_encryptable/encryptor'
6
+ require 'simple_encryptable/version'
7
+
8
+ module SimpleEncryptable
9
+ extend ActiveSupport::Concern
10
+
11
+ class_methods do
12
+ def attr_encryptable(*attributes)
13
+ options = attributes.last.is_a?(Hash) ? attributes.pop : {}
14
+
15
+ attributes.each do |attribute|
16
+ define_method("#{attribute}=".to_sym) do |value|
17
+ return if value.nil?
18
+
19
+ public_send(
20
+ "encrypted_#{attribute}=".to_sym,
21
+ Encryptor.encrypt(value, options)
22
+ )
23
+ end
24
+
25
+ define_method(attribute) do
26
+ value = public_send("encrypted_#{attribute}".to_sym)
27
+ Encryptor.decrypt(value, options) if value.present?
28
+ end
29
+
30
+ define_method("#{attribute}?".to_sym) do
31
+ value = send(attribute)
32
+ value.respond_to?(:empty?) ? !value.empty? : !!value
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'simple_encryptable/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'simple_encryptable'
7
+ spec.version = SimpleEncryptable::VERSION
8
+ spec.authors = ['Robert Korzeniec']
9
+ spec.email = ['r.korzeniec@gmail.com']
10
+
11
+ spec.summary = 'Simple encryption service, without all the extras'
12
+ spec.description = 'This simple enrtyption service was heavily inspired by https://pawelurbanek.com/rails-secure-encrypt-decrypt'
13
+
14
+ spec.license = 'MIT'
15
+ spec.homepage = 'https://github.com/rkorzeniec/simple_encryptable/'
16
+ spec.metadata['source_code_uri'] = 'https://github.com/rkorzeniec/simple_encryptable'
17
+ spec.metadata['changelog_uri'] = 'https://github.com/rkorzeniec/simple_encryptable/CHANGELOG.md'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0")
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(%r{^spec/})
22
+ spec.require_paths = ['lib']
23
+ spec.required_ruby_version = '>= 2.4'
24
+
25
+ spec.add_dependency 'activesupport', '>= 4.2'
26
+
27
+ spec.add_development_dependency 'bundler', '~> 1.17'
28
+ spec.add_development_dependency 'minitest', '~> 5.11.3'
29
+ spec.add_development_dependency 'minitest-profile', '~> 0.0.2'
30
+ spec.add_development_dependency 'minitest-reporters', '~> 1.3.6'
31
+ spec.add_development_dependency 'rake', '~> 12.0'
32
+ end
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ describe SimpleEncryptable::Encryptor do
4
+ describe '.encrypt' do
5
+ let(:encrypted_value) do
6
+ SimpleEncryptable::Encryptor.encrypt('foo', secret: 'bar', salt: 'baz')
7
+ end
8
+
9
+ it { refute_equal('foo', encrypted_value) }
10
+ it { refute_nil(encrypted_value) }
11
+
12
+ it { assert_kind_of(String, encrypted_value) }
13
+ it { assert_equal(110, encrypted_value.length) }
14
+
15
+ it do
16
+ exception = assert_raises(SimpleEncryptable::Error) do
17
+ SimpleEncryptable::Encryptor.encrypt('foo', {})
18
+ end
19
+ assert_equal('Secret option is missing.', exception.message)
20
+ end
21
+ end
22
+
23
+ describe '.decrypt' do
24
+ it do
25
+ value = SimpleEncryptable::Encryptor.encrypt('foo', secret: 'bar', salt: 'baz')
26
+
27
+ assert_equal(
28
+ 'foo',
29
+ SimpleEncryptable::Encryptor.decrypt(value, secret: 'bar', salt: 'baz')
30
+ )
31
+ end
32
+
33
+ it do
34
+ exception = assert_raises(SimpleEncryptable::Error) do
35
+ SimpleEncryptable::Encryptor.decrypt('foo', {})
36
+ end
37
+ assert_equal('Secret option is missing.', exception.message)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ require 'test_helper'
2
+
3
+ describe SimpleEncryptable do
4
+ it { assert_includes(SimpleEncryptable::Error.ancestors, StandardError) }
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'test_helper'
2
+
3
+ describe SimpleEncryptable do
4
+ it { assert_equal('0.1.0', SimpleEncryptable::VERSION) }
5
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
2
+ require 'simple_encryptable'
3
+
4
+ require 'minitest/autorun'
5
+ require 'minitest/reporters'
6
+ require 'minitest/profile'
7
+
8
+ Minitest::Reporters.use!
@@ -0,0 +1,85 @@
1
+ require 'test_helper'
2
+
3
+ class User
4
+ include SimpleEncryptable
5
+
6
+ attr_accessor :encrypted_email, :encrypted_password, :encrypted_token
7
+
8
+ attr_encryptable :email, secret: 'foo', salt: 'bar'
9
+ attr_encryptable :password, :token, secret: 'baz', salt: 'zab'
10
+ attr_encryptable :aux
11
+
12
+ def initialize(email: nil, password: nil, token: nil, aux: nil)
13
+ self.email = email
14
+ self.password = password
15
+ self.token = token
16
+ self.aux = aux
17
+ end
18
+ end
19
+
20
+
21
+ describe SimpleEncryptable do
22
+ describe '.attr_encryptable' do
23
+ let(:user) { User.new(email: 'john@example.com') }
24
+
25
+ it 'defines writer' do
26
+ assert(user.respond_to?(:email=))
27
+ end
28
+
29
+ it 'defines reader' do
30
+ assert(user.respond_to?(:email))
31
+ end
32
+
33
+ it 'defines boolean method' do
34
+ assert(user.respond_to?(:email?))
35
+ end
36
+
37
+ it 'encrypts email correctly' do
38
+ decrypted_email = SimpleEncryptable::Encryptor.decrypt(
39
+ user.encrypted_email, secret: 'foo', salt: 'bar'
40
+ )
41
+
42
+ assert_equal('john@example.com', decrypted_email)
43
+ end
44
+
45
+ it 'encrypted does not equal email' do
46
+ refute_equal('john@example.com', user.encrypted_email)
47
+ end
48
+
49
+ it 'encrypts as string' do
50
+ assert_kind_of(String, user.encrypted_email)
51
+ end
52
+
53
+ it 'encrypts always with same length' do
54
+ assert_equal(138, user.encrypted_email.size)
55
+ end
56
+
57
+ it 'decrypts correctly' do
58
+ assert_equal('john@example.com', user.email)
59
+ end
60
+
61
+ it 'encrypted when value set' do
62
+ assert(user.email?)
63
+ end
64
+
65
+ it 'encrypted when value set' do
66
+ user = User.new
67
+ refute(user.email?)
68
+ end
69
+
70
+ it 'handles multiple encriptions' do
71
+ user = User.new(password: 'password', token: 'secret')
72
+ assert(user.password?)
73
+ assert_equal('password', user.password)
74
+ assert(user.token?)
75
+ assert_equal('secret', user.token)
76
+ end
77
+
78
+ it do
79
+ exception = assert_raises(SimpleEncryptable::Error) do
80
+ User.new(aux: 'secret')
81
+ end
82
+ assert_equal('Secret option is missing.', exception.message)
83
+ end
84
+ end
85
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_encryptable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Robert Korzeniec
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-08-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.17'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.17'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 5.11.3
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 5.11.3
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-profile
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.0.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-reporters
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.3.6
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.3.6
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '12.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '12.0'
97
+ description: This simple enrtyption service was heavily inspired by https://pawelurbanek.com/rails-secure-encrypt-decrypt
98
+ email:
99
+ - r.korzeniec@gmail.com
100
+ executables:
101
+ - console
102
+ - setup
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - ".gitignore"
107
+ - ".travis.yml"
108
+ - CHANGELOG.md
109
+ - Gemfile
110
+ - LICENSE.txt
111
+ - README.md
112
+ - Rakefile
113
+ - bin/console
114
+ - bin/setup
115
+ - lib/simple_encryptable.rb
116
+ - lib/simple_encryptable/encryptor.rb
117
+ - lib/simple_encryptable/error.rb
118
+ - lib/simple_encryptable/version.rb
119
+ - simple_encryptable.gemspec
120
+ - test/simple_encryptor/test_encryptor.rb
121
+ - test/simple_encryptor/test_error.rb
122
+ - test/simple_encryptor/test_version.rb
123
+ - test/test_helper.rb
124
+ - test/test_simple_encryptor.rb
125
+ homepage: https://github.com/rkorzeniec/simple_encryptable/
126
+ licenses:
127
+ - MIT
128
+ metadata:
129
+ source_code_uri: https://github.com/rkorzeniec/simple_encryptable
130
+ changelog_uri: https://github.com/rkorzeniec/simple_encryptable/CHANGELOG.md
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '2.4'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubygems_version: 3.0.4
147
+ signing_key:
148
+ specification_version: 4
149
+ summary: Simple encryption service, without all the extras
150
+ test_files: []