voltron-encrypt 0.1.2
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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +65 -0
- data/Rakefile +6 -0
- data/app/models/voltron/id.rb +9 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/generators/templates/config/locales/blacklist.txt +921 -0
- data/lib/generators/templates/db/migrate/create_voltron_ids.rb +9 -0
- data/lib/generators/voltron/encrypt/install_generator.rb +91 -0
- data/lib/voltron/config/encrypt.rb +19 -0
- data/lib/voltron/encrypt/engine.rb +19 -0
- data/lib/voltron/encrypt/version.rb +5 -0
- data/lib/voltron/encrypt.rb +83 -0
- data/lib/voltron/encryptable.rb +125 -0
- data/voltron-encrypt.gemspec +30 -0
- metadata +176 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
module Voltron
|
2
|
+
class Encrypt
|
3
|
+
module Generators
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
|
6
|
+
source_root File.expand_path("../../../templates", __FILE__)
|
7
|
+
|
8
|
+
desc "Add Voltron Encrypt initializer"
|
9
|
+
|
10
|
+
def inject_initializer
|
11
|
+
|
12
|
+
voltron_initialzer_path = Rails.root.join("config", "initializers", "voltron.rb")
|
13
|
+
|
14
|
+
unless File.exist? voltron_initialzer_path
|
15
|
+
unless system("cd #{Rails.root.to_s} && rails generate voltron:install")
|
16
|
+
puts "Voltron initializer does not exist. Please ensure you have the 'voltron' gem installed and run `rails g voltron:install` to create it"
|
17
|
+
return false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
current_initiailzer = File.read voltron_initialzer_path
|
22
|
+
|
23
|
+
unless current_initiailzer.match(Regexp.new(/^# === Voltron Encrypt Configuration ===/))
|
24
|
+
inject_into_file(voltron_initialzer_path, after: "Voltron.setup do |config|\n") do
|
25
|
+
<<-CONTENT
|
26
|
+
|
27
|
+
# === Voltron Encrypt Configuration ===
|
28
|
+
|
29
|
+
# The offset used in generating base64 encoded ids. A higher number means larger ids (i.e. - "7feIds" instead of "6f"),
|
30
|
+
# but can potentially produce large base64 encoded ids
|
31
|
+
# DON'T change this number once records whose id's are being encoded exist in the database
|
32
|
+
# as all decoded ids will be incorrect
|
33
|
+
# config.encrypt.offset = 262144
|
34
|
+
|
35
|
+
# The location of the blacklist, words that should NOT be permitted in the form of generated ids
|
36
|
+
# Each word should be on it's own line, and only contain [A-Z], no spaces, dashes, underscores, or numbers
|
37
|
+
# Each word is automatically matched against it's literal, case-insensitive, and l33t spellings, with dashes
|
38
|
+
# and underscores optionally preceding/following each character.
|
39
|
+
# i.e. - the blacklist word "toke" will match [toke, tOKE, 7oke, t0k3, t-o-k-e, -t0--k3--, etc...]
|
40
|
+
# config.encrypt.blacklist = Rails.root.join("config", "locales", "blacklist.txt")
|
41
|
+
|
42
|
+
# The seed used to randomize base 64 characters. Once set, it should NOT EVER be changed.
|
43
|
+
# Doing so will result in incorrect decoded ids, followed by large crowds with pitchforks and torches
|
44
|
+
# Running `rake secret` is a good way to generate a random seed for this config value
|
45
|
+
# config.encrypt.seed = ""
|
46
|
+
CONTENT
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def copy_blacklist
|
52
|
+
unless File.exist? Rails.root.join("config", "locales", "blacklist.txt")
|
53
|
+
copy_file "config/locales/blacklist.txt", Rails.root.join("config", "locales", "blacklist.txt")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def copy_migrations
|
58
|
+
copy_migration "create_voltron_ids"
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
def copy_migration(filename)
|
64
|
+
if migration_exists?(Rails.root.join("db", "migrate"), filename)
|
65
|
+
say_status("skipped", "Migration #{filename}.rb already exists")
|
66
|
+
else
|
67
|
+
copy_file "db/migrate/#{filename}.rb", Rails.root.join("db", "migrate", "#{migration_number}_#{filename}.rb")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def migration_exists?(dirname, filename)
|
72
|
+
Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{filename}.rb$/).first
|
73
|
+
end
|
74
|
+
|
75
|
+
def migration_id_exists?(dirname, id)
|
76
|
+
Dir.glob("#{dirname}/#{id}*").length > 0
|
77
|
+
end
|
78
|
+
|
79
|
+
def migration_number
|
80
|
+
@migration_number ||= Time.now.strftime("%Y%m%d%H%M%S").to_i
|
81
|
+
|
82
|
+
while migration_id_exists?(Rails.root.join("db", "migrate"), @migration_number) do
|
83
|
+
@migration_number += 1
|
84
|
+
end
|
85
|
+
|
86
|
+
@migration_number
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Voltron
|
2
|
+
class Config
|
3
|
+
|
4
|
+
def encrypt
|
5
|
+
@encrypt ||= Encrypt.new
|
6
|
+
end
|
7
|
+
|
8
|
+
class Encrypt
|
9
|
+
|
10
|
+
attr_accessor :offset, :seed, :blacklist
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@offset ||= 262144
|
14
|
+
@seed ||= ""
|
15
|
+
@blacklist ||= Rails.root.join("config", "locales", "blacklist.txt")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Voltron
|
2
|
+
class Encrypt
|
3
|
+
class Engine < Rails::Engine
|
4
|
+
|
5
|
+
isolate_namespace Voltron
|
6
|
+
|
7
|
+
initializer "voltron.encrypt.initialize" do
|
8
|
+
::ActiveRecord::Base.send :extend, ::Voltron::Encryptable
|
9
|
+
|
10
|
+
# Corrects sidekiq resource lookup by forcing it to find_by_id rather than find with the model id
|
11
|
+
# We either want it to find with to_param value, or find_by_id with the actual id, this is the latter
|
12
|
+
::GlobalID::Locator.use Rails.application.railtie_name.remove("_application").dasherize do |gid|
|
13
|
+
gid.model_class.find_by_id gid.model_id
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "voltron"
|
2
|
+
require "voltron/encrypt/version"
|
3
|
+
require "voltron/config/encrypt"
|
4
|
+
require "voltron/encryptable"
|
5
|
+
|
6
|
+
module Voltron
|
7
|
+
class Encrypt
|
8
|
+
|
9
|
+
def encode(input)
|
10
|
+
radix = digits.length
|
11
|
+
i = input.to_i + Voltron.config.encrypt.offset.to_i # Increase the number just so we don't end up with id's like "E" or "d3" on low number ids
|
12
|
+
|
13
|
+
raise ArgumentError.new("Value #{val} cannot be less than zero") if i < 0
|
14
|
+
|
15
|
+
out = []
|
16
|
+
begin
|
17
|
+
rem = i % radix
|
18
|
+
i /= radix
|
19
|
+
out << digits[rem]
|
20
|
+
end until i == 0
|
21
|
+
|
22
|
+
out.reverse.join
|
23
|
+
end
|
24
|
+
|
25
|
+
def decode(input)
|
26
|
+
inp = input.to_s.split("")
|
27
|
+
out = 0
|
28
|
+
|
29
|
+
begin
|
30
|
+
chr = inp.shift
|
31
|
+
out += (digits.length**inp.length)*digits.index(chr)
|
32
|
+
end until inp.empty?
|
33
|
+
|
34
|
+
out - Voltron.config.encrypt.offset.to_i # Decrease the number by the same offset amount
|
35
|
+
end
|
36
|
+
|
37
|
+
def blacklisted?(input)
|
38
|
+
encoded = encode(input)
|
39
|
+
|
40
|
+
pattern = ["\\b([_\\-])*"]
|
41
|
+
encoded.split("").each do |c|
|
42
|
+
subs = translations[c.downcase] || []
|
43
|
+
c = "\\#{c}" if c == "-"
|
44
|
+
pattern << "[#{c}#{subs.join}]([_\\-])*"
|
45
|
+
end
|
46
|
+
pattern << "\\b"
|
47
|
+
|
48
|
+
regex = Regexp.new(pattern.join, Regexp::IGNORECASE)
|
49
|
+
!blacklist(encoded.length).match(regex).nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def blacklist(len = 6)
|
55
|
+
if File.exist?(Voltron.config.encrypt.blacklist.to_s)
|
56
|
+
File.readlines(Voltron.config.encrypt.blacklist).map(&:strip).reject { |line| line.length > len }.join(" ")
|
57
|
+
else
|
58
|
+
""
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def translations
|
63
|
+
{
|
64
|
+
"a" => ["4"],
|
65
|
+
"e" => ["3"],
|
66
|
+
"i" => ["1", "l"],
|
67
|
+
"o" => ["0"],
|
68
|
+
"s" => ["5"],
|
69
|
+
"t" => ["7"],
|
70
|
+
"b" => ["8"],
|
71
|
+
"z" => ["2"],
|
72
|
+
"g" => ["9"]
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
def digits
|
77
|
+
rnd = Random.new(Voltron.config.encrypt.seed.to_s.to_i(24))
|
78
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".split("").shuffle(random: rnd)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
require "voltron/encrypt/engine" if defined?(Rails)
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Voltron
|
2
|
+
module Encryptable
|
3
|
+
|
4
|
+
def encrypted_id
|
5
|
+
extend ClassMethods
|
6
|
+
include InstanceMethods
|
7
|
+
|
8
|
+
has_one :encryptable, as: :resource, class_name: "Voltron::Id"
|
9
|
+
|
10
|
+
before_create do
|
11
|
+
self.build_encryptable id: find_id
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def find(*args)
|
17
|
+
scope = args.slice!(0)
|
18
|
+
options = args.slice!(0) || {}
|
19
|
+
|
20
|
+
if !options[:bypass] && ![:first, :last, :all].include?(scope.try(:to_sym))
|
21
|
+
scope = decoded_ids(scope)
|
22
|
+
end
|
23
|
+
|
24
|
+
super(scope)
|
25
|
+
end
|
26
|
+
|
27
|
+
def exists?(conditions = :none)
|
28
|
+
if conditions.is_a?(String)
|
29
|
+
# If conditions is a string, assume it's an encoded id
|
30
|
+
super(decoded_ids(conditions))
|
31
|
+
else
|
32
|
+
# Otherwise do what exists? normally does
|
33
|
+
super(conditions)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def destroy(id)
|
38
|
+
super(decoded_ids(id))
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete(id)
|
42
|
+
super(decoded_ids(id))
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def decoded_ids(*ids)
|
48
|
+
crypt = Voltron::Encrypt.new
|
49
|
+
|
50
|
+
ids.flatten!
|
51
|
+
ids.map! { |id| crypt.decode(id).to_i }
|
52
|
+
ids.reject! { |id| id > 9223372036854775807 } # Remove id if given decoded value is greater than max PostgreSQL value
|
53
|
+
ids = Voltron::Id.where(id: ids).pluck(:resource_id)
|
54
|
+
ids = ids.first if ids.length == 1
|
55
|
+
ids
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
module InstanceMethods
|
60
|
+
def to_param
|
61
|
+
return super if encryptable.nil?
|
62
|
+
|
63
|
+
crypt = Voltron::Encrypt.new
|
64
|
+
crypt.encode(encryptable.id)
|
65
|
+
end
|
66
|
+
|
67
|
+
def find_id
|
68
|
+
# Helps determine the min/max value. For example if amount is 1100, min will be 1024, if amount is 947, min will be 1
|
69
|
+
amount = Voltron::Id.count.to_f
|
70
|
+
|
71
|
+
# The range of ids from which we try to find an unused id, i.e. - (1..1024), (1025..2048), (2049..3073)
|
72
|
+
factor = 1024.to_f
|
73
|
+
|
74
|
+
# Get the min and max value of the range segment
|
75
|
+
min = (((amount/factor).floor*factor) + 1).to_i
|
76
|
+
max = (((amount+1)/factor).ceil*factor).to_i
|
77
|
+
|
78
|
+
# Get all ids in the determined range segment, these are the ids we cannot choose from
|
79
|
+
used = Voltron::Id.where(id: min..max).pluck(:id)
|
80
|
+
# Get the candidates, an array of values from min to max, subtracting the used values from above
|
81
|
+
candidates = ((min..max).to_a - used).shuffle
|
82
|
+
# Get the first candidate, the first value off the shuffled array
|
83
|
+
candidate = candidates.shift
|
84
|
+
|
85
|
+
# Check for blacklisted words given the candidate id
|
86
|
+
while crypt.blacklisted?(candidate) do
|
87
|
+
# If id chosen is a blacklisted word, insert it as a placeholder record and try again
|
88
|
+
Voltron::Id.create(id: candidate, resource_id: 0, resource_type: :blacklist)
|
89
|
+
|
90
|
+
# If no more candidates to choose from, re-run find_id, it will get a new set of candidates from the next segment
|
91
|
+
return find_id if candidates.empty?
|
92
|
+
|
93
|
+
# Pick the next candidate
|
94
|
+
candidate = candidates.shift
|
95
|
+
end
|
96
|
+
|
97
|
+
# The id chosen is good, not a blacklisted word. Use it
|
98
|
+
candidate
|
99
|
+
end
|
100
|
+
|
101
|
+
def reload(options = nil)
|
102
|
+
clear_aggregation_cache
|
103
|
+
clear_association_cache
|
104
|
+
self.class.connection.clear_query_cache
|
105
|
+
|
106
|
+
fresh_object =
|
107
|
+
if options && options[:lock]
|
108
|
+
self.class.unscoped { self.class.lock(options[:lock]).find_by(id: encryptable.resource_id) }
|
109
|
+
else
|
110
|
+
self.class.unscoped { self.class.find(encryptable.resource_id, bypass: true) }
|
111
|
+
end
|
112
|
+
|
113
|
+
@attributes = fresh_object.instance_variable_get("@attributes")
|
114
|
+
@new_record = false
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def crypt
|
121
|
+
@crypt ||= Voltron::Encrypt.new
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'voltron/encrypt/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "voltron-encrypt"
|
8
|
+
spec.version = Voltron::Encrypt::VERSION
|
9
|
+
spec.authors = ["Eric Hainer"]
|
10
|
+
spec.email = ["eric@commercekitchen.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Enables base 64 encoded ids on rails models}
|
13
|
+
spec.homepage = "https://github.com/ehainer/voltron-encrypt"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "rails", ">= 4.2"
|
22
|
+
spec.add_dependency "voltron", ">= 0.1.0"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", ">= 1.12"
|
25
|
+
spec.add_development_dependency "rake", ">= 10.0"
|
26
|
+
spec.add_development_dependency "rspec", ">= 3.0"
|
27
|
+
spec.add_development_dependency "rspec-rails", ">= 3.4"
|
28
|
+
spec.add_development_dependency "sqlite3", ">= 1.2"
|
29
|
+
spec.add_development_dependency "simplecov", "0.11.0"
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: voltron-encrypt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Hainer
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-04 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: '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: voltron
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.1.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.12'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.12'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-rails
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.4'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.4'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: sqlite3
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.2'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.2'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.11.0
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.11.0
|
125
|
+
description:
|
126
|
+
email:
|
127
|
+
- eric@commercekitchen.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".gitignore"
|
133
|
+
- ".rspec"
|
134
|
+
- ".travis.yml"
|
135
|
+
- CODE_OF_CONDUCT.md
|
136
|
+
- Gemfile
|
137
|
+
- LICENSE.txt
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- app/models/voltron/id.rb
|
141
|
+
- bin/console
|
142
|
+
- bin/setup
|
143
|
+
- lib/generators/templates/config/locales/blacklist.txt
|
144
|
+
- lib/generators/templates/db/migrate/create_voltron_ids.rb
|
145
|
+
- lib/generators/voltron/encrypt/install_generator.rb
|
146
|
+
- lib/voltron/config/encrypt.rb
|
147
|
+
- lib/voltron/encrypt.rb
|
148
|
+
- lib/voltron/encrypt/engine.rb
|
149
|
+
- lib/voltron/encrypt/version.rb
|
150
|
+
- lib/voltron/encryptable.rb
|
151
|
+
- voltron-encrypt.gemspec
|
152
|
+
homepage: https://github.com/ehainer/voltron-encrypt
|
153
|
+
licenses:
|
154
|
+
- MIT
|
155
|
+
metadata: {}
|
156
|
+
post_install_message:
|
157
|
+
rdoc_options: []
|
158
|
+
require_paths:
|
159
|
+
- lib
|
160
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
170
|
+
requirements: []
|
171
|
+
rubyforge_project:
|
172
|
+
rubygems_version: 2.4.8
|
173
|
+
signing_key:
|
174
|
+
specification_version: 4
|
175
|
+
summary: Enables base 64 encoded ids on rails models
|
176
|
+
test_files: []
|