1 #
2 # httpauth/htpasswd -- Apache compatible htpasswd 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: htpasswd.rb,v 1.4 2003/07/22 19:20:45 gotoyuzo Exp $
9
10 require 'webrick/httpauth/userdb'
11 require 'webrick/httpauth/basicauth'
12 require 'tempfile'
13
14 module WEBrick
15 module HTTPAuth
16 class Htpasswd
17 include UserDB
18
19 def initialize(path)
20 @path = path
21 @mtime = Time.at(0)
22 @passwd = Hash.new
23 @auth_type = BasicAuth
24 open(@path,"a").close unless File::exist?(@path)
25 reload
26 end
27
28 def reload
29 mtime = File::mtime(@path)
30 if mtime > @mtime
31 @passwd.clear
32 open(@path){|io|
33 while line = io.gets
34 line.chomp!
35 case line
36 when %r!\A[^:]+:[a-zA-Z0-9./]{13}\z!
37 user, pass = line.split(":")
38 when /:\$/, /:\{SHA\}/
39 raise NotImplementedError,
40 'MD5, SHA1 .htpasswd file not supported'
41 else
42 raise StandardError, 'bad .htpasswd file'
43 end
44 @passwd[user] = pass
45 end
46 }
47 @mtime = mtime
48 end
49 end
50
51 def flush(output=nil)
52 output ||= @path
53 tmp = Tempfile.new("htpasswd", File::dirname(output))
54 begin
55 each{|item| tmp.puts(item.join(":")) }
56 tmp.close
57 File::rename(tmp.path, output)
58 rescue
59 tmp.close(true)
60 end
61 end
62
63 def get_passwd(realm, user, reload_db)
64 reload() if reload_db
65 @passwd[user]
66 end
67
68 def set_passwd(realm, user, pass)
69 @passwd[user] = make_passwd(realm, user, pass)
70 end
71
72 def delete_passwd(realm, user)
73 @passwd.delete(user)
74 end
75
76 def each
77 @passwd.keys.sort.each{|user|
78 yield([user, @passwd[user]])
79 }
80 end
81 end
82 end
83 end