1 #
2 # httpauth/htdigest.rb -- Apache compatible htdigest file
3 #
4 # Author: IPR -- Internet Programming with Ruby -- writers
5 # Copyright (c) 2003 Internet Programming with Ruby writers. All rights
6 # reserved.
7 #
8 # $IPR: htdigest.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $
9
10 require 'webrick/httpauth/userdb'
11 require 'webrick/httpauth/digestauth'
12 require 'tempfile'
13
14 module WEBrick
15 module HTTPAuth
16 class Htdigest
17 include UserDB
18
19 def initialize(path)
20 @path = path
21 @mtime = Time.at(0)
22 @digest = Hash.new
23 @mutex = Mutex::new
24 @auth_type = DigestAuth
25 open(@path,"a").close unless File::exist?(@path)
26 reload
27 end
28
29 def reload
30 mtime = File::mtime(@path)
31 if mtime > @mtime
32 @digest.clear
33 open(@path){|io|
34 while line = io.gets
35 line.chomp!
36 user, realm, pass = line.split(/:/, 3)
37 unless @digest[realm]
38 @digest[realm] = Hash.new
39 end
40 @digest[realm][user] = pass
41 end
42 }
43 @mtime = mtime
44 end
45 end
46
47 def flush(output=nil)
48 output ||= @path
49 tmp = Tempfile.new("htpasswd", File::dirname(output))
50 begin
51 each{|item| tmp.puts(item.join(":")) }
52 tmp.close
53 File::rename(tmp.path, output)
54 rescue
55 tmp.close(true)
56 end
57 end
58
59 def get_passwd(realm, user, reload_db)
60 reload() if reload_db
61 if hash = @digest[realm]
62 hash[user]
63 end
64 end
65
66 def set_passwd(realm, user, pass)
67 @mutex.synchronize{
68 unless @digest[realm]
69 @digest[realm] = Hash.new
70 end
71 @digest[realm][user] = make_passwd(realm, user, pass)
72 }
73 end
74
75 def delete_passwd(realm, user)
76 if hash = @digest[realm]
77 hash.delete(user)
78 end
79 end
80
81 def each
82 @digest.keys.sort.each{|realm|
83 hash = @digest[realm]
84 hash.keys.sort.each{|user|
85 yield([user, realm, hash[user]])
86 }
87 }
88 end
89 end
90 end
91 end