ramaze 2011.01.30 → 2011.07.25

Sign up to get free protection for your applications and to get access to all the features.
Files changed (229) hide show
  1. data/.gitignore +2 -1
  2. data/.mailmap +2 -0
  3. data/.rvmrc +1 -0
  4. data/README.md +119 -197
  5. data/Rakefile +14 -97
  6. data/bin/ramaze +6 -14
  7. data/doc/AUTHORS +8 -4
  8. data/doc/CHANGELOG +3784 -3339
  9. data/examples/app/chat/start.rb +2 -2
  10. data/lib/proto/app.rb +2 -3
  11. data/lib/proto/config.ru +4 -5
  12. data/lib/proto/controller/init.rb +11 -4
  13. data/lib/proto/controller/main.rb +12 -7
  14. data/lib/proto/layout/default.xhtml +56 -23
  15. data/lib/proto/model/init.rb +3 -1
  16. data/lib/proto/public/css/grid.css +107 -0
  17. data/lib/proto/public/css/layout.css +81 -0
  18. data/lib/proto/public/css/reset.css +123 -0
  19. data/lib/proto/public/css/text.css +109 -0
  20. data/lib/proto/public/images/bg.png +0 -0
  21. data/lib/proto/spec/main.rb +2 -2
  22. data/lib/proto/start.rb +11 -1
  23. data/lib/proto/view/index.xhtml +27 -23
  24. data/lib/ramaze.rb +0 -1
  25. data/lib/ramaze/app.rb +85 -12
  26. data/lib/ramaze/app_graph.rb +107 -0
  27. data/lib/ramaze/bin/console.rb +87 -0
  28. data/lib/ramaze/bin/create.rb +94 -0
  29. data/lib/ramaze/bin/helper.rb +107 -0
  30. data/lib/ramaze/bin/restart.rb +95 -0
  31. data/lib/ramaze/bin/runner.rb +141 -0
  32. data/lib/ramaze/bin/start.rb +206 -0
  33. data/lib/ramaze/bin/status.rb +152 -0
  34. data/lib/ramaze/bin/stop.rb +112 -0
  35. data/lib/ramaze/cache.rb +9 -4
  36. data/lib/ramaze/cache/localmemcache.rb +10 -13
  37. data/lib/ramaze/cache/lru.rb +49 -7
  38. data/lib/ramaze/cache/memcache.rb +170 -92
  39. data/lib/ramaze/cache/sequel.rb +301 -118
  40. data/lib/ramaze/controller.rb +108 -9
  41. data/lib/ramaze/controller/default.rb +15 -2
  42. data/lib/ramaze/current.rb +14 -2
  43. data/lib/ramaze/dependencies.rb +46 -0
  44. data/lib/ramaze/files.rb +38 -3
  45. data/lib/ramaze/gestalt.rb +12 -12
  46. data/lib/ramaze/helper.rb +0 -2
  47. data/lib/ramaze/helper/auth.rb +30 -23
  48. data/lib/ramaze/helper/blue_form.rb +175 -126
  49. data/lib/ramaze/helper/csrf.rb +76 -91
  50. data/lib/ramaze/helper/email.rb +105 -0
  51. data/lib/ramaze/helper/erector.rb +16 -15
  52. data/lib/ramaze/helper/gestalt.rb +2 -2
  53. data/lib/ramaze/helper/layout.rb +89 -73
  54. data/lib/ramaze/helper/link.rb +7 -6
  55. data/lib/ramaze/helper/localize.rb +6 -5
  56. data/lib/ramaze/helper/markaby.rb +25 -23
  57. data/lib/ramaze/helper/maruku.rb +3 -3
  58. data/lib/ramaze/helper/paginate.rb +19 -27
  59. data/lib/ramaze/helper/remarkably.rb +3 -3
  60. data/lib/ramaze/helper/request_accessor.rb +3 -3
  61. data/lib/ramaze/helper/send_file.rb +12 -8
  62. data/lib/ramaze/helper/simple_captcha.rb +5 -6
  63. data/lib/ramaze/helper/stack.rb +7 -4
  64. data/lib/ramaze/helper/tagz.rb +10 -11
  65. data/lib/ramaze/helper/thread.rb +19 -16
  66. data/lib/ramaze/helper/ultraviolet.rb +7 -4
  67. data/lib/ramaze/helper/user.rb +40 -21
  68. data/lib/ramaze/helper/xhtml.rb +29 -20
  69. data/lib/ramaze/log.rb +3 -11
  70. data/lib/ramaze/log/analogger.rb +5 -4
  71. data/lib/ramaze/log/growl.rb +9 -7
  72. data/lib/ramaze/log/hub.rb +3 -5
  73. data/lib/ramaze/log/informer.rb +15 -12
  74. data/lib/ramaze/log/knotify.rb +3 -5
  75. data/lib/ramaze/log/logger.rb +3 -5
  76. data/lib/ramaze/log/logging.rb +6 -8
  77. data/lib/ramaze/log/rotatinginformer.rb +27 -17
  78. data/lib/ramaze/log/syslog.rb +7 -7
  79. data/lib/ramaze/log/xosd.rb +3 -5
  80. data/lib/ramaze/middleware_compiler.rb +27 -4
  81. data/lib/ramaze/reloader.rb +50 -12
  82. data/lib/ramaze/reloader/watch_inotify.rb +4 -5
  83. data/lib/ramaze/reloader/watch_stat.rb +3 -3
  84. data/lib/ramaze/request.rb +18 -8
  85. data/lib/ramaze/response.rb +38 -7
  86. data/lib/ramaze/rest.rb +36 -0
  87. data/lib/ramaze/setup.rb +101 -31
  88. data/lib/ramaze/spec.rb +1 -1
  89. data/lib/ramaze/spec/bacon.rb +6 -3
  90. data/lib/ramaze/spec/helper/bacon.rb +0 -1
  91. data/lib/ramaze/version.rb +1 -1
  92. data/lib/ramaze/view.rb +2 -11
  93. data/lib/ramaze/view/erector.rb +46 -31
  94. data/lib/ramaze/view/erubis.rb +7 -3
  95. data/lib/ramaze/view/ezamar.rb +7 -3
  96. data/lib/ramaze/view/gestalt.rb +9 -3
  97. data/lib/ramaze/view/haml.rb +7 -3
  98. data/lib/ramaze/view/liquid.rb +3 -3
  99. data/lib/ramaze/view/lokar.rb +7 -3
  100. data/lib/ramaze/view/mustache.rb +11 -5
  101. data/lib/ramaze/view/nagoro.rb +3 -3
  102. data/lib/ramaze/view/sass.rb +1 -1
  103. data/lib/ramaze/view/slippers.rb +40 -13
  104. data/lib/ramaze/view/tagz.rb +9 -5
  105. data/ramaze.gemspec +23 -128
  106. data/spec/helper.rb +5 -0
  107. data/spec/ramaze/bin/app/config.ru +11 -0
  108. data/spec/ramaze/bin/create.rb +28 -0
  109. data/spec/ramaze/bin/runner.rb +30 -0
  110. data/spec/ramaze/bin/start.rb +38 -0
  111. data/spec/ramaze/cache/memcache.rb +10 -3
  112. data/spec/ramaze/cache/sequel.rb +7 -0
  113. data/spec/ramaze/controller/provide_inheritance.rb +0 -10
  114. data/spec/ramaze/dispatcher/file.rb +19 -15
  115. data/spec/ramaze/helper/auth.rb +10 -9
  116. data/spec/ramaze/helper/blue_form.rb +121 -68
  117. data/spec/ramaze/helper/email.rb +69 -0
  118. data/spec/ramaze/helper/layout.rb +12 -15
  119. data/spec/ramaze/helper/layout/alternative.xhtml +5 -0
  120. data/spec/ramaze/helper/user.rb +2 -0
  121. data/spec/ramaze/log/growl.rb +14 -1
  122. data/spec/{contrib → ramaze}/rest.rb +1 -1
  123. data/spec/ramaze/session/memcache.rb +2 -2
  124. data/spec/ramaze/view/sass.rb +1 -1
  125. data/tasks/bacon.rake +3 -3
  126. data/tasks/gem.rake +17 -18
  127. data/tasks/rcov.rake +2 -3
  128. data/tasks/release.rake +8 -65
  129. data/tasks/setup.rake +10 -8
  130. data/tasks/todo.rake +9 -5
  131. data/tasks/yard.rake +3 -2
  132. metadata +105 -397
  133. data/MANIFEST +0 -532
  134. data/TODO.md +0 -19
  135. data/benchmark/bench_templates/bench.rb +0 -67
  136. data/benchmark/bench_templates/view/large.erb +0 -79
  137. data/benchmark/bench_templates/view/large.haml +0 -41
  138. data/benchmark/bench_templates/view/large.lok +0 -79
  139. data/benchmark/bench_templates/view/large.xhtml +0 -79
  140. data/benchmark/bench_templates/view/small.erb +0 -21
  141. data/benchmark/bench_templates/view/small.haml +0 -12
  142. data/benchmark/bench_templates/view/small.lok +0 -21
  143. data/benchmark/bench_templates/view/small.xhtml +0 -21
  144. data/benchmark/results.txt +0 -131
  145. data/benchmark/run.rb +0 -355
  146. data/benchmark/suite/minimal.rb +0 -11
  147. data/benchmark/suite/no_informer.rb +0 -7
  148. data/benchmark/suite/no_sessions.rb +0 -9
  149. data/benchmark/suite/no_template.rb +0 -7
  150. data/benchmark/suite/simple.rb +0 -5
  151. data/benchmark/suite/template_erubis.rb +0 -8
  152. data/benchmark/suite/template_etanni.rb +0 -8
  153. data/benchmark/suite/template_ezamar.rb +0 -8
  154. data/benchmark/suite/template_haml.rb +0 -13
  155. data/benchmark/suite/template_liquid.rb +0 -11
  156. data/benchmark/suite/template_markaby.rb +0 -9
  157. data/benchmark/suite/template_nagoro.rb +0 -8
  158. data/benchmark/suite/template_redcloth.rb +0 -13
  159. data/benchmark/suite/template_tenjin.rb +0 -8
  160. data/benchmark/test.rb +0 -35
  161. data/doc/FAQ +0 -92
  162. data/doc/INSTALL +0 -92
  163. data/doc/TODO +0 -29
  164. data/doc/meta/announcement.txt +0 -119
  165. data/doc/meta/configuration.txt +0 -163
  166. data/doc/meta/internals.txt +0 -278
  167. data/doc/meta/users.kml +0 -64
  168. data/doc/tutorial/todolist.html +0 -1512
  169. data/doc/tutorial/todolist.txt +0 -920
  170. data/examples/app/sourceview/public/coderay.css +0 -104
  171. data/examples/app/sourceview/public/images/file.gif +0 -0
  172. data/examples/app/sourceview/public/images/folder.gif +0 -0
  173. data/examples/app/sourceview/public/images/tv-collapsable-last.gif +0 -0
  174. data/examples/app/sourceview/public/images/tv-collapsable.gif +0 -0
  175. data/examples/app/sourceview/public/images/tv-expandable-last.gif +0 -0
  176. data/examples/app/sourceview/public/images/tv-expandable.gif +0 -0
  177. data/examples/app/sourceview/public/images/tv-item-last.gif +0 -0
  178. data/examples/app/sourceview/public/images/tv-item.gif +0 -0
  179. data/examples/app/sourceview/public/jquery.js +0 -11
  180. data/examples/app/sourceview/public/jquery.treeview.css +0 -48
  181. data/examples/app/sourceview/public/jquery.treeview.js +0 -223
  182. data/examples/app/sourceview/public/sourceview.js +0 -52
  183. data/examples/app/sourceview/start.rb +0 -79
  184. data/examples/app/sourceview/view/index.haml +0 -59
  185. data/examples/helpers/httpdigest.rb +0 -107
  186. data/lib/proto/public/css/screen.css +0 -30
  187. data/lib/proto/public/js/jquery.js +0 -7179
  188. data/lib/ramaze/contrib/addressable_route.rb +0 -56
  189. data/lib/ramaze/contrib/app_graph.rb +0 -64
  190. data/lib/ramaze/contrib/email.rb +0 -88
  191. data/lib/ramaze/contrib/facebook.rb +0 -23
  192. data/lib/ramaze/contrib/facebook/facebook.rb +0 -171
  193. data/lib/ramaze/contrib/gettext.rb +0 -113
  194. data/lib/ramaze/contrib/gettext/mo.rb +0 -155
  195. data/lib/ramaze/contrib/gettext/parser.rb +0 -46
  196. data/lib/ramaze/contrib/gettext/po.rb +0 -109
  197. data/lib/ramaze/contrib/gzip_filter.rb +0 -1
  198. data/lib/ramaze/contrib/maruku_uv.rb +0 -59
  199. data/lib/ramaze/contrib/profiling.rb +0 -36
  200. data/lib/ramaze/contrib/rest.rb +0 -23
  201. data/lib/ramaze/contrib/sequel/create_join.rb +0 -26
  202. data/lib/ramaze/contrib/sequel/form_field.rb +0 -129
  203. data/lib/ramaze/contrib/sequel/image.rb +0 -196
  204. data/lib/ramaze/contrib/sequel/relation.rb +0 -98
  205. data/lib/ramaze/helper/httpdigest.rb +0 -96
  206. data/lib/ramaze/tool/bin.rb +0 -340
  207. data/lib/ramaze/tool/create.rb +0 -48
  208. data/lib/ramaze/tool/project_creator.rb +0 -120
  209. data/lib/ramaze/view/less.rb +0 -12
  210. data/lib/ramaze/view/maruku.rb +0 -15
  211. data/lib/ramaze/view/redcloth.rb +0 -21
  212. data/spec/contrib/addressable_route.rb +0 -30
  213. data/spec/examples/helpers/httpdigest.rb +0 -64
  214. data/spec/examples/templates/template_redcloth.rb +0 -13
  215. data/spec/ramaze/bin/ramaze.rb +0 -96
  216. data/spec/ramaze/helper/httpdigest.rb +0 -176
  217. data/spec/ramaze/view/less.rb +0 -60
  218. data/spec/ramaze/view/less/file.css.less +0 -8
  219. data/spec/ramaze/view/redcloth.rb +0 -66
  220. data/spec/ramaze/view/redcloth/external.redcloth +0 -8
  221. data/tasks/copyright.rake +0 -21
  222. data/tasks/gem_setup.rake +0 -112
  223. data/tasks/git.rake +0 -46
  224. data/tasks/grancher.rake +0 -12
  225. data/tasks/jquery.rake +0 -15
  226. data/tasks/manifest.rake +0 -4
  227. data/tasks/metric_changes.rake +0 -24
  228. data/tasks/reversion.rake +0 -8
  229. data/tasks/traits.rake +0 -21
@@ -4,20 +4,24 @@ require 'digest'
4
4
  module Ramaze
5
5
  module Helper
6
6
  ##
7
- # A relatively basic yet useful helper that can be used to protect your application
8
- # from CSRF attacks/exploits. Note that this helper merely generates the required data,
9
- # and provides several methods. You still need to manually add the token to each form.
7
+ # A relatively basic yet useful helper that can be used to protect your
8
+ # application from CSRF attacks/exploits. Note that this helper merely
9
+ # generates the required data, and provides several methods. You still need
10
+ # to manually add the token to each form.
10
11
  #
11
- # The reason for this is because this is quite simple. Ramaze is meant as a framework that
12
- # works with any given helper, ORM, template engine and so on. If we were to automatically
13
- # load this helper and include (a perhaps more advanced) CSRF system that would mean that
14
- # every form helper, official or third-party, would have to support that specific system.
15
- # However, there's no need to panic as it's very easy to setup a basic anti CSRF system.
12
+ # The reason for this is because this is quite simple. Ramaze is meant as a
13
+ # framework that works with any given helper, ORM, template engine and so
14
+ # on. If we were to automatically load this helper and include (a perhaps
15
+ # more advanced) CSRF system that would mean that every form helper,
16
+ # official or third-party, would have to support that specific system.
17
+ # However, there's no need to panic as it's very easy to setup a basic anti
18
+ # CSRF system.
16
19
  #
17
20
  # == Usage
18
21
  #
19
- # In order to enable CSRF protection we need to do two things. Load the helper and create
20
- # a before_all block in a controller. Take a look at the following code:
22
+ # In order to enable CSRF protection we need to do two things. Load the
23
+ # helper and create a before_all block in a controller. Take a look at the
24
+ # following code:
21
25
  #
22
26
  # class BaseController < Ramaze::Controller
23
27
  # before_all do
@@ -25,8 +29,9 @@ module Ramaze
25
29
  # end
26
30
  # end
27
31
  #
28
- # This would output "Hello, before_all!" to the console upon each request. Not very useful
29
- # but it does show what the before_all block can do. On to actual CSRF related code!
32
+ # This would output "Hello, before_all!" to the console upon each request.
33
+ # Not very useful but it does show what the before_all block can do. On to
34
+ # actual CSRF related code!
30
35
  #
31
36
  # class BaseController < Ramaze::Controller
32
37
  # before_all do
@@ -36,10 +41,11 @@ module Ramaze
36
41
  # end
37
42
  # end
38
43
  #
39
- # This example introduces an extra block that validates the current request.
40
- # Whenever a user requests a controller that either extends BaseController or has it's own
41
- # before_all block Ramaze will check if the current request data contains a CSRF token.
42
- # Of course an if/end isn't very useful if it doesn't do anything, let's add some code.
44
+ # This example introduces an extra block that validates the current
45
+ # request. Whenever a user requests a controller that either extends
46
+ # BaseController or has it's own before_all block Ramaze will check if the
47
+ # current request data contains a CSRF token. Of course an if/end isn't
48
+ # very useful if it doesn't do anything, let's add some code.
43
49
  #
44
50
  # class BaseController < Ramaze::Controller
45
51
  # before_all do
@@ -49,14 +55,17 @@ module Ramaze
49
55
  # end
50
56
  # end
51
57
  #
52
- # The code above checks if the current method is "save" (or any other of the provided methods)
53
- # and checks if an CSRF token is supplied if the method matches. Protected methods require
54
- # a token in ALL HTTP requests (GET, POST, etc). While this may seem weird since GET is generally
55
- # used for safe actions it actually makes sence. Ramaze stores both the POST and GET parameters in
56
- # the request.params hash. While this makes it easy to work with POST/GET data this also makes it
57
- # easier to spoof POST requests using a GET request, thus this helper protects ALL request methods.
58
+ # The code above checks if the current method is "save" (or any other of
59
+ # the provided methods) and checks if an CSRF token is supplied if the
60
+ # method matches. Protected methods require a token in ALL HTTP requests
61
+ # (GET, POST, etc). While this may seem weird since GET is generally used
62
+ # for safe actions it actually makes sense. Ramaze stores both the POST and
63
+ # GET parameters in the request.params hash. While this makes it easy to
64
+ # work with POST/GET data this also makes it easier to spoof POST requests
65
+ # using a GET request, thus this helper protects ALL request methods.
58
66
  #
59
- # If you're a lazy person you can copy-paste the example below and adapt it to your needs.
67
+ # If you're a lazy person you can copy-paste the example below and adapt it
68
+ # to your needs.
60
69
  #
61
70
  # class BaseController < Ramaze::Controller
62
71
  # before_all do
@@ -69,11 +78,12 @@ module Ramaze
69
78
  # @author Yorick Peterse
70
79
  #
71
80
  module CSRF
72
-
81
+
73
82
  ##
74
- # Method that can be used to protect the specified methods against CSRF exploits.
75
- # Each protected method will require the token to be stored in a field called "csrf_token".
76
- # This method will then validate that token against the current token in the session.
83
+ # Method that can be used to protect the specified methods against CSRF
84
+ # exploits. Each protected method will require the token to be stored in
85
+ # a field called "csrf_token". This method will then validate that token
86
+ # against the current token in the session.
77
87
  #
78
88
  # @author Yorick Peterse
79
89
  # @param [Strings/Symbol] *methods Methods that will be protected/unprotected.
@@ -93,22 +103,20 @@ module Ramaze
93
103
  # THINK: For now the field name is hard-coded to "csrf_token". While
94
104
  # this is perfectly fine in most cases it might be a good idea
95
105
  # to allow developers to change the name of this field (for whatever the reason).
96
- if validate_csrf_token(request.params['csrf_token']) != true
97
- yield
98
- end
106
+ yield unless validate_csrf_token(request.params['csrf_token'])
99
107
  end
100
108
  end
101
-
109
+
102
110
  ##
103
- # Generate a new token and create the session array that will be used to validate the client.
104
- # The following items are stored in the session:
111
+ # Generate a new token and create the session array that will be used to
112
+ # validate the client. The following items are stored in the session:
105
113
  #
106
114
  # * token: An unique hash that will be stored in each form
107
115
  # * agent: The visitor's user agent
108
116
  # * ip: The IP address of the visitor
109
117
  # * time: Timestamp that indicates at what time the data was generated.
110
118
  #
111
- # Note that this method will be automatically called if no CSRF token exists.
119
+ # Note that this method will be automatically called if no CSRF token exists.
112
120
  #
113
121
  # @author Yorick Peterse
114
122
  # @param [Hash] Additional arguments that can be set such as the TTL.
@@ -116,66 +124,59 @@ module Ramaze
116
124
  #
117
125
  def generate_csrf_token args = {}
118
126
  # Default TTL is 15 minutes
119
- if args[:ttl]
120
- ttl = args[:ttl]
121
- else
122
- ttl = 900
123
- end
124
-
125
- # Generate all the required data
126
- time = Time.new.to_i.to_s
127
- number = SecureRandom.random_number(10000).to_s
128
- base64 = SecureRandom.base64.to_s
129
- token = Digest::SHA2.new(512).hexdigest(srand.to_s + rand.to_s + time + number + base64).to_s
130
-
131
- # Get several details from the client such as the user agent, IP, etc
132
- ip = request.env['REMOTE_ADDR']
133
- agent = request.env['HTTP_USER_AGENT']
134
- host = request.env['REMOTE_HOST']
135
-
136
- # Time to store all the data
127
+ ttl = args[:ttl] || (15 * 60)
128
+
129
+ # Get some good entropy
130
+ random = SecureRandom.random_bytes(512)
131
+ # and some not so good entropy
132
+ time = Time.now.to_f
133
+
134
+ # Hash it together
135
+ token = Digest::SHA512.hexdigest(random + time.to_s)
136
+
137
+ # Time to store all the data we want to check later.
137
138
  session[:_csrf] = {
138
139
  :time => time.to_i,
139
140
  :token => token,
140
- :ip => ip,
141
- :agent => agent,
142
- :host => host,
141
+ :ip => request.env['REMOTE_ADDR'],
142
+ :agent => request.env['HTTP_USER_AGENT'],
143
+ :host => request.env['REMOTE_HOST'],
143
144
  :ttl => ttl
144
145
  }
145
-
146
+
146
147
  # Prevent this method from returning any value (it isn't needed anyway)
147
148
  return
148
149
  end
149
-
150
+
150
151
  ##
151
152
  # Retrieves the current value of the CSRF token.
152
153
  #
153
154
  # @author Yorick Peterse
154
155
  # @return [String] The current CSRF token.
155
156
  # @example
156
- #
157
+ #
157
158
  # form(@data, :method => :post) do |f|
158
159
  # f.input_hidden :csrf_token, get_csrf_token()
159
160
  # end
160
161
  #
161
162
  def get_csrf_token
162
- if !session[:_csrf] or !self.validate_csrf_token(session[:_csrf][:token])
163
+ if !session[:_csrf] || !self.validate_csrf_token(session[:_csrf][:token])
163
164
  self.generate_csrf_token
164
165
  end
165
-
166
+
166
167
  # Land ho!
167
168
  return session[:_csrf][:token]
168
169
  end
169
-
170
+
170
171
  ##
171
- # Validates the request based on the current session date stored in _csrf.
172
- # The following items are verified:
172
+ # Validates the request based on the current session date stored in
173
+ # _csrf. The following items are verified:
173
174
  #
174
175
  # * Do the user agent, ip and token match those supplied by the visitor?
175
176
  # * Has the token been expired? (after 15 minutes).
176
177
  #
177
- # If any of these checks fail this method will return FALSE. It's your job to
178
- # take action based on the results of this method.
178
+ # If any of these checks fail this method will return FALSE. It's your
179
+ # job to take action based on the results of this method.
179
180
  #
180
181
  # @author Yorick Peterse
181
182
  # @param [String] input_token The CSRF token to validate.
@@ -188,38 +189,22 @@ module Ramaze
188
189
  # end
189
190
  # end
190
191
  #
191
- def validate_csrf_token input_token
192
+ def validate_csrf_token(input_token)
192
193
  # Check if the CSRF data has been generated and generate it if this
193
194
  # hasn't been done already (usually on the first request).
194
195
  if !session[:_csrf] or session[:_csrf].empty?
195
196
  self.generate_csrf_token
196
197
  end
197
-
198
- # Get several details from the client such as the user agent, IP, etc
199
- ip = session[:_csrf][:ip]
200
- agent = session[:_csrf][:agent]
201
- host = session[:_csrf][:host]
202
-
203
- # Get the current time and the time when the token was created
204
- now = Time.new.to_i
205
- token_time = session[:_csrf][:time]
206
-
198
+
199
+ _csrf = session[:_csrf]
200
+
207
201
  # Mirror mirror on the wall, who's the most secure of them all?
208
- results = Array.new
209
- results.push( session[:_csrf][:token] == input_token )
210
- results.push( (now - token_time) <= session[:_csrf][:ttl] )
211
- results.push( host == request.env['REMOTE_HOST'] )
212
- results.push( ip == request.env['REMOTE_ADDR'] )
213
- results.push( agent == request.env['HTTP_USER_AGENT'] )
214
-
215
- # Verify the results
216
- if results.include?(false)
217
- return false
218
- else
219
- return true
220
- end
202
+ session[:_csrf][:token] == input_token &&
203
+ (Time.now.to_f - _csrf[:time]) <= _csrf[:ttl] &&
204
+ _csrf[:host] == request.env['REMOTE_HOST'] &&
205
+ _csrf[:ip] == request.env['REMOTE_ADDR'] &&
206
+ _csrf[:agent] == request.env['HTTP_USER_AGENT']
221
207
  end
222
-
223
- end # <-- End of CSRF module
208
+ end
224
209
  end
225
210
  end
@@ -0,0 +1,105 @@
1
+ require 'net/smtp'
2
+
3
+ module Ramaze
4
+ module Helper
5
+ ##
6
+ # The Email helper can be used as a simple way of sending Emails from your
7
+ # application. In order to use this helper you first need to load it:
8
+ #
9
+ # class Comments < Ramaze::Controller
10
+ # helper :email
11
+ # end
12
+ #
13
+ # Sending an Email can be done by calling the method send_email():
14
+ #
15
+ # send_email('info@yorickpeterse.com', 'Hello, world!', 'Hello, this is an Email')
16
+ #
17
+ # Ramaze will log any errors in case the Email could not be sent so you don't have to
18
+ # worry about this.
19
+ #
20
+ # == Options
21
+ #
22
+ # This module can be configured using Innate::Optioned. Say you want to change the
23
+ # SMTP host you simply need to do the following:
24
+ #
25
+ # Ramaze::Helper::Email.options.host = 'mail.google.com'
26
+ #
27
+ # Various other options are available, for a full list of these options run the
28
+ # following in an IRB session:
29
+ #
30
+ # puts Ramaze::Helper::Email.options
31
+ #
32
+ # By default this helper uses \r\n for newlines, this can be changed as following:
33
+ #
34
+ # Ramaze::Helper::Email.options.newline = "\n"
35
+ #
36
+ # It's important that this setting matches the settings of your SMTP server as
37
+ # otherwise you (usually) won't be able to send any Emails.
38
+ #
39
+ # @author Yorick Peterse
40
+ # @author Michael Fellinger
41
+ # @since 16-06-2011
42
+ #
43
+ module Email
44
+ include Innate::Optioned
45
+
46
+ options.dsl do
47
+ o 'The SMTP server to use for sending Emails' , :host , ''
48
+ o 'The SMTP helo domain' , :helo_domain , ''
49
+ o 'The username for the SMTP server' , :username , ''
50
+ o 'The password for the SMTP server' , :password , ''
51
+ o 'The sender\'s Email address' , :sender , ''
52
+ o 'The port of the SMTP server' , :port , 25
53
+ o 'The authentication type of the SMTP server' , :auth_type , :login
54
+ o 'An array of addresses to forward the Emails to', :bcc , []
55
+ o 'The name (including the Email) of the sender' , :sender_full , nil
56
+ o 'A prefix to use for the subjects of the Emails', :subject_prefix, ''
57
+ o 'The type of newlines to use for the Email' , :newline , "\r\n"
58
+ o 'The generator to use for Email IDs' , :generator , lambda {
59
+ "<" + Time.now.to_i.to_s + "@" + Ramaze::Helper::Email.options.helo_domain + ">"
60
+ }
61
+ end
62
+
63
+ ##
64
+ # Sends an Email over SMTP.
65
+ #
66
+ # @example
67
+ # send_email('info@yorickpeterse.com', 'Hello, world!', 'Hello, this is an Email')
68
+ #
69
+ # @author Yorick Peterse
70
+ # @author Michael Fellinger
71
+ # @since 16-06-2011
72
+ # @param [String] recipient The Email address to send the Email to.
73
+ # @param [String] subject The subject of the Email.
74
+ # @param [String] message The body of the Email
75
+ #
76
+ def send_email(recipient, subject, message)
77
+ sender = Email.options.sender_full || "#{Email.options.sender} <#{Email.options.sender}>"
78
+ subject = [Email.options.subject_prefix, subject].join(' ').strip
79
+ id = Email.options.generator.call
80
+
81
+ # Generate the body of the Email
82
+ email = [
83
+ "From: #{sender}", "To: <#{recipient}>", "Date: #{Time.now.rfc2822}",
84
+ "Subject: #{subject}", "Message-Id: #{id}", '', message
85
+ ].join(Email.options.newline)
86
+
87
+ # Send the Email
88
+ email_options = []
89
+
90
+ [:host, :port, :helo_domain, :username, :password, :auth_type].each do |k|
91
+ email_options.push(Email.options[k])
92
+ end
93
+
94
+ begin
95
+ Net::SMTP.start(*email_options) do |smtp|
96
+ smtp.send_message(email, Email.options.sender, [recipient, *Email.options.bcc])
97
+ Ramaze::Log.info("Email sent to #{recipient} with subject \"#{subject}\"")
98
+ end
99
+ rescue => e
100
+ Ramaze::Log.error("Failed to send an Email to #{recipient}: #{e.inspect}")
101
+ end
102
+ end
103
+ end # Email
104
+ end # Helper
105
+ end # Ramaze
@@ -4,9 +4,7 @@
4
4
  require 'erector'
5
5
 
6
6
  module Ramaze
7
-
8
7
  module Helper
9
-
10
8
  ##
11
9
  # Allows you to use some shortcuts for Erector in your Controller.
12
10
  #
@@ -14,9 +12,8 @@ module Ramaze
14
12
  # Refer to the Erector-documentation and testsuite for more examples.
15
13
  #
16
14
  # @example
17
- #
18
- # erector { h1 "Apples & Oranges" } #=> "<h1>Apples &amp; Oranges</h1>"
19
- # erector { h1(:class => 'fruits&floots'){ text 'Apples' } } #=> "<h1 class=\"fruits&amp;floots\">Apples</h1>"
15
+ # erector { h1 "Apples & Oranges" } #=> "<h1>Apples &amp; Oranges</h1>"
16
+ # erector { h1(:class => 'fruits&floots'){ text 'Apples' } }
20
17
  #
21
18
  module Erector
22
19
  include ::Erector::Mixin
@@ -41,8 +38,10 @@ module Ramaze
41
38
  # end
42
39
  # end
43
40
  #
44
- # @param [Hash] args Hash containing extra options such as the xml:lang and xmlns attribute.
45
- # @param [Block] block Block that contains the inner data of the <html> element.
41
+ # @param [Hash] args Hash containing extra options such as the xml:lang
42
+ # and xmlns attribute.
43
+ # @param [Block] block Block that contains the inner data of the <html>
44
+ # element.
46
45
  #
47
46
  def strict_xhtml(*args, &block)
48
47
  raw! '<?xml version="1.0" encoding="UTF-8"?>'
@@ -73,7 +72,8 @@ module Ramaze
73
72
  # end
74
73
  #
75
74
  # @param [String] expr The if expression, such as 'IE' or 'lte IE7'.
76
- # @param [block] block Block that contains the data that needs to be loaded for the specified browser.
75
+ # @param [block] block Block that contains the data that needs to be
76
+ # loaded for the specified browser.
77
77
  #
78
78
  def ie_if(expr, &block)
79
79
  raw! "<!--[if #{expr}]>"
@@ -97,8 +97,10 @@ module Ramaze
97
97
  #
98
98
  # css 'css/reset.css', :media => 'print'
99
99
  #
100
- # @param [String] href The path (either absolute or relative) to the CSS file.
101
- # @param [Hash] args A hash containing additional arguments to add to the CSS tag.
100
+ # @param [String] href The path (either absolute or relative) to the CSS
101
+ # file.
102
+ # @param [Hash] args A hash containing additional arguments to add to
103
+ # the CSS tag.
102
104
  #
103
105
  def css(href, args = {})
104
106
  attrs = {
@@ -109,8 +111,7 @@ module Ramaze
109
111
 
110
112
  link attrs
111
113
  end
112
- end
113
- end
114
- end
115
- end
116
-
114
+ end # Erector::Widget
115
+ end # Erector
116
+ end # Helper
117
+ end # Ramaze
@@ -2,8 +2,8 @@ require 'ramaze/gestalt'
2
2
 
3
3
  module Ramaze
4
4
  module Helper
5
- ##
6
- # Gestalt is the custom HTML/XML builder for Ramaze, based on a very simple DSL it will build your markup.
5
+ # Gestalt is the custom HTML/XML builder for Ramaze, based on a very simple
6
+ # DSL it will build your markup.
7
7
  module Gestalt
8
8
  CACHE_G = {}
9
9