attr_password 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 +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:
|