diff --git a/app/controllers/concerns/facebook_concern.rb b/app/controllers/concerns/facebook_concern.rb new file mode 100644 index 000000000..edf77879d --- /dev/null +++ b/app/controllers/concerns/facebook_concern.rb @@ -0,0 +1,47 @@ +module FacebookConcern + extend ActiveSupport::Concern + + class InvalidDigestError < StandardError; end + + private + + def mark_deleting(id) + key = processing_key(id) + ::Redis::Alfred.set(key, true) + end + + def unset_deleting(id) + key = processing_key(id) + ::Redis::Alfred.del(key) + end + + def deleting?(id) + key = processing_key(id) + ::Redis::Alfred.get(key).present? + end + + def delete_key(id) + format(::Redis::Alfred::META_DELETE_PROCESSING, id: id) + end + + def parse_fb_signed_request(signed_request) + encoded_signature, payload = signed_request.split('.', 2) + + decoded_signature = Base64.urlsafe_decode64(encoded_signature) + decoded_payload = JSON.parse(Base64.urlsafe_decode64(payload)) + + expected_signature = OpenSSL::HMAC.digest('sha256', app_secret, payload) + + raise InvalidDigestError if decoded_signature != expected_signature + + decoded_payload + end + + def app_url_base + ENV.fetch('FRONTEND_URL', nil) + end + + def app_secret + GlobalConfigService.load('FB_APP_SECRET', '') + end +end diff --git a/app/controllers/facebook/confirm_controller.rb b/app/controllers/facebook/confirm_controller.rb index d5007c4b5..32b153157 100644 --- a/app/controllers/facebook/confirm_controller.rb +++ b/app/controllers/facebook/confirm_controller.rb @@ -1,20 +1,13 @@ class Facebook::ConfirmController < ApplicationController - class InvalidDigestError < StandardError; end + include FacebookConcern def show @id_to_process = params[:id] - if processing? + if deleting? render plain: 'Processing', status: :ok else render plain: 'Data Deleted Successfully', status: :ok end end - - private - - def processing? - key = format(::Redis::Alfred::META_DELETE_PROCESSING, id: @id_to_process) - ::Redis::Alfred.get(key).present? - end end diff --git a/app/controllers/facebook/delete_controller.rb b/app/controllers/facebook/delete_controller.rb index b4b2b792e..8c2668419 100644 --- a/app/controllers/facebook/delete_controller.rb +++ b/app/controllers/facebook/delete_controller.rb @@ -1,12 +1,12 @@ class Facebook::DeleteController < ApplicationController - class InvalidDigestError < StandardError; end + include FacebookConcern def create signed_request = params['signed_request'] payload = parse_fb_signed_request(signed_request) id_to_process = payload['user_id'] - mark_processing(id_to_process) + mark_deleting(id_to_process) Webhooks::FacebookDeleteJob.perform_later(id_to_process) status_url = "#{app_url_base}/facebook/confirm/#{id_to_process}" @@ -14,35 +14,4 @@ class Facebook::DeleteController < ApplicationController rescue InvalidDigestError render json: { error: 'Invalid signature' }, status: :unprocessable_entity end - - private - - def mark_processing(id_to_process) - # we use this key to check if the deletion is completed or not - # Once the key is gone, we know the deletion is completed - # And we can show as such - key = format(::Redis::Alfred::META_DELETE_PROCESSING, id: id_to_process) - ::Redis::Alfred.set(key, true) - end - - def app_url_base - ENV.fetch('FRONTEND_URL', nil) - end - - def parse_fb_signed_request(signed_request) - encoded_signature, payload = signed_request.split('.', 2) - - decoded_signature = Base64.urlsafe_decode64(encoded_signature) - decoded_payload = JSON.parse(Base64.urlsafe_decode64(payload)) - - expected_signature = OpenSSL::HMAC.digest('sha256', app_secret, payload) - - raise InvalidDigestError if decoded_signature != expected_signature - - decoded_payload - end - - def app_secret - GlobalConfigService.load('FB_APP_SECRET', '') - end end