atheneum 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +170 -0
- data/Rakefile +2 -0
- data/atheneum.gemspec +30 -0
- data/lib/atheneum.rb +12 -0
- data/lib/atheneum/errors.rb +3 -0
- data/lib/atheneum/storage.rb +44 -0
- data/lib/atheneum/strategy.rb +21 -0
- data/lib/atheneum/strategy/base.rb +25 -0
- data/lib/atheneum/strategy/crypt.rb +13 -0
- data/lib/atheneum/strategy/reverse.rb +15 -0
- data/lib/atheneum/strategy/upper_case.rb +15 -0
- data/lib/atheneum/version.rb +3 -0
- data/tasks/test.rake +16 -0
- data/test/atheneum/atheneum_test.rb +112 -0
- data/test/strategy/crypt_test.rb +28 -0
- data/test/test_config.rb +6 -0
- metadata +141 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9dee1c4b05491234603c1a15261ed81340af57c0
|
4
|
+
data.tar.gz: 509d97ddd98bfba60f7ee36514a17478ed7c651d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 691ec9670f1f3e9cd80e5e3979a4df8fb3b4696fe21064adaf0eda0976d88cd7974cbc960ac9ec5612993078cab14fde09eb322fea62313989fa3fab72c165fb
|
7
|
+
data.tar.gz: 8ddea8d1d9137b75e2fcad952721bdc587d1e12754b9765a21d132cbc18c966ed368c9df215201358d4628578b59e97d365c21c11278add919f6bbff2bc89b6e
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Peter
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
# Atheneum
|
2
|
+
> *noun* **place where records are stored**
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Add this line to your application's Gemfile:
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
gem 'atheneum'
|
10
|
+
```
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install atheneum
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
### Basic#
|
22
|
+
|
23
|
+
You have a user record, it's always a user, that has a password. There is a `crypted_password` field on your model from the database. Atheneum can use the crypt strategy to take care of storing and retrieving the password. It will also privatise the original attribute accessors so the objects public interface is only the new attribute accessors.
|
24
|
+
|
25
|
+
**NB: you must also include bcrypt in your gems for this example**
|
26
|
+
|
27
|
+
```rb
|
28
|
+
class UserRecord < Struct.new(:crypted_password)
|
29
|
+
include Atheneum.crypt(:password)
|
30
|
+
end
|
31
|
+
|
32
|
+
user_record = UserRecord.new
|
33
|
+
user_record.password = 'password'
|
34
|
+
puts user
|
35
|
+
# => #<struct UserRecord crypted_password="$2a$10$0lScjOJwCUVdtqGrtIgww.RbvVWXGPD.oISi4DBcIgK3f3YO66aju">
|
36
|
+
|
37
|
+
user_record.password == 'password'
|
38
|
+
# => true
|
39
|
+
|
40
|
+
user_record.crypted_password
|
41
|
+
# => NoMethodError: private method `crypted_password' called for #<UserRecord:0x0000000236f9f0>
|
42
|
+
|
43
|
+
|
44
|
+
# Without Atheneum
|
45
|
+
class UserRecord < Struct.new(:crypted_password)
|
46
|
+
def password=(password)
|
47
|
+
self.crypted_password = BCrypt::Password.create(password).to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
def password
|
51
|
+
BCrypt::Password.new(crypted_password)
|
52
|
+
end
|
53
|
+
|
54
|
+
private :crypted_password, :crypted_password=
|
55
|
+
end
|
56
|
+
```
|
57
|
+
#### Options
|
58
|
+
|
59
|
+
Storage methods accept more than one attribute. They also take an optional configuration hash
|
60
|
+
|
61
|
+
- **privatise** *(default: true)* Sets whether existing accessors should privatised
|
62
|
+
|
63
|
+
- **prefix** Overwrites the strategies default prefix
|
64
|
+
|
65
|
+
Strategies with no default prefix will use the strategies name eg `SomeStrategy` => `some_strategy`
|
66
|
+
|
67
|
+
#### New Storage Strategy
|
68
|
+
|
69
|
+
Say you wanted some strings to be reversed before adding to the database. Perhaps exceptionally mild security.
|
70
|
+
|
71
|
+
Atheneum looks up strategy classes namespaced under `Atheneum::Strategy`. These need to implement a pack and unpack method as well as optionally generating the storage location
|
72
|
+
|
73
|
+
```rb
|
74
|
+
module Atheneum
|
75
|
+
class Strategy
|
76
|
+
class Reverse < Base
|
77
|
+
|
78
|
+
def pack(item)
|
79
|
+
item.reverse
|
80
|
+
end
|
81
|
+
|
82
|
+
def unpack(item)
|
83
|
+
item.reverse
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class LocationRecord < Struct.new(:obscured_address, :obscured_name)
|
91
|
+
include Atheneum.reverse :address, :name, :prefix => 'obscured', :privatise => false
|
92
|
+
end
|
93
|
+
|
94
|
+
location_record = LocationRecord.new
|
95
|
+
|
96
|
+
location_record.name = 'office'
|
97
|
+
|
98
|
+
location_record.obscured_name
|
99
|
+
# => "eciffo"
|
100
|
+
```
|
101
|
+
|
102
|
+
## Why?
|
103
|
+
|
104
|
+
By privatising the existing attributes then the record object can remain an *immaculate record*, it appears to have only getters and setters. This is an example of how I have been using them. The example is with sequel, I have yet to try with active record but the priciple should hold.
|
105
|
+
|
106
|
+
```rb
|
107
|
+
require "sequel"
|
108
|
+
require "atheneum"
|
109
|
+
require "bcrypt"
|
110
|
+
|
111
|
+
# connect to an in-memory database
|
112
|
+
DB = Sequel.sqlite
|
113
|
+
|
114
|
+
# create an users table
|
115
|
+
DB.create_table :users do
|
116
|
+
primary_key :id
|
117
|
+
String :email
|
118
|
+
String :crypted_password
|
119
|
+
end
|
120
|
+
|
121
|
+
# create a user record
|
122
|
+
class UserRecord < Sequel::Model(:users)
|
123
|
+
Atheneum.crypt :password
|
124
|
+
end
|
125
|
+
|
126
|
+
# create a user model
|
127
|
+
class User < SimpleDelegator
|
128
|
+
|
129
|
+
def check_password(candidate_password)
|
130
|
+
password == candidate_password
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def model
|
136
|
+
__getobj__
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
# In production
|
142
|
+
user = User.new(UserRecord.new)
|
143
|
+
user.password = 'password'
|
144
|
+
user.check_password('password')
|
145
|
+
# => true
|
146
|
+
|
147
|
+
# In test
|
148
|
+
TestRecord = Struct.new(:email, :password)
|
149
|
+
user = User.new(TestRecord.new)
|
150
|
+
user.password = 'password'
|
151
|
+
user.check_password('password')
|
152
|
+
# => true
|
153
|
+
```
|
154
|
+
|
155
|
+
#### Immaculate Record
|
156
|
+
|
157
|
+
An immaculate record is one that acts purely as a data structure. In practise this works for all classes that can be proxied with a Struct/OpenStruct. Its value is in
|
158
|
+
|
159
|
+
- Separating all buisness logic from state
|
160
|
+
|
161
|
+
- fast tests
|
162
|
+
|
163
|
+
|
164
|
+
## Contributing
|
165
|
+
|
166
|
+
1. Fork it ( https://github.com/[my-github-username]/atheneum/fork )
|
167
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
168
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
169
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
170
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/atheneum.gemspec
ADDED
@@ -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 'atheneum/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "atheneum"
|
8
|
+
spec.version = Atheneum::VERSION
|
9
|
+
spec.authors = ["Peter"]
|
10
|
+
spec.email = ["peterhsaxton@gmail.com"]
|
11
|
+
spec.summary = %q{A micro gem for the immaculate inclusion of BCrypt protected data for example passwords}
|
12
|
+
spec.description = %q{Simply declare attributes that require obscuring and that will make it so.
|
13
|
+
Useful in exposing buisness logic in objects that use BCrypt
|
14
|
+
This gem currently assumes that BCrypt is available rather than adding it as a dependency,
|
15
|
+
future versions might support general strategies.
|
16
|
+
}
|
17
|
+
spec.homepage = ""
|
18
|
+
spec.license = "MIT"
|
19
|
+
|
20
|
+
spec.files = `git ls-files -z`.split("\x0")
|
21
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
|
+
spec.require_paths = ["lib"]
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "minitest", "~> 5.4.3"
|
28
|
+
spec.add_development_dependency "minitest-reporters", "~> 1.0.6"
|
29
|
+
spec.add_development_dependency "bcrypt", "~> 3.1.9"
|
30
|
+
end
|
data/lib/atheneum.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "atheneum/version"
|
2
|
+
require "atheneum/errors"
|
3
|
+
require "atheneum/strategy"
|
4
|
+
require "atheneum/storage"
|
5
|
+
|
6
|
+
module Atheneum
|
7
|
+
def self.method_missing(strategy, *attributes, &block)
|
8
|
+
options = attributes.pop if attributes.last.class == Hash
|
9
|
+
options ||= {}
|
10
|
+
Storage.generate strategy, attributes, options
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Atheneum
|
2
|
+
|
3
|
+
class Storage
|
4
|
+
def initialize(strategy)
|
5
|
+
@strategy = strategy
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :strategy
|
9
|
+
|
10
|
+
def for(records)
|
11
|
+
make_module(records, strategy)
|
12
|
+
end
|
13
|
+
|
14
|
+
def make_module(records, strategy)
|
15
|
+
Module.new do
|
16
|
+
records.each do |record|
|
17
|
+
define_method "#{record}=", ->(item){
|
18
|
+
self.send "#{strategy.store_for(record)}=", strategy.pack(item)
|
19
|
+
}
|
20
|
+
|
21
|
+
define_method record, -> (){
|
22
|
+
strategy.unpack(self.send("#{strategy.store_for(record)}"))
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
if strategy.privatise?
|
27
|
+
define_singleton_method :'included', ->(klass){
|
28
|
+
records.each do |record|
|
29
|
+
klass.send :private, strategy.store_for(record)
|
30
|
+
klass.send :private, "#{strategy.store_for(record)}="
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.generate strategy_name, attributes, options
|
39
|
+
strategy = Strategy.find strategy_name
|
40
|
+
storage = new strategy.new(options)
|
41
|
+
storage.for attributes
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative './strategy/reverse'
|
2
|
+
require_relative './strategy/upper_case'
|
3
|
+
require_relative './strategy/crypt'
|
4
|
+
|
5
|
+
module Atheneum
|
6
|
+
class Strategy
|
7
|
+
def self.find(name)
|
8
|
+
nodule = constantize(name)
|
9
|
+
begin
|
10
|
+
const_get(nodule)
|
11
|
+
rescue NameError
|
12
|
+
raise StrategyUndefined.new "Strategy \"#{nodule}\" not found"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.constantize(string)
|
17
|
+
string.to_s.split('_').map(&:capitalize).join
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Atheneum
|
2
|
+
class Strategy
|
3
|
+
class Base < Struct.new(:options)
|
4
|
+
|
5
|
+
def store_for(attribute)
|
6
|
+
"#{prefix}_#{attribute}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def prefix
|
10
|
+
options.fetch(:prefix){
|
11
|
+
default_prefix
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def default_prefix
|
16
|
+
str = self.class.name.split('::').last.split(/(?=[A-Z])/).map(&:downcase).join('_')
|
17
|
+
str[-1, 1] == 'e' ? str + 'd' : str + 'ed'
|
18
|
+
end
|
19
|
+
|
20
|
+
def privatise?
|
21
|
+
options.fetch(:privatise) { true }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/tasks/test.rake
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
|
3
|
+
test_tasks = Dir['test/*/'].map { |d| File.basename(d) }
|
4
|
+
|
5
|
+
test_tasks.each do |folder|
|
6
|
+
Rake::TestTask.new("test:#{folder}") do |test|
|
7
|
+
test.pattern = "test/#{folder}/**/*_test.rb"
|
8
|
+
test.verbose = true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "Run application test suite"
|
13
|
+
Rake::TestTask.new("test") do |test|
|
14
|
+
test.pattern = "test/**/*_test.rb"
|
15
|
+
test.verbose = true
|
16
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require_relative '../test_config'
|
2
|
+
|
3
|
+
class AtheneumTest < MiniTest::Test
|
4
|
+
def test_raises_error_for_undefined_strategy
|
5
|
+
err = assert_raises Atheneum::StrategyUndefined do
|
6
|
+
Atheneum.no_strategy
|
7
|
+
end
|
8
|
+
assert_match(/NoStrategy/, err.message)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_can_store_a_password_reversed
|
12
|
+
dummy_class = Struct.new(:reversed_password)
|
13
|
+
dummy_class = dummy_class.include Atheneum.reverse :password
|
14
|
+
store = dummy_class.new
|
15
|
+
store.password = 'password'
|
16
|
+
assert_equal 'password'.reverse, store.send(:reversed_password)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_can_retrieve_a_password_reversed
|
20
|
+
dummy_class = Struct.new(:reversed_password)
|
21
|
+
dummy_class = dummy_class.include Atheneum.reverse :password
|
22
|
+
store = dummy_class.new 'password'.reverse
|
23
|
+
assert_equal 'password', store.password
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_can_store_a_other_reversed
|
27
|
+
dummy_class = Struct.new(:reversed_other)
|
28
|
+
dummy_class = dummy_class.include Atheneum.reverse :other
|
29
|
+
store = dummy_class.new
|
30
|
+
store.other = 'other'
|
31
|
+
assert_equal 'other'.reverse, store.send(:reversed_other)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_can_retrieve_a_other_reversed
|
35
|
+
dummy_class = Struct.new(:reversed_other)
|
36
|
+
dummy_class = dummy_class.include Atheneum.reverse :other
|
37
|
+
store = dummy_class.new 'other'.reverse
|
38
|
+
assert_equal 'other', store.other
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_can_store_a_item_upper_cased
|
42
|
+
dummy_class = Struct.new(:upper_cased_item)
|
43
|
+
dummy_class = dummy_class.include Atheneum.upper_case :item
|
44
|
+
store = dummy_class.new
|
45
|
+
store.item = 'item'
|
46
|
+
assert_equal 'item'.upcase, store.send(:upper_cased_item)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_can_retrieve_a_item_upper_cased
|
50
|
+
dummy_class = Struct.new(:upper_cased_item)
|
51
|
+
dummy_class = dummy_class.include Atheneum.upper_case :item
|
52
|
+
store = dummy_class.new 'item'.upcase
|
53
|
+
assert_equal 'item', store.item
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_can_include_multiple_strategies
|
57
|
+
dummy_class = Struct.new(:upper_cased_item, :reversed_other)
|
58
|
+
dummy_class = dummy_class.include Atheneum.upper_case :item
|
59
|
+
dummy_class = dummy_class.include Atheneum.reverse :other
|
60
|
+
store = dummy_class.new 'item'.upcase, 'password'.reverse
|
61
|
+
assert_equal 'item', store.item
|
62
|
+
assert_equal 'password', store.other
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_method_missing_doesnt_affect_host_class
|
66
|
+
dummy_class = Struct.new(:reversed_password)
|
67
|
+
dummy_class = dummy_class.include Atheneum.reverse :password
|
68
|
+
assert_raises NoMethodError do
|
69
|
+
dummy_class.blah
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_privatizes_storage_methods
|
74
|
+
dummy_class = Struct.new(:reversed_password)
|
75
|
+
dummy_class = dummy_class.include Atheneum.reverse :password
|
76
|
+
store = dummy_class.new
|
77
|
+
assert_raises NoMethodError do
|
78
|
+
store.reversed_password
|
79
|
+
end
|
80
|
+
assert_raises NoMethodError do
|
81
|
+
store.reversed_password = 3
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_privatizes_storage_methods_diff
|
86
|
+
dummy_class = Struct.new(:upper_cased_item)
|
87
|
+
dummy_class = dummy_class.include Atheneum.upper_case :item
|
88
|
+
store = dummy_class.new
|
89
|
+
assert_raises NoMethodError do
|
90
|
+
store.upper_cased_item
|
91
|
+
end
|
92
|
+
assert_raises NoMethodError do
|
93
|
+
store.upper_cased_item = 3
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_doesnt_privatizes_storage_methods_diff_on_option
|
98
|
+
dummy_class = Struct.new(:upper_cased_item)
|
99
|
+
dummy_class = dummy_class.include Atheneum.upper_case :item, :privatise => false
|
100
|
+
store = dummy_class.new
|
101
|
+
store.upper_cased_item
|
102
|
+
store.upper_cased_item = 3
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_can_overwrite_prefix
|
106
|
+
dummy_class = Struct.new(:random_password)
|
107
|
+
dummy_class = dummy_class.include Atheneum.reverse :password, :prefix => :random
|
108
|
+
store = dummy_class.new
|
109
|
+
store.password = 'password'
|
110
|
+
assert_equal 'password'.reverse, store.send(:random_password)
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'bcrypt'
|
2
|
+
require_relative '../test_config'
|
3
|
+
|
4
|
+
BCrypt::Engine.cost = 1
|
5
|
+
|
6
|
+
class BcryptTest < MiniTest::Test
|
7
|
+
def strategy(options={})
|
8
|
+
@strategy = Atheneum::Strategy::Crypt.new options
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
@strategy = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_hashes_saved_string
|
16
|
+
BCrypt::Password.stub :create, 'hashed' do
|
17
|
+
assert_equal 'hashed', strategy.pack('string')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_returns_saved_item
|
22
|
+
assert_equal strategy.unpack(BCrypt::Password.create('password').to_s), 'password'
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_stored_attribute_prefixed_with_crypted
|
26
|
+
assert_equal 'crypted_password', strategy.store_for(:password)
|
27
|
+
end
|
28
|
+
end
|
data/test/test_config.rb
ADDED
metadata
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: atheneum
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
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.4.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.4.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-reporters
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.0.6
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.0.6
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bcrypt
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 3.1.9
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 3.1.9
|
83
|
+
description: "Simply declare attributes that require obscuring and that will make
|
84
|
+
it so.\n Useful in exposing buisness logic in objects that
|
85
|
+
use BCrypt\n This gem currently assumes that BCrypt is
|
86
|
+
available rather than adding it as a dependency,\n future
|
87
|
+
versions might support general strategies.\n "
|
88
|
+
email:
|
89
|
+
- peterhsaxton@gmail.com
|
90
|
+
executables: []
|
91
|
+
extensions: []
|
92
|
+
extra_rdoc_files: []
|
93
|
+
files:
|
94
|
+
- ".gitignore"
|
95
|
+
- Gemfile
|
96
|
+
- LICENSE.txt
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- atheneum.gemspec
|
100
|
+
- lib/atheneum.rb
|
101
|
+
- lib/atheneum/errors.rb
|
102
|
+
- lib/atheneum/storage.rb
|
103
|
+
- lib/atheneum/strategy.rb
|
104
|
+
- lib/atheneum/strategy/base.rb
|
105
|
+
- lib/atheneum/strategy/crypt.rb
|
106
|
+
- lib/atheneum/strategy/reverse.rb
|
107
|
+
- lib/atheneum/strategy/upper_case.rb
|
108
|
+
- lib/atheneum/version.rb
|
109
|
+
- tasks/test.rake
|
110
|
+
- test/atheneum/atheneum_test.rb
|
111
|
+
- test/strategy/crypt_test.rb
|
112
|
+
- test/test_config.rb
|
113
|
+
homepage: ''
|
114
|
+
licenses:
|
115
|
+
- MIT
|
116
|
+
metadata: {}
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
requirements: []
|
132
|
+
rubyforge_project:
|
133
|
+
rubygems_version: 2.2.2
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: A micro gem for the immaculate inclusion of BCrypt protected data for example
|
137
|
+
passwords
|
138
|
+
test_files:
|
139
|
+
- test/atheneum/atheneum_test.rb
|
140
|
+
- test/strategy/crypt_test.rb
|
141
|
+
- test/test_config.rb
|