123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- class ChannelsTwitterController < ApplicationController
- prepend_before_action :authenticate_and_authorize!, except: %i[webhook_incoming webhook_verify]
- skip_before_action :verify_csrf_token, only: %i[webhook_incoming webhook_verify]
- before_action :validate_webhook_signature!, only: :webhook_incoming
- def webhook_incoming
- @channel.process(params.permit!.to_h)
- render json: {}
- end
- def validate_webhook_signature!
- header_name = 'x-twitter-webhooks-signature'
- given_signature = request.headers[header_name]
- raise Exceptions::UnprocessableEntity, "Missing '#{header_name}' header" if given_signature.blank?
- calculated_signature = hmac_signature_by_app(request.raw_post)
- raise Exceptions::NotAuthorized if calculated_signature != given_signature
- raise Exceptions::UnprocessableEntity, __("The required parameter 'for_user_id' is missing.") if params[:for_user_id].blank?
- @channel = nil
- Channel.where(area: 'Twitter::Account', active: true).each do |channel|
- next if channel.options[:user].blank?
- next if channel.options[:user][:id].to_s != params[:for_user_id].to_s
- @channel = channel
- end
- raise Exceptions::UnprocessableEntity, "Could not find channel for user id '#{params[:for_user_id]}'!" if !@channel
- true
- end
- def hmac_signature_by_app(content)
- external_credential = ExternalCredential.find_by(name: 'twitter')
- raise Exceptions::UnprocessableEntity, __("The required 'ExternalCredential' 'twitter' could not be found.") if !external_credential
- hmac_signature_gen(external_credential.credentials[:consumer_secret], content)
- end
- def hmac_signature_gen(consumer_secret, content)
- hashed = OpenSSL::HMAC.digest('sha256', consumer_secret, content)
- hashed = Base64.strict_encode64(hashed)
- "sha256=#{hashed}"
- end
- def webhook_verify
- external_credential = Rails.cache.read('external_credential_twitter')
- if !external_credential && ExternalCredential.exists?(name: 'twitter')
- external_credential = ExternalCredential.find_by(name: 'twitter').credentials
- end
- raise Exceptions::UnprocessableEntity, __('The required value external_credential could not be found in the cache.') if external_credential.blank?
- raise Exceptions::UnprocessableEntity, __("The required value 'external_credential[:consumer_secret]' could not be found in the cache.") if external_credential[:consumer_secret].blank?
- raise Exceptions::UnprocessableEntity, __("The required parameter 'crc_token' is missing from the Twitter verify payload!") if params['crc_token'].blank?
- render json: {
- response_token: hmac_signature_gen(external_credential[:consumer_secret], params['crc_token'])
- }
- end
- def index
- assets = {}
- external_credential_ids = []
- ExternalCredential.where(name: 'twitter').each do |external_credential|
- assets = external_credential.assets(assets)
- external_credential_ids.push external_credential.id
- end
- channel_ids = []
- Channel.where(area: 'Twitter::Account').reorder(:id).each do |channel|
- assets = channel.assets(assets)
- channel_ids.push channel.id
- end
- render json: {
- assets: assets,
- channel_ids: channel_ids,
- external_credential_ids: external_credential_ids,
- callback_url: ExternalCredential.callback_url('twitter'),
- }
- end
- def update
- model_update_render(Channel, params)
- end
- def enable
- channel = Channel.find_by(id: params[:id], area: 'Twitter::Account')
- channel.active = true
- channel.save!
- render json: {}
- end
- def disable
- channel = Channel.find_by(id: params[:id], area: 'Twitter::Account')
- channel.active = false
- channel.save!
- render json: {}
- end
- def destroy
- channel = Channel.find_by(id: params[:id], area: 'Twitter::Account')
- channel.destroy
- render json: {}
- end
- end
|