Class: HTAuth::PasswdFile

Inherits:
File
  • Object
show all
Defined in:
lib/htauth/passwd_file.rb

Overview

Public: An API for managing an ‘htpasswd’ file

Examples

::HTAuth::PasswdFile.open("my.passwd") do |pf|
  pf.has_entry?('myuser')
  pf.add_or_update('someuser', 'a password')
  pf.delete('someolduser')
end

Constant Summary collapse

ENTRY_KLASS =

Private: The class implementing a single entry in the PasswdFile

HTAuth::PasswdEntry

Constants inherited from File

File::ALTER, File::CREATE, File::STDOUT_FLAG

Instance Attribute Summary

Attributes inherited from File

#file, #filename

Instance Method Summary collapse

Methods inherited from File

#contents, #dirty!, #dirty?, #initialize, #load_entries, open, #save!

Constructor Details

This class inherits a constructor from HTAuth::File

Instance Method Details

#add(username, password, algorithm = Algorithm::DEFAULT, algorithm_args = {}) ⇒ Object

Public: Add a new record to the file.

username - the username of the entry password - the password of the entry algorithm - the algorithm to use (default: “md5”). Valid options are:

"md5", "bcrypt", "argon2", "sha1", "plaintext", or "crypt"

algorithm_args - key-value pairs of arguments that are passed to the

algorithm, currently this is only used to pass the cost
to the bcrypt algorithm

Examples

passwd_file.add("newuser", "password")
passwd_file.save!

passwd_file.add("newuser", "password", "sha1")
passwd_file.save!

passwd_file.add("newuser", "password", "bcrypt", { cost: 12 })
passwd_file.save!

Returns nothing. Raises PasswdFileError if the give username already exists.

Raises:



118
119
120
121
122
123
124
125
126
127
# File 'lib/htauth/passwd_file.rb', line 118

def add(username, password, algorithm = Algorithm::DEFAULT, algorithm_args = {})
  raise PasswdFileError, "Unable to add already existing user #{username}" if has_entry?(username)

  new_entry = PasswdEntry.new(username, password, algorithm, algorithm_args)
  new_index = @lines.size
  @lines << new_entry.to_s
  @entries[new_entry.key] = { "entry" => new_entry, "line_index" => new_index }
  dirty!
  nil
end

#add_or_update(username, password, algorithm = Algorithm::DEFAULT, algorithm_args = {}) ⇒ Object

Public: Add or update the username entry with the new password and algorithm. This will add a new entry if the username does not exist in the file. If the entry does exist in the file, then the password of the entry is updated to the new password / algorithm

The file is not written to disk until #save! is called.

username - the username of the entry password - the password of the entry algorithm - the algorithm to use (default: “md5”). Valid options are:

"md5", "bcrypt", "argon2", "sha1", "plaintext", or "crypt"

algorithm_args - key-value pairs of arguments that are passed to the

algorithm, currently this is only used to pass the cost
to the bcrypt algorithm

Examples

passwd_file.add_or_update("newuser", "password", Algorithm::SHA1)
passwd_file.save!

passwd_file.add_or_update("newuser", "password")
passwd_file.save!

Returns nothing.



87
88
89
90
91
92
93
# File 'lib/htauth/passwd_file.rb', line 87

def add_or_update(username, password, algorithm = Algorithm::DEFAULT, algorithm_args = {})
  if has_entry?(username)
    update(username, password, algorithm, algorithm_args)
  else
    add(username, password, algorithm, algorithm_args)
  end
end

#authenticated?(username, password) ⇒ Boolean

Public: authenticates the password of a given username

Check the password file for the given user, and check the input password against the existing one.

Examples

authenticated = password_file.authenticated?("alice", "a secret")

Returns true or false if the user exists Raises PasswordFileErrorif the given username does not exist

Returns:

  • (Boolean)

Raises:



199
200
201
202
203
204
# File 'lib/htauth/passwd_file.rb', line 199

def authenticated?(username, password)
  raise PasswdFileError, "Unable to authenticate a non-existent user #{username}" unless has_entry?(username)

  ir = internal_record(username)
  ir["entry"].authenticated?(password)
end

#delete(username) ⇒ Object

Public: remove the given username from the file The file is not written to disk until #save! is called.

username - the username to remove

Examples

passwd_file.delete("myuser")
passwd_file.save!

Returns nothing



51
52
53
54
55
56
57
58
59
60
# File 'lib/htauth/passwd_file.rb', line 51

def delete(username)
  if has_entry?(username)
    ir = internal_record(username)
    line_index = ir["line_index"]
    @entries.delete(ir["entry"].key)
    @lines[line_index] = nil
    dirty!
  end
  nil
end

#entry_klassObject

Internal: returns the class used for each entry

Returns a Class



209
210
211
# File 'lib/htauth/passwd_file.rb', line 209

def entry_klass
  ENTRY_KLASS
end

#fetch(username) ⇒ Object

Public: Returns a copy of then given PasswdEntry from the file.

Updating the PasswdEntry instance returned by this method will NOT update the file. To update the file, use #update and #save!

username - the username of the entry

Examples

entry = password_file.fetch("myuser")

Returns a PasswdEntry if the entry is found Returns nil if the entry is not found



181
182
183
184
185
186
# File 'lib/htauth/passwd_file.rb', line 181

def fetch(username)
  return nil unless has_entry?(username)

  ir = internal_record(username)
  ir["entry"].dup
end

#has_entry?(username) ⇒ Boolean

Public: Checks if the given username exists in the file

username - the username to check

Examples

passwd_file.has_entry?("myuser")
# => true

Returns true or false if the username

Returns:

  • (Boolean)


35
36
37
38
# File 'lib/htauth/passwd_file.rb', line 35

def has_entry?(username)
  test_entry = PasswdEntry.new(username)
  @entries.key?(test_entry.key)
end

#update(username, password, algorithm = Algorithm::EXISTING, algorithm_args = {}) ⇒ Object

Public: Update an existing record in the file.

By default, the same algorithm that already exists for the entry will be used with the new password. You may change the algorithm for an entry by setting the ‘algorithm` parameter.

username - the username of the entry password - the password of the entry algorithm - the algorithm to use (default: “existing”). Valid options are:

"existing", "md5", "bcrypt", "argon2", "sha1", "plaintext", or "crypt"

algorithm_args - key-value pairs of arguments that are passed to the

algorithm, currently this is only used to pass the cost
to the bcrypt algorithm

Examples

passwd_file.update("newuser", "password")
passwd_file.save!

passwd_file.update("newuser", "password", "sha1")
passwd_file.save!

passwd_file.update("newuser", "password", "bcrypt", { cost: 12 })
passwd_file.save!

Returns nothing. Raises PasswdFileError if the give username does not exist.

Raises:



156
157
158
159
160
161
162
163
164
165
166
# File 'lib/htauth/passwd_file.rb', line 156

def update(username, password, algorithm = Algorithm::EXISTING, algorithm_args = {})
  raise PasswdFileError, "Unable to update non-existent user #{username}" unless has_entry?(username)

  ir = internal_record(username)
  ir["entry"].algorithm = algorithm
  ir["entry"].algorithm_args = algorithm_args.dup
  ir["entry"].password = password
  @lines[ir["line_index"]] = ir["entry"].to_s
  dirty!
  nil
end