Class: WEBrick::HTTPAuth::Htpasswd
- Inherits:
-
Object
- Object
- WEBrick::HTTPAuth::Htpasswd
- Includes:
- UserDB
- Defined in:
- lib/webrick/httpauth/htpasswd.rb
Overview
Htpasswd accesses apache-compatible password files. Passwords are matched to a realm where they are valid. For security, the path for a password database should be stored outside of the paths available to the HTTP server.
Htpasswd is intended for use with WEBrick::HTTPAuth::BasicAuth.
To create an Htpasswd database with a single user:
htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file'
htpasswd.set_passwd 'my realm', 'username', 'password'
htpasswd.flush
Instance Attribute Summary
Attributes included from UserDB
Instance Method Summary collapse
-
#delete_passwd(realm, user) ⇒ Object
Removes a password from the database for
user
inrealm
. -
#each ⇒ Object
Iterate passwords in the database.
-
#flush(output = nil) ⇒ Object
Flush the password database.
-
#get_passwd(realm, user, reload_db) ⇒ Object
Retrieves a password from the database for
user
inrealm
. -
#initialize(path, password_hash: nil) ⇒ Htpasswd
constructor
Open a password database at
path
. -
#reload ⇒ Object
Reload passwords from the database.
-
#set_passwd(realm, user, pass) ⇒ Object
Sets a password in the database for
user
inrealm
topass
.
Methods included from UserDB
Constructor Details
#initialize(path, password_hash: nil) ⇒ Htpasswd
Open a password database at path
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/webrick/httpauth/htpasswd.rb', line 38 def initialize(path, password_hash: nil) @path = path @mtime = Time.at(0) @passwd = Hash.new @auth_type = BasicAuth @password_hash = password_hash case @password_hash when nil # begin # require "string/crypt" # rescue LoadError # warn("Unable to load string/crypt, proceeding with deprecated use of String#crypt, consider using password_hash: :bcrypt") # end @password_hash = :crypt when :crypt # require "string/crypt" when :bcrypt require "bcrypt" else raise ArgumentError, "only :crypt and :bcrypt are supported for password_hash keyword argument" end File.open(@path,"a").close unless File.exist?(@path) reload end |
Instance Method Details
#delete_passwd(realm, user) ⇒ Object
Removes a password from the database for user
in realm
.
144 145 146 |
# File 'lib/webrick/httpauth/htpasswd.rb', line 144 def delete_passwd(realm, user) @passwd.delete(user) end |
#each ⇒ Object
Iterate passwords in the database.
151 152 153 154 155 |
# File 'lib/webrick/httpauth/htpasswd.rb', line 151 def each # :yields: [user, password] @passwd.keys.sort.each{|user| yield([user, @passwd[user]]) } end |
#flush(output = nil) ⇒ Object
Flush the password database. If output
is given the database will be written there instead of to the original path.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/webrick/httpauth/htpasswd.rb', line 103 def flush(output=nil) output ||= @path tmp = Tempfile.create("htpasswd", File::dirname(output)) renamed = false begin each{|item| tmp.puts(item.join(":")) } tmp.close File::rename(tmp.path, output) renamed = true ensure tmp.close File.unlink(tmp.path) if !renamed end end |
#get_passwd(realm, user, reload_db) ⇒ Object
Retrieves a password from the database for user
in realm
. If reload_db
is true the database will be reloaded first.
122 123 124 125 |
# File 'lib/webrick/httpauth/htpasswd.rb', line 122 def get_passwd(realm, user, reload_db) reload() if reload_db @passwd[user] end |
#reload ⇒ Object
Reload passwords from the database
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/webrick/httpauth/htpasswd.rb', line 68 def reload mtime = File::mtime(@path) if mtime > @mtime @passwd.clear File.open(@path){|io| while line = io.gets line.chomp! case line when %r!\A[^:]+:[a-zA-Z0-9./]{13}\z! if @password_hash == :bcrypt raise StandardError, ".htpasswd file contains crypt password, only bcrypt passwords supported" end user, pass = line.split(":", 2) when %r!\A[^:]+:\$2[aby]\$\d{2}\$.{53}\z! if @password_hash == :crypt raise StandardError, ".htpasswd file contains bcrypt password, only crypt passwords supported" end user, pass = line.split(":", 2) when /:\$/, /:{SHA}/ raise NotImplementedError, 'MD5, SHA1 .htpasswd file not supported' else raise StandardError, 'bad .htpasswd file' end @passwd[user] = pass end } @mtime = mtime end end |
#set_passwd(realm, user, pass) ⇒ Object
Sets a password in the database for user
in realm
to pass
.
130 131 132 133 134 135 136 137 138 139 |
# File 'lib/webrick/httpauth/htpasswd.rb', line 130 def set_passwd(realm, user, pass) if @password_hash == :bcrypt # Cost of 5 to match Apache default, and because the # bcrypt default of 10 will introduce significant delays # for every request. @passwd[user] = BCrypt::Password.create(pass, :cost=>5) else @passwd[user] = make_passwd(realm, user, pass) end end |