htauth 2.0.0 → 2.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.
@@ -41,8 +41,8 @@ describe HTAuth::CLI::Passwd do
41
41
  begin
42
42
  @htauth.run([ "-h" ])
43
43
  rescue SystemExit => se
44
- se.status.must_equal 1
45
- @stdout.string.must_match( /passwordfile username/m )
44
+ _(se.status).must_equal 1
45
+ _(@stdout.string).must_match( /passwordfile username/m )
46
46
  end
47
47
  end
48
48
 
@@ -50,8 +50,8 @@ describe HTAuth::CLI::Passwd do
50
50
  begin
51
51
  @htauth.run([ "--version" ])
52
52
  rescue SystemExit => se
53
- se.status.must_equal 1
54
- @stdout.string.must_match( /version #{HTAuth::VERSION}/)
53
+ _(se.status).must_equal 1
54
+ _(@stdout.string).must_match( /version #{HTAuth::VERSION}/)
55
55
  end
56
56
  end
57
57
 
@@ -62,11 +62,100 @@ describe HTAuth::CLI::Passwd do
62
62
  @stdin.rewind
63
63
  @htauth.run([ "-m", "-c", @new_file, "alice" ])
64
64
  rescue SystemExit => se
65
- se.status.must_equal 0
65
+ _(se.status).must_equal 0
66
66
  l = IO.readlines(@new_file)
67
67
  fields = l.first.split(':')
68
- fields.first.must_equal "alice"
69
- fields.last.must_match( /^\$apr1\$/ )
68
+ _(fields.first).must_equal "alice"
69
+ _(fields.last).must_match( /^\$apr1\$/ )
70
+ end
71
+ end
72
+
73
+ it "creates a new file with one bcrypt entry" do
74
+ begin
75
+ @stdin.puts "b secret"
76
+ @stdin.puts "b secret"
77
+ @stdin.rewind
78
+ @htauth.run([ "-B", "-c", @new_file, "brenda" ])
79
+ rescue SystemExit => se
80
+ _(se.status).must_equal 0
81
+ l = IO.readlines(@new_file)
82
+ fields = l.first.split(':')
83
+ _(fields.first).must_equal "brenda"
84
+ bcrypt_hash = fields.last
85
+
86
+ _(::BCrypt::Password.valid_hash?(bcrypt_hash)).wont_be_nil
87
+ end
88
+ end
89
+
90
+ it "allows the bcrypt cost to be set" do
91
+ begin
92
+ cost = 12
93
+ @stdin.puts "b secret"
94
+ @stdin.puts "b secret"
95
+ @stdin.rewind
96
+ @htauth.run([ "-C", "#{cost}", "-B", "-c", @new_file, "brenda" ])
97
+ rescue SystemExit => se
98
+ _(se.status).must_equal 0
99
+ l = IO.readlines(@new_file)
100
+ fields = l.first.split(':')
101
+ _(fields.first).must_equal "brenda"
102
+ bcrypt_hash = fields.last
103
+ _(::BCrypt::Password.valid_hash?(bcrypt_hash)).wont_be_nil
104
+
105
+ _, _version, count, _rest = bcrypt_hash.split("$")
106
+ _(count).must_equal ("%02d" % cost)
107
+ end
108
+ end
109
+
110
+ it "raises an error if the bcrypt cost is out of range" do
111
+ begin
112
+ @stdin.puts "b secret"
113
+ @stdin.puts "b secret"
114
+ @stdin.rewind
115
+ @htauth.run([ "-C", "42", "-B", "-c", @new_file, "brenda" ])
116
+ rescue SystemExit => se
117
+ _(@stderr.string).must_match( /ERROR:/m )
118
+ _(se.status).must_equal 1
119
+ end
120
+ end
121
+
122
+ it "raises an error if the bcrypt cost is not an integer" do
123
+ begin
124
+ @stdin.puts "b secret"
125
+ @stdin.puts "b secret"
126
+ @stdin.rewind
127
+ @htauth.run([ "-C", "forty-two", "-B", "-c", @new_file, "brenda" ])
128
+ rescue SystemExit => se
129
+ _(@stderr.string).must_match( /ERROR:/m )
130
+ _(se.status).must_equal 1
131
+ end
132
+
133
+ end
134
+
135
+ it "does not verify the password from stdin on -i option" do
136
+ begin
137
+ @stdin.puts "b secret"
138
+ @stdin.rewind
139
+ @htauth.run([ "-i", "-B", "-c", @new_file, "brenda" ])
140
+ rescue SystemExit => se
141
+ _(se.status).must_equal 0
142
+ l = IO.readlines(@new_file)
143
+ fields = l.first.split(':')
144
+ _(fields.first).must_equal "brenda"
145
+ bcrypt_hash = fields.last
146
+
147
+ _(::BCrypt::Password.valid_hash?(bcrypt_hash)).wont_be_nil
148
+ end
149
+ end
150
+
151
+ it "does not allow options -i and -b to both be set" do
152
+ begin
153
+ @stdin.puts "b secret"
154
+ @stdin.rewind
155
+ @htauth.run([ "-i", "-b", "-B", "-c", @new_file, "brenda", "b-secret" ])
156
+ rescue SystemExit => se
157
+ _(@stderr.string).must_match( /ERROR:/m )
158
+ _(se.status).must_equal 1
70
159
  end
71
160
  end
72
161
 
@@ -78,10 +167,10 @@ describe HTAuth::CLI::Passwd do
78
167
  @stdin.rewind
79
168
  @htauth.run([ "-c", @tf.path, "bob"])
80
169
  rescue SystemExit => se
81
- se.status.must_equal 0
170
+ _(se.status).must_equal 0
82
171
  after_lines = IO.readlines(@tf.path)
83
- after_lines.size.must_equal 1
84
- before_lines.size.must_equal 2
172
+ _(after_lines.size).must_equal 1
173
+ _(before_lines.size).must_equal 2
85
174
  end
86
175
  end
87
176
 
@@ -92,12 +181,12 @@ describe HTAuth::CLI::Passwd do
92
181
  @stdin.rewind
93
182
  @htauth.run([ "-s", @tf.path, "charlie" ])
94
183
  rescue SystemExit => se
95
- se.status.must_equal 0
184
+ _(se.status).must_equal 0
96
185
  after_lines = IO.readlines(@tf.path)
97
- after_lines.size.must_equal 3
186
+ _(after_lines.size).must_equal 3
98
187
  al = after_lines.last.split(':')
99
- al.first.must_equal "charlie"
100
- al.last.must_match( /\{SHA\}/ )
188
+ _(al.first).must_equal "charlie"
189
+ _(al.last).must_match( /\{SHA\}/ )
101
190
  end
102
191
  end
103
192
 
@@ -108,8 +197,8 @@ describe HTAuth::CLI::Passwd do
108
197
  @stdin.rewind
109
198
  @htauth.run(["-c", "-p", @tf.path, "bradley"])
110
199
  rescue SystemExit => se
111
- se.status.must_equal 0
112
- IO.read(@tf.path).strip.must_equal "bradley:a bad password"
200
+ _(se.status).must_equal 0
201
+ _(IO.read(@tf.path).strip).must_equal "bradley:a bad password"
113
202
  end
114
203
  end
115
204
 
@@ -117,8 +206,8 @@ describe HTAuth::CLI::Passwd do
117
206
  begin
118
207
  @htauth.run(["-c", "-p", "-b", @tf.path, "bradley", "a bad password"])
119
208
  rescue SystemExit => se
120
- se.status.must_equal 0
121
- IO.read(@tf.path).strip.must_equal "bradley:a bad password"
209
+ _(se.status).must_equal 0
210
+ _(IO.read(@tf.path).strip).must_equal "bradley:a bad password"
122
211
  end
123
212
  end
124
213
 
@@ -130,16 +219,16 @@ describe HTAuth::CLI::Passwd do
130
219
  @stdin.rewind
131
220
  @htauth.run([ "-d", @tf.path, "alice" ])
132
221
  rescue SystemExit => se
133
- @stderr.string.must_equal ""
134
- se.status.must_equal 0
222
+ _(@stderr.string).must_equal ""
223
+ _(se.status).must_equal 0
135
224
  after_lines = IO.readlines(@tf.path)
136
- after_lines.size.must_equal before_lines.size
225
+ _(after_lines.size).must_equal before_lines.size
137
226
 
138
227
  a_b = before_lines.first.split(":")
139
228
  a_a = after_lines.first.split(":")
140
229
 
141
- a_b.first.must_equal a_a.first
142
- a_b.last.wont_equal a_a.last
230
+ _(a_b.first).must_equal a_a.first
231
+ _(a_b.last).wont_equal a_a.last
143
232
  end
144
233
  end
145
234
 
@@ -147,9 +236,9 @@ describe HTAuth::CLI::Passwd do
147
236
  begin
148
237
  @htauth.run([ "-D", @tf.path, "bob" ])
149
238
  rescue SystemExit => se
150
- @stderr.string.must_equal ""
151
- se.status.must_equal 0
152
- IO.read(@tf.path).must_equal IO.read(PASSWD_DELETE_TEST_FILE)
239
+ _(@stderr.string).must_equal ""
240
+ _(se.status).must_equal 0
241
+ _(IO.read(@tf.path)).must_equal IO.read(PASSWD_DELETE_TEST_FILE)
153
242
  end
154
243
  end
155
244
 
@@ -157,8 +246,26 @@ describe HTAuth::CLI::Passwd do
157
246
  begin
158
247
  @htauth.run(["-n", "-p", "-b", "bradley", "a bad password"])
159
248
  rescue SystemExit => se
160
- se.status.must_equal 0
161
- @stdout.string.strip.must_equal "bradley:a bad password"
249
+ _(se.status).must_equal 0
250
+ _(@stdout.string.strip).must_equal "bradley:a bad password"
251
+ end
252
+ end
253
+
254
+ it "verifies a password when --verify is used - valid" do
255
+ begin
256
+ @htauth.run(["--verify", "-b", @tf.path, "alice", "a secret"])
257
+ rescue SystemExit => se
258
+ _(@stderr.string.strip).must_equal "Password for user alice correct."
259
+ _(se.status).must_equal 0
260
+ end
261
+ end
262
+
263
+ it "verifies a password when --verify is used - invalid" do
264
+ begin
265
+ @htauth.run(["--verify", "-b", @tf.path, "alice", "the wrong secret"])
266
+ rescue SystemExit => se
267
+ _(@stderr.string.strip).must_equal "Password verification for user alice failed."
268
+ _(se.status).must_equal 1
162
269
  end
163
270
  end
164
271
 
@@ -169,8 +276,8 @@ describe HTAuth::CLI::Passwd do
169
276
  @stdin.rewind
170
277
  @htauth.run([ "-c", "/etc/you-cannot-create-me", "alice"])
171
278
  rescue SystemExit => se
172
- @stderr.string.must_match( %r{Password file failure \(/etc/you-cannot-create-me\)}m )
173
- se.status.must_equal 1
279
+ _(@stderr.string).must_match( %r{Password file failure \(/etc/you-cannot-create-me\)}m )
280
+ _(se.status).must_equal 1
174
281
  end
175
282
  end
176
283
 
@@ -181,8 +288,8 @@ describe HTAuth::CLI::Passwd do
181
288
  @stdin.rewind
182
289
  @htauth.run([ @tf.path, "alice"])
183
290
  rescue SystemExit => se
184
- @stderr.string.must_match( /They don't match, sorry./m )
185
- se.status.must_equal 1
291
+ _(@stderr.string).must_match( /They don't match, sorry./m )
292
+ _(se.status).must_equal 1
186
293
  end
187
294
  end
188
295
 
@@ -190,8 +297,8 @@ describe HTAuth::CLI::Passwd do
190
297
  begin
191
298
  @htauth.run(["--blah"])
192
299
  rescue SystemExit => se
193
- @stderr.string.must_match( /ERROR:/m )
194
- se.status.must_equal 1
300
+ _(@stderr.string).must_match( /ERROR:/m )
301
+ _(se.status).must_equal 1
195
302
  end
196
303
  end
197
304
 
@@ -199,8 +306,25 @@ describe HTAuth::CLI::Passwd do
199
306
  begin
200
307
  @htauth.run(["-c", "-n"])
201
308
  rescue SystemExit => se
202
- @stderr.string.must_match( /ERROR:/m )
203
- se.status.must_equal 1
309
+ _(@stderr.string).must_match( /ERROR:/m )
310
+ _(se.status).must_equal 1
311
+ end
312
+ end
313
+
314
+ it "errors if multiple types of operations are attmpted to be used at once" do
315
+ begin
316
+ @htauth.run(["-n", "-D"])
317
+ rescue SystemExit => se
318
+ _(@stderr.string).must_match( /ERROR:/m )
319
+ _(se.status).must_equal 1
320
+ end
321
+
322
+ begin
323
+ @htauth.run(["--verify", "-D"])
324
+ rescue SystemExit => se
325
+ _(@stderr.string).must_match( /ERROR:/m )
326
+ _(se.status).must_equal 1
204
327
  end
328
+
205
329
  end
206
330
  end
@@ -2,15 +2,11 @@ require 'spec_helper'
2
2
  require 'htauth/crypt'
3
3
 
4
4
  describe HTAuth::Crypt do
5
- it "has a prefix" do
6
- HTAuth::Crypt.new.prefix.must_equal ""
7
- end
8
-
9
5
  it "encrypts the same way that apache does" do
10
6
  apache_salt = "L0LDd/.."
11
7
  apache_result = "L0ekWYm59LT1M"
12
8
  crypt = HTAuth::Crypt.new({ :salt => apache_salt} )
13
- crypt.encode("a secret").must_equal apache_result
9
+ _(crypt.encode("a secret")).must_equal apache_result
14
10
  end
15
11
  end
16
12
 
@@ -8,53 +8,53 @@ describe HTAuth::DigestEntry do
8
8
  end
9
9
 
10
10
  it "initializes with a user and realm" do
11
- @alice.user.must_equal "alice"
12
- @alice.realm.must_equal "htauth"
11
+ _(@alice.user).must_equal "alice"
12
+ _(@alice.realm).must_equal "htauth"
13
13
  end
14
14
 
15
15
  it "has the correct digest for a password" do
16
16
  @alice.password = "digit"
17
- @alice.digest.must_equal "4ed9e5744c6747af8f292d28afd6372e"
17
+ _(@alice.digest).must_equal "4ed9e5744c6747af8f292d28afd6372e"
18
18
  end
19
19
 
20
20
  it "returns username:realm for a key" do
21
- @alice.key.must_equal "alice:htauth"
21
+ _(@alice.key).must_equal "alice:htauth"
22
22
  end
23
23
 
24
24
  it "checks the password correctly" do
25
- @bob.authenticated?("b secret").must_equal true
25
+ _(@bob.authenticated?("b secret")).must_equal true
26
26
  end
27
27
 
28
28
  it "formats correctly when put to a string" do
29
- @bob.to_s.must_equal "bob:htauth:fcbeab6821d2ab3b00934c958db0fd1e"
29
+ _(@bob.to_s).must_equal "bob:htauth:fcbeab6821d2ab3b00934c958db0fd1e"
30
30
  end
31
31
 
32
32
  it "parses an input line" do
33
33
  @bob_new = HTAuth::DigestEntry.from_line("bob:htauth:fcbeab6821d2ab3b00934c958db0fd1e")
34
- @bob.user.must_equal @bob_new.user
35
- @bob.digest.must_equal @bob_new.digest
36
- @bob.realm.must_equal @bob_new.realm
34
+ _(@bob.user).must_equal @bob_new.user
35
+ _(@bob.digest).must_equal @bob_new.digest
36
+ _(@bob.realm).must_equal @bob_new.realm
37
37
  end
38
38
 
39
39
  it "knows if an input line is a possible entry and raises an exception" do
40
- lambda { HTAuth::DigestEntry.is_entry!("#stuff") }.must_raise(HTAuth::InvalidDigestEntry)
41
- lambda { HTAuth::DigestEntry.is_entry!("this:that:other:stuff") }.must_raise(HTAuth::InvalidDigestEntry)
42
- lambda { HTAuth::DigestEntry.is_entry!("this:that:other") }.must_raise(HTAuth::InvalidDigestEntry)
43
- lambda { HTAuth::DigestEntry.is_entry!("this:that:0a90549e8ffb2dd62f98252a95d88xyz") }.must_raise(HTAuth::InvalidDigestEntry)
40
+ _ { HTAuth::DigestEntry.is_entry!("#stuff") }.must_raise(HTAuth::InvalidDigestEntry)
41
+ _ { HTAuth::DigestEntry.is_entry!("this:that:other:stuff") }.must_raise(HTAuth::InvalidDigestEntry)
42
+ _ { HTAuth::DigestEntry.is_entry!("this:that:other") }.must_raise(HTAuth::InvalidDigestEntry)
43
+ _ { HTAuth::DigestEntry.is_entry!("this:that:0a90549e8ffb2dd62f98252a95d88xyz") }.must_raise(HTAuth::InvalidDigestEntry)
44
44
  end
45
45
 
46
46
  it "knows if an input line is a possible entry and returns false" do
47
- HTAuth::DigestEntry.is_entry?("#stuff").must_equal false
48
- HTAuth::DigestEntry.is_entry?("this:that:other:stuff").must_equal false
49
- HTAuth::DigestEntry.is_entry?("this:that:other").must_equal false
50
- HTAuth::DigestEntry.is_entry?("this:that:0a90549e8ffb2dd62f98252a95d88xyz").must_equal false
47
+ _(HTAuth::DigestEntry.is_entry?("#stuff")).must_equal false
48
+ _(HTAuth::DigestEntry.is_entry?("this:that:other:stuff")).must_equal false
49
+ _(HTAuth::DigestEntry.is_entry?("this:that:other")).must_equal false
50
+ _(HTAuth::DigestEntry.is_entry?("this:that:0a90549e8ffb2dd62f98252a95d88xyz")).must_equal false
51
51
  end
52
52
 
53
53
  it "knows if an input line is a possible entry and returns true" do
54
- HTAuth::DigestEntry.is_entry?("bob:htauth:0a90549e8ffb2dd62f98252a95d88697").must_equal true
54
+ _(HTAuth::DigestEntry.is_entry?("bob:htauth:0a90549e8ffb2dd62f98252a95d88697")).must_equal true
55
55
  end
56
56
 
57
57
  it "duplicates itself" do
58
- @alice.dup.to_s.must_equal @alice.to_s
58
+ _(@alice.dup.to_s).must_equal @alice.to_s
59
59
  end
60
60
  end
@@ -22,35 +22,35 @@ describe HTAuth::DigestFile do
22
22
 
23
23
  it "can add a new entry to an already existing digest file" do
24
24
  @digest_file.add_or_update("charlie", "htauth-new", "c secret")
25
- @digest_file.contents.must_equal IO.read(DIGEST_ADD_TEST_FILE)
25
+ _(@digest_file.contents).must_equal IO.read(DIGEST_ADD_TEST_FILE)
26
26
  end
27
27
 
28
28
  it "can tell if an entry already exists in the digest file" do
29
- @digest_file.has_entry?("alice", "htauth").must_equal true
30
- @digest_file.has_entry?("alice", "some other realm").must_equal false
29
+ _(@digest_file.has_entry?("alice", "htauth")).must_equal true
30
+ _(@digest_file.has_entry?("alice", "some other realm")).must_equal false
31
31
  end
32
32
 
33
33
  it "can update an entry in an already existing digest file" do
34
34
  @digest_file.add_or_update("alice", "htauth", "a new secret")
35
- @digest_file.contents.must_equal IO.read(DIGEST_UPDATE_TEST_FILE)
35
+ _(@digest_file.contents).must_equal IO.read(DIGEST_UPDATE_TEST_FILE)
36
36
  end
37
37
 
38
38
  it "fetches a copy of an entry" do
39
- @digest_file.fetch("alice", "htauth").to_s.must_equal "alice:htauth:2f361db93147d84831eb34f19d05bfbb"
39
+ _(@digest_file.fetch("alice", "htauth").to_s).must_equal "alice:htauth:2f361db93147d84831eb34f19d05bfbb"
40
40
  end
41
41
 
42
42
  it "raises an error if an attempt is made to alter a non-existenet file" do
43
- lambda { HTAuth::DigestFile.new("some-file") }.must_raise(HTAuth::FileAccessError)
43
+ _ { HTAuth::DigestFile.new("some-file") }.must_raise(HTAuth::FileAccessError)
44
44
  end
45
45
 
46
46
  # this test will only work on systems that have /etc/ssh_host_rsa_key
47
47
  it "raises an error if an attempt is made to open a file where no permissions are granted" do
48
- lambda { HTAuth::DigestFile.new("/etc/ssh_host_rsa_key") }.must_raise(HTAuth::FileAccessError)
48
+ _ { HTAuth::DigestFile.new("/etc/ssh_host_rsa_key") }.must_raise(HTAuth::FileAccessError)
49
49
  end
50
50
 
51
51
  it "deletes an entry" do
52
52
  @digest_file.delete("alice", "htauth")
53
- @digest_file.contents.must_equal IO.read(DIGEST_DELETE_TEST_FILE)
53
+ _(@digest_file.contents).must_equal IO.read(DIGEST_DELETE_TEST_FILE)
54
54
  end
55
55
 
56
56
  it "is usable in a ruby manner and yeilds itself when opened" do
@@ -59,7 +59,7 @@ describe HTAuth::DigestFile do
59
59
  pf.delete('bob', 'htauth')
60
60
  end
61
61
  lines = IO.readlines(@tf.path)
62
- lines.size.must_equal 1
63
- lines.first.strip.must_equal "alice:htauth:2f361db93147d84831eb34f19d05bfbb"
62
+ _(lines.size).must_equal 1
63
+ _(lines.first.strip).must_equal "alice:htauth:2f361db93147d84831eb34f19d05bfbb"
64
64
  end
65
65
  end
@@ -3,15 +3,11 @@ require File.join(File.dirname(__FILE__),"spec_helper.rb")
3
3
  require 'htauth/md5'
4
4
 
5
5
  describe HTAuth::Md5 do
6
- it "has a prefix" do
7
- HTAuth::Md5.new.prefix.must_equal "$apr1$"
8
- end
9
-
10
6
  it "encrypts the same way that apache does" do
11
7
  apache_salt = "L0LDd/.."
12
8
  apache_result = "$apr1$L0LDd/..$yhUzDjpxam5F1kWdtwMco1"
13
9
  md5 = HTAuth::Md5.new({ 'salt' => apache_salt })
14
- md5.encode("a secret").must_equal apache_result
10
+ _(md5.encode("a secret")).must_equal apache_result
15
11
  end
16
12
  end
17
13