Commit c4d1dd86e0e1ef06d8a085bc4cf87ac7423f27fd
Exists in
theme-brasil-digital-from-staging
and in
9 other branches
Merge branch 'api' into production
Conflicts: test/fixtures/article_followers.yml
Showing
7 changed files
with
107 additions
and
69 deletions
Show diff stats
app/models/environment.rb
... | ... | @@ -326,6 +326,9 @@ class Environment < ActiveRecord::Base |
326 | 326 | |
327 | 327 | settings_items :signup_welcome_screen_body, :type => String |
328 | 328 | |
329 | + #Captcha setings | |
330 | + settings_items :api_captcha_settings, :type => ActiveSupport::HashWithIndifferentAccess, :default => {} | |
331 | + | |
329 | 332 | def has_custom_welcome_screen? |
330 | 333 | settings[:signup_welcome_screen_body].present? |
331 | 334 | end | ... | ... |
app/models/user.rb
... | ... | @@ -129,7 +129,8 @@ class User < ActiveRecord::Base |
129 | 129 | end |
130 | 130 | |
131 | 131 | #FIXME make this test |
132 | - def private_token_expired? | |
132 | + def private_token_expired? | |
133 | + return true if self.private_token_generated_at.nil? | |
133 | 134 | self.generate_private_token! if self.private_token.nil? || (self.private_token_generated_at + 2.weeks < DateTime.now) |
134 | 135 | end |
135 | 136 | |
... | ... | @@ -357,19 +358,6 @@ class User < ActiveRecord::Base |
357 | 358 | @is_password_required = false |
358 | 359 | end |
359 | 360 | |
360 | - #FIXME make this test | |
361 | - def generate_private_token! | |
362 | - self.private_token = SecureRandom.hex | |
363 | - self.private_token_generated_at = DateTime.now | |
364 | - save(:validate => false) | |
365 | - end | |
366 | - | |
367 | - #FIXME make this test | |
368 | - def private_token_expired? | |
369 | - self.generate_private_token! if self.private_token.nil? || (self.private_token_generated_at + 2.weeks < DateTime.now) | |
370 | - end | |
371 | - | |
372 | - | |
373 | 361 | protected |
374 | 362 | |
375 | 363 | def normalize_email | ... | ... |
lib/noosfero/api/api.rb
1 | 1 | require 'grape' |
2 | 2 | #require 'rack/contrib' |
3 | +Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require_dependency file unless file =~ /api\.rb/} | |
3 | 4 | |
4 | -Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file unless file =~ /api\.rb/} | |
5 | 5 | module Noosfero |
6 | 6 | module API |
7 | 7 | class API < Grape::API |
... | ... | @@ -12,6 +12,13 @@ module Noosfero |
12 | 12 | use GrapeLogging::Middleware::RequestLogger, { logger: logger } |
13 | 13 | |
14 | 14 | rescue_from :all do |e| |
15 | + # Many brave warriors have fallen in the battle for fixing the API log | |
16 | + # Please, don't remove these 2 lines until the API log problem has | |
17 | + # been PROPERLY fixed by our savior!!! | |
18 | + # Otherwise we will have no clue of what went wrong in the API | |
19 | + puts "API error during processing: #{$!}" | |
20 | + puts "Backtrace:\n\t#{e.backtrace.join("\n\t")}" | |
21 | + # Thanks! | |
15 | 22 | logger.error e |
16 | 23 | end |
17 | 24 | |
... | ... | @@ -61,4 +68,4 @@ module Noosfero |
61 | 68 | end |
62 | 69 | end |
63 | 70 | end |
64 | 71 | -end |
72 | +end | |
65 | 73 | \ No newline at end of file | ... | ... |
lib/noosfero/api/helpers.rb
... | ... | @@ -4,6 +4,8 @@ |
4 | 4 | PRIVATE_TOKEN_PARAM = :private_token |
5 | 5 | ALLOWED_PARAMETERS = [:parent_id, :from, :until, :content_type] |
6 | 6 | |
7 | + include SanitizeParams | |
8 | + | |
7 | 9 | def current_user |
8 | 10 | private_token = (params[PRIVATE_TOKEN_PARAM] || headers['Private-Token']).to_s |
9 | 11 | @current_user ||= User.find_by_private_token(private_token) |
... | ... | @@ -91,6 +93,7 @@ |
91 | 93 | end |
92 | 94 | |
93 | 95 | def authenticate! |
96 | + | |
94 | 97 | unauthorized! unless current_user |
95 | 98 | end |
96 | 99 | |
... | ... | @@ -207,39 +210,29 @@ |
207 | 210 | # captcha_helpers # |
208 | 211 | ########################################## |
209 | 212 | |
210 | - def test_captcha(remote_ip, params) | |
211 | - return true unless API.NOOSFERO_CONF['api_captcha_enabled'] === true | |
212 | - | |
213 | - private_key = API.NOOSFERO_CONF['api_recaptcha_private_key'] | |
214 | - if private_key == nil | |
215 | - raise ArgumentError, "API.NOOSFERO_CONF['api_recaptcha_private_key'] not defined" | |
216 | - end | |
217 | - | |
218 | - api_captcha_version = API.NOOSFERO_CONF['api_captcha_version'] | |
219 | - unless api_captcha_version == 1 || api_captcha_version == 2 | |
220 | - raise ArgumentError, "API.NOOSFERO_CONF['api_captcha_version'] not defined" | |
221 | - end | |
222 | - | |
223 | - if api_captcha_version == 1 | |
224 | - api_recaptcha_verify_uri = API.NOOSFERO_CONF['api_recaptcha_v1_verify_uri'] | |
225 | - if api_recaptcha_verify_uri == nil | |
226 | - raise ArgumentError, "API.NOOSFERO_CONF['api_recaptcha_v1_verify_uri'] not defined" | |
213 | + def test_captcha(remote_ip, params, _environment = nil) | |
214 | + environment ||= _environment | |
215 | + d = environment.api_captcha_settings | |
216 | + return true unless d[:enabled] == true | |
217 | + | |
218 | + if d[:provider] == 'google' | |
219 | + raise ArgumentError, "Environment api_captcha_settings private_key not defined" if d[:private_key].nil? | |
220 | + raise ArgumentError, "Environment api_captcha_settings version not defined" unless d[:version] == 1 || d[:version] == 2 | |
221 | + raise ArgumentError, "Environment api_captcha_settings verify_uri not defined" if d[:verify_uri].nil? | |
222 | + if d[:version] == 1 | |
223 | + return verify_recaptcha_v1(remote_ip, d[:private_key], d[:verify_uri], params[:recaptcha_challenge_field], params[:recaptcha_response_field]) | |
227 | 224 | end |
228 | - return verify_recaptcha_v1(remote_ip, private_key, api_recaptcha_verify_uri, params[:recaptcha_challenge_field], params[:recaptcha_response_field]) | |
229 | - end | |
230 | - | |
231 | - if api_captcha_version == 2 | |
232 | - api_recaptcha_verify_uri = API.NOOSFERO_CONF['api_recaptcha_v2_verify_uri'] | |
233 | - if api_recaptcha_verify_uri == nil | |
234 | - raise ArgumentError, "API.NOOSFERO_CONF['api_recaptcha_v2_verify_uri'] not defined" | |
225 | + if d[:version] == 2 | |
226 | + return verify_recaptcha_v2(remote_ip, d[:private_key], d[:verify_uri], params[:g_recaptcha_response]) | |
235 | 227 | end |
236 | - return verify_recaptcha_v2(remote_ip, private_key, api_recaptcha_verify_uri, params[:g_recaptcha_response]) | |
237 | 228 | end |
238 | 229 | |
230 | + if d[:provider] == 'serpro' | |
231 | + #TODO ADD SERPRO's CAPTCHA | |
232 | + end | |
239 | 233 | end |
240 | 234 | |
241 | 235 | def verify_recaptcha_v1(remote_ip, private_key, api_recaptcha_verify_uri, recaptcha_challenge_field, recaptcha_response_field) |
242 | - | |
243 | 236 | if recaptcha_challenge_field == nil || recaptcha_response_field == nil |
244 | 237 | return _('Missing captcha data') |
245 | 238 | end | ... | ... |
lib/noosfero/api/session.rb
... | ... | @@ -29,7 +29,7 @@ module Noosfero |
29 | 29 | # password (required) - Password |
30 | 30 | # login - login |
31 | 31 | # Example Request: |
32 | - # POST /register?email=some@mail.com&password=pas&login=some | |
32 | + # POST /register?email=some@mail.com&password=pas&password_confirmation=pas&login=some | |
33 | 33 | params do |
34 | 34 | requires :email, type: String, desc: _("Email") |
35 | 35 | requires :login, type: String, desc: _("Login") | ... | ... |
lib/sanitize_params.rb
... | ... | @@ -2,33 +2,40 @@ module SanitizeParams |
2 | 2 | |
3 | 3 | protected |
4 | 4 | |
5 | - # Check each request parameter for | |
6 | - # improper HTML or Script tags | |
7 | - def sanitize_params | |
8 | - request.params.each { |k, v| | |
9 | - if v.is_a?(String) | |
10 | - params[k] = sanitize_param v | |
11 | - elsif v.is_a?(Array) | |
12 | - params[k] = sanitize_array v | |
13 | - end | |
14 | - } | |
15 | - end | |
5 | + # Check each request parameter for | |
6 | + # improper HTML or Script tags | |
7 | + def sanitize_params | |
8 | + sanitize_params_hash(request.params) | |
9 | + end | |
16 | 10 | |
17 | - # If the parameter was an array, | |
18 | - # try to sanitize each element in the array | |
19 | - def sanitize_array(array) | |
20 | - array.map! { |e| | |
21 | - if e.is_a?(String) | |
22 | - sanitize_param e | |
23 | - end | |
24 | - } | |
25 | - return array | |
26 | - end | |
11 | + # Given a params list sanitize all | |
12 | + def sanitize_params_hash(params) | |
13 | + params.each { |k, v| | |
14 | + if v.is_a?(String) | |
15 | + params[k] = sanitize_param v | |
16 | + elsif v.is_a?(Array) | |
17 | + params[k] = sanitize_array v | |
18 | + elsif v.kind_of?(Hash) | |
19 | + params[k] = sanitize_params_hash(v) | |
20 | + end | |
21 | + } | |
22 | + end | |
27 | 23 | |
28 | - # Santitize a single value | |
29 | - def sanitize_param(value) | |
30 | - allowed_tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) | |
31 | - ActionController::Base.helpers.sanitize(value, tags: allowed_tags, attributes: %w(href title)) | |
32 | - end | |
24 | + # If the parameter was an array, | |
25 | + # try to sanitize each element in the array | |
26 | + def sanitize_array(array) | |
27 | + array.map! { |e| | |
28 | + if e.is_a?(String) | |
29 | + sanitize_param e | |
30 | + end | |
31 | + } | |
32 | + return array | |
33 | + end | |
34 | + | |
35 | + # Santitize a single value | |
36 | + def sanitize_param(value) | |
37 | + allowed_tags = %w(a acronym b strong i em li ul ol h1 h2 h3 h4 h5 h6 blockquote br cite sub sup ins p) | |
38 | + ActionController::Base.helpers.sanitize(value, tags: allowed_tags, attributes: %w(href title)) | |
39 | + end | |
33 | 40 | |
34 | 41 | end | ... | ... |
test/unit/api/helpers_test.rb
... | ... | @@ -161,6 +161,46 @@ class APIHelpersTest < ActiveSupport::TestCase |
161 | 161 | assert_nil make_conditions_with_parameter[:type] |
162 | 162 | end |
163 | 163 | |
164 | + should 'do not test captcha when there are no settings' do | |
165 | + environment = Environment.new | |
166 | + assert test_captcha("127.0.0.1", {}, environment) | |
167 | + end | |
168 | + | |
169 | + should 'do not test captcha when captcha is disabled on settings' do | |
170 | + environment = Environment.new | |
171 | + environment.api_captcha_settings = { | |
172 | + enabled: false, | |
173 | + } | |
174 | + assert test_captcha("127.0.0.1", {}, environment) | |
175 | + end | |
176 | + | |
177 | + | |
178 | + should 'fail display recaptcha v1' do | |
179 | + environment = Environment.new | |
180 | + environment.api_captcha_settings = { | |
181 | + enabled: true, | |
182 | + provider: 'google', | |
183 | + version: 1, | |
184 | + private_key: '6LdsWAcTAAAAAB6maB_HalVyCc4asDAxPxloIMvY', | |
185 | + public_key: '6LdsWAcTAAAAAChTUUD6yu9fCDhdIZzNd7F53zf-', | |
186 | + verify_uri: 'https://www.google.com/recaptcha/api/verify', | |
187 | + } | |
188 | + assert_equal test_captcha("127.0.0.1", {}, environment), "Missing captcha data" | |
189 | + end | |
190 | + | |
191 | + should 'fail display recaptcha v2' do | |
192 | + environment = Environment.new | |
193 | + environment.api_captcha_settings = { | |
194 | + enabled: true, | |
195 | + provider: 'google', | |
196 | + version: 2, | |
197 | + private_key: '6LdsWAcTAAAAAB6maB_HalVyCc4asDAxPxloIMvY', | |
198 | + public_key: '6LdsWAcTAAAAAChTUUD6yu9fCDhdIZzNd7F53zf-', | |
199 | + verify_uri: 'https://www.google.com/recaptcha/api/siteverify', | |
200 | + } | |
201 | + assert_equal test_captcha("127.0.0.1", {}, environment), "Missing captcha data" | |
202 | + end | |
203 | + | |
164 | 204 | protected |
165 | 205 | |
166 | 206 | def error!(info, status) | ... | ... |