Commit 0318fee8ec6b070e505aa51075ea1b42e97313fb
Committed by
Rodrigo Souto
1 parent
4ddf407d
Exists in
master
and in
29 other branches
Support google recaptcha for the API
Showing
4 changed files
with
50 additions
and
19 deletions
Show diff stats
config/noosfero.yml.dist
| ... | ... | @@ -11,7 +11,14 @@ development: |
| 11 | 11 | max_upload_size: 5MB |
| 12 | 12 | hours_until_user_activation_check: 72 |
| 13 | 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 | 18 | test: |
| 16 | 19 | |
| 17 | 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 | 25 | \ No newline at end of file | ... | ... |
lib/noosfero/api/api.rb
| 1 | 1 | require 'grape' |
| 2 | 2 | #require 'rack/contrib' |
| 3 | + | |
| 3 | 4 | Dir["#{Rails.root}/lib/noosfero/api/*.rb"].each {|file| require file unless file =~ /api\.rb/} |
| 4 | 5 | module Noosfero |
| 5 | 6 | module API |
| 6 | 7 | class API < Grape::API |
| 7 | 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 | 19 | end |
| 16 | 20 | |
| 17 | 21 | before { setup_multitenancy } |
| ... | ... | @@ -22,9 +26,9 @@ module Noosfero |
| 22 | 26 | prefix "api" |
| 23 | 27 | format :json |
| 24 | 28 | content_type :txt, "text/plain" |
| 25 | - | |
| 29 | + | |
| 26 | 30 | helpers APIHelpers |
| 27 | - | |
| 31 | + | |
| 28 | 32 | mount V1::Articles |
| 29 | 33 | mount V1::Comments |
| 30 | 34 | mount V1::Users |
| ... | ... | @@ -33,7 +37,7 @@ module Noosfero |
| 33 | 37 | mount V1::Enterprises |
| 34 | 38 | mount V1::Categories |
| 35 | 39 | mount Session |
| 36 | - | |
| 40 | + | |
| 37 | 41 | # hook point which allow plugins to add Grape::API extensions to API::API |
| 38 | 42 | #finds for plugins which has api mount points classes defined (the class should extends Grape::API) |
| 39 | 43 | @plugins = Noosfero::Plugin.all.map { |p| p.constantize } | ... | ... |
lib/noosfero/api/helpers.rb
| ... | ... | @@ -102,7 +102,21 @@ module Noosfero |
| 102 | 102 | end |
| 103 | 103 | attrs |
| 104 | 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 | 121 | # error helpers # |
| 108 | 122 | ########################################## | ... | ... |
lib/noosfero/api/session.rb
| 1 | +require "uri" | |
| 2 | + | |
| 1 | 3 | module Noosfero |
| 2 | 4 | module API |
| 3 | - | |
| 5 | + | |
| 4 | 6 | class Session < Grape::API |
| 5 | - | |
| 7 | + | |
| 6 | 8 | # Login to get token |
| 7 | 9 | # |
| 8 | 10 | # Parameters: |
| ... | ... | @@ -13,13 +15,13 @@ module Noosfero |
| 13 | 15 | # POST http://localhost:3000/api/v1/login?login=adminuser&password=admin |
| 14 | 16 | post "/login" do |
| 15 | 17 | user ||= User.authenticate(params[:login], params[:password], environment) |
| 16 | - | |
| 18 | + | |
| 17 | 19 | return unauthorized! unless user |
| 18 | 20 | user.generate_private_token! |
| 19 | 21 | @current_user = user |
| 20 | 22 | present user, :with => Entities::UserLogin |
| 21 | 23 | end |
| 22 | - | |
| 24 | + | |
| 23 | 25 | # Create user. |
| 24 | 26 | # |
| 25 | 27 | # Parameters: |
| ... | ... | @@ -37,16 +39,20 @@ module Noosfero |
| 37 | 39 | unique_attributes! User, [:email, :login] |
| 38 | 40 | attrs = attributes_for_keys [:email, :login, :password] |
| 39 | 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 | 48 | user.activate |
| 43 | 49 | user.generate_private_token! |
| 44 | 50 | present user, :with => Entities::UserLogin |
| 45 | 51 | else |
| 46 | - something_wrong! | |
| 52 | + message = user.errors.to_json | |
| 53 | + render_api_error!(message, 400) | |
| 47 | 54 | end |
| 48 | 55 | end |
| 49 | - | |
| 50 | 56 | end |
| 51 | 57 | end |
| 52 | 58 | end | ... | ... |