htauth 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/HISTORY.md +7 -0
- data/Manifest.txt +4 -0
- data/README.md +36 -22
- data/Rakefile +8 -4
- data/lib/htauth.rb +1 -0
- data/lib/htauth/algorithm.rb +32 -29
- data/lib/htauth/bcrypt.rb +35 -0
- data/lib/htauth/cli/digest.rb +1 -1
- data/lib/htauth/cli/passwd.rb +90 -30
- data/lib/htauth/console.rb +5 -1
- data/lib/htauth/crypt.rb +15 -4
- data/lib/htauth/descendant_tracker.rb +46 -0
- data/lib/htauth/md5.rb +27 -7
- data/lib/htauth/passwd_entry.rb +22 -17
- data/lib/htauth/passwd_file.rb +46 -12
- data/lib/htauth/plaintext.rb +11 -4
- data/lib/htauth/sha1.rb +8 -5
- data/lib/htauth/version.rb +1 -1
- data/spec/algorithm_spec.rb +8 -0
- data/spec/bcrypt_spec.rb +33 -0
- data/spec/cli/digest_spec.rb +22 -23
- data/spec/cli/passwd_spec.rb +160 -36
- data/spec/crypt_spec.rb +1 -5
- data/spec/digest_entry_spec.rb +19 -19
- data/spec/digest_file_spec.rb +10 -10
- data/spec/md5_spec.rb +1 -5
- data/spec/passwd_entry_spec.rb +63 -42
- data/spec/passwd_file_spec.rb +31 -13
- data/spec/plaintext_spec.rb +1 -5
- data/spec/sha1_spec.rb +1 -5
- data/tasks/default.rake +3 -3
- data/tasks/this.rb +2 -2
- metadata +32 -13
data/spec/passwd_entry_spec.rb
CHANGED
@@ -9,130 +9,151 @@ describe HTAuth::PasswdEntry do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it "initializes with a user and realm" do
|
12
|
-
@alice.user.must_equal "alice"
|
12
|
+
_(@alice.user).must_equal "alice"
|
13
13
|
end
|
14
14
|
|
15
15
|
it "has the correct crypt password" do
|
16
16
|
@alice.password = "a secret"
|
17
|
-
@alice.digest.must_equal "mDwdZuXalQ5zk"
|
17
|
+
_(@alice.digest).must_equal "mDwdZuXalQ5zk"
|
18
18
|
end
|
19
19
|
|
20
20
|
it "encrypts correctly for md5" do
|
21
21
|
bob = HTAuth::PasswdEntry.new("bob", "b secret", "md5", { :salt => @salt })
|
22
|
-
bob.digest.must_equal "$apr1$lo1tk/..$CarApvZPee0F6Wj1U0GxZ1"
|
22
|
+
_(bob.digest).must_equal "$apr1$lo1tk/..$CarApvZPee0F6Wj1U0GxZ1"
|
23
23
|
end
|
24
24
|
|
25
25
|
it "encrypts correctly for sha1" do
|
26
26
|
bob = HTAuth::PasswdEntry.new("bob", "b secret", "sha1", { :salt => @salt })
|
27
|
-
bob.digest.must_equal "{SHA}b/tjGXbX80MEKVnF200S43ca4hY="
|
27
|
+
_(bob.digest).must_equal "{SHA}b/tjGXbX80MEKVnF200S43ca4hY="
|
28
28
|
end
|
29
29
|
|
30
30
|
it "encrypts correctly for plaintext" do
|
31
31
|
bob = HTAuth::PasswdEntry.new("bob", "b secret", "plaintext", { :salt => @salt })
|
32
|
-
bob.digest.must_equal "b secret"
|
32
|
+
_(bob.digest).must_equal "b secret"
|
33
33
|
end
|
34
34
|
|
35
35
|
it "encrypts with crypt as a default, when parsed from crypt()'d line" do
|
36
36
|
bob2 = HTAuth::PasswdEntry.from_line(@bob.to_s)
|
37
|
-
bob2.algorithm.must_be_instance_of(
|
38
|
-
bob2.algorithm.size.must_equal 2
|
37
|
+
_(bob2.algorithm).must_be_instance_of(HTAuth::Crypt)
|
39
38
|
bob2.password = "another secret"
|
40
|
-
bob2.algorithm.must_be_instance_of(HTAuth::Crypt)
|
39
|
+
_(bob2.algorithm).must_be_instance_of(HTAuth::Crypt)
|
41
40
|
end
|
42
41
|
|
43
42
|
it "encrypts with crypt as a default, when parsed from plaintext line" do
|
44
43
|
p = HTAuth::PasswdEntry.new('paul', 'p secret', 'plaintext')
|
45
44
|
p2 = HTAuth::PasswdEntry.from_line(p.to_s)
|
46
|
-
p2.algorithm.must_be_instance_of(
|
47
|
-
p2.algorithm.size.must_equal 2
|
45
|
+
_(p2.algorithm).must_be_instance_of(HTAuth::Plaintext)
|
48
46
|
p2.password = "another secret"
|
49
|
-
p2.algorithm.must_be_instance_of(HTAuth::Crypt)
|
47
|
+
_(p2.algorithm).must_be_instance_of(HTAuth::Crypt)
|
50
48
|
end
|
51
49
|
|
52
50
|
it "encrypts with md5 as default, when parsed from an md5 line" do
|
53
51
|
m = HTAuth::PasswdEntry.new("mary", "m secret", "md5")
|
54
52
|
m2 = HTAuth::PasswdEntry.from_line(m.to_s)
|
55
|
-
m2.algorithm.must_be_instance_of(HTAuth::Md5)
|
53
|
+
_(m2.algorithm).must_be_instance_of(HTAuth::Md5)
|
56
54
|
end
|
57
55
|
|
58
56
|
it "encrypts with sha1 as default, when parsed from an sha1 line" do
|
59
57
|
s = HTAuth::PasswdEntry.new("steve", "s secret", "sha1")
|
60
58
|
s2 = HTAuth::PasswdEntry.from_line(s.to_s)
|
61
|
-
s2.algorithm.must_be_instance_of(HTAuth::Sha1)
|
59
|
+
_(s2.algorithm).must_be_instance_of(HTAuth::Sha1)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "encrypts with bcrypt as default when parsed from a bcrypt line" do
|
63
|
+
b = HTAuth::PasswdEntry.new("brenda", "b secret", "bcrypt")
|
64
|
+
b2 = HTAuth::PasswdEntry.from_line(b.to_s)
|
65
|
+
_(b2.algorithm).must_be_instance_of(HTAuth::Bcrypt)
|
62
66
|
end
|
63
67
|
|
64
68
|
it "determins the algorithm to be crypt when checking a password" do
|
65
69
|
bob2 = HTAuth::PasswdEntry.from_line(@bob.to_s)
|
66
|
-
bob2.algorithm.must_be_instance_of(
|
67
|
-
bob2.
|
68
|
-
bob2.
|
69
|
-
bob2.algorithm.must_be_instance_of(HTAuth::Crypt)
|
70
|
+
_(bob2.algorithm).must_be_instance_of(HTAuth::Crypt)
|
71
|
+
_(bob2.authenticated?("b secret")).must_equal true
|
72
|
+
_(bob2.algorithm).must_be_instance_of(HTAuth::Crypt)
|
70
73
|
end
|
71
74
|
|
72
75
|
it "determins the algorithm to be plain when checking a password" do
|
73
76
|
bob2 = HTAuth::PasswdEntry.from_line("bob:b secret")
|
74
|
-
bob2.algorithm.must_be_instance_of(
|
75
|
-
bob2.
|
76
|
-
bob2.
|
77
|
-
bob2.algorithm.must_be_instance_of(HTAuth::Plaintext)
|
77
|
+
_(bob2.algorithm).must_be_instance_of(HTAuth::Plaintext)
|
78
|
+
_(bob2.authenticated?("b secret")).must_equal true
|
79
|
+
_(bob2.algorithm).must_be_instance_of(HTAuth::Plaintext)
|
78
80
|
end
|
79
81
|
|
80
82
|
it "authenticates correctly against md5" do
|
81
83
|
m = HTAuth::PasswdEntry.new("mary", "m secret", "md5")
|
82
84
|
m2 = HTAuth::PasswdEntry.from_line(m.to_s)
|
83
|
-
m2.authenticated?("m secret").must_equal true
|
85
|
+
_(m2.authenticated?("m secret")).must_equal true
|
84
86
|
end
|
85
87
|
|
86
88
|
it "authenticates correctly against sha1" do
|
87
89
|
s = HTAuth::PasswdEntry.new("steve", "s secret", "sha1")
|
88
90
|
s2 = HTAuth::PasswdEntry.from_line(s.to_s)
|
89
|
-
s2.authenticated?("s secret").must_equal true
|
91
|
+
_(s2.authenticated?("s secret")).must_equal true
|
92
|
+
end
|
93
|
+
|
94
|
+
it "authenticates correctly against bcrypt" do
|
95
|
+
s = HTAuth::PasswdEntry.new("brenda", "b secret", "bcrypt")
|
96
|
+
s2 = HTAuth::PasswdEntry.from_line(s.to_s)
|
97
|
+
_(s2.authenticated?("b secret")).must_equal true
|
90
98
|
end
|
91
99
|
|
100
|
+
it "can update the cost of an entry after initialization before encoding password" do
|
101
|
+
s = HTAuth::PasswdEntry.new("brenda", "b secret", "bcrypt")
|
102
|
+
_(s.algorithm.cost).must_equal(::HTAuth::Bcrypt::DEFAULT_APACHE_COST)
|
92
103
|
|
104
|
+
s2 = HTAuth::PasswdEntry.from_line(s.to_s)
|
105
|
+
s2.algorithm_args = { :cost => 12 }
|
106
|
+
s2.password = "b secret" # forces recalculation
|
93
107
|
|
108
|
+
_(s2.algorithm.cost).must_equal(12)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "raises an error if assinging an invalid algorithm" do
|
112
|
+
b = HTAuth::PasswdEntry.new("brenda", "b secret", "bcrypt")
|
113
|
+
_ { b.algorithm = 42 }.must_raise(HTAuth::InvalidAlgorithmError)
|
114
|
+
end
|
94
115
|
|
95
116
|
it "returns username for a key" do
|
96
|
-
@alice.key.must_equal "alice"
|
117
|
+
_(@alice.key).must_equal "alice"
|
97
118
|
end
|
98
119
|
|
99
120
|
it "checks the password correctly" do
|
100
|
-
@bob.authenticated?("b secret").must_equal true
|
121
|
+
_(@bob.authenticated?("b secret")).must_equal true
|
101
122
|
end
|
102
123
|
|
103
124
|
it "formats correctly when put to a string" do
|
104
|
-
@bob.to_s.must_equal "bob:b8Ml4Jp9I0N8E"
|
125
|
+
_(@bob.to_s).must_equal "bob:b8Ml4Jp9I0N8E"
|
105
126
|
end
|
106
127
|
|
107
128
|
it "parses an input line" do
|
108
129
|
@bob_new = HTAuth::PasswdEntry.from_line("bob:b8Ml4Jp9I0N8E")
|
109
|
-
@bob.user.must_equal @bob_new.user
|
110
|
-
@bob.digest.must_equal @bob_new.digest
|
130
|
+
_(@bob.user).must_equal @bob_new.user
|
131
|
+
_(@bob.digest).must_equal @bob_new.digest
|
111
132
|
end
|
112
133
|
|
113
134
|
it "knows if an input line is a possible entry and raises an exception" do
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
135
|
+
_ { HTAuth::PasswdEntry.is_entry!("#stuff") }.must_raise(HTAuth::InvalidPasswdEntry)
|
136
|
+
_ { HTAuth::PasswdEntry.is_entry!("this:that:other:stuff") }.must_raise(HTAuth::InvalidPasswdEntry)
|
137
|
+
_ { HTAuth::PasswdEntry.is_entry!("this:that:other") }.must_raise(HTAuth::InvalidPasswdEntry)
|
138
|
+
_ { HTAuth::PasswdEntry.is_entry!("this:that:0a90549e8ffb2dd62f98252a95d88xyz") }.must_raise(HTAuth::InvalidPasswdEntry)
|
118
139
|
end
|
119
140
|
|
120
141
|
it "knows if an input line is a possible entry and returns false" do
|
121
|
-
HTAuth::PasswdEntry.is_entry?("#stuff").must_equal false
|
122
|
-
HTAuth::PasswdEntry.is_entry?("this:that:other:stuff").must_equal false
|
123
|
-
HTAuth::PasswdEntry.is_entry?("this:that:other").must_equal false
|
124
|
-
HTAuth::PasswdEntry.is_entry?("this:that:0a90549e8ffb2dd62f98252a95d88xyz").must_equal false
|
142
|
+
_(HTAuth::PasswdEntry.is_entry?("#stuff")).must_equal false
|
143
|
+
_(HTAuth::PasswdEntry.is_entry?("this:that:other:stuff")).must_equal false
|
144
|
+
_(HTAuth::PasswdEntry.is_entry?("this:that:other")).must_equal false
|
145
|
+
_(HTAuth::PasswdEntry.is_entry?("this:that:0a90549e8ffb2dd62f98252a95d88xyz")).must_equal false
|
125
146
|
end
|
126
147
|
|
127
148
|
it "knows if an input line is a possible entry and returns true" do
|
128
|
-
HTAuth::PasswdEntry.is_entry?("bob:irRm0g.SDfCyI").must_equal true
|
129
|
-
HTAuth::PasswdEntry.is_entry?("bob:b secreat").must_equal true
|
130
|
-
HTAuth::PasswdEntry.is_entry?("bob:{SHA}b/tjGXbX80MEKVnF200S43ca4hY=").must_equal true
|
131
|
-
HTAuth::PasswdEntry.is_entry?("bob:$apr1$lo1tk/..$CarApvZPee0F6Wj1U0GxZ1").must_equal true
|
132
|
-
|
149
|
+
_(HTAuth::PasswdEntry.is_entry?("bob:irRm0g.SDfCyI")).must_equal true
|
150
|
+
_(HTAuth::PasswdEntry.is_entry?("bob:b secreat")).must_equal true
|
151
|
+
_(HTAuth::PasswdEntry.is_entry?("bob:{SHA}b/tjGXbX80MEKVnF200S43ca4hY=")).must_equal true
|
152
|
+
_(HTAuth::PasswdEntry.is_entry?("bob:$apr1$lo1tk/..$CarApvZPee0F6Wj1U0GxZ1")).must_equal true
|
153
|
+
_(HTAuth::PasswdEntry.is_entry?("bob:$2y$05$ts3k1r.t0Cne6j6DLt0/SepT5X4qthDFEdfqHBBMO5MhqzyMz34j2")).must_equal true
|
133
154
|
end
|
134
155
|
|
135
156
|
it "duplicates itself" do
|
136
|
-
@alice.dup.to_s.must_equal @alice.to_s
|
157
|
+
_(@alice.dup.to_s).must_equal @alice.to_s
|
137
158
|
end
|
138
159
|
end
|
data/spec/passwd_file_spec.rb
CHANGED
@@ -22,45 +22,63 @@ describe HTAuth::PasswdFile do
|
|
22
22
|
|
23
23
|
it "can add a new entry to an already existing passwd file" do
|
24
24
|
@passwd_file.add_or_update("charlie", "c secret", "sha1")
|
25
|
-
@passwd_file.contents.must_equal IO.read(PASSWD_ADD_TEST_FILE)
|
25
|
+
_(@passwd_file.contents).must_equal IO.read(PASSWD_ADD_TEST_FILE)
|
26
26
|
end
|
27
27
|
|
28
28
|
it "can tell if an entry already exists in the passwd file" do
|
29
|
-
@passwd_file.has_entry?("alice").must_equal true
|
30
|
-
@passwd_file.has_entry?("david").must_equal false
|
29
|
+
_(@passwd_file.has_entry?("alice")).must_equal true
|
30
|
+
_(@passwd_file.has_entry?("david")).must_equal false
|
31
31
|
end
|
32
32
|
|
33
33
|
it "can update an entry in an already existing passwd file, algorithm can change" do
|
34
34
|
@passwd_file.add_or_update("alice", "a new secret", "sha1")
|
35
|
-
@passwd_file.contents.must_equal IO.read(PASSWD_UPDATE_TEST_FILE)
|
35
|
+
_(@passwd_file.contents).must_equal IO.read(PASSWD_UPDATE_TEST_FILE)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "can update an entry in an already existing passwd file, algorithm and arguments can change" do
|
39
|
+
@passwd_file.add_or_update("brenda", "b secret", "bcrypt")
|
40
|
+
entry = @passwd_file.fetch("brenda")
|
41
|
+
_(entry.algorithm.cost).must_equal(::HTAuth::Bcrypt::DEFAULT_APACHE_COST)
|
42
|
+
@passwd_file.add_or_update("brenda", "b secret", "bcrypt", :cost => 12)
|
43
|
+
entry = @passwd_file.fetch("brenda")
|
44
|
+
_(entry.algorithm.cost).must_equal(12)
|
36
45
|
end
|
37
46
|
|
38
47
|
it "fetches a copy of an entry" do
|
39
|
-
@passwd_file.fetch("alice").to_s.must_equal "alice:$apr1$DghnA...$CsPcgerfsI/Ryy0AOAJtb0"
|
48
|
+
_(@passwd_file.fetch("alice").to_s).must_equal "alice:$apr1$DghnA...$CsPcgerfsI/Ryy0AOAJtb0"
|
40
49
|
end
|
41
50
|
|
42
|
-
it "raises an error if an attempt is made to alter a non-
|
43
|
-
|
51
|
+
it "raises an error if an attempt is made to alter a non-existent file" do
|
52
|
+
_ { HTAuth::PasswdFile.new("some-file") }.must_raise(HTAuth::FileAccessError)
|
44
53
|
end
|
45
54
|
|
46
55
|
# this test will only work on systems that have /etc/ssh_host_rsa_key
|
47
56
|
it "raises an error if an attempt is made to open a file where no permissions are granted" do
|
48
|
-
|
57
|
+
_ { HTAuth::PasswdFile.new("/etc/ssh_host_rsa_key") }.must_raise(HTAuth::FileAccessError)
|
49
58
|
end
|
50
59
|
|
51
60
|
it "deletes an entry" do
|
52
61
|
@passwd_file.delete("bob")
|
53
|
-
@passwd_file.contents.must_equal IO.read(PASSWD_DELETE_TEST_FILE)
|
62
|
+
_(@passwd_file.contents).must_equal IO.read(PASSWD_DELETE_TEST_FILE)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "checks authentication of an entry - true" do
|
66
|
+
_(@passwd_file.authenticated?("alice", "a secret")).must_equal true
|
54
67
|
end
|
55
68
|
|
56
|
-
it "
|
69
|
+
it "checks authentication of an entry - false" do
|
70
|
+
_(@passwd_file.authenticated?("alice", "the wrong secret")).must_equal false
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
it "is usable in a ruby manner and yields itself when opened" do
|
57
75
|
HTAuth::PasswdFile.open(@tf.path) do |pf|
|
58
76
|
pf.add_or_update("alice", "a new secret", "md5")
|
59
77
|
pf.delete('bob')
|
60
78
|
end
|
61
79
|
lines = IO.readlines(@tf.path)
|
62
|
-
lines.size.must_equal 1
|
63
|
-
lines.first.split(':').first.must_equal "alice"
|
64
|
-
lines.first.split(':').last.must_match( /\$apr1\$/ )
|
80
|
+
_(lines.size).must_equal 1
|
81
|
+
_(lines.first.split(':').first).must_equal "alice"
|
82
|
+
_(lines.first.split(':').last).must_match( /\$apr1\$/ )
|
65
83
|
end
|
66
84
|
end
|
data/spec/plaintext_spec.rb
CHANGED
@@ -2,14 +2,10 @@ require 'spec_helper'
|
|
2
2
|
require 'htauth/plaintext'
|
3
3
|
|
4
4
|
describe HTAuth::Plaintext do
|
5
|
-
it "has a prefix" do
|
6
|
-
HTAuth::Plaintext.new.prefix.must_equal ""
|
7
|
-
end
|
8
|
-
|
9
5
|
it "encrypts the same way that apache does" do
|
10
6
|
apache_result = "a secret"
|
11
7
|
pt = HTAuth::Plaintext.new
|
12
|
-
pt.encode("a secret").must_equal apache_result
|
8
|
+
_(pt.encode("a secret")).must_equal apache_result
|
13
9
|
end
|
14
10
|
end
|
15
11
|
|
data/spec/sha1_spec.rb
CHANGED
@@ -2,14 +2,10 @@ require 'spec_helper'
|
|
2
2
|
require 'htauth/sha1'
|
3
3
|
|
4
4
|
describe HTAuth::Sha1 do
|
5
|
-
it "has a prefix" do
|
6
|
-
HTAuth::Sha1.new.prefix.must_equal "{SHA}"
|
7
|
-
end
|
8
|
-
|
9
5
|
it "encrypts the same way that apache does" do
|
10
6
|
apache_result = "{SHA}ZrnlrvmM7ZCOV3FAvM7la89NKbk="
|
11
7
|
sha1 = HTAuth::Sha1.new
|
12
|
-
sha1.encode("a secret").must_equal apache_result
|
8
|
+
_(sha1.encode("a secret")).must_equal apache_result
|
13
9
|
end
|
14
10
|
end
|
15
11
|
|
data/tasks/default.rake
CHANGED
@@ -38,7 +38,7 @@ task :develop => "develop:default"
|
|
38
38
|
begin
|
39
39
|
require 'rake/testtask'
|
40
40
|
Rake::TestTask.new( :test ) do |t|
|
41
|
-
t.ruby_opts = %w[ -w
|
41
|
+
t.ruby_opts = %w[ -w ]
|
42
42
|
t.libs = %w[ lib spec test ]
|
43
43
|
t.pattern = "{test,spec}/**/{test_*,*_spec}.rb"
|
44
44
|
end
|
@@ -159,7 +159,7 @@ namespace :fixme do
|
|
159
159
|
end
|
160
160
|
|
161
161
|
desc "See if the fixme tools are outdated"
|
162
|
-
task :outdated
|
162
|
+
task :outdated do
|
163
163
|
if fixme_up_to_date? then
|
164
164
|
puts "Fixme files are up to date."
|
165
165
|
else
|
@@ -170,7 +170,7 @@ namespace :fixme do
|
|
170
170
|
end
|
171
171
|
|
172
172
|
desc "Update outdated fixme files"
|
173
|
-
task :update
|
173
|
+
task :update do
|
174
174
|
if fixme_up_to_date? then
|
175
175
|
puts "Fixme files are already up to date."
|
176
176
|
else
|
data/tasks/this.rb
CHANGED
@@ -28,7 +28,7 @@ class ThisProject
|
|
28
28
|
@exclude_from_manifest = Regexp.union(/\.(git|DS_Store)/,
|
29
29
|
/^(doc|coverage|pkg|tmp|Gemfile(\.lock)?)/,
|
30
30
|
/^[^\/]+\.gemspec/,
|
31
|
-
/\.(swp|jar|bundle|so|rvmrc|travis.yml)$/,
|
31
|
+
/\.(swp|jar|bundle|so|rvmrc|travis.yml|byebug_history|fossa.yml|ruby-version)$/,
|
32
32
|
/~$/)
|
33
33
|
@gemspecs = Hash.new
|
34
34
|
yield self if block_given?
|
@@ -146,7 +146,7 @@ class ThisProject
|
|
146
146
|
spec.rdoc_options = [ "--main" , 'README.md',
|
147
147
|
"--markup", "tomdoc" ]
|
148
148
|
|
149
|
-
spec.required_ruby_version = '>=
|
149
|
+
spec.required_ruby_version = '>= 2.2.2'
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
metadata
CHANGED
@@ -1,71 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: htauth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Hinegardner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-04-02 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'
|
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'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rake
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - "~>"
|
18
32
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
33
|
+
version: '13.0'
|
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
|
-
version: '
|
40
|
+
version: '13.0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: minitest
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - "~>"
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
version: '5.
|
47
|
+
version: '5.5'
|
34
48
|
type: :development
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
52
|
- - "~>"
|
39
53
|
- !ruby/object:Gem::Version
|
40
|
-
version: '5.
|
54
|
+
version: '5.5'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rdoc
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
61
|
+
version: '6.2'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
68
|
+
version: '6.2'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: simplecov
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0.
|
75
|
+
version: '0.17'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0.
|
82
|
+
version: '0.17'
|
69
83
|
description: HTAuth is a pure ruby replacement for the Apache support programs htdigest
|
70
84
|
and htpasswd. Command line and API access are provided for access to htdigest and
|
71
85
|
htpasswd files.
|
@@ -90,11 +104,13 @@ files:
|
|
90
104
|
- bin/htpasswd-ruby
|
91
105
|
- lib/htauth.rb
|
92
106
|
- lib/htauth/algorithm.rb
|
107
|
+
- lib/htauth/bcrypt.rb
|
93
108
|
- lib/htauth/cli.rb
|
94
109
|
- lib/htauth/cli/digest.rb
|
95
110
|
- lib/htauth/cli/passwd.rb
|
96
111
|
- lib/htauth/console.rb
|
97
112
|
- lib/htauth/crypt.rb
|
113
|
+
- lib/htauth/descendant_tracker.rb
|
98
114
|
- lib/htauth/digest_entry.rb
|
99
115
|
- lib/htauth/digest_file.rb
|
100
116
|
- lib/htauth/entry.rb
|
@@ -106,6 +122,8 @@ files:
|
|
106
122
|
- lib/htauth/plaintext.rb
|
107
123
|
- lib/htauth/sha1.rb
|
108
124
|
- lib/htauth/version.rb
|
125
|
+
- spec/algorithm_spec.rb
|
126
|
+
- spec/bcrypt_spec.rb
|
109
127
|
- spec/cli/digest_spec.rb
|
110
128
|
- spec/cli/passwd_spec.rb
|
111
129
|
- spec/crypt_spec.rb
|
@@ -143,21 +161,22 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
143
161
|
requirements:
|
144
162
|
- - ">="
|
145
163
|
- !ruby/object:Gem::Version
|
146
|
-
version:
|
164
|
+
version: 2.2.2
|
147
165
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
166
|
requirements:
|
149
167
|
- - ">="
|
150
168
|
- !ruby/object:Gem::Version
|
151
169
|
version: '0'
|
152
170
|
requirements: []
|
153
|
-
|
154
|
-
rubygems_version: 2.4.5
|
171
|
+
rubygems_version: 3.0.3
|
155
172
|
signing_key:
|
156
173
|
specification_version: 4
|
157
174
|
summary: HTAuth is a pure ruby replacement for the Apache support programs htdigest
|
158
175
|
and htpasswd. Command line and API access are provided for access to htdigest and
|
159
176
|
htpasswd files.
|
160
177
|
test_files:
|
178
|
+
- spec/algorithm_spec.rb
|
179
|
+
- spec/bcrypt_spec.rb
|
161
180
|
- spec/cli/digest_spec.rb
|
162
181
|
- spec/cli/passwd_spec.rb
|
163
182
|
- spec/crypt_spec.rb
|