ramaze 2011.01.30 → 2011.07.25
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/.mailmap +2 -0
- data/.rvmrc +1 -0
- data/README.md +119 -197
- data/Rakefile +14 -97
- data/bin/ramaze +6 -14
- data/doc/AUTHORS +8 -4
- data/doc/CHANGELOG +3784 -3339
- data/examples/app/chat/start.rb +2 -2
- data/lib/proto/app.rb +2 -3
- data/lib/proto/config.ru +4 -5
- data/lib/proto/controller/init.rb +11 -4
- data/lib/proto/controller/main.rb +12 -7
- data/lib/proto/layout/default.xhtml +56 -23
- data/lib/proto/model/init.rb +3 -1
- data/lib/proto/public/css/grid.css +107 -0
- data/lib/proto/public/css/layout.css +81 -0
- data/lib/proto/public/css/reset.css +123 -0
- data/lib/proto/public/css/text.css +109 -0
- data/lib/proto/public/images/bg.png +0 -0
- data/lib/proto/spec/main.rb +2 -2
- data/lib/proto/start.rb +11 -1
- data/lib/proto/view/index.xhtml +27 -23
- data/lib/ramaze.rb +0 -1
- data/lib/ramaze/app.rb +85 -12
- data/lib/ramaze/app_graph.rb +107 -0
- data/lib/ramaze/bin/console.rb +87 -0
- data/lib/ramaze/bin/create.rb +94 -0
- data/lib/ramaze/bin/helper.rb +107 -0
- data/lib/ramaze/bin/restart.rb +95 -0
- data/lib/ramaze/bin/runner.rb +141 -0
- data/lib/ramaze/bin/start.rb +206 -0
- data/lib/ramaze/bin/status.rb +152 -0
- data/lib/ramaze/bin/stop.rb +112 -0
- data/lib/ramaze/cache.rb +9 -4
- data/lib/ramaze/cache/localmemcache.rb +10 -13
- data/lib/ramaze/cache/lru.rb +49 -7
- data/lib/ramaze/cache/memcache.rb +170 -92
- data/lib/ramaze/cache/sequel.rb +301 -118
- data/lib/ramaze/controller.rb +108 -9
- data/lib/ramaze/controller/default.rb +15 -2
- data/lib/ramaze/current.rb +14 -2
- data/lib/ramaze/dependencies.rb +46 -0
- data/lib/ramaze/files.rb +38 -3
- data/lib/ramaze/gestalt.rb +12 -12
- data/lib/ramaze/helper.rb +0 -2
- data/lib/ramaze/helper/auth.rb +30 -23
- data/lib/ramaze/helper/blue_form.rb +175 -126
- data/lib/ramaze/helper/csrf.rb +76 -91
- data/lib/ramaze/helper/email.rb +105 -0
- data/lib/ramaze/helper/erector.rb +16 -15
- data/lib/ramaze/helper/gestalt.rb +2 -2
- data/lib/ramaze/helper/layout.rb +89 -73
- data/lib/ramaze/helper/link.rb +7 -6
- data/lib/ramaze/helper/localize.rb +6 -5
- data/lib/ramaze/helper/markaby.rb +25 -23
- data/lib/ramaze/helper/maruku.rb +3 -3
- data/lib/ramaze/helper/paginate.rb +19 -27
- data/lib/ramaze/helper/remarkably.rb +3 -3
- data/lib/ramaze/helper/request_accessor.rb +3 -3
- data/lib/ramaze/helper/send_file.rb +12 -8
- data/lib/ramaze/helper/simple_captcha.rb +5 -6
- data/lib/ramaze/helper/stack.rb +7 -4
- data/lib/ramaze/helper/tagz.rb +10 -11
- data/lib/ramaze/helper/thread.rb +19 -16
- data/lib/ramaze/helper/ultraviolet.rb +7 -4
- data/lib/ramaze/helper/user.rb +40 -21
- data/lib/ramaze/helper/xhtml.rb +29 -20
- data/lib/ramaze/log.rb +3 -11
- data/lib/ramaze/log/analogger.rb +5 -4
- data/lib/ramaze/log/growl.rb +9 -7
- data/lib/ramaze/log/hub.rb +3 -5
- data/lib/ramaze/log/informer.rb +15 -12
- data/lib/ramaze/log/knotify.rb +3 -5
- data/lib/ramaze/log/logger.rb +3 -5
- data/lib/ramaze/log/logging.rb +6 -8
- data/lib/ramaze/log/rotatinginformer.rb +27 -17
- data/lib/ramaze/log/syslog.rb +7 -7
- data/lib/ramaze/log/xosd.rb +3 -5
- data/lib/ramaze/middleware_compiler.rb +27 -4
- data/lib/ramaze/reloader.rb +50 -12
- data/lib/ramaze/reloader/watch_inotify.rb +4 -5
- data/lib/ramaze/reloader/watch_stat.rb +3 -3
- data/lib/ramaze/request.rb +18 -8
- data/lib/ramaze/response.rb +38 -7
- data/lib/ramaze/rest.rb +36 -0
- data/lib/ramaze/setup.rb +101 -31
- data/lib/ramaze/spec.rb +1 -1
- data/lib/ramaze/spec/bacon.rb +6 -3
- data/lib/ramaze/spec/helper/bacon.rb +0 -1
- data/lib/ramaze/version.rb +1 -1
- data/lib/ramaze/view.rb +2 -11
- data/lib/ramaze/view/erector.rb +46 -31
- data/lib/ramaze/view/erubis.rb +7 -3
- data/lib/ramaze/view/ezamar.rb +7 -3
- data/lib/ramaze/view/gestalt.rb +9 -3
- data/lib/ramaze/view/haml.rb +7 -3
- data/lib/ramaze/view/liquid.rb +3 -3
- data/lib/ramaze/view/lokar.rb +7 -3
- data/lib/ramaze/view/mustache.rb +11 -5
- data/lib/ramaze/view/nagoro.rb +3 -3
- data/lib/ramaze/view/sass.rb +1 -1
- data/lib/ramaze/view/slippers.rb +40 -13
- data/lib/ramaze/view/tagz.rb +9 -5
- data/ramaze.gemspec +23 -128
- data/spec/helper.rb +5 -0
- data/spec/ramaze/bin/app/config.ru +11 -0
- data/spec/ramaze/bin/create.rb +28 -0
- data/spec/ramaze/bin/runner.rb +30 -0
- data/spec/ramaze/bin/start.rb +38 -0
- data/spec/ramaze/cache/memcache.rb +10 -3
- data/spec/ramaze/cache/sequel.rb +7 -0
- data/spec/ramaze/controller/provide_inheritance.rb +0 -10
- data/spec/ramaze/dispatcher/file.rb +19 -15
- data/spec/ramaze/helper/auth.rb +10 -9
- data/spec/ramaze/helper/blue_form.rb +121 -68
- data/spec/ramaze/helper/email.rb +69 -0
- data/spec/ramaze/helper/layout.rb +12 -15
- data/spec/ramaze/helper/layout/alternative.xhtml +5 -0
- data/spec/ramaze/helper/user.rb +2 -0
- data/spec/ramaze/log/growl.rb +14 -1
- data/spec/{contrib → ramaze}/rest.rb +1 -1
- data/spec/ramaze/session/memcache.rb +2 -2
- data/spec/ramaze/view/sass.rb +1 -1
- data/tasks/bacon.rake +3 -3
- data/tasks/gem.rake +17 -18
- data/tasks/rcov.rake +2 -3
- data/tasks/release.rake +8 -65
- data/tasks/setup.rake +10 -8
- data/tasks/todo.rake +9 -5
- data/tasks/yard.rake +3 -2
- metadata +105 -397
- data/MANIFEST +0 -532
- data/TODO.md +0 -19
- data/benchmark/bench_templates/bench.rb +0 -67
- data/benchmark/bench_templates/view/large.erb +0 -79
- data/benchmark/bench_templates/view/large.haml +0 -41
- data/benchmark/bench_templates/view/large.lok +0 -79
- data/benchmark/bench_templates/view/large.xhtml +0 -79
- data/benchmark/bench_templates/view/small.erb +0 -21
- data/benchmark/bench_templates/view/small.haml +0 -12
- data/benchmark/bench_templates/view/small.lok +0 -21
- data/benchmark/bench_templates/view/small.xhtml +0 -21
- data/benchmark/results.txt +0 -131
- data/benchmark/run.rb +0 -355
- data/benchmark/suite/minimal.rb +0 -11
- data/benchmark/suite/no_informer.rb +0 -7
- data/benchmark/suite/no_sessions.rb +0 -9
- data/benchmark/suite/no_template.rb +0 -7
- data/benchmark/suite/simple.rb +0 -5
- data/benchmark/suite/template_erubis.rb +0 -8
- data/benchmark/suite/template_etanni.rb +0 -8
- data/benchmark/suite/template_ezamar.rb +0 -8
- data/benchmark/suite/template_haml.rb +0 -13
- data/benchmark/suite/template_liquid.rb +0 -11
- data/benchmark/suite/template_markaby.rb +0 -9
- data/benchmark/suite/template_nagoro.rb +0 -8
- data/benchmark/suite/template_redcloth.rb +0 -13
- data/benchmark/suite/template_tenjin.rb +0 -8
- data/benchmark/test.rb +0 -35
- data/doc/FAQ +0 -92
- data/doc/INSTALL +0 -92
- data/doc/TODO +0 -29
- data/doc/meta/announcement.txt +0 -119
- data/doc/meta/configuration.txt +0 -163
- data/doc/meta/internals.txt +0 -278
- data/doc/meta/users.kml +0 -64
- data/doc/tutorial/todolist.html +0 -1512
- data/doc/tutorial/todolist.txt +0 -920
- data/examples/app/sourceview/public/coderay.css +0 -104
- data/examples/app/sourceview/public/images/file.gif +0 -0
- data/examples/app/sourceview/public/images/folder.gif +0 -0
- data/examples/app/sourceview/public/images/tv-collapsable-last.gif +0 -0
- data/examples/app/sourceview/public/images/tv-collapsable.gif +0 -0
- data/examples/app/sourceview/public/images/tv-expandable-last.gif +0 -0
- data/examples/app/sourceview/public/images/tv-expandable.gif +0 -0
- data/examples/app/sourceview/public/images/tv-item-last.gif +0 -0
- data/examples/app/sourceview/public/images/tv-item.gif +0 -0
- data/examples/app/sourceview/public/jquery.js +0 -11
- data/examples/app/sourceview/public/jquery.treeview.css +0 -48
- data/examples/app/sourceview/public/jquery.treeview.js +0 -223
- data/examples/app/sourceview/public/sourceview.js +0 -52
- data/examples/app/sourceview/start.rb +0 -79
- data/examples/app/sourceview/view/index.haml +0 -59
- data/examples/helpers/httpdigest.rb +0 -107
- data/lib/proto/public/css/screen.css +0 -30
- data/lib/proto/public/js/jquery.js +0 -7179
- data/lib/ramaze/contrib/addressable_route.rb +0 -56
- data/lib/ramaze/contrib/app_graph.rb +0 -64
- data/lib/ramaze/contrib/email.rb +0 -88
- data/lib/ramaze/contrib/facebook.rb +0 -23
- data/lib/ramaze/contrib/facebook/facebook.rb +0 -171
- data/lib/ramaze/contrib/gettext.rb +0 -113
- data/lib/ramaze/contrib/gettext/mo.rb +0 -155
- data/lib/ramaze/contrib/gettext/parser.rb +0 -46
- data/lib/ramaze/contrib/gettext/po.rb +0 -109
- data/lib/ramaze/contrib/gzip_filter.rb +0 -1
- data/lib/ramaze/contrib/maruku_uv.rb +0 -59
- data/lib/ramaze/contrib/profiling.rb +0 -36
- data/lib/ramaze/contrib/rest.rb +0 -23
- data/lib/ramaze/contrib/sequel/create_join.rb +0 -26
- data/lib/ramaze/contrib/sequel/form_field.rb +0 -129
- data/lib/ramaze/contrib/sequel/image.rb +0 -196
- data/lib/ramaze/contrib/sequel/relation.rb +0 -98
- data/lib/ramaze/helper/httpdigest.rb +0 -96
- data/lib/ramaze/tool/bin.rb +0 -340
- data/lib/ramaze/tool/create.rb +0 -48
- data/lib/ramaze/tool/project_creator.rb +0 -120
- data/lib/ramaze/view/less.rb +0 -12
- data/lib/ramaze/view/maruku.rb +0 -15
- data/lib/ramaze/view/redcloth.rb +0 -21
- data/spec/contrib/addressable_route.rb +0 -30
- data/spec/examples/helpers/httpdigest.rb +0 -64
- data/spec/examples/templates/template_redcloth.rb +0 -13
- data/spec/ramaze/bin/ramaze.rb +0 -96
- data/spec/ramaze/helper/httpdigest.rb +0 -176
- data/spec/ramaze/view/less.rb +0 -60
- data/spec/ramaze/view/less/file.css.less +0 -8
- data/spec/ramaze/view/redcloth.rb +0 -66
- data/spec/ramaze/view/redcloth/external.redcloth +0 -8
- data/tasks/copyright.rake +0 -21
- data/tasks/gem_setup.rake +0 -112
- data/tasks/git.rake +0 -46
- data/tasks/grancher.rake +0 -12
- data/tasks/jquery.rake +0 -15
- data/tasks/manifest.rake +0 -4
- data/tasks/metric_changes.rake +0 -24
- data/tasks/reversion.rake +0 -8
- data/tasks/traits.rake +0 -21
data/lib/ramaze/helper/csrf.rb
CHANGED
@@ -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
|
8
|
-
# from CSRF attacks/exploits. Note that this helper merely
|
9
|
-
# and provides several methods. You still need
|
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
|
12
|
-
# works with any given helper, ORM, template engine and so
|
13
|
-
# load this helper and include (a perhaps
|
14
|
-
#
|
15
|
-
#
|
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
|
20
|
-
# a before_all block in a controller. Take a look at the
|
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.
|
29
|
-
# but it does show what the before_all block can do. On to
|
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
|
40
|
-
# Whenever a user requests a controller that either extends
|
41
|
-
# before_all block Ramaze will check if the
|
42
|
-
# Of course an if/end isn't
|
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
|
53
|
-
# and checks if an CSRF token is supplied if the
|
54
|
-
# a token in ALL HTTP requests
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
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
|
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
|
75
|
-
# Each protected method will require the token to be stored in
|
76
|
-
# This method will then validate that token
|
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
|
-
|
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
|
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
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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 =>
|
141
|
-
:agent =>
|
142
|
-
: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]
|
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
|
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
|
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
|
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
|
-
|
199
|
-
|
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
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
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
|
19
|
-
# erector { h1(:class => 'fruits&floots'){ text 'Apples' } } #=> "<h1 class=\"fruits&floots\">Apples</h1>"
|
15
|
+
# erector { h1 "Apples & Oranges" } #=> "<h1>Apples & 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
|
45
|
-
#
|
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
|
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
|
101
|
-
#
|
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
|
-
#
|
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
|
|