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:



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

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!
  return 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.



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

def add_or_update(username, password, algorithm = Algorithm::DEFAULT, algorithm_args = {})
  if has_entry?(username) then
    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:



195
196
197
198
199
# File 'lib/htauth/passwd_file.rb', line 195

def authenticated?(username, password)
  raise PasswdFileError, "Unable to authenticate a non-existent user #{username}" unless has_entry?(username)
  ir = internal_record(username)
  return 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



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

def delete(username)
  if has_entry?(username) then 
    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



204
205
206
# File 'lib/htauth/passwd_file.rb', line 204

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



178
179
180
181
182
# File 'lib/htauth/passwd_file.rb', line 178

def fetch(username)
  return nil unless has_entry?(username)
  ir = internal_record(username)
  return 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)


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

def has_entry?(username)
  test_entry = PasswdEntry.new(username)
  @entries.has_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:



154
155
156
157
158
159
160
161
162
163
# File 'lib/htauth/passwd_file.rb', line 154

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!
  return nil
end