qoobaa-rack 1.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/COPYING +18 -0
  2. data/KNOWN-ISSUES +18 -0
  3. data/RDOX +0 -0
  4. data/README +353 -0
  5. data/Rakefile +164 -0
  6. data/SPEC +164 -0
  7. data/bin/rackup +176 -0
  8. data/contrib/rack_logo.svg +111 -0
  9. data/example/lobster.ru +4 -0
  10. data/example/protectedlobster.rb +14 -0
  11. data/example/protectedlobster.ru +8 -0
  12. data/lib/rack/adapter/camping.rb +22 -0
  13. data/lib/rack/auth/abstract/handler.rb +37 -0
  14. data/lib/rack/auth/abstract/request.rb +37 -0
  15. data/lib/rack/auth/basic.rb +58 -0
  16. data/lib/rack/auth/digest/md5.rb +124 -0
  17. data/lib/rack/auth/digest/nonce.rb +51 -0
  18. data/lib/rack/auth/digest/params.rb +55 -0
  19. data/lib/rack/auth/digest/request.rb +40 -0
  20. data/lib/rack/auth/openid.rb +487 -0
  21. data/lib/rack/builder.rb +63 -0
  22. data/lib/rack/cascade.rb +41 -0
  23. data/lib/rack/chunked.rb +49 -0
  24. data/lib/rack/commonlogger.rb +52 -0
  25. data/lib/rack/conditionalget.rb +47 -0
  26. data/lib/rack/content_length.rb +29 -0
  27. data/lib/rack/content_type.rb +23 -0
  28. data/lib/rack/deflater.rb +96 -0
  29. data/lib/rack/directory.rb +153 -0
  30. data/lib/rack/file.rb +88 -0
  31. data/lib/rack/handler/cgi.rb +61 -0
  32. data/lib/rack/handler/evented_mongrel.rb +8 -0
  33. data/lib/rack/handler/fastcgi.rb +88 -0
  34. data/lib/rack/handler/lsws.rb +60 -0
  35. data/lib/rack/handler/mongrel.rb +87 -0
  36. data/lib/rack/handler/scgi.rb +62 -0
  37. data/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
  38. data/lib/rack/handler/thin.rb +18 -0
  39. data/lib/rack/handler/webrick.rb +71 -0
  40. data/lib/rack/handler.rb +69 -0
  41. data/lib/rack/head.rb +19 -0
  42. data/lib/rack/lint.rb +546 -0
  43. data/lib/rack/lobster.rb +65 -0
  44. data/lib/rack/lock.rb +16 -0
  45. data/lib/rack/methodoverride.rb +27 -0
  46. data/lib/rack/mime.rb +204 -0
  47. data/lib/rack/mock.rb +187 -0
  48. data/lib/rack/recursive.rb +57 -0
  49. data/lib/rack/reloader.rb +107 -0
  50. data/lib/rack/request.rb +248 -0
  51. data/lib/rack/response.rb +183 -0
  52. data/lib/rack/rewindable_input.rb +100 -0
  53. data/lib/rack/session/abstract/id.rb +142 -0
  54. data/lib/rack/session/cookie.rb +91 -0
  55. data/lib/rack/session/memcache.rb +109 -0
  56. data/lib/rack/session/pool.rb +100 -0
  57. data/lib/rack/showexceptions.rb +349 -0
  58. data/lib/rack/showstatus.rb +106 -0
  59. data/lib/rack/static.rb +38 -0
  60. data/lib/rack/urlmap.rb +55 -0
  61. data/lib/rack/utils.rb +528 -0
  62. data/lib/rack.rb +90 -0
  63. data/rack.gemspec +60 -0
  64. data/test/cgi/lighttpd.conf +20 -0
  65. data/test/cgi/test +9 -0
  66. data/test/cgi/test.fcgi +8 -0
  67. data/test/cgi/test.ru +7 -0
  68. data/test/multipart/binary +0 -0
  69. data/test/multipart/empty +10 -0
  70. data/test/multipart/file1.txt +1 -0
  71. data/test/multipart/ie +6 -0
  72. data/test/multipart/nested +10 -0
  73. data/test/multipart/none +9 -0
  74. data/test/multipart/text +10 -0
  75. data/test/spec_rack_auth_basic.rb +73 -0
  76. data/test/spec_rack_auth_digest.rb +226 -0
  77. data/test/spec_rack_auth_openid.rb +84 -0
  78. data/test/spec_rack_builder.rb +84 -0
  79. data/test/spec_rack_camping.rb +51 -0
  80. data/test/spec_rack_cascade.rb +48 -0
  81. data/test/spec_rack_cgi.rb +89 -0
  82. data/test/spec_rack_chunked.rb +62 -0
  83. data/test/spec_rack_commonlogger.rb +61 -0
  84. data/test/spec_rack_conditionalget.rb +41 -0
  85. data/test/spec_rack_content_length.rb +43 -0
  86. data/test/spec_rack_content_type.rb +30 -0
  87. data/test/spec_rack_deflater.rb +127 -0
  88. data/test/spec_rack_directory.rb +61 -0
  89. data/test/spec_rack_fastcgi.rb +89 -0
  90. data/test/spec_rack_file.rb +75 -0
  91. data/test/spec_rack_handler.rb +43 -0
  92. data/test/spec_rack_head.rb +30 -0
  93. data/test/spec_rack_lint.rb +521 -0
  94. data/test/spec_rack_lobster.rb +45 -0
  95. data/test/spec_rack_lock.rb +38 -0
  96. data/test/spec_rack_methodoverride.rb +60 -0
  97. data/test/spec_rack_mock.rb +243 -0
  98. data/test/spec_rack_mongrel.rb +189 -0
  99. data/test/spec_rack_recursive.rb +77 -0
  100. data/test/spec_rack_request.rb +504 -0
  101. data/test/spec_rack_response.rb +218 -0
  102. data/test/spec_rack_rewindable_input.rb +118 -0
  103. data/test/spec_rack_session_cookie.rb +82 -0
  104. data/test/spec_rack_session_memcache.rb +250 -0
  105. data/test/spec_rack_session_pool.rb +172 -0
  106. data/test/spec_rack_showexceptions.rb +21 -0
  107. data/test/spec_rack_showstatus.rb +72 -0
  108. data/test/spec_rack_static.rb +37 -0
  109. data/test/spec_rack_thin.rb +91 -0
  110. data/test/spec_rack_urlmap.rb +185 -0
  111. data/test/spec_rack_utils.rb +467 -0
  112. data/test/spec_rack_webrick.rb +130 -0
  113. data/test/testrequest.rb +57 -0
  114. data/test/unregistered_handler/rack/handler/unregistered.rb +7 -0
  115. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +7 -0
  116. metadata +276 -0
@@ -0,0 +1,58 @@
1
+ require 'rack/auth/abstract/handler'
2
+ require 'rack/auth/abstract/request'
3
+
4
+ module Rack
5
+ module Auth
6
+ # Rack::Auth::Basic implements HTTP Basic Authentication, as per RFC 2617.
7
+ #
8
+ # Initialize with the Rack application that you want protecting,
9
+ # and a block that checks if a username and password pair are valid.
10
+ #
11
+ # See also: <tt>example/protectedlobster.rb</tt>
12
+
13
+ class Basic < AbstractHandler
14
+
15
+ def call(env)
16
+ auth = Basic::Request.new(env)
17
+
18
+ return unauthorized unless auth.provided?
19
+
20
+ return bad_request unless auth.basic?
21
+
22
+ if valid?(auth)
23
+ env['REMOTE_USER'] = auth.username
24
+
25
+ return @app.call(env)
26
+ end
27
+
28
+ unauthorized
29
+ end
30
+
31
+
32
+ private
33
+
34
+ def challenge
35
+ 'Basic realm="%s"' % realm
36
+ end
37
+
38
+ def valid?(auth)
39
+ @authenticator.call(*auth.credentials)
40
+ end
41
+
42
+ class Request < Auth::AbstractRequest
43
+ def basic?
44
+ :basic == scheme
45
+ end
46
+
47
+ def credentials
48
+ @credentials ||= params.unpack("m*").first.split(/:/, 2)
49
+ end
50
+
51
+ def username
52
+ credentials.first
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,124 @@
1
+ require 'rack/auth/abstract/handler'
2
+ require 'rack/auth/digest/request'
3
+ require 'rack/auth/digest/params'
4
+ require 'rack/auth/digest/nonce'
5
+ require 'digest/md5'
6
+
7
+ module Rack
8
+ module Auth
9
+ module Digest
10
+ # Rack::Auth::Digest::MD5 implements the MD5 algorithm version of
11
+ # HTTP Digest Authentication, as per RFC 2617.
12
+ #
13
+ # Initialize with the [Rack] application that you want protecting,
14
+ # and a block that looks up a plaintext password for a given username.
15
+ #
16
+ # +opaque+ needs to be set to a constant base64/hexadecimal string.
17
+ #
18
+ class MD5 < AbstractHandler
19
+
20
+ attr_accessor :opaque
21
+
22
+ attr_writer :passwords_hashed
23
+
24
+ def initialize(*args)
25
+ super
26
+ @passwords_hashed = nil
27
+ end
28
+
29
+ def passwords_hashed?
30
+ !!@passwords_hashed
31
+ end
32
+
33
+ def call(env)
34
+ auth = Request.new(env)
35
+
36
+ unless auth.provided?
37
+ return unauthorized
38
+ end
39
+
40
+ if !auth.digest? || !auth.correct_uri? || !valid_qop?(auth)
41
+ return bad_request
42
+ end
43
+
44
+ if valid?(auth)
45
+ if auth.nonce.stale?
46
+ return unauthorized(challenge(:stale => true))
47
+ else
48
+ env['REMOTE_USER'] = auth.username
49
+
50
+ return @app.call(env)
51
+ end
52
+ end
53
+
54
+ unauthorized
55
+ end
56
+
57
+
58
+ private
59
+
60
+ QOP = 'auth'.freeze
61
+
62
+ def params(hash = {})
63
+ Params.new do |params|
64
+ params['realm'] = realm
65
+ params['nonce'] = Nonce.new.to_s
66
+ params['opaque'] = H(opaque)
67
+ params['qop'] = QOP
68
+
69
+ hash.each { |k, v| params[k] = v }
70
+ end
71
+ end
72
+
73
+ def challenge(hash = {})
74
+ "Digest #{params(hash)}"
75
+ end
76
+
77
+ def valid?(auth)
78
+ valid_opaque?(auth) && valid_nonce?(auth) && valid_digest?(auth)
79
+ end
80
+
81
+ def valid_qop?(auth)
82
+ QOP == auth.qop
83
+ end
84
+
85
+ def valid_opaque?(auth)
86
+ H(opaque) == auth.opaque
87
+ end
88
+
89
+ def valid_nonce?(auth)
90
+ auth.nonce.valid?
91
+ end
92
+
93
+ def valid_digest?(auth)
94
+ digest(auth, @authenticator.call(auth.username)) == auth.response
95
+ end
96
+
97
+ def md5(data)
98
+ ::Digest::MD5.hexdigest(data)
99
+ end
100
+
101
+ alias :H :md5
102
+
103
+ def KD(secret, data)
104
+ H([secret, data] * ':')
105
+ end
106
+
107
+ def A1(auth, password)
108
+ [ auth.username, auth.realm, password ] * ':'
109
+ end
110
+
111
+ def A2(auth)
112
+ [ auth.method, auth.uri ] * ':'
113
+ end
114
+
115
+ def digest(auth, password)
116
+ password_hash = passwords_hashed? ? password : H(A1(auth, password))
117
+
118
+ KD(password_hash, [ auth.nonce, auth.nc, auth.cnonce, QOP, H(A2(auth)) ] * ':')
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,51 @@
1
+ require 'digest/md5'
2
+
3
+ module Rack
4
+ module Auth
5
+ module Digest
6
+ # Rack::Auth::Digest::Nonce is the default nonce generator for the
7
+ # Rack::Auth::Digest::MD5 authentication handler.
8
+ #
9
+ # +private_key+ needs to set to a constant string.
10
+ #
11
+ # +time_limit+ can be optionally set to an integer (number of seconds),
12
+ # to limit the validity of the generated nonces.
13
+
14
+ class Nonce
15
+
16
+ class << self
17
+ attr_accessor :private_key, :time_limit
18
+ end
19
+
20
+ def self.parse(string)
21
+ new(*string.unpack("m*").first.split(' ', 2))
22
+ end
23
+
24
+ def initialize(timestamp = Time.now, given_digest = nil)
25
+ @timestamp, @given_digest = timestamp.to_i, given_digest
26
+ end
27
+
28
+ def to_s
29
+ [([ @timestamp, digest ] * ' ')].pack("m*").strip
30
+ end
31
+
32
+ def digest
33
+ ::Digest::MD5.hexdigest([ @timestamp, self.class.private_key ] * ':')
34
+ end
35
+
36
+ def valid?
37
+ digest == @given_digest
38
+ end
39
+
40
+ def stale?
41
+ !self.class.time_limit.nil? && (@timestamp - Time.now.to_i) < self.class.time_limit
42
+ end
43
+
44
+ def fresh?
45
+ !stale?
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,55 @@
1
+ module Rack
2
+ module Auth
3
+ module Digest
4
+ class Params < Hash
5
+
6
+ def self.parse(str)
7
+ split_header_value(str).inject(new) do |header, param|
8
+ k, v = param.split('=', 2)
9
+ header[k] = dequote(v)
10
+ header
11
+ end
12
+ end
13
+
14
+ def self.dequote(str) # From WEBrick::HTTPUtils
15
+ ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
16
+ ret.gsub!(/\\(.)/, "\\1")
17
+ ret
18
+ end
19
+
20
+ def self.split_header_value(str)
21
+ str.scan( /(\w+\=(?:"[^\"]+"|[^,]+))/n ).collect{ |v| v[0] }
22
+ end
23
+
24
+ def initialize
25
+ super
26
+
27
+ yield self if block_given?
28
+ end
29
+
30
+ def [](k)
31
+ super k.to_s
32
+ end
33
+
34
+ def []=(k, v)
35
+ super k.to_s, v.to_s
36
+ end
37
+
38
+ UNQUOTED = ['qop', 'nc', 'stale']
39
+
40
+ def to_s
41
+ inject([]) do |parts, (k, v)|
42
+ parts << "#{k}=" + (UNQUOTED.include?(k) ? v.to_s : quote(v))
43
+ parts
44
+ end.join(', ')
45
+ end
46
+
47
+ def quote(str) # From WEBrick::HTTPUtils
48
+ '"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
49
+ end
50
+
51
+ end
52
+ end
53
+ end
54
+ end
55
+
@@ -0,0 +1,40 @@
1
+ require 'rack/auth/abstract/request'
2
+ require 'rack/auth/digest/params'
3
+ require 'rack/auth/digest/nonce'
4
+
5
+ module Rack
6
+ module Auth
7
+ module Digest
8
+ class Request < Auth::AbstractRequest
9
+
10
+ def method
11
+ @env['rack.methodoverride.original_method'] || @env['REQUEST_METHOD']
12
+ end
13
+
14
+ def digest?
15
+ :digest == scheme
16
+ end
17
+
18
+ def correct_uri?
19
+ (@env['SCRIPT_NAME'].to_s + @env['PATH_INFO'].to_s) == uri
20
+ end
21
+
22
+ def nonce
23
+ @nonce ||= Nonce.parse(params['nonce'])
24
+ end
25
+
26
+ def params
27
+ @params ||= Params.parse(parts.last)
28
+ end
29
+
30
+ def method_missing(sym)
31
+ if params.has_key? key = sym.to_s
32
+ return params[key]
33
+ end
34
+ super
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+ end