Commit c4d1dd86e0e1ef06d8a085bc4cf87ac7423f27fd

Authored by Victor Costa
2 parents 3a9e86d7 ef5a4c0a

Merge branch 'api' into production

Conflicts:
	test/fixtures/article_followers.yml
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 &lt; 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 &lt; 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)
... ...