2021-06-01 12:20:20 +00:00
|
|
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
|
|
|
|
2017-02-15 02:35:22 +00:00
|
|
|
class ChannelsTwitterController < ApplicationController
|
2020-03-19 09:39:51 +00:00
|
|
|
prepend_before_action -> { authentication_check && authorize! }, except: %i[webhook_incoming webhook_verify]
|
2018-12-03 14:10:36 +00:00
|
|
|
skip_before_action :verify_csrf_token, only: %i[webhook_incoming webhook_verify]
|
|
|
|
|
|
|
|
before_action :validate_webhook_signature!, only: :webhook_incoming
|
|
|
|
|
|
|
|
def webhook_incoming
|
2020-01-06 08:20:59 +00:00
|
|
|
@channel.process(params.permit!.to_h)
|
2018-12-03 14:10:36 +00:00
|
|
|
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
|
2021-11-15 15:58:19 +00:00
|
|
|
raise Exceptions::UnprocessableEntity, __("Missing 'for_user_id' in payload!") if params[:for_user_id].blank?
|
2018-12-03 14:10:36 +00:00
|
|
|
|
|
|
|
@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, "No such 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')
|
2021-11-15 15:58:19 +00:00
|
|
|
raise Exceptions::UnprocessableEntity, __('No such external_credential \'twitter\'!') if !external_credential
|
2018-12-03 14:10:36 +00:00
|
|
|
|
|
|
|
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
|
2021-05-31 13:05:54 +00:00
|
|
|
external_credential = Cache.read('external_credential_twitter')
|
2018-12-03 14:10:36 +00:00
|
|
|
if !external_credential && ExternalCredential.exists?(name: 'twitter')
|
|
|
|
external_credential = ExternalCredential.find_by(name: 'twitter').credentials
|
|
|
|
end
|
2021-11-15 15:58:19 +00:00
|
|
|
raise Exceptions::UnprocessableEntity, __('No external_credential in cache!') if external_credential.blank?
|
|
|
|
raise Exceptions::UnprocessableEntity, __('No external_credential[:consumer_secret] in cache!') if external_credential[:consumer_secret].blank?
|
|
|
|
raise Exceptions::UnprocessableEntity, __('No crc_token in verify payload from twitter!') if params['crc_token'].blank?
|
2018-12-03 14:10:36 +00:00
|
|
|
|
|
|
|
render json: {
|
|
|
|
response_token: hmac_signature_gen(external_credential[:consumer_secret], params['crc_token'])
|
|
|
|
}
|
|
|
|
end
|
2017-02-15 02:35:22 +00:00
|
|
|
|
|
|
|
def index
|
|
|
|
assets = {}
|
2018-12-03 14:10:36 +00:00
|
|
|
external_credential_ids = []
|
2017-10-01 12:25:52 +00:00
|
|
|
ExternalCredential.where(name: 'twitter').each do |external_credential|
|
2017-02-15 02:35:22 +00:00
|
|
|
assets = external_credential.assets(assets)
|
2018-12-03 14:10:36 +00:00
|
|
|
external_credential_ids.push external_credential.id
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2017-02-15 02:35:22 +00:00
|
|
|
channel_ids = []
|
2017-10-01 12:25:52 +00:00
|
|
|
Channel.where(area: 'Twitter::Account').order(:id).each do |channel|
|
2017-02-15 02:35:22 +00:00
|
|
|
assets = channel.assets(assets)
|
|
|
|
channel_ids.push channel.id
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2017-02-15 02:35:22 +00:00
|
|
|
render json: {
|
2018-12-19 17:31:51 +00:00
|
|
|
assets: assets,
|
|
|
|
channel_ids: channel_ids,
|
2018-12-03 14:10:36 +00:00
|
|
|
external_credential_ids: external_credential_ids,
|
2018-12-19 17:31:51 +00:00
|
|
|
callback_url: ExternalCredential.callback_url('twitter'),
|
2017-02-15 02:35:22 +00:00
|
|
|
}
|
|
|
|
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
|