zero_auth 0.0.1.beta → 0.0.2.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/bschaeffer/zero_auth.svg?branch=master)](https://travis-ci.org/bschaeffer/zero_auth) [![Inline docs](http://inch-ci.org/github/bschaeffer/zero_auth.png?branch=master)](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:
|