attr_password 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/Gemfile +3 -0
- data/Rakefile +6 -0
- data/attr_password.gemspec +29 -0
- data/bin/console +8 -0
- data/bin/setup +6 -0
- data/lib/attr_password.rb +81 -0
- data/lib/attr_password/adapters.rb +60 -0
- data/lib/attr_password/adapters/active_record.rb +63 -0
- data/lib/attr_password/adapters/base.rb +57 -0
- data/lib/attr_password/adapters/ruby.rb +27 -0
- data/lib/attr_password/bcrypt.rb +44 -0
- data/lib/attr_password/constants.rb +3 -0
- data/lib/attr_password/des.rb +40 -0
- data/lib/attr_password/md5.rb +40 -0
- data/lib/attr_password/sha256.rb +40 -0
- data/lib/attr_password/sha512.rb +40 -0
- data/spec/matchers/version.rb +21 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/unit/attr_password_spec.rb +11 -0
- metadata +152 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 12f7073d0568e2ee43eec82a4e70aaeca7b37178
|
4
|
+
data.tar.gz: b763a893e3545fa58010056bd821d3e4a1cc79a2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d56419de3d7969899236100484b99707fe97e032da24e252257923b1dd928407f0d845d1e4671c0537ea295d032c951458d1fd4cb30079a38ed30841959117aa
|
7
|
+
data.tar.gz: 08f5939ed8163a4ea99a021282d0d093a40895eba070c9a42c3ed8a5628dc4a86d57dcd21ab24cfd9cbf33437b10c9ad578ff0f044b0f3a75c9792376abb8cb2
|
data/.gitignore
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# OS Files #
|
2
|
+
############
|
3
|
+
.DS_Store
|
4
|
+
.Trashes
|
5
|
+
ehthumbs.db
|
6
|
+
Icon?
|
7
|
+
Thumbs.db
|
8
|
+
|
9
|
+
# Ruby Files #
|
10
|
+
##############
|
11
|
+
/Gemfile.lock
|
12
|
+
/.bundle/
|
13
|
+
/.yardoc
|
14
|
+
/_yardoc/
|
15
|
+
/coverage/
|
16
|
+
/doc/
|
17
|
+
/pkg/
|
18
|
+
/tmp/
|
19
|
+
/spec/reports/
|
20
|
+
/vendor/bundle/
|
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'attr_password/constants'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'attr_password'
|
8
|
+
spec.version = AttrPassword::VERSION
|
9
|
+
spec.authors = ['Rediweb Hosting']
|
10
|
+
spec.email = ['support@rediwebhosting.uk']
|
11
|
+
|
12
|
+
spec.summary = %q{Password Attribute}
|
13
|
+
spec.description = %q{Store passwords securely.}
|
14
|
+
spec.homepage = 'https://rubygems.org/gems/attr_password'
|
15
|
+
spec.license = 'GPL-3.0'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/(?!((console|setup)$))}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_dependency 'activerecord', '~> 4.2'
|
23
|
+
spec.add_dependency 'bcrypt', '~> 3.1'
|
24
|
+
spec.add_dependency 'unix-crypt', '~> 1.3'
|
25
|
+
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
29
|
+
end
|
data/bin/console
ADDED
data/bin/setup
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# The password attribute module
|
2
|
+
#
|
3
|
+
module AttrPassword
|
4
|
+
class << self
|
5
|
+
# Require dependencies
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
# >> AttrPassword.require!
|
9
|
+
# => nil
|
10
|
+
#
|
11
|
+
def require!
|
12
|
+
require 'bcrypt'
|
13
|
+
require 'unix_crypt'
|
14
|
+
|
15
|
+
require 'attr_password/constants'
|
16
|
+
require 'attr_password/adapters'
|
17
|
+
|
18
|
+
require 'attr_password/bcrypt'
|
19
|
+
require 'attr_password/sha512'
|
20
|
+
require 'attr_password/sha256'
|
21
|
+
require 'attr_password/md5'
|
22
|
+
require 'attr_password/des'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Add the password functionality
|
27
|
+
#
|
28
|
+
# Arguments:
|
29
|
+
# algorithm: (Symbol) (Default :bcrypt)
|
30
|
+
#
|
31
|
+
# Example:
|
32
|
+
# >> class Test
|
33
|
+
# >> has_password :bcrypt
|
34
|
+
# >> end
|
35
|
+
#
|
36
|
+
def has_password(algorithm = :bcrypt)
|
37
|
+
# Get the backend crypt class
|
38
|
+
backend = case algorithm
|
39
|
+
when :bcrypt
|
40
|
+
AttrPassword::BCrypt.new
|
41
|
+
when :sha512
|
42
|
+
AttrPassword::SHA512.new
|
43
|
+
when :sha256
|
44
|
+
AttrPassword::SHA256.new
|
45
|
+
when :md5
|
46
|
+
AttrPassword::MD5.new
|
47
|
+
when :des
|
48
|
+
AttrPassword::DES.new
|
49
|
+
else
|
50
|
+
return false
|
51
|
+
end
|
52
|
+
|
53
|
+
define_method("password=") do |password|
|
54
|
+
# Get the adapter
|
55
|
+
adapter = AttrPassword::Adapters.for(self)
|
56
|
+
|
57
|
+
# Get the crypted password
|
58
|
+
crypted_password = password ? backend.crypt_password(password) : nil
|
59
|
+
|
60
|
+
# Set the password hash
|
61
|
+
adapter.write_attribute(:crypted_password, crypted_password)
|
62
|
+
end
|
63
|
+
|
64
|
+
define_method("valid_password?") do |password|
|
65
|
+
# Ensure the password is not nil
|
66
|
+
return false if password.nil?
|
67
|
+
|
68
|
+
# Get the adapter
|
69
|
+
adapter = AttrPassword::Adapters.for(self)
|
70
|
+
|
71
|
+
# Check if the password is valid
|
72
|
+
backend.validate_password(password, crypted_password)
|
73
|
+
end
|
74
|
+
|
75
|
+
true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Require dependencies
|
80
|
+
#
|
81
|
+
AttrPassword.require!
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module AttrPassword
|
2
|
+
# This module contains the adapters
|
3
|
+
#
|
4
|
+
module Adapters
|
5
|
+
class << self
|
6
|
+
# Require the adapters
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# >> AttrPassword::Adapters.require!
|
10
|
+
# => true
|
11
|
+
#
|
12
|
+
def require!
|
13
|
+
require 'attr_password/adapters/base'
|
14
|
+
|
15
|
+
# Get the glob for the adapters directory
|
16
|
+
adapters_glob = File.expand_path('../adapters/**/*.rb', __FILE__)
|
17
|
+
|
18
|
+
# Loop over each adapter file
|
19
|
+
Dir.glob(adapters_glob).each do |adapter|
|
20
|
+
# Require the adapter file
|
21
|
+
require(adapter)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Find the best adapter for an object
|
26
|
+
#
|
27
|
+
# Arguments:
|
28
|
+
# object: (Object)
|
29
|
+
#
|
30
|
+
# Example:
|
31
|
+
# >> AttrPassword::Adapters.for(object)
|
32
|
+
# => #<AttrPassword::Adapters::Ruby:0x00000000000000>
|
33
|
+
#
|
34
|
+
def for(object)
|
35
|
+
# The list of all adapters
|
36
|
+
adapters = [
|
37
|
+
AttrPassword::Adapters::ActiveRecord,
|
38
|
+
AttrPassword::Adapters::Ruby
|
39
|
+
]
|
40
|
+
|
41
|
+
# Loop over each adapter
|
42
|
+
adapters.each do |klass|
|
43
|
+
# Create a new instance of the adapter
|
44
|
+
adapter = klass.new(object)
|
45
|
+
|
46
|
+
# Ensure the adapter is available
|
47
|
+
next unless adapter.available?
|
48
|
+
|
49
|
+
return adapter
|
50
|
+
end
|
51
|
+
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Require the adapters
|
59
|
+
#
|
60
|
+
AttrPassword::Adapters.require!
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module AttrPassword
|
2
|
+
module Adapters
|
3
|
+
# The ActiveRecord adapter
|
4
|
+
#
|
5
|
+
class ActiveRecord < Base
|
6
|
+
class << self
|
7
|
+
# Attempt to inject the AttrPassword class into ActiveRecord::Base
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# >> AttrPassword::Adapters::ActiveRecord.inject!
|
11
|
+
# => nil
|
12
|
+
#
|
13
|
+
def inject!
|
14
|
+
# Ensure the ActiveRecord::Base class is defined
|
15
|
+
return false unless defined?(::ActiveRecord::Base)
|
16
|
+
|
17
|
+
# Make the ActiveRecord::Base class extend the AttrPassword class
|
18
|
+
::ActiveRecord::Base.send(:extend, AttrPassword)
|
19
|
+
|
20
|
+
true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Check if this adapter can be used for the object
|
25
|
+
#
|
26
|
+
# Example:
|
27
|
+
# >> adapter.available?
|
28
|
+
# => true
|
29
|
+
#
|
30
|
+
def available?
|
31
|
+
# Ensure the ActiveRecord::Base class is defined
|
32
|
+
return false unless defined?(::ActiveRecord::Base)
|
33
|
+
|
34
|
+
# Check if the object inherits from ActiveRecord::Base
|
35
|
+
@object.class.ancestors.include?(::ActiveRecord::Base)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Read an attribute
|
39
|
+
#
|
40
|
+
# Example:
|
41
|
+
# >> adapter.read_attribute(:hello_world)
|
42
|
+
# => "Hello, World!"
|
43
|
+
#
|
44
|
+
def read_attribute(attribute)
|
45
|
+
@object.send(:read_attribute, attribute.to_sym)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Write an attribute
|
49
|
+
#
|
50
|
+
# Example:
|
51
|
+
# >> adapter.write_attribute(:hello_world, "Hello, World!")
|
52
|
+
# => true
|
53
|
+
#
|
54
|
+
def write_attribute(attribute, value)
|
55
|
+
@object.send(:write_attribute, attribute, value)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Attempt to inject the AttrPassword class into ActiveRecord::Base
|
62
|
+
#
|
63
|
+
AttrPassword::Adapters::ActiveRecord.inject!
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module AttrPassword
|
2
|
+
module Adapters
|
3
|
+
# The base adapter
|
4
|
+
#
|
5
|
+
class Base
|
6
|
+
# The object the adapter relates to
|
7
|
+
#
|
8
|
+
attr_reader :object
|
9
|
+
|
10
|
+
# Create a new instance of this adapter
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
# >> AttrPassword::Adapters::Base.new(object)
|
14
|
+
# => #<AttrPassword::Adapters::Base:0x00000000000000>
|
15
|
+
#
|
16
|
+
def initialize(object)
|
17
|
+
# Ensure the object exists
|
18
|
+
unless object
|
19
|
+
raise 'The object property cannot be nil.'
|
20
|
+
end
|
21
|
+
|
22
|
+
# Store the object
|
23
|
+
@object = object
|
24
|
+
end
|
25
|
+
|
26
|
+
# Check if this adapter can be used for the object
|
27
|
+
#
|
28
|
+
# Example:
|
29
|
+
# >> adapter.available?
|
30
|
+
# => true
|
31
|
+
#
|
32
|
+
def available?
|
33
|
+
true
|
34
|
+
end
|
35
|
+
|
36
|
+
# Read an attribute
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
# >> adapter.read_attribute(:hello_world)
|
40
|
+
# => "Hello, World!"
|
41
|
+
#
|
42
|
+
def read_attribute(attribute, value)
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
# Write an attribute
|
47
|
+
#
|
48
|
+
# Example:
|
49
|
+
# >> adapter.write_attribute(:hello_world, "Hello, World!")
|
50
|
+
# => true
|
51
|
+
#
|
52
|
+
def write_attribute(attribute, value)
|
53
|
+
false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module AttrPassword
|
2
|
+
module Adapters
|
3
|
+
# The ActiveRecord adapter
|
4
|
+
#
|
5
|
+
class Ruby < Base
|
6
|
+
# Read an attribute
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# >> adapter.read_attribute(:hello_world)
|
10
|
+
# => "Hello, World!"
|
11
|
+
#
|
12
|
+
def read_attribute(attribute)
|
13
|
+
@object.instance_variable_get("@#{attribute}")
|
14
|
+
end
|
15
|
+
|
16
|
+
# Write an attribute
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
# >> adapter.write_attribute(:hello_world, "Hello, World!")
|
20
|
+
# => true
|
21
|
+
#
|
22
|
+
def write_attribute(attribute, value)
|
23
|
+
@object.instance_variable_set("@#{attribute}", value)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module AttrPassword
|
2
|
+
# The BCrypt class
|
3
|
+
#
|
4
|
+
class BCrypt
|
5
|
+
# Crypt the password
|
6
|
+
#
|
7
|
+
# Arguments:
|
8
|
+
# password: (String)
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
# >> backend.crypt_password("P@ssw0rd")
|
12
|
+
# => "$2a$10$Ou0no1.WrBtZm2rF4Te7getynnENc2wESKZDLyJTmqnSPV1TEXZ8y"
|
13
|
+
#
|
14
|
+
def crypt_password(password)
|
15
|
+
# Get the BCrypt password
|
16
|
+
bcrypt = ::BCrypt::Password.create(password)
|
17
|
+
|
18
|
+
# Get the BCrypt string
|
19
|
+
bcrypt.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
# Check if a password is valid
|
23
|
+
#
|
24
|
+
# Arguments:
|
25
|
+
# password_hash: (String)
|
26
|
+
# password: (String)
|
27
|
+
#
|
28
|
+
# Example:
|
29
|
+
# >> backend.crypt_password("P@ssw0rd", "$2a$10$Ou0no1.WrBtZm2rF4Te7getynnENc2wESKZDLyJTmqnSPV1TEXZ8y")
|
30
|
+
# => true
|
31
|
+
#
|
32
|
+
def validate_password(password, password_hash)
|
33
|
+
begin
|
34
|
+
# Load the BCrypt password hash
|
35
|
+
bcrypt = ::BCrypt::Password.new(password_hash)
|
36
|
+
|
37
|
+
# Check if the password is valid
|
38
|
+
bcrypt == password
|
39
|
+
rescue => e
|
40
|
+
return false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module AttrPassword
|
2
|
+
# The DES class
|
3
|
+
#
|
4
|
+
class DES
|
5
|
+
# Crypt the password
|
6
|
+
#
|
7
|
+
# Arguments:
|
8
|
+
# password: (String)
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
# >> backend.crypt_password("P@ssw0rd")
|
12
|
+
# => "5F9dBJsU0KiKQ"
|
13
|
+
#
|
14
|
+
def crypt_password(password)
|
15
|
+
# Get the DES crypt password
|
16
|
+
UnixCrypt::DES.build(password)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Check if a password is valid
|
20
|
+
#
|
21
|
+
# Arguments:
|
22
|
+
# password_hash: (String)
|
23
|
+
# password: (String)
|
24
|
+
#
|
25
|
+
# Example:
|
26
|
+
# >> backend.crypt_password("P@ssw0rd", "5F9dBJsU0KiKQ")
|
27
|
+
# => true
|
28
|
+
#
|
29
|
+
def validate_password(password, password_hash)
|
30
|
+
# Ensure the password is set
|
31
|
+
return false unless password
|
32
|
+
|
33
|
+
# Ensure the password hash is set
|
34
|
+
return false unless password_hash
|
35
|
+
|
36
|
+
# Check if the password is valid
|
37
|
+
UnixCrypt.valid?(password, password_hash)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module AttrPassword
|
2
|
+
# The MD5 class
|
3
|
+
#
|
4
|
+
class MD5
|
5
|
+
# Crypt the password
|
6
|
+
#
|
7
|
+
# Arguments:
|
8
|
+
# password: (String)
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
# >> backend.crypt_password("P@ssw0rd")
|
12
|
+
# => "$1$zKiCUMIJ$9w79XD.6T1tQZ3xF2ztcK."
|
13
|
+
#
|
14
|
+
def crypt_password(password)
|
15
|
+
# Get the MD5 crypt password
|
16
|
+
UnixCrypt::MD5.build(password)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Check if a password is valid
|
20
|
+
#
|
21
|
+
# Arguments:
|
22
|
+
# password_hash: (String)
|
23
|
+
# password: (String)
|
24
|
+
#
|
25
|
+
# Example:
|
26
|
+
# >> backend.crypt_password("P@ssw0rd", "$1$zKiCUMIJ$9w79XD.6T1tQZ3xF2ztcK.")
|
27
|
+
# => true
|
28
|
+
#
|
29
|
+
def validate_password(password, password_hash)
|
30
|
+
# Ensure the password is set
|
31
|
+
return false unless password
|
32
|
+
|
33
|
+
# Ensure the password hash is set
|
34
|
+
return false unless password_hash
|
35
|
+
|
36
|
+
# Check if the password is valid
|
37
|
+
UnixCrypt.valid?(password, password_hash)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module AttrPassword
|
2
|
+
# The SHA256 class
|
3
|
+
#
|
4
|
+
class SHA256
|
5
|
+
# Crypt the password
|
6
|
+
#
|
7
|
+
# Arguments:
|
8
|
+
# password: (String)
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
# >> backend.crypt_password("P@ssw0rd")
|
12
|
+
# => "$5$1zQaVXCHYfnNQALN$BKZbxVPaCnhgigMSLDMlmxSLPZHY1HBOEypeL3ZHfbD"
|
13
|
+
#
|
14
|
+
def crypt_password(password)
|
15
|
+
# Get the SHA256 crypt password
|
16
|
+
UnixCrypt::SHA256.build(password)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Check if a password is valid
|
20
|
+
#
|
21
|
+
# Arguments:
|
22
|
+
# password_hash: (String)
|
23
|
+
# password: (String)
|
24
|
+
#
|
25
|
+
# Example:
|
26
|
+
# >> backend.crypt_password("P@ssw0rd", "$5$1zQaVXCHYfnNQALN$BKZbxVPaCnhgigMSLDMlmxSLPZHY1HBOEypeL3ZHfbD")
|
27
|
+
# => true
|
28
|
+
#
|
29
|
+
def validate_password(password, password_hash)
|
30
|
+
# Ensure the password is set
|
31
|
+
return false unless password
|
32
|
+
|
33
|
+
# Ensure the password hash is set
|
34
|
+
return false unless password_hash
|
35
|
+
|
36
|
+
# Check if the password is valid
|
37
|
+
UnixCrypt.valid?(password, password_hash)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module AttrPassword
|
2
|
+
# The SHA512 class
|
3
|
+
#
|
4
|
+
class SHA512
|
5
|
+
# Crypt the password
|
6
|
+
#
|
7
|
+
# Arguments:
|
8
|
+
# password: (String)
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
# >> backend.crypt_password("P@ssw0rd")
|
12
|
+
# => "$6$x7NCbuLU4Bdr2SrU$qb.a9XG7AFszgj0qDO66Xce5pFI5eRcGhAyIrmylEuhYHIsyoCk6DKBOKW/eleMSjBuY10kgtS2zvicwLxZj91"
|
13
|
+
#
|
14
|
+
def crypt_password(password)
|
15
|
+
# Get the SHA512 crypt password
|
16
|
+
UnixCrypt::SHA512.build(password)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Check if a password is valid
|
20
|
+
#
|
21
|
+
# Arguments:
|
22
|
+
# password_hash: (String)
|
23
|
+
# password: (String)
|
24
|
+
#
|
25
|
+
# Example:
|
26
|
+
# >> backend.crypt_password("P@ssw0rd", "$6$x7NCbuLU4Bdr2SrU$qb.a9XG7AFszgj0qDO66Xce5pFI5eRcGhAyIrmylEuhYHIsyoCk6DKBOKW/eleMSjBuY10kgtS2zvicwLxZj91")
|
27
|
+
# => true
|
28
|
+
#
|
29
|
+
def validate_password(password, password_hash)
|
30
|
+
# Ensure the password is set
|
31
|
+
return false unless password
|
32
|
+
|
33
|
+
# Ensure the password hash is set
|
34
|
+
return false unless password_hash
|
35
|
+
|
36
|
+
# Check if the password is valid
|
37
|
+
UnixCrypt.valid?(password, password_hash)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module AttrPassword
|
2
|
+
module RSpec
|
3
|
+
module Matchers
|
4
|
+
module Version
|
5
|
+
extend ::RSpec::Matchers::DSL
|
6
|
+
|
7
|
+
matcher :be_semantic_version do
|
8
|
+
match do |string|
|
9
|
+
next false if "0.0.0" == string
|
10
|
+
|
11
|
+
string =~ /^[0-9]+\.[0-9]+\.[0-9]+$/
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message do |string|
|
15
|
+
"%s is not a semantic version" % string
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'attr_password'
|
3
|
+
|
4
|
+
Dir.glob(File.expand_path('../matchers/**/*.rb', __FILE__)).each do |matcher|
|
5
|
+
require(matcher)
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.expect_with :rspec do |expectations|
|
10
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
11
|
+
end
|
12
|
+
|
13
|
+
config.mock_with :rspec do |mocks|
|
14
|
+
mocks.verify_partial_doubles = true
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: attr_password
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rediweb Hosting
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
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: bcrypt
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: unix-crypt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
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: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.11'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.11'
|
97
|
+
description: Store passwords securely.
|
98
|
+
email:
|
99
|
+
- support@rediwebhosting.uk
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- Gemfile
|
106
|
+
- Rakefile
|
107
|
+
- attr_password.gemspec
|
108
|
+
- bin/console
|
109
|
+
- bin/setup
|
110
|
+
- lib/attr_password.rb
|
111
|
+
- lib/attr_password/adapters.rb
|
112
|
+
- lib/attr_password/adapters/active_record.rb
|
113
|
+
- lib/attr_password/adapters/base.rb
|
114
|
+
- lib/attr_password/adapters/ruby.rb
|
115
|
+
- lib/attr_password/bcrypt.rb
|
116
|
+
- lib/attr_password/constants.rb
|
117
|
+
- lib/attr_password/des.rb
|
118
|
+
- lib/attr_password/md5.rb
|
119
|
+
- lib/attr_password/sha256.rb
|
120
|
+
- lib/attr_password/sha512.rb
|
121
|
+
- spec/matchers/version.rb
|
122
|
+
- spec/spec_helper.rb
|
123
|
+
- spec/unit/attr_password_spec.rb
|
124
|
+
homepage: https://rubygems.org/gems/attr_password
|
125
|
+
licenses:
|
126
|
+
- GPL-3.0
|
127
|
+
metadata: {}
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
requirements: []
|
143
|
+
rubyforge_project:
|
144
|
+
rubygems_version: 2.5.1
|
145
|
+
signing_key:
|
146
|
+
specification_version: 4
|
147
|
+
summary: Password Attribute
|
148
|
+
test_files:
|
149
|
+
- spec/matchers/version.rb
|
150
|
+
- spec/spec_helper.rb
|
151
|
+
- spec/unit/attr_password_spec.rb
|
152
|
+
has_rdoc:
|