Commit 0318fee8ec6b070e505aa51075ea1b42e97313fb

Authored by Evandro Junior
Committed by Rodrigo Souto
1 parent 4ddf407d

Support google recaptcha for the API

config/noosfero.yml.dist
@@ -11,7 +11,14 @@ development: @@ -11,7 +11,14 @@ development:
11 max_upload_size: 5MB 11 max_upload_size: 5MB
12 hours_until_user_activation_check: 72 12 hours_until_user_activation_check: 72
13 exclude_profile_identifier_pattern: index(\..*)?|home(\..*)? 13 exclude_profile_identifier_pattern: index(\..*)?|home(\..*)?
  14 + api_recaptcha_site_key: '6LdsWAcTAAAAAChTUUD6yu9fCDhdIZzNd7F53zf-'
  15 + api_recaptcha_private_key: '6LdsWAcTAAAAAB6maB_HalVyCc4asDAxPxloIMvY'
  16 + api_recaptcha_verify_uri: 'https://www.google.com/recaptcha/api/siteverify'
14 17
15 test: 18 test:
16 19
17 production: 20 production:
  21 + api_recaptcha_site_key: '6LcLPAcTAAAAAKsd0bxY_TArhD_A7OL19SRCW7_i'
  22 + api_recaptcha_private_key: '6LcLPAcTAAAAAE36SN1M2w1I7Hn8upwXYZ_YQZ5-'
  23 + api_recaptcha_verify_uri: 'https://www.google.com/recaptcha/api/siteverify'
  24 +
18 \ No newline at end of file 25 \ No newline at end of file
lib/noosfero/api/api.rb
1 require 'grape' 1 require 'grape'
2 #require 'rack/contrib' 2 #require 'rack/contrib'
  3 +
3 Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file unless file =~ /api\.rb/} 4 Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file unless file =~ /api\.rb/}
4 module Noosfero 5 module Noosfero
5 module API 6 module API
6 class API < Grape::API 7 class API < Grape::API
7 use Rack::JSONP 8 use Rack::JSONP
8 -  
9 - logger = Logger.new(File.join(Rails.root, 'log', "#{ENV['RAILS_ENV'] || 'production'}_api.log"))  
10 - logger.formatter = GrapeLogging::Formatters::Default.new  
11 - use RequestLogger, { logger: logger }  
12 -  
13 - rescue_from :all do |e|  
14 - logger.error e 9 +
  10 + @@NOOSFERO_CONF = nil
  11 +
  12 + def self.NOOSFERO_CONF
  13 + if @@NOOSFERO_CONF
  14 + @@NOOSFERO_CONF
  15 + else
  16 + file = Rails.root.join('config', 'noosfero.yml')
  17 + @@NOOSFERO_CONF = File.exists?(file) ? YAML.load_file(file)[Rails.env] || {} : {}
  18 + end
15 end 19 end
16 20
17 before { setup_multitenancy } 21 before { setup_multitenancy }
@@ -22,9 +26,9 @@ module Noosfero @@ -22,9 +26,9 @@ module Noosfero
22 prefix "api" 26 prefix "api"
23 format :json 27 format :json
24 content_type :txt, "text/plain" 28 content_type :txt, "text/plain"
25 - 29 +
26 helpers APIHelpers 30 helpers APIHelpers
27 - 31 +
28 mount V1::Articles 32 mount V1::Articles
29 mount V1::Comments 33 mount V1::Comments
30 mount V1::Users 34 mount V1::Users
@@ -33,7 +37,7 @@ module Noosfero @@ -33,7 +37,7 @@ module Noosfero
33 mount V1::Enterprises 37 mount V1::Enterprises
34 mount V1::Categories 38 mount V1::Categories
35 mount Session 39 mount Session
36 - 40 +
37 # hook point which allow plugins to add Grape::API extensions to API::API 41 # hook point which allow plugins to add Grape::API extensions to API::API
38 #finds for plugins which has api mount points classes defined (the class should extends Grape::API) 42 #finds for plugins which has api mount points classes defined (the class should extends Grape::API)
39 @plugins = Noosfero::Plugin.all.map { |p| p.constantize } 43 @plugins = Noosfero::Plugin.all.map { |p| p.constantize }
lib/noosfero/api/helpers.rb
@@ -102,7 +102,21 @@ module Noosfero @@ -102,7 +102,21 @@ module Noosfero
102 end 102 end
103 attrs 103 attrs
104 end 104 end
105 - 105 +
  106 + def verify_recaptcha_v2(remote_ip, g_recaptcha_response, private_key, api_recaptcha_verify_uri)
  107 + verify_hash = {
  108 + "secret" => private_key,
  109 + "remoteip" => remote_ip,
  110 + "response" => g_recaptcha_response
  111 + }
  112 + uri = URI(api_recaptcha_verify_uri)
  113 + https = Net::HTTP.new(uri.host, uri.port)
  114 + https.use_ssl = true
  115 + request = Net::HTTP::Post.new(uri.path)
  116 + request.set_form_data(verify_hash)
  117 + JSON.parse(https.request(request).body)
  118 + end
  119 +
106 ########################################## 120 ##########################################
107 # error helpers # 121 # error helpers #
108 ########################################## 122 ##########################################
lib/noosfero/api/session.rb
  1 +require "uri"
  2 +
1 module Noosfero 3 module Noosfero
2 module API 4 module API
3 - 5 +
4 class Session < Grape::API 6 class Session < Grape::API
5 - 7 +
6 # Login to get token 8 # Login to get token
7 # 9 #
8 # Parameters: 10 # Parameters:
@@ -13,13 +15,13 @@ module Noosfero @@ -13,13 +15,13 @@ module Noosfero
13 # POST http://localhost:3000/api/v1/login?login=adminuser&password=admin 15 # POST http://localhost:3000/api/v1/login?login=adminuser&password=admin
14 post "/login" do 16 post "/login" do
15 user ||= User.authenticate(params[:login], params[:password], environment) 17 user ||= User.authenticate(params[:login], params[:password], environment)
16 - 18 +
17 return unauthorized! unless user 19 return unauthorized! unless user
18 user.generate_private_token! 20 user.generate_private_token!
19 @current_user = user 21 @current_user = user
20 present user, :with => Entities::UserLogin 22 present user, :with => Entities::UserLogin
21 end 23 end
22 - 24 +
23 # Create user. 25 # Create user.
24 # 26 #
25 # Parameters: 27 # Parameters:
@@ -37,16 +39,20 @@ module Noosfero @@ -37,16 +39,20 @@ module Noosfero
37 unique_attributes! User, [:email, :login] 39 unique_attributes! User, [:email, :login]
38 attrs = attributes_for_keys [:email, :login, :password] 40 attrs = attributes_for_keys [:email, :login, :password]
39 attrs[:password_confirmation] = attrs[:password] 41 attrs[:password_confirmation] = attrs[:password]
40 - user = User.new(attrs)  
41 - if user.save 42 + remote_ip = (request.respond_to?(:remote_ip) && request.remote_ip) || (env && env['REMOTE_ADDR'])
  43 + private_key = API.NOOSFERO_CONF['api_recaptcha_private_key']
  44 + api_recaptcha_verify_uri = API.NOOSFERO_CONF['api_recaptcha_verify_uri']
  45 + captcha_result = verify_recaptcha_v2(remote_ip, params['g-recaptcha-response'], private_key, api_recaptcha_verify_uri)
  46 + user = User.new(attrs)
  47 + if captcha_result["success"] and user.save!
42 user.activate 48 user.activate
43 user.generate_private_token! 49 user.generate_private_token!
44 present user, :with => Entities::UserLogin 50 present user, :with => Entities::UserLogin
45 else 51 else
46 - something_wrong! 52 + message = user.errors.to_json
  53 + render_api_error!(message, 400)
47 end 54 end
48 end 55 end
49 -  
50 end 56 end
51 end 57 end
52 end 58 end