htauth 2.3.0 → 3.0.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.md +14 -0
  3. data/Manifest.txt +4 -28
  4. data/exe/htdigest-ruby +14 -0
  5. data/exe/htpasswd-ruby +14 -0
  6. data/htauth.gemspec +33 -0
  7. data/lib/htauth/algorithm.rb +30 -29
  8. data/lib/htauth/argon2.rb +45 -36
  9. data/lib/htauth/bcrypt.rb +12 -11
  10. data/lib/htauth/cli/digest.rb +42 -46
  11. data/lib/htauth/cli/passwd.rb +126 -115
  12. data/lib/htauth/cli.rb +5 -3
  13. data/lib/htauth/console.rb +9 -6
  14. data/lib/htauth/crypt.rb +11 -9
  15. data/lib/htauth/descendant_tracker.rb +11 -9
  16. data/lib/htauth/digest_entry.rb +22 -20
  17. data/lib/htauth/digest_file.rb +25 -18
  18. data/lib/htauth/entry.rb +3 -1
  19. data/lib/htauth/error.rb +6 -5
  20. data/lib/htauth/file.rb +35 -39
  21. data/lib/htauth/md5.rb +35 -34
  22. data/lib/htauth/passwd_entry.rb +26 -24
  23. data/lib/htauth/passwd_file.rb +26 -21
  24. data/lib/htauth/plaintext.rb +7 -5
  25. data/lib/htauth/sha1.rb +9 -7
  26. data/lib/htauth/version.rb +3 -1
  27. data/lib/htauth.rb +29 -28
  28. metadata +15 -133
  29. data/Rakefile +0 -29
  30. data/bin/htdigest-ruby +0 -12
  31. data/bin/htpasswd-ruby +0 -12
  32. data/spec/algorithm_spec.rb +0 -7
  33. data/spec/argon2_spec.rb +0 -28
  34. data/spec/bcrypt_spec.rb +0 -32
  35. data/spec/cli/digest_spec.rb +0 -149
  36. data/spec/cli/passwd_spec.rb +0 -346
  37. data/spec/crypt_spec.rb +0 -11
  38. data/spec/digest_entry_spec.rb +0 -59
  39. data/spec/digest_file_spec.rb +0 -64
  40. data/spec/md5_spec.rb +0 -11
  41. data/spec/passwd_entry_spec.rb +0 -172
  42. data/spec/passwd_file_spec.rb +0 -84
  43. data/spec/plaintext_spec.rb +0 -11
  44. data/spec/sha1_spec.rb +0 -10
  45. data/spec/spec_helper.rb +0 -25
  46. data/spec/test.add.digest +0 -3
  47. data/spec/test.add.passwd +0 -3
  48. data/spec/test.delete.digest +0 -1
  49. data/spec/test.delete.passwd +0 -1
  50. data/spec/test.original.digest +0 -2
  51. data/spec/test.original.passwd +0 -2
  52. data/spec/test.update.digest +0 -2
  53. data/spec/test.update.passwd +0 -2
  54. data/tasks/default.rake +0 -250
  55. data/tasks/this.rb +0 -208
  56. /data/{LICENSE → LICENSE.txt} +0 -0
@@ -1,13 +1,14 @@
1
- require 'htauth/cli'
1
+ # frozen_string_literal: true
2
2
 
3
- require 'ostruct'
4
- require 'optparse'
3
+ require "htauth/cli"
4
+
5
+ require "ostruct"
6
+ require "optparse"
5
7
 
6
8
  module HTAuth
7
9
  module CLI
8
10
  # Internal: Implemenation of the commandline htpasswd-ruby
9
11
  class Passwd
10
-
11
12
  MAX_PASSWD_LENGTH = 255
12
13
 
13
14
  attr_accessor :passwd_file
@@ -19,14 +20,14 @@ module HTAuth
19
20
  end
20
21
 
21
22
  def options
22
- if @options.nil? then
23
+ if @options.nil?
23
24
  @options = ::OpenStruct.new
24
25
  @options.batch_mode = false
25
26
  @options.file_mode = File::ALTER
26
27
  @options.passwdfile = nil
27
28
  @options.algorithm = Algorithm::EXISTING
28
29
  @options.algorithm_args = {}
29
- @options.read_stdin_once= false
30
+ @options.read_stdin_once = false
30
31
  @options.send_to_stdout = false
31
32
  @options.show_version = false
32
33
  @options.show_help = false
@@ -38,96 +39,94 @@ module HTAuth
38
39
  end
39
40
 
40
41
  def option_parser
41
- if not @option_parser then
42
- @option_parser = OptionParser.new(nil, 16) do |op|
43
- op.banner = <<-EOB
44
- Usage:
45
- #{op.program_name} [-acimBdpsD] [--verify] [-C cost] passwordfile username
46
- #{op.program_name} -b[acmBdpsD] [--verify] [-C cost] passwordfile username password
42
+ @option_parser ||= OptionParser.new(nil, 16) do |op|
43
+ op.banner = <<~BANNER
44
+ Usage:
45
+ #{op.program_name} [-acimBdpsD] [--verify] [-C cost] passwordfile username
46
+ #{op.program_name} -b[acmBdpsD] [--verify] [-C cost] passwordfile username password
47
47
 
48
- #{op.program_name} -n[imBdps] [-C cost] username
49
- #{op.program_name} -nb[mBdps] [-C cost] username password
50
- EOB
48
+ #{op.program_name} -n[imBdps] [-C cost] username
49
+ #{op.program_name} -nb[mBdps] [-C cost] username password
50
+ BANNER
51
51
 
52
- op.separator ""
52
+ op.separator ""
53
53
 
54
- op.on("--argon2", "Force argon2 encryption of the password.") do |a|
55
- options.algorithm = Algorithm::ARGON2
56
- end
54
+ op.on("--argon2", "Force argon2 encryption of the password.") do |_a|
55
+ options.algorithm = Algorithm::ARGON2
56
+ end
57
57
 
58
- op.on("-b", "--batch", "Batch mode, get the password from the command line, rather than prompt.") do |b|
59
- options.batch_mode = b
60
- end
58
+ op.on("-b", "--batch", "Batch mode, get the password from the command line, rather than prompt.") do |b|
59
+ options.batch_mode = b
60
+ end
61
61
 
62
- op.on("-B", "--bcrypt", "Force bcrypt encryption of the password.") do |b|
63
- options.algorithm = Algorithm::BCRYPT
64
- end
62
+ op.on("-B", "--bcrypt", "Force bcrypt encryption of the password.") do |_b|
63
+ options.algorithm = Algorithm::BCRYPT
64
+ end
65
65
 
66
- op.on("-CCOST", "--cost COST", "Set the computing time used for the bcrypt algorithm",
67
- "(higher is more secure but slower, default: 5, valid: 4 to 31).") do |c|
68
- if c !~ /\A\d+\z/ then
69
- raise ::OptionParser::ParseError, "the bcrypt cost must be an integer from 4 to 31, `#{c}` is invalid"
70
- end
71
-
72
- cost = c.to_i
73
- if (4..31).include?(cost)
74
- options.algorithm_args = { :cost => cost }
75
- else
76
- raise ::OptionParser::ParseError, "the bcrypt cost must be an integer from 4 to 31, `#{c}` is invalid"
77
- end
66
+ op.on("-CCOST", "--cost COST", "Set the computing time used for the bcrypt algorithm",
67
+ "(higher is more secure but slower, default: 5, valid: 4 to 31).") do |c|
68
+ unless /\A\d+\z/.match?(c)
69
+ raise ::OptionParser::ParseError, "the bcrypt cost must be an integer from 4 to 31, `#{c}` is invalid"
78
70
  end
79
71
 
80
- op.on("-c", "--create", "Create a new file; this overwrites an existing file.") do |c|
81
- options.file_mode = HTAuth::File::CREATE
82
- options.operation << :add_or_update
72
+ cost = c.to_i
73
+ unless (4..31).cover?(cost)
74
+ raise ::OptionParser::ParseError, "the bcrypt cost must be an integer from 4 to 31, `#{c}` is invalid"
83
75
  end
84
76
 
85
- op.on("-d", "--crypt", "Force CRYPT encryption of the password.") do |c|
86
- options.algorithm = Algorithm::CRYPT
87
- end
77
+ options.algorithm_args = { cost: cost }
78
+ end
88
79
 
89
- op.on("-D", "--delete", "Delete the specified user.") do |d|
90
- options.operation << :delete
91
- end
80
+ op.on("-c", "--create", "Create a new file; this overwrites an existing file.") do |_c|
81
+ options.file_mode = HTAuth::File::CREATE
82
+ options.operation << :add_or_update
83
+ end
92
84
 
93
- op.on("-h", "--help", "Display this help.") do |h|
94
- options.show_help = h
95
- end
85
+ op.on("-d", "--crypt", "Force CRYPT encryption of the password.") do |_c|
86
+ options.algorithm = Algorithm::CRYPT
87
+ end
96
88
 
97
- op.on("-i", "--stdin", "Read the passwod from stdin without verivication (for script usage).") do |i|
98
- options.read_stdin_once = true
99
- end
89
+ op.on("-D", "--delete", "Delete the specified user.") do |_d|
90
+ options.operation << :delete
91
+ end
100
92
 
101
- op.on("-m", "--md5", "Force MD5 encryption of the password (default).") do |m|
102
- options.algorithm = Algorithm::MD5
103
- end
93
+ op.on("-h", "--help", "Display this help.") do |h|
94
+ options.show_help = h
95
+ end
104
96
 
105
- op.on("-n", "--stdout", "Do not update the file; Display the results on stdout instead.") do |n|
106
- options.send_to_stdout = true
107
- options.passwdfile = HTAuth::File::STDOUT_FLAG
108
- options.operation << :stdout
109
- end
97
+ op.on("-i", "--stdin", "Read the passwod from stdin without verivication (for script usage).") do |_i|
98
+ options.read_stdin_once = true
99
+ end
110
100
 
111
- op.on("-p", "--plaintext", "Do not encrypt the password (plaintext).") do |p|
112
- options.algorithm = Algorithm::PLAINTEXT
113
- end
101
+ op.on("-m", "--md5", "Force MD5 encryption of the password (default).") do |_m|
102
+ options.algorithm = Algorithm::MD5
103
+ end
114
104
 
115
- op.on("-s", "--sha1", "Force SHA encryption of the password.") do |s|
116
- options.algorithm = Algorithm::SHA1
117
- end
105
+ op.on("-n", "--stdout", "Do not update the file; Display the results on stdout instead.") do |_n|
106
+ options.send_to_stdout = true
107
+ options.passwdfile = HTAuth::File::STDOUT_FLAG
108
+ options.operation << :stdout
109
+ end
118
110
 
119
- op.on("-v", "--version", "Show version info.") do |v|
120
- options.show_version = v
121
- end
111
+ op.on("-p", "--plaintext", "Do not encrypt the password (plaintext).") do |_p|
112
+ options.algorithm = Algorithm::PLAINTEXT
113
+ end
122
114
 
123
- op.on("--verify", "Verify password for the specified user.") do |v|
124
- options.operation << :verify
125
- end
115
+ op.on("-s", "--sha1", "Force SHA encryption of the password.") do |_s|
116
+ options.algorithm = Algorithm::SHA1
117
+ end
126
118
 
127
- op.separator ""
119
+ op.on("-v", "--version", "Show version info.") do |v|
120
+ options.show_version = v
121
+ end
128
122
 
129
- op.separator "The SHA algorihtm does not use a salt and is less secure than the MD5 algorithm."
123
+ op.on("--verify", "Verify password for the specified user.") do |_v|
124
+ options.operation << :verify
130
125
  end
126
+
127
+ op.separator ""
128
+
129
+ op.separator "The SHA algorihtm does not use a salt and is less secure than the MD5 algorithm."
131
130
  end
132
131
  @option_parser
133
132
  end
@@ -143,35 +142,48 @@ Usage:
143
142
  end
144
143
 
145
144
  def parse_options(argv)
146
- begin
147
- option_parser.parse!(argv)
148
- show_version if options.show_version
149
- show_help if options.show_help
150
-
151
- raise ::OptionParser::ParseError, "only one of --create, --stdout, --verify, --delete may be specified" if options.operation.size > 1
152
- raise ::OptionParser::ParseError, "Unable to send to stdout AND create a new file" if options.send_to_stdout and (options.file_mode == File::CREATE)
153
- raise ::OptionParser::ParseError, "a username is needed" if options.send_to_stdout and argv.size < 1
154
- raise ::OptionParser::ParseError, "a username and password are needed" if options.send_to_stdout and options.batch_mode and ( argv.size < 2 )
155
- raise ::OptionParser::ParseError, "a passwordfile, username and password are needed " if not options.send_to_stdout and options.batch_mode and ( argv.size < 3 )
156
- raise ::OptionParser::ParseError, "a passwordfile and username are needed" if argv.size < 2
157
- raise ::OptionParser::ParseError, "options -i and -b are mutually exclusive" if options.batch_mode && options.read_stdin_once
158
-
159
- options.operation = options.operation.shift || :add_or_update
160
- options.passwdfile = argv.shift unless options.send_to_stdout
161
- options.username = argv.shift
162
- options.password = argv.shift if options.batch_mode
163
-
164
- rescue ::OptionParser::ParseError => pe
165
- $stderr.puts "ERROR: #{option_parser.program_name} - #{pe}"
166
- show_help
167
- exit 1
145
+ option_parser.parse!(argv)
146
+ show_version if options.show_version
147
+ show_help if options.show_help
148
+
149
+ if options.operation.size > 1
150
+ raise ::OptionParser::ParseError,
151
+ "only one of --create, --stdout, --verify, --delete may be specified"
152
+ end
153
+ if options.send_to_stdout && (options.file_mode == File::CREATE)
154
+ raise ::OptionParser::ParseError,
155
+ "Unable to send to stdout AND create a new file"
156
+ end
157
+ raise ::OptionParser::ParseError, "a username is needed" if options.send_to_stdout && argv.empty?
158
+ if options.send_to_stdout && options.batch_mode && (argv.size < 2)
159
+ raise ::OptionParser::ParseError,
160
+ "a username and password are needed"
168
161
  end
162
+ if !options.send_to_stdout && options.batch_mode && (argv.size < 3)
163
+ raise ::OptionParser::ParseError,
164
+ "a passwordfile, username and password are needed "
165
+ end
166
+ raise ::OptionParser::ParseError, "a passwordfile and username are needed" if argv.size < 2
167
+ if options.batch_mode && options.read_stdin_once
168
+ raise ::OptionParser::ParseError,
169
+ "options -i and -b are mutually exclusive"
170
+ end
171
+
172
+ options.operation = options.operation.shift || :add_or_update
173
+ options.passwdfile = argv.shift unless options.send_to_stdout
174
+ options.username = argv.shift
175
+ options.password = argv.shift if options.batch_mode
176
+ rescue ::OptionParser::ParseError => e
177
+ warn "ERROR: #{option_parser.program_name} - #{e}"
178
+ show_help
179
+ exit 1
169
180
  end
170
181
 
171
- def fetch_password(width=20)
182
+ def fetch_password(width = 20)
172
183
  return options.password if options.batch_mode
184
+
173
185
  console = Console.new
174
- if options.read_stdin_once then
186
+ if options.read_stdin_once
175
187
  pw_in = console.read_answer
176
188
  return pw_in
177
189
  end
@@ -188,10 +200,10 @@ Usage:
188
200
  raise PasswordError, "They don't match, sorry." unless pw_in == pw_validate
189
201
  end
190
202
 
191
- return pw_in
203
+ pw_in
192
204
  end
193
205
 
194
- def run(argv, env = ENV)
206
+ def run(argv, _env = ENV)
195
207
  begin
196
208
  parse_options(argv)
197
209
  console = Console.new
@@ -201,16 +213,15 @@ Usage:
201
213
  passwd_file.delete(options.username)
202
214
  passwd_file.save!
203
215
  when :verify
204
- if passwd_file.has_entry?(options.username) then
205
- pw_in = fetch_password
206
- if passwd_file.authenticated?(options.username, pw_in) then
207
- $stderr.puts "Password for user #{options.username} correct."
208
- else
209
- raise HTAuth::Error, "Password verification for user #{options.username} failed."
210
- end
211
- else
212
- raise HTAuth::Error, "User #{options.username} not found"
216
+ raise HTAuth::Error, "User #{options.username} not found" unless passwd_file.has_entry?(options.username)
217
+
218
+ pw_in = fetch_password
219
+ unless passwd_file.authenticated?(options.username, pw_in)
220
+ raise HTAuth::Error, "Password verification for user #{options.username} failed."
213
221
  end
222
+
223
+ warn "Password for user #{options.username} correct."
224
+
214
225
  when :add_or_update
215
226
  options.password = fetch_password
216
227
  action = passwd_file.has_entry?(options.username) ? "Changing" : "Adding"
@@ -222,16 +233,16 @@ Usage:
222
233
  passwd_file.add_or_update(options.username, options.password, options.algorithm, options.algorithm_args)
223
234
  passwd_file.save!
224
235
  end
225
- rescue HTAuth::FileAccessError => fae
236
+ rescue HTAuth::FileAccessError => e
226
237
  msg = "Password file failure (#{options.passwdfile}) "
227
- $stderr.puts "#{msg}: #{fae.message}"
238
+ warn "#{msg}: #{e.message}"
228
239
  exit 1
229
- rescue HTAuth::Error => pe
230
- $stderr.puts "#{pe.message}"
240
+ rescue HTAuth::Error => e
241
+ warn e.message
231
242
  exit 1
232
- rescue SignalException => se
243
+ rescue SignalException => e
233
244
  $stderr.puts
234
- $stderr.puts "Interrupted #{se}"
245
+ warn "Interrupted #{e}"
235
246
  exit 1
236
247
  end
237
248
  exit 0
data/lib/htauth/cli.rb CHANGED
@@ -1,7 +1,9 @@
1
- require 'htauth'
2
- require 'htauth/console'
1
+ # frozen_string_literal: true
2
+
3
+ require "htauth"
4
+ require "htauth/console"
3
5
  module HTAuth
6
+ # Internal: Commande Line Module
4
7
  module CLI
5
-
6
8
  end
7
9
  end
@@ -1,13 +1,14 @@
1
- require 'io/console'
2
- require 'htauth/error'
1
+ # frozen_string_literal: true
2
+
3
+ require "io/console"
4
+ require "htauth/error"
3
5
 
4
6
  # With many thanks to JEG2 - http://graysoftinc.com/terminal-tricks/random-access-terminal
5
7
  #
6
8
  module HTAuth
7
9
  # Internal: Utility class for managing console input/output
8
10
  class Console
9
- attr_reader :input
10
- attr_reader :output
11
+ attr_reader :input, :output
11
12
 
12
13
  def initialize(input = $stdin, output = $stdout)
13
14
  @input = input
@@ -23,9 +24,11 @@ module HTAuth
23
24
  answer = read_answer
24
25
  output.puts
25
26
  raise ConsoleError, "No input given" if answer.nil?
27
+
26
28
  answer.strip!
27
- raise ConsoleError, "No input given" if answer.length == 0
28
- return answer
29
+ raise ConsoleError, "No input given" if answer.empty?
30
+
31
+ answer
29
32
  end
30
33
 
31
34
  def read_answer
data/lib/htauth/crypt.rb CHANGED
@@ -1,26 +1,28 @@
1
- require 'htauth/algorithm'
1
+ # frozen_string_literal: true
2
+
3
+ require "htauth/algorithm"
2
4
 
3
5
  module HTAuth
4
6
  # Internal: The basic crypt algorithm
5
7
  class Crypt < Algorithm
6
-
7
8
  ENTRY_LENGTH = 13
8
- ENTRY_REGEX = %r{\A[^$:\s]{#{ENTRY_LENGTH}}\z}
9
+ ENTRY_REGEX = /\A[^$:\s]{#{ENTRY_LENGTH}}\z/
9
10
 
10
11
  def self.handles?(password_entry)
11
12
  ENTRY_REGEX.match?(password_entry)
12
13
  end
13
14
 
14
15
  def self.extract_salt_from_existing_password_field(existing)
15
- existing[0,2]
16
+ existing[0, 2]
16
17
  end
17
18
 
18
19
  def initialize(params = {})
19
- if existing = (params['existing'] || params[:existing]) then
20
- @salt = self.class.extract_salt_from_existing_password_field(existing)
21
- else
22
- @salt = params[:salt] || params['salt'] || gen_salt
23
- end
20
+ super()
21
+ @salt = if (existing = params["existing"] || params[:existing])
22
+ self.class.extract_salt_from_existing_password_field(existing)
23
+ else
24
+ params[:salt] || params["salt"] || gen_salt
25
+ end
24
26
  end
25
27
 
26
28
  def encode(password)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HTAuth
2
4
  #
3
5
  # Use by either
@@ -18,28 +20,28 @@ module HTAuth
18
20
  # them in a Set that is available via the 'children' method.
19
21
  #
20
22
  module DescendantTracker
21
- def inherited( klass )
22
- return unless klass.instance_of?( Class )
23
- self.children << klass
23
+ def inherited(klass)
24
+ super
25
+ return unless klass.instance_of?(Class)
26
+
27
+ children << klass
24
28
  end
25
29
 
26
30
  #
27
31
  # The list of children that are registered
28
32
  #
29
33
  def children
30
- unless defined? @children
31
- @children = Array.new
32
- end
33
- return @children
34
+ @children = [] unless defined? @children
35
+ @children
34
36
  end
35
37
 
36
38
  #
37
39
  # find the child that returns truthy for then given method and
38
40
  # parameters
39
41
  #
40
- def find_child( method, *args )
42
+ def find_child(method, *args)
41
43
  children.find do |child|
42
- child.send( method, *args )
44
+ child.send(method, *args)
43
45
  end
44
46
  end
45
47
  end
@@ -1,12 +1,13 @@
1
- require 'htauth/error'
2
- require 'htauth/entry'
3
- require 'htauth/algorithm'
4
- require 'digest/md5'
1
+ # frozen_string_literal: true
2
+
3
+ require "htauth/error"
4
+ require "htauth/entry"
5
+ require "htauth/algorithm"
6
+ require "digest/md5"
5
7
 
6
8
  module HTAuth
7
9
  # Internal: Object version of a single record from an htdigest file
8
10
  class DigestEntry
9
-
10
11
  # Internal: The user of this entry
11
12
  attr_accessor :user
12
13
  # Internal: The realm of this entry
@@ -21,10 +22,10 @@ module HTAuth
21
22
  #
22
23
  # Returns an instance of DigestEntry
23
24
  def from_line(line)
24
- parts = is_entry!(line)
25
+ parts = entry!(line)
25
26
  d = DigestEntry.new(parts[0], parts[1])
26
27
  d.digest = parts[2]
27
- return d
28
+ d
28
29
  end
29
30
 
30
31
  # Internal: test if the given line is valid for this Entry class
@@ -37,30 +38,31 @@ module HTAuth
37
38
  #
38
39
  # Returns the individual parts of the line
39
40
  # Raises InvalidDigestEntry if it is not a a valid entry
40
- def is_entry!(line)
41
- raise InvalidDigestEntry, "line commented out" if line =~ /\A#/
41
+ def entry!(line)
42
+ raise InvalidDigestEntry, "line commented out" if line.start_with?("#")
43
+
42
44
  parts = line.strip.split(":")
43
45
  raise InvalidDigestEntry, "line must be of the format username:realm:md5checksum" if parts.size != 3
44
- raise InvalidDigestEntry, "md5 checksum is not 32 characters long" if parts.last.size != 32
45
- raise InvalidDigestEntry, "md5 checksum has invalid characters" if parts.last !~ /\A[[:xdigit:]]{32}\Z/
46
- return parts
46
+ raise InvalidDigestEntry, "md5 checksum is not 32 characters long" if parts.last.size != 32
47
+ raise InvalidDigestEntry, "md5 checksum has invalid characters" unless /\A[[:xdigit:]]{32}\Z/.match?(parts.last)
48
+
49
+ parts
47
50
  end
48
51
 
49
52
  # Internal: Returns whether or not the line is a valid entry
50
53
  #
51
54
  # Returns true or false
52
- def is_entry?(line)
53
- begin
54
- is_entry!(line)
55
- return true
56
- rescue InvalidDigestEntry
57
- return false
58
- end
55
+ def entry?(line)
56
+ entry!(line)
57
+ true
58
+ rescue InvalidDigestEntry
59
+ false
59
60
  end
60
61
  end
61
62
 
62
63
  # Internal: Create a new Entry with the given user, realm and password
63
64
  def initialize(user, realm, password = "")
65
+ super()
64
66
  @user = user
65
67
  @realm = realm
66
68
  @digest = calc_digest(password)
@@ -79,7 +81,7 @@ module HTAuth
79
81
  # Public: Check if the given password is the password of this entry.
80
82
  def authenticated?(check_password)
81
83
  check = calc_digest(check_password)
82
- return Algorithm.secure_compare(check, digest)
84
+ Algorithm.secure_compare(check, digest)
83
85
  end
84
86
 
85
87
  # Internal: Returns the key of this entry
@@ -1,7 +1,9 @@
1
- require 'stringio'
2
- require 'htauth/error'
3
- require 'htauth/file'
4
- require 'htauth/digest_entry'
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+ require "htauth/error"
5
+ require "htauth/file"
6
+ require "htauth/digest_entry"
5
7
 
6
8
  module HTAuth
7
9
  # Public: An API for managing an 'htdigest' file
@@ -15,7 +17,6 @@ module HTAuth
15
17
  # end
16
18
  #
17
19
  class DigestFile < HTAuth::File
18
-
19
20
  # Private: The class implementing a single entry in the DigestFile
20
21
  ENTRY_KLASS = HTAuth::DigestEntry
21
22
 
@@ -32,7 +33,7 @@ module HTAuth
32
33
  # Returns true or false if the username/realm combination is found.
33
34
  def has_entry?(username, realm)
34
35
  test_entry = DigestEntry.new(username, realm)
35
- @entries.has_key?(test_entry.key)
36
+ @entries.key?(test_entry.key)
36
37
  end
37
38
 
38
39
  # Public: remove the given username / realm from the file.
@@ -48,10 +49,10 @@ module HTAuth
48
49
  #
49
50
  # Returns nothing
50
51
  def delete(username, realm)
51
- if has_entry?(username, realm) then
52
+ if has_entry?(username, realm)
52
53
  ir = internal_record(username, realm)
53
- line_index = ir['line_index']
54
- @entries.delete(ir['entry'].key)
54
+ line_index = ir["line_index"]
55
+ @entries.delete(ir["entry"].key)
55
56
  @lines[line_index] = nil
56
57
  dirty!
57
58
  end
@@ -76,7 +77,7 @@ module HTAuth
76
77
  #
77
78
  # Returns nothing.
78
79
  def add_or_update(username, realm, password)
79
- if has_entry?(username, realm) then
80
+ if has_entry?(username, realm)
80
81
  update(username, realm, password)
81
82
  else
82
83
  add(username, realm, password)
@@ -97,14 +98,16 @@ module HTAuth
97
98
  # Returns nothing.
98
99
  # Raises DigestFileError if the give username / realm already exists.
99
100
  def add(username, realm, password)
100
- raise DigestFileError, "Unable to add already existing user #{username} in realm #{realm}" if has_entry?(username, realm)
101
+ raise DigestFileError, "Unable to add already existing user #{username} in realm #{realm}" if has_entry?(
102
+ username, realm
103
+ )
101
104
 
102
105
  new_entry = DigestEntry.new(username, realm, password)
103
106
  new_index = @lines.size
104
107
  @lines << new_entry.to_s
105
- @entries[new_entry.key] = { 'entry' => new_entry, 'line_index' => new_index }
108
+ @entries[new_entry.key] = { "entry" => new_entry, "line_index" => new_index }
106
109
  dirty!
107
- return nil
110
+ nil
108
111
  end
109
112
 
110
113
  # Public: Updates an existing username / relam entry with a new password
@@ -121,12 +124,15 @@ module HTAuth
121
124
  # Returns nothing
122
125
  # Raises DigestfileError if the username / realm is not found in the file
123
126
  def update(username, realm, password)
124
- raise DigestFileError, "Unable to update non-existent user #{username} in realm #{realm}" unless has_entry?(username, realm)
127
+ raise DigestFileError, "Unable to update non-existent user #{username} in realm #{realm}" unless has_entry?(
128
+ username, realm
129
+ )
130
+
125
131
  ir = internal_record(username, realm)
126
- ir['entry'].password = password
127
- @lines[ir['line_index']] = ir['entry'].to_s
132
+ ir["entry"].password = password
133
+ @lines[ir["line_index"]] = ir["entry"].to_s
128
134
  dirty!
129
- return nil
135
+ nil
130
136
  end
131
137
 
132
138
  # Public: Returns the given DigestEntry from the file.
@@ -145,8 +151,9 @@ module HTAuth
145
151
  # Returns nil if the entry is not found
146
152
  def fetch(username, realm)
147
153
  return nil unless has_entry?(username, realm)
154
+
148
155
  ir = internal_record(username, realm)
149
- return ir['entry'].dup
156
+ ir["entry"].dup
150
157
  end
151
158
 
152
159
  # Internal: returns the class used for each entry
data/lib/htauth/entry.rb CHANGED
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module HTAuth
2
4
  # Internal: base class from which all entries are derived
3
5
  class Entry
4
6
  # Internal: return a new instance of this entry
5
7
  def dup
6
- self.class.from_line(self.to_s)
8
+ self.class.from_line(to_s)
7
9
  end
8
10
  end
9
11
  end