Commit 796cdd6ed65b204d356da54d202b17de93844b14

Authored by Evandro Junior
Committed by Victor Costa
1 parent 7e2363ea

api: refactoring captcha

app/models/environment.rb
... ... @@ -348,9 +348,6 @@ class Environment < ActiveRecord::Base
348 348  
349 349 settings_items :signup_welcome_screen_body, :type => String
350 350  
351   - #Captcha settings
352   - settings_items :api_captcha_settings, :type => ActiveSupport::HashWithIndifferentAccess, :default => {}
353   -
354 351 def has_custom_welcome_screen?
355 352 settings[:signup_welcome_screen_body].present?
356 353 end
... ...
lib/noosfero/api/captcha_session_store.rb
... ... @@ -1,30 +0,0 @@
1   -class Noosfero::API::CaptchaSessionStore
2   -
3   - attr_accessor :data
4   - attr_reader :private_token
5   -
6   - def self.create
7   - key = SecureRandom.hex
8   - store = Noosfero::API::CaptchaSessionStore.new(key)
9   - Rails.cache.write(store.private_token, store, expires_in: 300)
10   - return store
11   - end
12   -
13   - def initialize(key)
14   - @private_token = key
15   - end
16   -
17   - def self.get(key)
18   - Rails.cache.fetch(key)
19   - end
20   -
21   - def store
22   - Rails.cache.write(@private_token, self)
23   - end
24   -
25   - def destroy
26   - Rails.cache.delete(@private_token)
27   - end
28   -
29   -
30   -end
lib/noosfero/api/helpers.rb
... ... @@ -23,13 +23,14 @@ require 'grape'
23 23  
24 24 def current_tmp_user
25 25 private_token = (params[PRIVATE_TOKEN_PARAM] || headers['Private-Token']).to_s
26   - @current_tmp_user = Noosfero::API::CaptchaSessionStore.get(private_token)
  26 + ## Get the "captcha" session store
  27 + @current_tmp_user = Noosfero::API::SessionStore.get("captcha##{private_token}")
27 28 @current_tmp_user
28 29 end
29 30  
30 31 def logout_tmp_user
31 32 @current_tmp_user = nil
32   - end
  33 + end
33 34  
34 35 def current_user
35 36 private_token = (params[PRIVATE_TOKEN_PARAM] || headers['Private-Token']).to_s
... ... @@ -273,7 +274,7 @@ require 'grape'
273 274 unauthorized! unless current_user
274 275 end
275 276  
276   - # Allows the anonymous captcha user authentication
  277 + # Allows the anonymous captcha user authentication
277 278 # to pass the check. Used by the articles/vote to allow
278 279 # the vote without login
279 280 def authenticate_allow_captcha!
... ... @@ -411,99 +412,14 @@ require 'grape'
411 412 ##########################################
412 413  
413 414 def test_captcha(remote_ip, params, environment)
414   - d = environment.api_captcha_settings
415   - return true unless d[:enabled] == true
416   - msg_icve = _('Internal captcha validation error')
417   - msg_eacs = 'Environment api_captcha_settings'
418   - s = 500
419   -
420   - if d[:provider] == 'google'
421   - return render_api_error!(msg_icve, s, nil, "#{msg_eacs} private_key not defined") if d[:private_key].nil?
422   - return render_api_error!(msg_icve, s, nil, "#{msg_eacs} version not defined") unless d[:version] == 1 || d[:version] == 2
423   - if d[:version] == 1
424   - d[:verify_uri] ||= 'https://www.google.com/recaptcha/api/verify'
425   - return verify_recaptcha_v1(remote_ip, d[:private_key], d[:verify_uri], params[:recaptcha_challenge_field], params[:recaptcha_response_field])
426   - end
427   - if d[:version] == 2
428   - d[:verify_uri] ||= 'https://www.google.com/recaptcha/api/siteverify'
429   - return verify_recaptcha_v2(remote_ip, d[:private_key], d[:verify_uri], params[:g_recaptcha_response])
430   - end
431   - end
432   - if d[:provider] == 'serpro'
433   - return render_api_error!(msg_icve, s, nil, "#{msg_eacs} verify_uri not defined") if d[:verify_uri].nil?
434   - return verify_serpro_captcha(d[:serpro_client_id], params[:txtToken_captcha_serpro_gov_br], params[:captcha_text], d[:verify_uri])
435   - end
436   - return render_api_error!(msg_icve, s, nil, "#{msg_eacs} provider not defined")
437   - end
438   -
439   - def verify_recaptcha_v1(remote_ip, private_key, api_recaptcha_verify_uri, recaptcha_challenge_field, recaptcha_response_field)
440   - if recaptcha_challenge_field == nil || recaptcha_response_field == nil
441   - return render_api_error!(_('Captcha validation error'), 500, nil, _('Missing captcha data'))
442   - end
443   -
444   - verify_hash = {
445   - "privatekey" => private_key,
446   - "remoteip" => remote_ip,
447   - "challenge" => recaptcha_challenge_field,
448   - "response" => recaptcha_response_field
449   - }
450   - uri = URI(api_recaptcha_verify_uri)
451   - https = Net::HTTP.new(uri.host, uri.port)
452   - https.use_ssl = true
453   - request = Net::HTTP::Post.new(uri.path)
454   - request.set_form_data(verify_hash)
455   - begin
456   - result = https.request(request).body.split("\n")
457   - rescue Exception => e
458   - return render_api_error!(_('Internal captcha validation error'), 500, nil, "Error validating Googles' recaptcha version 1: #{e.message}")
459   - end
460   - return true if result[0] == "true"
461   - return render_api_error!(_("Wrong captcha text, please try again"), 403, nil, "Error validating Googles' recaptcha version 1: #{result[1]}") if result[1] == "incorrect-captcha-sol"
462   - #Catches all errors at the end
463   - return render_api_error!(_("Internal recaptcha validation error"), 500, nil, "Error validating Googles' recaptcha version 1: #{result[1]}")
464   - end
465   -
466   - def verify_recaptcha_v2(remote_ip, private_key, api_recaptcha_verify_uri, g_recaptcha_response)
467   - return render_api_error!(_('Captcha validation error'), 500, nil, _('Missing captcha data')) if g_recaptcha_response == nil
468   - verify_hash = {
469   - "secret" => private_key,
470   - "remoteip" => remote_ip,
471   - "response" => g_recaptcha_response
472   - }
473   - uri = URI(api_recaptcha_verify_uri)
474   - https = Net::HTTP.new(uri.host, uri.port)
475   - https.use_ssl = true
476   - request = Net::HTTP::Post.new(uri.path)
477   - request.set_form_data(verify_hash)
478   - begin
479   - body = https.request(request).body
480   - rescue Exception => e
481   - return render_api_error!(_('Internal captcha validation error'), 500, nil, "recaptcha error: #{e.message}")
482   - end
483   - captcha_result = JSON.parse(body)
484   - captcha_result["success"] ? true : captcha_result
485   - end
486   -
487   - def verify_serpro_captcha(client_id, token, captcha_text, verify_uri)
488   - return render_api_error!(_("Error processing token validation"), 500, nil, "Missing Serpro's Captcha token") unless token
489   - return render_api_error!(_('Captcha text has not been filled'), 403) unless captcha_text
490   - uri = URI(verify_uri)
491   - http = Net::HTTP.new(uri.host, uri.port)
492   - request = Net::HTTP::Post.new(uri.path)
493   - verify_string = "#{client_id}&#{token}&#{captcha_text}"
494   - request.body = verify_string
495   - begin
496   - body = http.request(request).body
497   - rescue Exception => e
498   - return render_api_error!(_('Internal captcha validation error'), 500, nil, "Serpro captcha error: #{e.message}")
  415 + captcha_plugin_enabled = @plugins.dispatch(:test_captcha, remote_ip, params, environment).map {|p| p if ! ( p===nil ) }
  416 + return true if captcha_plugin_enabled.size == 0
  417 + if captcha_plugin_enabled.size > 1
  418 + return render_api_error!(_("Error processing Captcha"), 500, nil, "More than one captcha plugin enabled")
499 419 end
500   - return true if body == '1'
501   - return render_api_error!(_("Internal captcha validation error"), 500, body, "Unable to reach Serpro's Captcha validation service") if body == "Activity timed out"
502   - return render_api_error!(_("Wrong captcha text, please try again"), 403) if body == 0
503   - return render_api_error!(_("Serpro's captcha token not found"), 500) if body == 2
504   - return render_api_error!(_("No data sent to validation server or other serious problem"), 500) if body == -1
505   - #Catches all errors at the end
506   - return render_api_error!(_("Internal captcha validation error"), 500, nil, "Error validating Serpro's captcha #{body}")
  420 + test_result = captcha_plugin_enabled[0]
  421 + return true if test_result === true
  422 + render_api_error!(test_result[:user_message], test_result[:status], test_result[:log_message], test_result[:javascript_console_message])
507 423 end
508 424  
509 425 end
... ...
lib/noosfero/api/session.rb
... ... @@ -16,7 +16,11 @@ module Noosfero
16 16 # this return is just to improve the clarity of the execution path
17 17 return unless test_captcha(remote_ip, params, environment)
18 18 ## Creates and caches a captcha session store
19   - store = Noosfero::API::CaptchaSessionStore.create
  19 + store = Noosfero::API::SessionStore.create("captcha")
  20 + ## Initialize the data for the session store
  21 + store.data = []
  22 + ## Put it back in cache
  23 + store.store
20 24 { "private_token" => "#{store.private_token}" }
21 25 end
22 26  
... ...
lib/noosfero/api/session_store.rb 0 → 100644
... ... @@ -0,0 +1,53 @@
  1 +## A session store for the API. It can store
  2 +## generic data on the Rails Cache to simulate
  3 +## a stateful session for API methods
  4 +class Noosfero::API::SessionStore
  5 +
  6 + ## A generic data value to allow storing any
  7 + ## value within this SessionStore
  8 + attr_accessor :data
  9 + ## The user private_token associated with this SessionStore
  10 + attr_reader :private_token
  11 + ## The key for this SessionStore in the Rails Cache
  12 + attr_reader :key
  13 +
  14 + ## Call this method to create and store a SessionStore
  15 + ## in Rails Cache. The SessionStore is returned. The
  16 + ## client_key parameter, if used, will uniquely identify
  17 + ## this SessionStore in Rails Cache, along with the user
  18 + ## private_token in the form: client_key#private_token
  19 + def self.create(client_key = nil)
  20 + private_token = SecureRandom.hex
  21 + store = Noosfero::API::SessionStore.new(client_key, private_token)
  22 + Rails.cache.write(store.key, store, expires_in: 300)
  23 + return store
  24 + end
  25 +
  26 + ## Creates a new SessionStore. Do not use directly in cliente code.
  27 + ## Please use the self.create method instead
  28 + def initialize(client_key, private_token)
  29 + ## Creates the key to store this object in Rails Cache
  30 + key = "#{client_key}#" if client_key
  31 + key = "#{key}#{private_token}"
  32 + @key = key
  33 + @private_token = private_token
  34 + end
  35 +
  36 + ## Returns the SessionStore in Rails Cache associated
  37 + ## with the given key
  38 + def self.get(key)
  39 + Rails.cache.fetch(key)
  40 + end
  41 +
  42 + ## Stores this SessionStore in Rails Cache using the
  43 + ## key attribute as the unique identifier
  44 + def store
  45 + Rails.cache.write(@key, self)
  46 + end
  47 +
  48 + ## Remove this session store from Rails Cache
  49 + def destroy
  50 + Rails.cache.delete(@key)
  51 + end
  52 +
  53 +end
... ...
lib/noosfero/api/v1/articles.rb
... ... @@ -149,13 +149,24 @@ module Noosfero
149 149 # FIXME verify allowed values
150 150 render_api_error!('Vote value not allowed', 400) unless [-1, 1].include?(value)
151 151 article = find_article(environment.articles, params[:id])
152   -
153   - begin
  152 + ## If login with captcha
  153 + if @current_tmp_user
  154 + vote = (@current_tmp_user.data.include? article.id) ? false : true
  155 + if vote
  156 + @current_tmp_user.data << article.id
  157 + @current_tmp_user.store
  158 + begin
  159 + vote = Vote.new(:voteable => article, :voter => current_person, :vote => value)
  160 + {:vote => vote.save}
  161 + rescue ActiveRecord::RecordInvalid => e
  162 + render_api_error!(e.message, 400)
  163 + end
  164 + else
  165 + {:vote => false}
  166 + end
  167 + else
154 168 vote = Vote.new(:voteable => article, :voter => current_person, :vote => value)
155   - saved = vote.save!
156   - {:vote => saved}
157   - rescue ActiveRecord::RecordInvalid => e
158   - render_api_error!(e.message, 400)
  169 + {:vote => vote.save}
159 170 end
160 171 end
161 172  
... ...
lib/noosfero/plugin.rb
... ... @@ -671,6 +671,11 @@ class Noosfero::Plugin
671 671 nil
672 672 end
673 673  
  674 + #By default will return nil that will mean not implented by the plugin
  675 + def test_captcha(*args)
  676 + nil
  677 + end
  678 +
674 679 # -> Adds additional blocks to profiles and environments.
675 680 # Your plugin must implements a class method called 'extra_blocks'
676 681 # that returns a hash with the following syntax.
... ...
plugins/serpro_captcha 0 → 160000
... ... @@ -0,0 +1 @@
  1 +Subproject commit 6bc22cb64bf23a142d934b7e1818ce02d073b578
... ...
test/unit/api/articles_test.rb
... ... @@ -127,6 +127,37 @@ class ArticlesTest &lt; ActiveSupport::TestCase
127 127 assert_equal 1, json['total_followers']
128 128 end
129 129  
  130 + should 'not perform a vote twice in same article' do
  131 + article = fast_create(Article, :profile_id => @person.id, :name => "Some thing")
  132 + @params[:value] = 1
  133 + ## Perform a vote twice in API should compute only one vote
  134 + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}"
  135 + json = JSON.parse(last_response.body)
  136 +
  137 + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}"
  138 + json = JSON.parse(last_response.body)
  139 +
  140 + total = article.votes_total
  141 +
  142 + assert_equal 1, total
  143 + end
  144 +
  145 + should 'not perform a vote in favor and against a proposal' do
  146 + article = fast_create(Article, :profile_id => @person.id, :name => "Some thing")
  147 + @params[:value] = 1
  148 + ## Perform a vote in favor a proposal
  149 + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}"
  150 + json = JSON.parse(last_response.body)
  151 + assert_equal 201, last_response.status
  152 + ## Perform a vote against a proposal
  153 + @params[:value] = -1
  154 + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}"
  155 + json = JSON.parse(last_response.body)
  156 + ## The api should not allow to save this vote
  157 + assert_equal false, json['vote']
  158 + end
  159 +
  160 +
130 161 should 'perform a vote in a article identified by id' do
131 162 article = fast_create(Article, :profile_id => @person.id, :name => "Some thing")
132 163 @params[:value] = 1
... ... @@ -136,6 +167,7 @@ class ArticlesTest &lt; ActiveSupport::TestCase
136 167  
137 168 assert_not_equal 401, last_response.status
138 169 assert_equal true, json['vote']
  170 +
139 171 end
140 172  
141 173 should 'not perform a vote in a archived article' do
... ...
test/unit/api/helpers_test.rb
1 1 require File.dirname(__FILE__) + '/test_helper';
2 2  
  3 +
3 4 require File.expand_path(File.dirname(__FILE__) + "/../../../lib/noosfero/api/helpers")
4 5  
5 6 class APIHelpersTest < ActiveSupport::TestCase
... ... @@ -216,88 +217,15 @@ class APIHelpersTest &lt; ActiveSupport::TestCase
216 217  
217 218 ###### Captcha tests ######
218 219  
219   -should 'do not test captcha when there are no settings' do
220   - environment = Environment.new
221   - assert test_captcha("127.0.0.1", {}, environment)
222   -end
223   -
224   -should 'do not test captcha when captcha is disabled on settings' do
225   - environment = Environment.new
226   - environment.api_captcha_settings = {
227   - enabled: false,
228   - }
229   - assert test_captcha("127.0.0.1", {}, environment)
230   -end
231   -
232   -should 'fail display recaptcha v1' do
233   - environment = Environment.new
234   - environment.api_captcha_settings = {
235   - enabled: true,
236   - provider: 'google',
237   - version: 1,
238   - private_key: '6LdsWAcTAAAAAB6maB_HalVyCc4asDAxPxloIMvY',
239   - public_key: '6LdsWAcTAAAAAChTUUD6yu9fCDhdIZzNd7F53zf-',
240   - verify_uri: 'https://www.google.com/recaptcha/api/verify',
241   - }
242   - r = test_captcha('127.0.0.1', params, environment)
243   - assert_equal(_("Missing captcha data"), r[0][:javascript_console_message])
244   -end
245   -
246   -should 'fail display recaptcha v2' do
247   - environment = Environment.new
248   - environment.api_captcha_settings = {
249   - enabled: true,
250   - provider: 'google',
251   - version: 2,
252   - private_key: '6LdsWAcTAAAAAB6maB_HalVyCc4asDAxPxloIMvY',
253   - public_key: '6LdsWAcTAAAAAChTUUD6yu9fCDhdIZzNd7F53zf-',
254   - verify_uri: 'https://www.google.com/recaptcha/api/siteverify',
255   - }
256   - r = test_captcha('127.0.0.1', params, environment)
257   - assert_equal(_("Missing captcha data"), r[0][:javascript_console_message])
258   -end
259   -
260   -should 'verify if user filled Serpro\' captcha text' do
261   - environment = Environment.new
262   - environment.api_captcha_settings = {
263   - enabled: true,
264   - provider: 'serpro',
265   - serpro_client_id: '0000000000000000',
266   - verify_uri: 'http://localhost/api/verify',
267   - }
268   - params = {}
269   - params[:txtToken_captcha_serpro_gov_br] = '4324343'
270   - assert_equal(_('Captcha text has not been filled'), test_captcha('127.0.0.1', params, environment)[0]['message'])
271   -end
272   -
273   -should 'verify if Serpro\' captcha token has been sent' do
274   - environment = Environment.new
275   - environment.api_captcha_settings = {
276   - enabled: true,
277   - provider: 'serpro',
278   - serpro_client_id: '0000000000000000',
279   - verify_uri: 'http://localhost/api/verify',
280   - }
281   - params = {}
282   - params[:captcha_text] = '4324343'
283   - r = test_captcha('127.0.0.1', params, environment)
284   - assert_equal(_("Missing Serpro's Captcha token"), r[0][:javascript_console_message])
285   -end
286   -
287   -should 'captcha serpro say name or service not known' do
288   - environment = Environment.new
289   - environment.api_captcha_settings = {
290   - enabled: true,
291   - provider: 'serpro',
292   - serpro_client_id: '0000000000000000',
293   - verify_uri: 'http://someserverthatdoesnotexist.mycompanythatdoesnotexist.com/validate',
294   - }
295   - params = {}
296   - params[:txtToken_captcha_serpro_gov_br] = '4324343'
297   - params[:captcha_text] = '4324343'
298   - r = test_captcha('127.0.0.1', params, environment)
299   - assert (r[0][:javascript_console_message]).starts_with?("Serpro captcha error: getaddrinfo")
300   -end
  220 +# def plugins
  221 +# environment = Environment.default
  222 +# Noosfero::Plugin::Manager.new(environment, self)
  223 +# end
  224 +#
  225 +# should 'do not test captcha when there is no captcha plugin enabled' do
  226 +# environment = Environment.new
  227 +# assert test_captcha("127.0.0.1", {}, environment)
  228 +# end
301 229  
302 230 ###### END Captcha tests ######
303 231  
... ...
test/unit/api/login_captcha_test.rb
... ... @@ -3,20 +3,8 @@ require File.dirname(__FILE__) + &#39;/test_helper&#39;
3 3 class LoginCaptchaTest < ActiveSupport::TestCase
4 4  
5 5 def setup()
6   - @environment = Environment.default
7   - @environment.api_captcha_settings = {
8   - enabled: true,
9   - provider: 'serpro',
10   - serpro_client_id: '0000000000000000',
11   - verify_uri: 'http://captcha.serpro.gov.br/validate',
12   - }
13   - @environment.save!
14   - @url = "/api/v1/login-captcha?"
15   - end
16   -
17   - def create_article(name)
18   - person = fast_create(Person, :environment_id => @environment.id)
19   - fast_create(Article, :profile_id => person.id, :name => name)
  6 + @url = "/api/v1/login-captcha"
  7 + OutcomeCaptcha.outcome_captcha_test = true
20 8 end
21 9  
22 10 should 'not perform a vote without authentication' do
... ... @@ -34,7 +22,6 @@ class LoginCaptchaTest &lt; ActiveSupport::TestCase
34 22 assert_not_nil @private_token
35 23 end
36 24  
37   -
38 25 should 'perform a vote in an article identified by id' do
39 26 login_with_captcha
40 27 article = create_article('Article 1')
... ... @@ -42,11 +29,31 @@ class LoginCaptchaTest &lt; ActiveSupport::TestCase
42 29  
43 30 post "/api/v1/articles/#{article.id}/vote?#{params.to_query}"
44 31 json = JSON.parse(last_response.body)
45   -
  32 +
46 33 assert_not_equal 401, last_response.status
47 34 assert_equal true, json['vote']
48 35 end
49 36  
  37 + should 'not perform a vote twice in same article' do
  38 + login_with_captcha
  39 + article = create_article('Article 1')
  40 + params[:value] = 1
  41 +
  42 + ## Perform a vote twice in API should compute only one vote
  43 + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}"
  44 + json = JSON.parse(last_response.body)
  45 + assert_equal true, json['vote']
  46 +
  47 + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}"
  48 + json = JSON.parse(last_response.body)
  49 + ## Should not allow vote again
  50 + assert_equal false, json['vote']
  51 +
  52 + total = article.votes_total
  53 +
  54 + assert_equal 1, total
  55 + end
  56 +
50 57 should 'not follow any article' do
51 58 login_with_captcha
52 59 article = create_article('Article 1')
... ... @@ -57,9 +64,11 @@ class LoginCaptchaTest &lt; ActiveSupport::TestCase
57 64 end
58 65  
59 66 should 'not generate private token when login without captcha' do
  67 + OutcomeCaptcha.outcome_captcha_test = false
60 68 params = {}
61 69 post "#{@url}#{params.to_query}"
62 70 json = JSON.parse(last_response.body)
  71 + assert_equal last_response.status, 403
63 72 assert json["private_token"].blank?
64 73 end
65 74  
... ... @@ -70,4 +79,8 @@ class LoginCaptchaTest &lt; ActiveSupport::TestCase
70 79 assert ret == @private_token
71 80 end
72 81  
73   -end
74 82 \ No newline at end of file
  83 + should 'do login captcha from api' do
  84 + do_login_captcha_from_api
  85 + end
  86 +
  87 +end
... ...
test/unit/api/session_store_test.rb 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +require File.dirname(__FILE__) + '/test_helper'
  2 +
  3 +class SessionStoreTest < ActiveSupport::TestCase
  4 +
  5 + should 'create a session store without client key' do
  6 + store = Noosfero::API::SessionStore.create
  7 + assert_not_nil store
  8 + private_token = store.private_token
  9 + assert_not_nil private_token
  10 + key = store.key
  11 + assert_not_nil key
  12 + assert_equal key, private_token
  13 + end
  14 +
  15 + should 'create a session store with client key' do
  16 + store = Noosfero::API::SessionStore.create("mykey")
  17 + assert_not_nil store
  18 + private_token = store.private_token
  19 + assert_not_nil private_token
  20 + key = store.key
  21 + assert_not_nil key
  22 + assert_equal key, "mykey##{private_token}"
  23 + end
  24 +
  25 + should 'get a session store with client key' do
  26 + store = Noosfero::API::SessionStore.create("mykey")
  27 + retrieved = Noosfero::API::SessionStore.get(store.key)
  28 + assert_not_nil retrieved
  29 + end
  30 +
  31 + should 'not get a destroyed session store with client key' do
  32 + store = Noosfero::API::SessionStore.create("mykey")
  33 + store.destroy
  34 + retrieved = Noosfero::API::SessionStore.get(store.key)
  35 + assert_nil retrieved
  36 + end
  37 +
  38 + should 'store data in session store' do
  39 + store = Noosfero::API::SessionStore.create("mykey")
  40 + store.data = [1, 2]
  41 + ## Put it back in cache
  42 + store.store
  43 + retrieved = Noosfero::API::SessionStore.get(store.key)
  44 + assert_equal [1,2], retrieved.data
  45 + end
  46 +
  47 +end
0 48 \ No newline at end of file
... ...
test/unit/api/session_test.rb
... ... @@ -4,6 +4,7 @@ class SessionTest &lt; ActiveSupport::TestCase
4 4  
5 5 def setup
6 6 login_api
  7 + OutcomeCaptcha.outcome_captcha_test = true
7 8 end
8 9  
9 10 should 'generate private token when login' do
... ... @@ -89,22 +90,6 @@ class SessionTest &lt; ActiveSupport::TestCase
89 90 json = JSON.parse(last_response.body)
90 91 end
91 92  
92   - should 'detected error, Name or service not known, for Serpro captcha communication' do
93   - environment = Environment.default
94   - environment.api_captcha_settings = {
95   - enabled: true,
96   - provider: 'serpro',
97   - serpro_client_id: '0000000000000000',
98   - verify_uri: 'http://someserverthatdoesnotexist.mycompanythatdoesnotexist.com/validate',
99   - }
100   - environment.save!
101   - params = {:login => "newuserapi", :password => "newuserapi", :password_confirmation => "newuserapi", :email => "newuserapi@email.com",
102   - :txtToken_captcha_serpro_gov_br => '4324343', :captcha_text => '4030320'}
103   - post "/api/v1/register?#{params.to_query}"
104   - message = JSON.parse(last_response.body)['javascript_console_message']
105   - assert_equal "Serpro captcha error: getaddrinfo: Name or service not known", message
106   - end
107   -
108 93 # TODO: Add another test cases to check register situations
109 94 should 'activate a user' do
110 95 params = {
... ... @@ -185,7 +170,7 @@ class SessionTest &lt; ActiveSupport::TestCase
185 170  
186 171 should 'do not change user password when password confirmation is wrong' do
187 172 user = create_user
188   - user.activate
  173 + user.activate
189 174 task = ChangePassword.create!(:requestor => user.person)
190 175 params = {:code => task.code, :password => 'secret', :password_confirmation => 's3cret'}
191 176 patch "/api/v1/new_password?#{params.to_query}"
... ... @@ -200,6 +185,14 @@ class SessionTest &lt; ActiveSupport::TestCase
200 185 assert_equal 404, last_response.status
201 186 end
202 187  
  188 + should 'do not register a user if captcha fails' do
  189 + OutcomeCaptcha.outcome_captcha_test = false
  190 + Environment.default.enable('skip_new_user_email_confirmation')
  191 + params = {:login => "newuserapi_ewa ", :password => "newuserapi", :password_confirmation => "newuserapi", :email => "newuserapi@email.com" }
  192 + post "/api/v1/register?#{params.to_query}"
  193 + assert_equal 403, last_response.status
  194 + end
  195 +
203 196 should 'not return private token when the registered user is inactive' do
204 197 params = {:login => "newuserapi", :password => "newuserapi", :password_confirmation => "newuserapi", :email => "newuserapi@email.com" }
205 198 post "/api/v1/register?#{params.to_query}"
... ...
test/unit/api/test_helper.rb
1 1 require File.dirname(__FILE__) + '/../../test_helper'
  2 +require File.join(Rails.root, '/lib/noosfero/api/helpers.rb')
  3 +
  4 +class OutcomeCaptcha
  5 + class << self
  6 + attr_accessor :outcome_captcha_test
  7 + end
  8 + @outcome_captcha_test = true
  9 +end
  10 +
  11 +module Noosfero
  12 + module API
  13 + module APIHelpers
  14 + def test_captcha(*args)
  15 + return true if OutcomeCaptcha.outcome_captcha_test
  16 + render_api_error!("Error testing captcha", 403)
  17 + end
  18 + end
  19 + end
  20 +end
2 21  
3 22 class ActiveSupport::TestCase
4 23  
5 24 include Rack::Test::Methods
  25 + include Noosfero::API::APIHelpers
6 26  
7 27 def app
8 28 Noosfero::API::API
... ... @@ -15,31 +35,18 @@ class ActiveSupport::TestCase
15 35 json
16 36 end
17 37  
18   - ## Performs a login using the session.rb but mocking the
19   - ## real HTTP request to validate the captcha.
20 38 def do_login_captcha_from_api
21   - # Request mocking
22   - #Net::HTTP::Post Mock
23   - request = mock
24   - #Net::HTTP Mock
25   - http = mock
26   - uri = URI(environment.api_captcha_settings[:verify_uri])
27   - Net::HTTP.expects(:new).with(uri.host, uri.port).returns(http)
28   - Net::HTTP::Post.expects(:new).with(uri.path).returns(request)
29   -
30   - # Captcha required codes
31   - request.stubs(:body=).with("0000000000000000&4324343&4030320")
32   - http.stubs(:request).with(request).returns(http)
33   -
34   - # Captcha validation success !!
35   - http.stubs(:body).returns("1")
36   -
37   - params = {:txtToken_captcha_serpro_gov_br => '4324343', :captcha_text => '4030320'}
38   - post "#{@url}#{params.to_query}"
39   - json = JSON.parse(last_response.body)
  39 + post "/api/v1/login-captcha"
  40 + json = JSON.parse(last_response.body)
40 41 json
41 42 end
42 43  
  44 + def create_article(name)
  45 + @environment = Environment.default
  46 + person = fast_create(Person, :environment_id => @environment.id)
  47 + fast_create(Article, :profile_id => person.id, :name => name)
  48 + end
  49 +
43 50 def login_api
44 51 @environment = Environment.default
45 52 @user = User.create!(:login => 'testapi', :password => 'testapi', :password_confirmation => 'testapi', :email => 'test@test.org', :environment => @environment)
... ...