zero_auth 0.0.1.beta → 0.0.2.beta
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 +4 -4
- data/.rspec +3 -0
- data/.travis.yml +9 -0
- data/.yardopts +2 -0
- data/README.md +56 -2
- data/Rakefile +5 -1
- data/lib/zero_auth/model/password.rb +183 -0
- data/lib/zero_auth/password.rb +39 -0
- data/lib/zero_auth/utils.rb +31 -0
- data/lib/zero_auth/version.rb +1 -1
- data/lib/zero_auth.rb +12 -0
- data/spec/lib/zero_auth/model/password_spec.rb +86 -0
- data/spec/lib/zero_auth/password_spec.rb +31 -0
- data/spec/lib/zero_auth/utils_spec.rb +26 -0
- data/spec/spec_helper.rb +22 -0
- data/zero_auth.gemspec +7 -2
- metadata +82 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e5293b8a8a5c64cb80f819e0afc5fe0da191223
|
4
|
+
data.tar.gz: 52511c99d61691eaf31db9a9effb837ef285ed0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32125971bae43ce2cae06f9dab77afae3eb58daa9f834ad288024067facd7afff2d5c1a9793e2c8e881419c6e30809ea7076203fc7dc4937cff7b40e7cac8c3a
|
7
|
+
data.tar.gz: 84c2a65e27f0a4d64f642196fdff381fb76105141633b3400fe6882879c766ae13b92c2255d87919e0e531968264bc29a54e3673275a3feddf235d24cf9072c3
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
# ZeroAuth
|
1
|
+
# ZeroAuth [](https://travis-ci.org/bschaeffer/zero_auth) [](http://inch-ci.org/github/bschaeffer/zero_auth)
|
2
2
|
|
3
3
|
**Zero configuration** authentication starter for your Rails project.
|
4
4
|
|
5
|
+
* Docs: http://rdoc.info/github/bschaeffer/zero_auth
|
6
|
+
|
5
7
|
## Installation
|
6
8
|
|
7
9
|
Add this line to your application's Gemfile:
|
@@ -18,8 +20,60 @@ Or install it yourself as:
|
|
18
20
|
|
19
21
|
## Usage
|
20
22
|
|
21
|
-
|
23
|
+
### Models
|
24
|
+
|
25
|
+
#### `ZeroAuth::Model::Password`
|
26
|
+
|
27
|
+
* Docs: http://rdoc.info/github/bschaeffer/zero_auth/ZeroAuth/Model/Password
|
28
|
+
* Provides password salting and hashing using `BCrypt`.
|
29
|
+
* Instance method authentication.
|
30
|
+
* **Requires** `password_salt` and `password_hash` attributes.
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
class User
|
34
|
+
include ZeroAuth::Model::Password
|
35
|
+
attr_accessor :password_salt, :password_hash
|
36
|
+
end
|
37
|
+
|
38
|
+
user = User.new
|
39
|
+
user.password = 'password'
|
40
|
+
|
41
|
+
user.password_salt # => BCrypt::Engine.generate_salt
|
42
|
+
user.password_hash # => BCrypt::Password
|
43
|
+
|
44
|
+
user.has_password?('password') # => true
|
45
|
+
user.has_password?('pa$$w0rD') # => false
|
46
|
+
|
47
|
+
user.authenticate!('password') # => true
|
48
|
+
user.authenticate!('pa$$word') # => raises ZeroAuth::Unauthorized
|
49
|
+
```
|
50
|
+
|
51
|
+
##### Rails Setup
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
# migration
|
55
|
+
change_table :users do |t|
|
56
|
+
t.string :password_salt, null: false, default: ""
|
57
|
+
t.string :password_hash, null: false, default: ""
|
58
|
+
end
|
59
|
+
|
60
|
+
# model
|
61
|
+
class User < ActiveRecord::Base
|
62
|
+
include ZeroAuth::Model::Password
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
##### MongoMapper Setup
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
class User < ActiveRecord::Base
|
70
|
+
include MongoMapper::Document
|
71
|
+
include ZeroAuth::Model::Password
|
22
72
|
|
73
|
+
key :password_salt, String
|
74
|
+
key :password_hash, String
|
75
|
+
end
|
76
|
+
```
|
23
77
|
|
24
78
|
## Contributing
|
25
79
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,183 @@
|
|
1
|
+
module ZeroAuth
|
2
|
+
module Model
|
3
|
+
# The `Password` module includes the following features:
|
4
|
+
#
|
5
|
+
# * Password **salting** and **hashing** using `BCrypt`.
|
6
|
+
# * Instance level authentication method.
|
7
|
+
#
|
8
|
+
# ...yup, that's it. The idea is to provide a quick, secure way to store
|
9
|
+
# encrypted passwords. It is almost identical to Rails' own
|
10
|
+
# [has_secure_password](http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html)
|
11
|
+
# method, with the only exception being ZeroAuth uses a unique salt stored
|
12
|
+
# alongside and used to compute a password's hash.
|
13
|
+
#
|
14
|
+
# ### Requirement
|
15
|
+
#
|
16
|
+
# Your object must be able to write to the `password_salt` and the
|
17
|
+
# `password_hash` attributes (we handle the `password` attribute), so you
|
18
|
+
# might want to do something like this in a Rails migration:
|
19
|
+
#
|
20
|
+
# ```ruby
|
21
|
+
# change_table :users do |t|
|
22
|
+
# t.string :password_salt, null: false, default: ""
|
23
|
+
# t.string :password_hash, null: false, default: ""
|
24
|
+
# end
|
25
|
+
# ```
|
26
|
+
#
|
27
|
+
# ...or something like this using [`MongoMapper`](http://mongomapper.com/):
|
28
|
+
#
|
29
|
+
# ```ruby
|
30
|
+
# class User
|
31
|
+
# include MongoMapper::Document
|
32
|
+
# include ZeroAuth::Model::Password
|
33
|
+
#
|
34
|
+
# key :password_salt, String
|
35
|
+
# key :password_hash, String
|
36
|
+
# end
|
37
|
+
# ```
|
38
|
+
#
|
39
|
+
# ### Usage
|
40
|
+
#
|
41
|
+
# ```ruby
|
42
|
+
# class User < ActiveRecord::Base
|
43
|
+
# include ZeroAuth::Model::Password
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# user = User.create(email: 'email@me.com', password: 'password')
|
47
|
+
#
|
48
|
+
# user.has_password?('password') # => true
|
49
|
+
# user.has_password?('pa$$w0rD') # => false
|
50
|
+
#
|
51
|
+
# user.authenticate!('password') # => true
|
52
|
+
# user.authenticate!('pa$$word') # => raises ZeroAuth::Unauthorized
|
53
|
+
# ```
|
54
|
+
#
|
55
|
+
# ### Implementing Validations
|
56
|
+
#
|
57
|
+
# This module provides a {#requires_password?} helper method that, by
|
58
|
+
# default, simply checks whether this object is a `#new_record?` (if
|
59
|
+
# we can check that) or if the `#password` attributes is `empty?`.
|
60
|
+
#
|
61
|
+
# Again, with ActiveRecord or ActiveModel as an example, you can utilize it
|
62
|
+
# like this:
|
63
|
+
#
|
64
|
+
# ```ruby
|
65
|
+
# class User < ActiveRecord
|
66
|
+
# include ZeroAuth::Model::Password
|
67
|
+
#
|
68
|
+
# with_options if: :requires_password? do |pw|
|
69
|
+
# pw.validates :password, length: {in: 8..40}, confirmation: true
|
70
|
+
# end
|
71
|
+
# end
|
72
|
+
# ```
|
73
|
+
#
|
74
|
+
# You can also simply override the {#requires_password?} method to require
|
75
|
+
# validation when an `:old_password` attribute is present:
|
76
|
+
#
|
77
|
+
# ```ruby
|
78
|
+
# attr_accesor :old_password
|
79
|
+
#
|
80
|
+
# def requires_password?
|
81
|
+
# super || old_password.present?
|
82
|
+
# end
|
83
|
+
# ```
|
84
|
+
#
|
85
|
+
# ### Customize Authentication Class Method
|
86
|
+
#
|
87
|
+
# The {ZeroAuth::Model::Password} module leaves record retreival and the
|
88
|
+
# exact authentication tree up to the developer, but implementing a
|
89
|
+
# custom class method is trivial. An example using `ActiveRecord` might look
|
90
|
+
# something like this:
|
91
|
+
#
|
92
|
+
# ```ruby
|
93
|
+
# class User < ActiveRecord::Base
|
94
|
+
# include ZeroAuth::Model::Password
|
95
|
+
#
|
96
|
+
# def self.authenticate(email, password)
|
97
|
+
# begin
|
98
|
+
# self.authenticate!(email, password)
|
99
|
+
# rescue ZeroAuth::Unauthorized
|
100
|
+
# end
|
101
|
+
# end
|
102
|
+
#
|
103
|
+
# def self.authenticate!(email, password)
|
104
|
+
# begin
|
105
|
+
# record = self.find_by!(email: email)
|
106
|
+
# record.authenticate!(password) && record
|
107
|
+
# rescue ActiveRecord::RecordNotFound
|
108
|
+
# fail ZeroAuth::Unauthorized
|
109
|
+
# end
|
110
|
+
# end
|
111
|
+
# end
|
112
|
+
# ```
|
113
|
+
#
|
114
|
+
# **Note** the use of the {ZeroAuth::Unauthorized} exception. This is a
|
115
|
+
# custom error class provided to allow a standard way for your application
|
116
|
+
# to capture exceptions regarding authentication and authorization.
|
117
|
+
#
|
118
|
+
# The implementation above is certainly a personal perference, but the
|
119
|
+
# logic, again, is left up to you.
|
120
|
+
#
|
121
|
+
module Password
|
122
|
+
|
123
|
+
# Calls `attr_reader :password` on the including class.
|
124
|
+
#
|
125
|
+
def self.included(base)
|
126
|
+
base.class_eval { attr_reader :password }
|
127
|
+
end
|
128
|
+
|
129
|
+
# If the given password is not `nil?`, generates a `password_salt` and
|
130
|
+
# encrypts the given password into the `password_hash` using that salt.
|
131
|
+
# The salt and hash are generated using {ZeroAuth::Password.generate_salt}
|
132
|
+
# and {ZeroAuth::Utils.create_password}.
|
133
|
+
#
|
134
|
+
# @param unencrypted_password [String] the unencrypted password_attribute
|
135
|
+
# @return [Mixed] the unencrypted password
|
136
|
+
#
|
137
|
+
def password=(unencrypted_password)
|
138
|
+
if unencrypted_password.nil?
|
139
|
+
@password = nil
|
140
|
+
self.password_salt = nil
|
141
|
+
self.password_hash = nil
|
142
|
+
else
|
143
|
+
@password = unencrypted_password
|
144
|
+
self.password_salt = ZeroAuth::Password.generate_salt
|
145
|
+
self.password_hash = ZeroAuth::Password.create(password, password_salt)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Checks that the object is a `#new_record?` (if we can) or that the
|
150
|
+
# `password` attribute is not empty.
|
151
|
+
#
|
152
|
+
# @return [Boolean]
|
153
|
+
#
|
154
|
+
def requires_password?
|
155
|
+
is_new = (respond_to?(:new_record?) && new_record?)
|
156
|
+
is_new || !ZeroAuth::Utils.empty?(password)
|
157
|
+
end
|
158
|
+
|
159
|
+
# A helper method that takes a given password and raises a
|
160
|
+
# {ZeroAuth::Unauthorized} error if the call to `has_password?` fails.
|
161
|
+
#
|
162
|
+
# @params password [String] password to test
|
163
|
+
#
|
164
|
+
# @return [Nil]
|
165
|
+
# @raise {ZeroAuth::Unauthorized} if the given password is not valid
|
166
|
+
#
|
167
|
+
def authenticate!(test_password)
|
168
|
+
has_password?(test_password) || fail(ZeroAuth::Unauthorized)
|
169
|
+
end
|
170
|
+
|
171
|
+
# Compares the given password with the current password attributes using
|
172
|
+
# {ZeroAuth::Utils.compare_password}.
|
173
|
+
#
|
174
|
+
# @param test_password [String] password to test
|
175
|
+
# @return [Boolean]
|
176
|
+
#
|
177
|
+
def has_password?(test_password)
|
178
|
+
return false unless !ZeroAuth::Utils.empty?(password_hash)
|
179
|
+
ZeroAuth::Password.compare(password_hash, password_salt, test_password)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'bcrypt'
|
2
|
+
|
3
|
+
module ZeroAuth
|
4
|
+
class Password
|
5
|
+
|
6
|
+
# @return [String] a salt created by `BCrypt::Engine.generate_salt`
|
7
|
+
#
|
8
|
+
def self.generate_salt
|
9
|
+
BCrypt::Engine.generate_salt
|
10
|
+
end
|
11
|
+
|
12
|
+
# Generates a `BCrypt::Password` with a hard-coded cost of **9** (which
|
13
|
+
# will probably change soon).
|
14
|
+
#
|
15
|
+
# @param password [String] the given password
|
16
|
+
# @param salt [Sting] the password salt
|
17
|
+
#
|
18
|
+
# @return [BCrypt::Password]
|
19
|
+
#
|
20
|
+
def self.create(password, salt)
|
21
|
+
BCrypt::Password.create("#{password}#{salt}", cost: 9)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Compares a given encrypted password and the salt used to generate it with
|
25
|
+
# an unencrypted_password. Uses {ZeroAuth::Utils.secure_compare}.
|
26
|
+
#
|
27
|
+
# @param encrypted [String] the encrypted password
|
28
|
+
# @param salt [String] the salt used to generate that password
|
29
|
+
# @param unencrypted [String] the plain text password to compare
|
30
|
+
#
|
31
|
+
# @return [Boolean] true if they are equal, false if they aren't
|
32
|
+
#
|
33
|
+
def self.compare(encrypted, salt, unencrypted)
|
34
|
+
bcrypt = BCrypt::Password.new(encrypted)
|
35
|
+
password = BCrypt::Engine.hash_secret("#{unencrypted}#{salt}", bcrypt.salt)
|
36
|
+
ZeroAuth::Utils.secure_compare(password, encrypted)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'bcrypt'
|
2
|
+
|
3
|
+
module ZeroAuth
|
4
|
+
class Utils
|
5
|
+
|
6
|
+
# Uses a "constant time" comparison algorithm I would never have thought
|
7
|
+
# about so I copied it line for line from `Devise.secure_compare`:
|
8
|
+
#
|
9
|
+
# https://github.com/plataformatec/devise/blob/11c88754791322c8c4c5c123149f5435eda3b932/lib/devise.rb#L481
|
10
|
+
#
|
11
|
+
# @params a [String] first string to compare
|
12
|
+
# @params second [String] second string to compare
|
13
|
+
#
|
14
|
+
# @return [Boolean] true if they are equal, false if they aren't
|
15
|
+
#
|
16
|
+
def self.secure_compare(a, b)
|
17
|
+
return false if empty?(a) || empty?(b) || a.bytesize != b.bytesize
|
18
|
+
l = a.unpack "C#{a.bytesize}"
|
19
|
+
|
20
|
+
res = 0
|
21
|
+
b.each_byte { |byte| res |= byte ^ l.shift }
|
22
|
+
res == 0
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# @!visibility private
|
27
|
+
def self.empty?(v)
|
28
|
+
v.respond_to?(:empty?) ? v.empty? : !v
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/zero_auth/version.rb
CHANGED
data/lib/zero_auth.rb
CHANGED
@@ -1,4 +1,16 @@
|
|
1
1
|
require "zero_auth/version"
|
2
2
|
|
3
3
|
module ZeroAuth
|
4
|
+
autoload :Utils, 'zero_auth/utils'
|
5
|
+
autoload :Password, 'zero_auth/password'
|
6
|
+
|
7
|
+
module Model
|
8
|
+
autoload :Password, 'zero_auth/model/password'
|
9
|
+
end
|
10
|
+
|
11
|
+
# Exception raised througout the library when a method expected to
|
12
|
+
# perform some type of authentication on user supplied parameters cannot be
|
13
|
+
# authenticated.
|
14
|
+
#
|
15
|
+
class Unauthorized < StandardError; end
|
4
16
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ZeroAuth::Model::Password do
|
4
|
+
class User
|
5
|
+
include ZeroAuth::Model::Password
|
6
|
+
attr_accessor :password_salt, :password_hash
|
7
|
+
end
|
8
|
+
|
9
|
+
class ArUser < User
|
10
|
+
def new_record?
|
11
|
+
false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:user) { User.new }
|
16
|
+
before { user.password = "password" }
|
17
|
+
|
18
|
+
describe "#password=" do
|
19
|
+
it "sets the hash and salt to nil given a nil password" do
|
20
|
+
user.password = nil
|
21
|
+
expect(user.password_salt).to eq(nil)
|
22
|
+
expect(user.password_hash).to eq(nil)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "sets the hash and salt given a non-nil password" do
|
26
|
+
user.password = "password"
|
27
|
+
salt = user.password_salt
|
28
|
+
hash = user.password_hash
|
29
|
+
|
30
|
+
expect(salt).to_not be_empty
|
31
|
+
expect(hash).to_not be_empty
|
32
|
+
|
33
|
+
expected_salt = ZeroAuth::Password.generate_salt
|
34
|
+
expect(salt.length).to eq(expected_salt.length)
|
35
|
+
|
36
|
+
hash_result = ZeroAuth::Password.compare(hash, salt, "password")
|
37
|
+
expect(hash_result).to eq(true)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#has_password?" do
|
42
|
+
it "returns true given a valid password" do
|
43
|
+
expect(user.has_password?("password")).to eq(true)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns false for an invalid password" do
|
47
|
+
expect(user.has_password?("test")).to eq(false)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#authenticate!" do
|
52
|
+
it "raises a ZeroAuth::Unauthorized error for an invalid password" do
|
53
|
+
user.password = "password"
|
54
|
+
expect{user.authenticate!("other")}.to raise_error(ZeroAuth::Unauthorized)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns true for a valid password" do
|
58
|
+
user.password = "password"
|
59
|
+
expect(user.authenticate!("password")).to eq(true)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#requires_password?" do
|
64
|
+
let(:password) { nil }
|
65
|
+
before { user.password = password }
|
66
|
+
subject { user.requires_password? }
|
67
|
+
|
68
|
+
context "when the object is not a new #new_record?" do
|
69
|
+
context "and its password_hash is empty" do
|
70
|
+
it { is_expected.to eq(false) }
|
71
|
+
end
|
72
|
+
|
73
|
+
context "and its password is not-empty" do
|
74
|
+
let(:password) { "password" }
|
75
|
+
it { is_expected.to eq(true) }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when the object is a #new_record?" do
|
80
|
+
let(:user) { ArUser.new }
|
81
|
+
before { allow(user).to receive(:new_record?) { true } }
|
82
|
+
|
83
|
+
it { is_expected.to eq(true) }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ZeroAuth::Password do
|
4
|
+
|
5
|
+
describe ".generate_salt" do
|
6
|
+
it "returns a BCrypt generated salt" do
|
7
|
+
expect(ZeroAuth::Password.generate_salt).to match(/^\$2a\$\d+\$/)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".create" do
|
12
|
+
it "returns a BCrypt::Password" do
|
13
|
+
password = ZeroAuth::Password.create("password", "salt")
|
14
|
+
expect(password).to be_a(BCrypt::Password)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe ".compare" do
|
19
|
+
let(:password) { ZeroAuth::Password.create("password", "salt").to_s }
|
20
|
+
|
21
|
+
it "returns true for matching passwords" do
|
22
|
+
result = ZeroAuth::Password.compare(password, "salt", "password")
|
23
|
+
expect(result).to eq(true)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns false for non-matching passwords" do
|
27
|
+
result = ZeroAuth::Password.compare(password, "salt", "other")
|
28
|
+
expect(result).to eq(false)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ZeroAuth::Utils do
|
4
|
+
|
5
|
+
describe ".secure_compare" do
|
6
|
+
it "returns true for equal values" do
|
7
|
+
expect(ZeroAuth::Utils.secure_compare("password", "password")).to eq(true)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns false for non-equal values" do
|
11
|
+
expect(ZeroAuth::Utils.secure_compare("password", "other")).to eq(false)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns false for empty strings" do
|
15
|
+
expect(ZeroAuth::Utils.secure_compare("password", "")).to eq(false)
|
16
|
+
expect(ZeroAuth::Utils.secure_compare("", "password")).to eq(false)
|
17
|
+
expect(ZeroAuth::Utils.secure_compare("", "")).to eq(false)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns false for nil values" do
|
21
|
+
expect(ZeroAuth::Utils.secure_compare("password", nil)).to eq(false)
|
22
|
+
expect(ZeroAuth::Utils.secure_compare(nil, "password")).to eq(false)
|
23
|
+
expect(ZeroAuth::Utils.secure_compare(nil, nil)).to eq(false)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
Bundler.setup
|
3
|
+
|
4
|
+
require 'zero_auth'
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
if config.files_to_run.one?
|
8
|
+
config.default_formatter = 'doc'
|
9
|
+
end
|
10
|
+
|
11
|
+
config.order = :random
|
12
|
+
Kernel.srand config.seed
|
13
|
+
|
14
|
+
config.expect_with :rspec do |expectations|
|
15
|
+
expectations.syntax = :expect
|
16
|
+
end
|
17
|
+
|
18
|
+
config.mock_with :rspec do |mocks|
|
19
|
+
mocks.syntax = :expect
|
20
|
+
mocks.verify_partial_doubles = true
|
21
|
+
end
|
22
|
+
end
|
data/zero_auth.gemspec
CHANGED
@@ -17,6 +17,11 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^spec/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.
|
21
|
-
|
20
|
+
spec.add_dependency 'bcrypt', '~> 3.1.7'
|
21
|
+
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
23
|
+
spec.add_development_dependency 'rake'
|
24
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
25
|
+
spec.add_development_dependency 'redcarpet'
|
26
|
+
spec.add_development_dependency 'yard'
|
22
27
|
end
|
metadata
CHANGED
@@ -1,41 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zero_auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2.beta
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Braden Schaeffer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bcrypt
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.1.7
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.1.7
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
|
-
- - ~>
|
31
|
+
- - "~>"
|
18
32
|
- !ruby/object:Gem::Version
|
19
33
|
version: '1.5'
|
20
34
|
type: :development
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
|
-
- - ~>
|
38
|
+
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '1.5'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- -
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: redcarpet
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
32
88
|
- !ruby/object:Gem::Version
|
33
89
|
version: '0'
|
34
90
|
type: :development
|
35
91
|
prerelease: false
|
36
92
|
version_requirements: !ruby/object:Gem::Requirement
|
37
93
|
requirements:
|
38
|
-
- -
|
94
|
+
- - ">="
|
39
95
|
- !ruby/object:Gem::Version
|
40
96
|
version: '0'
|
41
97
|
description: Zero configuration authentication starter for Rails.
|
@@ -45,13 +101,23 @@ executables: []
|
|
45
101
|
extensions: []
|
46
102
|
extra_rdoc_files: []
|
47
103
|
files:
|
48
|
-
- .gitignore
|
104
|
+
- ".gitignore"
|
105
|
+
- ".rspec"
|
106
|
+
- ".travis.yml"
|
107
|
+
- ".yardopts"
|
49
108
|
- Gemfile
|
50
109
|
- LICENSE.txt
|
51
110
|
- README.md
|
52
111
|
- Rakefile
|
53
112
|
- lib/zero_auth.rb
|
113
|
+
- lib/zero_auth/model/password.rb
|
114
|
+
- lib/zero_auth/password.rb
|
115
|
+
- lib/zero_auth/utils.rb
|
54
116
|
- lib/zero_auth/version.rb
|
117
|
+
- spec/lib/zero_auth/model/password_spec.rb
|
118
|
+
- spec/lib/zero_auth/password_spec.rb
|
119
|
+
- spec/lib/zero_auth/utils_spec.rb
|
120
|
+
- spec/spec_helper.rb
|
55
121
|
- zero_auth.gemspec
|
56
122
|
homepage: https://github.com/bschaeffer/zero_auth
|
57
123
|
licenses:
|
@@ -63,18 +129,23 @@ require_paths:
|
|
63
129
|
- lib
|
64
130
|
required_ruby_version: !ruby/object:Gem::Requirement
|
65
131
|
requirements:
|
66
|
-
- -
|
132
|
+
- - ">="
|
67
133
|
- !ruby/object:Gem::Version
|
68
134
|
version: '0'
|
69
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
136
|
requirements:
|
71
|
-
- -
|
137
|
+
- - ">"
|
72
138
|
- !ruby/object:Gem::Version
|
73
139
|
version: 1.3.1
|
74
140
|
requirements: []
|
75
141
|
rubyforge_project:
|
76
|
-
rubygems_version: 2.2.
|
142
|
+
rubygems_version: 2.2.2
|
77
143
|
signing_key:
|
78
144
|
specification_version: 4
|
79
145
|
summary: Zero configuration authentication starter for Rails.
|
80
|
-
test_files:
|
146
|
+
test_files:
|
147
|
+
- spec/lib/zero_auth/model/password_spec.rb
|
148
|
+
- spec/lib/zero_auth/password_spec.rb
|
149
|
+
- spec/lib/zero_auth/utils_spec.rb
|
150
|
+
- spec/spec_helper.rb
|
151
|
+
has_rdoc:
|