dm-is-authenticatable 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.md +8 -0
- data/Gemfile +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +15 -12
- data/Rakefile +2 -2
- data/gemspec.yml +2 -2
- data/lib/dm-is-authenticatable/is/authenticatable.rb +34 -23
- data/spec/integration/authenticatable_spec.rb +67 -29
- metadata +49 -16
data/ChangeLog.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
### 0.2.0 / 2012-10-06
|
2
|
+
|
3
|
+
* Added {DataMapper::Is::Authenticatable::InstanceMethods#password_required?}.
|
4
|
+
* Added {DataMapper::Is::Authenticatable::InstanceMethods#has_password?}.
|
5
|
+
* {DataMapper::Is::Authenticatable::ClassMethods#authenticate}:
|
6
|
+
* Simply return `nil` instead of raising exceptions in
|
7
|
+
* Support authenticating models without encrypted passwords.
|
8
|
+
|
1
9
|
### 0.1.2 / 2011-10-26
|
2
10
|
|
3
11
|
* Require bcrypt-ruby ~> 3.0, >= 2.1.0.
|
data/Gemfile
CHANGED
@@ -88,16 +88,16 @@ DO_VERSION = '~> 0.10.2'
|
|
88
88
|
DM_DO_ADAPTERS = %w[ sqlite postgres mysql oracle sqlserver ]
|
89
89
|
RAILS = 'http://github.com/rails/rails.git'
|
90
90
|
|
91
|
-
gem 'bcrypt-ruby', '~> 2.1'
|
91
|
+
gem 'bcrypt-ruby', ['~> 3.0', '>= 2.1']
|
92
92
|
|
93
93
|
gem 'dm-core', DM_VERSION, :git => "#{DATAMAPPER}/dm-core.git"
|
94
94
|
gem 'dm-types', DM_VERSION, :git => "#{DATAMAPPER}/dm-types.git"
|
95
95
|
gem 'dm-validations', DM_VERSION, :git => "#{DATAMAPPER}/dm-validations.git"
|
96
96
|
|
97
97
|
group :development do
|
98
|
-
gem 'rake',
|
99
|
-
gem '
|
100
|
-
gem 'rspec',
|
98
|
+
gem 'rake', '~> 0.8'
|
99
|
+
gem 'rubygems-tasks', '~> 0.1'
|
100
|
+
gem 'rspec', '~> 2.4'
|
101
101
|
|
102
102
|
gem 'kramdown', '~> 0.12'
|
103
103
|
gem 'yard', '~> 0.7'
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
# dm-is-authenticatable
|
2
2
|
|
3
|
-
* [Source](
|
4
|
-
* [Issues](
|
3
|
+
* [Source](https://github.com/postmodern/dm-is-authenticatable)
|
4
|
+
* [Issues](https://github.com/postmodern/dm-is-authenticatable/issues)
|
5
5
|
* [Documentation](http://rubydoc.info/gems/dm-is-authenticatable/frames)
|
6
6
|
* [Email](mailto:postmodern.mod3 at gmail.com)
|
7
7
|
|
8
8
|
## Description
|
9
9
|
|
10
10
|
A DataMapper plugin for adding authentication and encrypted passwords to
|
11
|
-
your DataMapper models. Ideal for use with
|
12
|
-
[warden]
|
13
|
-
[sinatra_warden](http://github.com/jsmestad/sinatra_warden).
|
11
|
+
your DataMapper models. Ideal for use with [warden], [sinatra_warden] or
|
12
|
+
[padrino-warden].
|
14
13
|
|
15
14
|
## Example
|
16
15
|
|
@@ -59,7 +58,7 @@ Handles finding and authenticating resources in the database:
|
|
59
58
|
User.authenticate(:name => 'bob', :password => 'secret')
|
60
59
|
# => #<User: ...>
|
61
60
|
|
62
|
-
Using dm-is-authenticatable with [
|
61
|
+
Using dm-is-authenticatable with [warden]:
|
63
62
|
|
64
63
|
Warden::Manager.serialize_into_session { |user| user.id }
|
65
64
|
Warden::Manager.serialize_from_session { |id| User.get(id) }
|
@@ -72,7 +71,7 @@ Using dm-is-authenticatable with [Warden](http://github.com/hassox/warden#readme
|
|
72
71
|
|
73
72
|
def authenticate!
|
74
73
|
attributes = {
|
75
|
-
:name
|
74
|
+
:name => params['name'],
|
76
75
|
:password => params['password']
|
77
76
|
}
|
78
77
|
|
@@ -86,10 +85,10 @@ Using dm-is-authenticatable with [Warden](http://github.com/hassox/warden#readme
|
|
86
85
|
|
87
86
|
## Requirements
|
88
87
|
|
89
|
-
* [bcrypt-ruby](
|
90
|
-
* [dm-core](
|
91
|
-
* [dm-types](
|
92
|
-
* [dm-validations](
|
88
|
+
* [bcrypt-ruby](https://github.com/codahale/bcrypt-ruby#readme) ~> 3.0, >= 2.1.0
|
89
|
+
* [dm-core](https://github.com/datamapper/dm-core#readme) ~> 1.0
|
90
|
+
* [dm-types](https://github.com/datamapper/dm-types#readme) ~> 1.0
|
91
|
+
* [dm-validations](https://github.com/datamapper/dm-validations#readme) ~> 1.0
|
93
92
|
|
94
93
|
## Install
|
95
94
|
|
@@ -97,6 +96,10 @@ Using dm-is-authenticatable with [Warden](http://github.com/hassox/warden#readme
|
|
97
96
|
|
98
97
|
## License
|
99
98
|
|
100
|
-
Copyright (c) 2010-
|
99
|
+
Copyright (c) 2010-2012 Hal Brodigan
|
101
100
|
|
102
101
|
See {file:LICENSE.txt} for license information.
|
102
|
+
|
103
|
+
[warden]: https://github.com/hassox/warden#readme
|
104
|
+
[sinatra_warden]: https://github.com/jsmestad/sinatra_warden#readme
|
105
|
+
[padrino-warden]: https://github.com/jondot/padrino-warden#readme
|
data/Rakefile
CHANGED
data/gemspec.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
name: dm-is-authenticatable
|
2
|
-
version: 0.
|
2
|
+
version: 0.2.0
|
3
3
|
summary: DataMapper plugin for adding authentication to models.
|
4
4
|
description:
|
5
5
|
A DataMapper plugin for adding authentication and encrypted passwords to
|
@@ -8,7 +8,7 @@ description:
|
|
8
8
|
license: MIT
|
9
9
|
authors: Postmodern
|
10
10
|
email: postmodern.mod3@gmail.com
|
11
|
-
homepage:
|
11
|
+
homepage: https://github.com/postmodern/dm-is-authenticatable#readme
|
12
12
|
has_yard: true
|
13
13
|
|
14
14
|
dependencies:
|
@@ -4,13 +4,10 @@ require 'dm-validations'
|
|
4
4
|
module DataMapper
|
5
5
|
module Is
|
6
6
|
module Authenticatable
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
def is_authenticatable
|
7
|
+
def is_authenticatable(options={})
|
11
8
|
# The encrypted password
|
12
9
|
property :encrypted_password, DataMapper::Property::BCryptHash
|
13
|
-
|
10
|
+
|
14
11
|
extend DataMapper::Is::Authenticatable::ClassMethods
|
15
12
|
include DataMapper::Is::Authenticatable::InstanceMethods
|
16
13
|
|
@@ -27,29 +24,16 @@ module DataMapper
|
|
27
24
|
# @option attributes [String] :password
|
28
25
|
# The clear-text password to authenticate with.
|
29
26
|
#
|
30
|
-
# @return [DataMapper::Resource]
|
31
|
-
# The authenticated resource.
|
32
|
-
#
|
33
|
-
# @raise [UnknownResource]
|
34
|
-
# The authenticatable resource could not be found in the repository.
|
35
|
-
#
|
36
|
-
# @raise [ArgumentError]
|
37
|
-
# The `:password` option was not specified.
|
27
|
+
# @return [DataMapper::Resource, nil]
|
28
|
+
# The authenticated resource. If the resource could not be found,
|
29
|
+
# or the password did not match, `nil` will be returned.
|
38
30
|
#
|
39
31
|
def authenticate(attributes)
|
40
32
|
password = attributes.delete(:password)
|
41
33
|
resource = self.first(attributes)
|
42
34
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
unless password
|
48
|
-
raise(ArgumentError,"must specify the :password option",caller)
|
49
|
-
end
|
50
|
-
|
51
|
-
if resource.encrypted_password == password
|
52
|
-
resource
|
35
|
+
if (resource && resource.has_password?(password))
|
36
|
+
return resource
|
53
37
|
end
|
54
38
|
end
|
55
39
|
end
|
@@ -74,6 +58,33 @@ module DataMapper
|
|
74
58
|
self.encrypted_password = new_password
|
75
59
|
@password = new_password
|
76
60
|
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Determines if a password is required for authentication.
|
64
|
+
#
|
65
|
+
# @return [Boolean]
|
66
|
+
# Specifies whether a password is required or not.
|
67
|
+
#
|
68
|
+
# @since 0.2.0
|
69
|
+
#
|
70
|
+
def password_required?
|
71
|
+
!self.encrypted_password.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Determines if the submitted password matches the `encrypted_password`.
|
76
|
+
#
|
77
|
+
# @param [String] submitted_password
|
78
|
+
# The submitted password.
|
79
|
+
#
|
80
|
+
# @return [Boolean]
|
81
|
+
# Specifies whether the submitted password matches.
|
82
|
+
#
|
83
|
+
# @since 0.2.0
|
84
|
+
#
|
85
|
+
def has_password?(submitted_password)
|
86
|
+
!password_required? || (self.encrypted_password == submitted_password)
|
87
|
+
end
|
77
88
|
end
|
78
89
|
end
|
79
90
|
end
|
@@ -3,9 +3,7 @@ require 'spec_helper'
|
|
3
3
|
require 'integration/models/user'
|
4
4
|
|
5
5
|
describe DataMapper::Is::Authenticatable do
|
6
|
-
before(:all)
|
7
|
-
User.auto_migrate!
|
8
|
-
end
|
6
|
+
before(:all) { User.auto_migrate! }
|
9
7
|
|
10
8
|
let(:password) { 'secret' }
|
11
9
|
|
@@ -15,41 +13,80 @@ describe DataMapper::Is::Authenticatable do
|
|
15
13
|
subject.class.properties.should be_named(:encrypted_password)
|
16
14
|
end
|
17
15
|
|
18
|
-
|
19
|
-
subject.password
|
20
|
-
end
|
16
|
+
describe "validations" do
|
17
|
+
before { subject.password = password }
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
it "should require password confirmation" do
|
20
|
+
subject.should_not be_valid
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should require the confirmation password match the password" do
|
24
|
+
subject.password_confirmation = 'fail'
|
25
|
+
|
26
|
+
subject.should_not be_valid
|
27
|
+
end
|
25
28
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
it "should confirmed both passwords" do
|
30
|
+
subject.password_confirmation = password
|
31
|
+
|
32
|
+
subject.should be_valid
|
33
|
+
end
|
29
34
|
end
|
30
35
|
|
31
|
-
|
32
|
-
|
33
|
-
|
36
|
+
describe "#password" do
|
37
|
+
it "should not have a default password" do
|
38
|
+
subject.password.should be_nil
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should allow setting the password" do
|
42
|
+
subject.password = password
|
43
|
+
subject.password.should == password
|
44
|
+
end
|
34
45
|
end
|
35
46
|
|
36
|
-
|
37
|
-
|
38
|
-
|
47
|
+
describe "#password_required?" do
|
48
|
+
context "when encrypted_password is nil" do
|
49
|
+
before { subject.encrypted_password = nil }
|
50
|
+
|
51
|
+
it "should return false" do
|
52
|
+
subject.should_not be_password_required
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when encrypted_password is set" do
|
57
|
+
before { subject.password = password }
|
58
|
+
|
59
|
+
it "should return true" do
|
60
|
+
subject.should be_password_required
|
61
|
+
end
|
62
|
+
end
|
39
63
|
end
|
40
64
|
|
41
|
-
|
42
|
-
subject.password = password
|
43
|
-
|
65
|
+
describe "#has_password?" do
|
66
|
+
before { subject.password = password }
|
67
|
+
|
68
|
+
it "should compare the plain-text password against #encrypted_password" do
|
69
|
+
subject.should have_password(password)
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when #password_required? is false" do
|
73
|
+
before { subject.stub(:password_required?).and_return(false) }
|
44
74
|
|
45
|
-
|
75
|
+
it "should return true" do
|
76
|
+
subject.should have_password('does not matter')
|
77
|
+
end
|
78
|
+
end
|
46
79
|
end
|
47
80
|
|
48
|
-
|
49
|
-
|
50
|
-
|
81
|
+
describe "#encrypted_password" do
|
82
|
+
it "should not have an encrypted password by default" do
|
83
|
+
subject.encrypted_password.should be_nil
|
84
|
+
end
|
51
85
|
|
52
|
-
|
86
|
+
it "should update the encrypted password when setting the password" do
|
87
|
+
subject.password = password
|
88
|
+
subject.encrypted_password.should == password
|
89
|
+
end
|
53
90
|
end
|
54
91
|
|
55
92
|
describe "authenticate" do
|
@@ -64,13 +101,14 @@ describe DataMapper::Is::Authenticatable do
|
|
64
101
|
subject { User }
|
65
102
|
|
66
103
|
it "should not allow authenticating with unknown resources" do
|
67
|
-
|
68
|
-
|
69
|
-
|
104
|
+
user = subject.authenticate(:name => 'alice', :password => password)
|
105
|
+
|
106
|
+
user.should be_nil
|
70
107
|
end
|
71
108
|
|
72
109
|
it "should allow authenticating with a password" do
|
73
110
|
user = subject.authenticate(:name => name, :password => password)
|
111
|
+
|
74
112
|
user.name.should == name
|
75
113
|
end
|
76
114
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-is-authenticatable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-10-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bcrypt-ruby
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -24,10 +24,18 @@ dependencies:
|
|
24
24
|
version: 2.1.0
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
|
-
version_requirements:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.0'
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 2.1.0
|
28
36
|
- !ruby/object:Gem::Dependency
|
29
37
|
name: dm-core
|
30
|
-
requirement:
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
31
39
|
none: false
|
32
40
|
requirements:
|
33
41
|
- - ~>
|
@@ -35,10 +43,15 @@ dependencies:
|
|
35
43
|
version: '1.0'
|
36
44
|
type: :runtime
|
37
45
|
prerelease: false
|
38
|
-
version_requirements:
|
46
|
+
version_requirements: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ~>
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '1.0'
|
39
52
|
- !ruby/object:Gem::Dependency
|
40
53
|
name: dm-types
|
41
|
-
requirement:
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
42
55
|
none: false
|
43
56
|
requirements:
|
44
57
|
- - ~>
|
@@ -46,10 +59,15 @@ dependencies:
|
|
46
59
|
version: '1.0'
|
47
60
|
type: :runtime
|
48
61
|
prerelease: false
|
49
|
-
version_requirements:
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ~>
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '1.0'
|
50
68
|
- !ruby/object:Gem::Dependency
|
51
69
|
name: dm-validations
|
52
|
-
requirement:
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
53
71
|
none: false
|
54
72
|
requirements:
|
55
73
|
- - ~>
|
@@ -57,10 +75,15 @@ dependencies:
|
|
57
75
|
version: '1.0'
|
58
76
|
type: :runtime
|
59
77
|
prerelease: false
|
60
|
-
version_requirements:
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ~>
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '1.0'
|
61
84
|
- !ruby/object:Gem::Dependency
|
62
85
|
name: bundler
|
63
|
-
requirement:
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
64
87
|
none: false
|
65
88
|
requirements:
|
66
89
|
- - ~>
|
@@ -68,10 +91,15 @@ dependencies:
|
|
68
91
|
version: '1.0'
|
69
92
|
type: :development
|
70
93
|
prerelease: false
|
71
|
-
version_requirements:
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ~>
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '1.0'
|
72
100
|
- !ruby/object:Gem::Dependency
|
73
101
|
name: yard
|
74
|
-
requirement:
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
75
103
|
none: false
|
76
104
|
requirements:
|
77
105
|
- - ~>
|
@@ -79,7 +107,12 @@ dependencies:
|
|
79
107
|
version: '0.7'
|
80
108
|
type: :development
|
81
109
|
prerelease: false
|
82
|
-
version_requirements:
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ~>
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0.7'
|
83
116
|
description: A DataMapper plugin for adding authentication and encrypted passwords
|
84
117
|
to your DataMapper models.
|
85
118
|
email: postmodern.mod3@gmail.com
|
@@ -105,7 +138,7 @@ files:
|
|
105
138
|
- spec/integration/authenticatable_spec.rb
|
106
139
|
- spec/integration/models/user.rb
|
107
140
|
- spec/spec_helper.rb
|
108
|
-
homepage:
|
141
|
+
homepage: https://github.com/postmodern/dm-is-authenticatable#readme
|
109
142
|
licenses:
|
110
143
|
- MIT
|
111
144
|
post_install_message:
|
@@ -126,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
159
|
version: '0'
|
127
160
|
requirements: []
|
128
161
|
rubyforge_project:
|
129
|
-
rubygems_version: 1.8.
|
162
|
+
rubygems_version: 1.8.24
|
130
163
|
signing_key:
|
131
164
|
specification_version: 3
|
132
165
|
summary: DataMapper plugin for adding authentication to models.
|