diff --git a/spec/requests/external_credentials_spec.rb b/spec/requests/external_credentials_spec.rb
index af32439d4..7ecf2e06b 100644
--- a/spec/requests/external_credentials_spec.rb
+++ b/spec/requests/external_credentials_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe 'External Credentials', type: :request do
end
context 'authenticated as admin' do
- before { authenticated_as(admin_user) }
+ before { authenticated_as(admin_user, via: :browser) }
describe '#index' do
it 'responds with an array of ExternalCredential records' do
@@ -177,116 +177,348 @@ RSpec.describe 'External Credentials', type: :request do
end
end
- context 'for Twitter' do
- let(:invalid_credentials) do
- { consumer_key: 123, consumer_secret: 123, oauth_token: 123, oauth_token_secret: 123 }
+ context 'for Twitter', :use_vcr do
+ shared_context 'for callback URL configuration' do
+ # NOTE: When recording a new VCR cassette for these tests,
+ # the URL below must match the callback URL
+ # registered with developer.twitter.com.
+ before do
+ Setting.set('http_type', 'https')
+ Setting.set('fqdn', 'zammad.example.com')
+ end
end
- describe '#app_verify' do
- describe 'failure cases' do
- context 'when permission for Twitter channel is deactivated' do
- before { Permission.find_by(name: 'admin.channel_twitter').update(active: false) }
+ shared_examples 'for failure cases' do
+ it 'responds with the appropriate status and error message' do
+ send(*endpoint, as: :json, params: try(:params) || {})
- it 'returns 401 unauthorized with internal (Zammad) error' do
- post '/api/v1/external_credentials/twitter/app_verify', as: :json
- expect(response).to have_http_status(:unauthorized)
- expect(json_response).to include('error' => 'Not authorized (user)!')
+ expect(response).to have_http_status(status)
+ expect(json_response).to include('error' => error_message)
+ end
+ end
+
+ let(:valid_credentials) { attributes_for(:twitter_credential)[:credentials] }
+ let(:invalid_credentials) { attributes_for(:twitter_credential, :invalid)[:credentials] }
+
+ describe 'POST /api/v1/external_credentials/twitter/app_verify' do
+ let(:endpoint) { [:post, '/api/v1/external_credentials/twitter/app_verify'] }
+
+ context 'when permission for Twitter channel is deactivated' do
+ before { Permission.find_by(name: 'admin.channel_twitter').update(active: false) }
+
+ include_examples 'for failure cases' do
+ let(:status) { :unauthorized }
+ let(:error_message) { 'Not authorized (user)!' }
+ end
+ end
+
+ context 'with no credentials' do
+ include_examples 'for failure cases' do
+ let(:status) { :ok }
+ let(:error_message) { 'No consumer_key param!' }
+ end
+ end
+
+ context 'with invalid credential params' do
+ let(:params) { invalid_credentials }
+
+ include_examples 'for failure cases' do
+ let(:status) { :ok }
+ let(:error_message) { '401 Authorization Required' }
+ end
+ end
+
+ context 'with valid credential params but misconfigured callback URL' do
+ let(:params) { valid_credentials }
+
+ include_examples 'for failure cases' do
+ let(:status) { :ok }
+ let(:error_message) { <<~ERR.chomp }
+ 403 Forbidden, maybe credentials wrong or callback_url for application wrong configured.
+ ERR
+ end
+ end
+
+ context 'with valid credential params and callback URL but no dev env registered' do
+ let(:params) { valid_credentials }
+
+ include_context 'for callback URL configuration'
+ include_examples 'for failure cases' do
+ let(:status) { :ok }
+ let(:error_message) { <<~ERR.chomp }
+ Unable to get list of webooks. Maybe you do not have an Twitter developer approval right now or you use the wrong 'Dev environment label': Forbidden.
+ ERR
+ end
+ end
+
+ context 'with valid credential params and callback URL but wrong dev env label' do
+ let(:params) { valid_credentials.merge(env: 'foo') }
+
+ include_context 'for callback URL configuration'
+ include_examples 'for failure cases' do
+ let(:status) { :ok }
+ let(:error_message) { <<~ERR.chomp }
+ Unable to get list of webooks. Maybe you do not have an Twitter developer approval right now or you use the wrong 'Dev environment label': Unable to get list of webooks. You use the wrong 'Dev environment label', only {:environments=>[{:environment_name=>\"zammad\", :webhooks=>[]}]} available.
+ ERR
+ end
+ end
+
+ context 'with valid credential params, callback URL, and dev env label' do
+ let(:env_name) { valid_credentials[:env] }
+
+ include_context 'for callback URL configuration'
+
+ shared_examples 'for successful webhook connection' do
+ let(:webhook_id) { '1241980494134145024' }
+
+ it 'responds 200 OK with the new webhook ID' do
+ send(*endpoint, as: :json, params: valid_credentials)
+
+ expect(response).to have_http_status(:ok)
+ expect(json_response).to match('attributes' => hash_including('webhook_id' => webhook_id))
end
end
- context 'with no credentials' do
- it 'returns 200 with internal (Zammad) error' do
- post '/api/v1/external_credentials/twitter/app_verify', as: :json
+ context 'with no existing webhooks' do
+ let(:webhook_url) { "#{Setting.get('http_type')}://#{Setting.get('fqdn')}#{Rails.configuration.api_path}/channels_twitter_webhook" }
- expect(response).to have_http_status(:ok)
- expect(json_response).to include('error' => 'No consumer_key param!')
+ include_examples 'for successful webhook connection'
+
+ it 'registers a new webhook' do
+ send(*endpoint, as: :json, params: valid_credentials)
+
+ expect(WebMock)
+ .to have_requested(:post, "https://api.twitter.com/1.1/account_activity/all/#{env_name}/webhooks.json")
+ .with(body: "url=#{CGI.escape(webhook_url)}" )
end
end
- context 'with invalid credentials, via request params' do
- it 'returns 200 with remote (Twitter auth) error', :use_vcr do
- post '/api/v1/external_credentials/twitter/app_verify', params: invalid_credentials, as: :json
+ context 'with an existing webhook registered to another app' do
+ include_examples 'for successful webhook connection'
- expect(response).to have_http_status(:ok)
- expect(json_response).to include('error' => '401 Authorization Required')
+ it 'deletes all existing webhooks first' do
+ send(*endpoint, as: :json, params: valid_credentials)
+
+ expect(WebMock)
+ .to have_requested(:delete, "https://api.twitter.com/1.1/account_activity/all/#{env_name}/webhooks/1241981813595049984.json")
end
end
- context 'with invalid credentials, via existing ExternalCredential record' do
- before { create(:twitter_credential, credentials: invalid_credentials) }
+ context 'with an existing, invalid webhook registered to Zammad' do
+ include_examples 'for successful webhook connection'
- it 'returns 200 with remote (Twitter auth) error', :use_vcr do
- post '/api/v1/external_credentials/twitter/app_verify', as: :json
+ it 'revalidates by manually triggering a challenge-response check' do
+ send(*endpoint, as: :json, params: valid_credentials)
- expect(response).to have_http_status(:ok)
- expect(json_response).to include('error' => '401 Authorization Required')
+ expect(WebMock)
+ .to have_requested(:put, "https://api.twitter.com/1.1/account_activity/all/#{env_name}/webhooks/1241980494134145024.json")
+ end
+ end
+
+ context 'with an existing, valid webhook registered to Zammad' do
+ include_examples 'for successful webhook connection'
+
+ it 'uses the existing webhook' do
+ send(*endpoint, as: :json, params: valid_credentials)
+
+ expect(WebMock)
+ .not_to have_requested(:post, "https://api.twitter.com/1.1/account_activity/all/#{env_name}/webhooks.json")
end
end
end
end
- describe '#link_account' do
- describe 'failure cases' do
- context 'with no credentials' do
- it 'returns 422 unprocessable entity with internal (Zammad) error' do
- get '/api/v1/external_credentials/twitter/link_account', as: :json
+ describe 'GET /api/v1/external_credentials/twitter/link_account' do
+ let(:endpoint) { [:get, '/api/v1/external_credentials/twitter/link_account'] }
- expect(response).to have_http_status(:unprocessable_entity)
- expect(json_response).to include('error' => 'No twitter app configured!')
- end
+ context 'with no Twitter app' do
+ include_examples 'for failure cases' do
+ let(:status) { :unprocessable_entity }
+ let(:error_message) { 'No twitter app configured!' }
+ end
+ end
+
+ context 'with invalid Twitter app (configured with invalid credentials)' do
+ let!(:twitter_credential) { create(:twitter_credential, :invalid) }
+
+ include_examples 'for failure cases' do
+ let(:status) { :internal_server_error }
+ let(:error_message) { '401 Authorization Required' }
+ end
+ end
+
+ context 'with a valid Twitter app but misconfigured callback URL' do
+ let!(:twitter_credential) { create(:twitter_credential) }
+
+ include_examples 'for failure cases' do
+ let(:status) { :internal_server_error }
+ let(:error_message) { <<~ERR.chomp }
+ 403 Forbidden, maybe credentials wrong or callback_url for application wrong configured.
+ ERR
+ end
+ end
+
+ context 'with a valid Twitter app and callback URL' do
+ let!(:twitter_credential) { create(:twitter_credential) }
+
+ include_context 'for callback URL configuration'
+
+ it 'requests OAuth request token from Twitter API' do
+ send(*endpoint, as: :json)
+
+ expect(WebMock)
+ .to have_requested(:post, 'https://api.twitter.com/oauth/request_token')
+ .with(headers: { 'Authorization' => /oauth_consumer_key="#{twitter_credential.credentials[:consumer_key]}"/ } )
end
- context 'with invalid credentials, via request params' do
- it 'returns 422 unprocessable entity with internal (Zammad) error' do
- get '/api/v1/external_credentials/twitter/link_account', params: invalid_credentials, as: :json
+ it 'redirects to Twitter authorization URL' do
+ send(*endpoint, as: :json)
- expect(response).to have_http_status(:unprocessable_entity)
- expect(json_response).to include('error' => 'No twitter app configured!')
- end
+ expect(response).to redirect_to(%r{^https://api.twitter.com/oauth/authorize\?oauth_token=\w+$})
end
- context 'with invalid credentials, via ExternalCredential record' do
- before { create(:twitter_credential, credentials: invalid_credentials) }
+ it 'saves request token to session hash' do
+ send(*endpoint, as: :json)
- it 'returns 500 with remote (Twitter auth) error', :use_vcr do
- get '/api/v1/external_credentials/twitter/link_account', as: :json
-
- expect(response).to have_http_status(:internal_server_error)
- expect(json_response).to include('error' => '401 Authorization Required')
- end
+ expect(session[:request_token]).to be_a(OAuth::RequestToken)
end
end
end
- describe '#callback' do
- describe 'failure cases' do
- context 'with no credentials' do
- it 'returns 422 unprocessable entity with internal (Zammad) error' do
- get '/api/v1/external_credentials/twitter/callback', as: :json
+ describe 'GET /api/v1/external_credentials/twitter/callback' do
+ let(:endpoint) { [:get, '/api/v1/external_credentials/twitter/callback'] }
- expect(response).to have_http_status(:unprocessable_entity)
- expect(json_response).to include('error' => 'No twitter app configured!')
+ context 'with no Twitter app' do
+ include_examples 'for failure cases' do
+ let(:status) { :unprocessable_entity }
+ let(:error_message) { 'No twitter app configured!' }
+ end
+ end
+
+ context 'with valid Twitter app but no request token' do
+ let!(:twitter_credential) { create(:twitter_credential) }
+
+ include_examples 'for failure cases' do
+ let(:status) { :unprocessable_entity }
+ let(:error_message) { 'No request_token for session found!' }
+ end
+ end
+
+ context 'with valid Twitter app and request token but non-matching OAuth token (via params)' do
+ include_context 'for callback URL configuration'
+
+ let!(:twitter_credential) { create(:twitter_credential) }
+
+ before { get '/api/v1/external_credentials/twitter/link_account', as: :json }
+
+ include_examples 'for failure cases' do
+ let(:status) { :unprocessable_entity }
+ let(:error_message) { 'Invalid oauth_token given!' }
+ end
+ end
+
+ # NOTE: Want to delete/regenerate the VCR cassettes for these examples?
+ # It's gonna be messy--each one is actually two cassettes merged into one.
+ #
+ # Why? The OAuth flow can't be fully reproduced in a request spec:
+ #
+ # 1. User clicks "Add Twitter account" in Zammad.
+ # Zammad asks Twitter for request token, saves it to session,
+ # and redirects user to Twitter.
+ # 2. User clicks "Authorize app" on Twitter.
+ # Twitter generates temporary OAuth credentials
+ # and redirects user back to this endpoint (with creds in URL query string).
+ # 3. Zammad asks Twitter for an access token
+ # (using request token from Step 1 + OAuth creds from Step 2).
+ #
+ # In these tests (Step 2), the user hits this endpoint
+ # with parameters that ONLY the Twitter OAuth server can generate.
+ # In the VCR cassette for Step 3,
+ # Zammad sends these parameters back to Twitter for validation.
+ # Without valid credentials in Step 2, Step 3 will always fail.
+ #
+ # Instead, we have to record the VCR cassette in a live development instance
+ # and stitch the cassette together with a cassette for Step 1.
+ #
+ # tl;dr A feature spec might have made more sense here.
+ context 'with valid Twitter app, request token, and matching OAuth token (via params)' do
+ include_context 'for callback URL configuration'
+
+ let!(:twitter_credential) { create(:twitter_credential) }
+
+ # For illustrative purposes only.
+ # These parameters cannot be used to record a new VCR cassette (see note above).
+ let(:params) { { oauth_token: oauth_token, oauth_verifier: oauth_verifier } }
+ let(:oauth_token) { 'DyhnyQAAAAAA9CNXAAABcSxAexs' }
+ let(:oauth_verifier) { '15DOeRkjP4JkOSVqULkTKA1SCuIPP105' }
+
+ before { get '/api/v1/external_credentials/twitter/link_account', as: :json }
+
+ context 'if Twitter account has already been added' do
+ let!(:channel) { create(:twitter_channel, custom_options: channel_options) }
+ let(:channel_options) do
+ {
+ user: {
+ id: '1205290247124217856',
+ screen_name: 'pennbrooke1',
+ }
+ }
+ end
+
+ it 'uses the existing channel' do
+ expect { send(*endpoint, as: :json, params: params) }
+ .not_to change(Channel, :count)
+ end
+
+ it 'updates channel properties' do
+ expect { send(*endpoint, as: :json, params: params) }
+ .to change { channel.reload.options[:user][:name] }
+ .and change { channel.reload.options[:auth][:external_credential_id] }
+ .and change { channel.reload.options[:auth][:oauth_token] }
+ .and change { channel.reload.options[:auth][:oauth_token_secret] }
+ end
+
+ it 'subscribes to webhooks' do
+ send(*endpoint, as: :json, params: params)
+
+ expect(WebMock)
+ .to have_requested(:post, "https://api.twitter.com/1.1/account_activity/all/#{twitter_credential.credentials[:env]}/subscriptions.json")
+
+ expect(channel.reload.options['subscribed_to_webhook_id'])
+ .to eq(twitter_credential.credentials[:webhook_id])
end
end
- context 'with invalid credentials, via request params' do
- it 'returns 422 unprocessable entity with internal (Zammad) error' do
- get '/api/v1/external_credentials/twitter/callback', params: invalid_credentials, as: :json
+ it 'creates a new channel' do
+ expect { send(*endpoint, as: :json, params: params) }
+ .to change(Channel, :count).by(1)
- expect(response).to have_http_status(:unprocessable_entity)
- expect(json_response).to include('error' => 'No twitter app configured!')
- end
+ expect(Channel.last.options)
+ .to include('adapter' => 'twitter')
+ .and include('user' => hash_including('id', 'screen_name', 'name'))
+ .and include('auth' => hash_including('external_credential_id', 'oauth_token', 'oauth_token_secret'))
end
- context 'with invalid credentials, via ExternalCredential record' do
- before { create(:twitter_credential, credentials: invalid_credentials) }
+ it 'redirects to the newly created channel' do
+ send(*endpoint, as: :json, params: params)
- it 'returns 422 unprocessable entity with internal (Zammad) error' do
- get '/api/v1/external_credentials/twitter/callback', as: :json
+ expect(response).to redirect_to(%r{/#channels/twitter/#{Channel.last.id}$})
+ end
- expect(response).to have_http_status(:unprocessable_entity)
- expect(json_response).to include('error' => 'No request_token for session found!')
- end
+ it 'clears the :request_token session variable' do
+ send(*endpoint, as: :json, params: params)
+
+ expect(session[:request_token]).to be(nil)
+ end
+
+ it 'subscribes to webhooks' do
+ send(*endpoint, as: :json, params: params)
+
+ expect(WebMock)
+ .to have_requested(:post, "https://api.twitter.com/1.1/account_activity/all/#{twitter_credential.credentials[:env]}/subscriptions.json")
+
+ expect(Channel.last.options['subscribed_to_webhook_id'])
+ .to eq(twitter_credential.credentials[:webhook_id])
end
end
end
diff --git a/test/data/vcr_cassettes/requests/external_credentials/if_twitter_account_has_already_been_added_subscribes_to_webhooks.yml b/test/data/vcr_cassettes/requests/external_credentials/if_twitter_account_has_already_been_added_subscribes_to_webhooks.yml
new file mode 100644
index 000000000..c2048b994
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/if_twitter_account_has_already_been_added_subscribes_to_webhooks.yml
@@ -0,0 +1,312 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="cRQcN4SYlNvQmxLERXdkHw0b8WkgopWyZfshYZ0bQ5c",
+ oauth_signature="1QKjkAywyA9C28RyxllXH4I%2B8dk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585562755", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158556275926104897; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_2VPPoqwsc7qTrmUTl7TOqQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - d5c96afbba7d4a8d9767a2520f1014b9
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 00d90bb200263ca8
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=DyhnyQAAAAAA9CNXAAABcSxAexs&oauth_token_secret=ubeISX6MlS1PTPAp8udaQ2yRqHlNWdCf&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 10:05:59 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/access_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="2Wj2SwZSjbQpBx5pgSqAcwXuREAZCW9cYk7IgK79M",
+ oauth_signature="zv4lFCYM8OgJleXMzjSrh6bkzb4%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585442", oauth_token="DyhnyQAAAAAA9CNXAAABcSxAexs", oauth_verifier="15DOeRkjP4JkOSVqULkTKA1SCuIPP105",
+ oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '174'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544330530048; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_r1gFYSkkPVRlfj2/S3iBhA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 4c532e72e52e91a920ec7ede1d738a7d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '437'
+ X-Transaction:
+ - 002d00030028d5ad
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=REDACTED&oauth_token_secret=6Izq6rCcuJs07inPgc7oMVbq0sjLzuxFLcRq2gp5ulJQW&user_id=1205290247124217856&screen_name=pennbrooke1
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:03 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account/verify_credentials.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="d8377bbeda339f59394d528d368c5bd6",
+ oauth_signature="665K11LI%2FY0%2BZrf0AD%2BPJnrehVY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585443", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '1928'
+ Content-Type:
+ - application/json;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544430987067; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - lang=en; Path=/
+ - personalization_id="v1_KepQ+bqW3x/y43slZzYqcA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Access-Level:
+ - read-write-directmessages
+ X-Connection-Hash:
+ - fe7eed972598e46753f044b0f5f1c34e
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '75'
+ X-Rate-Limit-Remaining:
+ - '72'
+ X-Rate-Limit-Reset:
+ - '1585585445'
+ X-Response-Time:
+ - '155'
+ X-Transaction:
+ - 00d3169e00a6aa44
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ - BouncerExempt
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":1205290247124217856,"id_str":"1205290247124217856","name":"pennbrooke","screen_name":"pennbrooke1","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":1,"listed_count":0,"created_at":"Fri
+ Dec 13 00:56:10 +0000 2019","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":20,"lang":null,"status":{"created_at":"Thu
+ Mar 12 06:57:32 +0000 2020","id":1237996127103811584,"id_str":"1237996127103811584","text":"zammadzammadzammad","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[],"urls":[]},"source":"\u003ca
+ href=\"https:\/\/zammad.com\/\" rel=\"nofollow\"\u003ezammad\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"lv"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"F5F8FA","profile_background_image_url":null,"profile_background_image_url_https":null,"profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none","suspended":false,"needs_phone_verification":false}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:04 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/subscriptions.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="97f965f030c78cf792bd551bd8252d16",
+ oauth_signature="bTbM1ut0%2Bly3dtA6MqArPRq3wYk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585444", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 409
+ message: Conflict
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '66'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544515442211; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_I7zU3t0hJJakpotS4JM6yQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - b195905c1f696c9a9fc408e990adc77d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '130'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":355,"message":"Subscription already exists."}]}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:05 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/if_twitter_account_has_already_been_added_updates_channel_properties.yml b/test/data/vcr_cassettes/requests/external_credentials/if_twitter_account_has_already_been_added_updates_channel_properties.yml
new file mode 100644
index 000000000..30c8a959a
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/if_twitter_account_has_already_been_added_updates_channel_properties.yml
@@ -0,0 +1,312 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="cRQcN4SYlNvQmxLERXdkHw0b8WkgopWyZfshYZ0bQ5c",
+ oauth_signature="1QKjkAywyA9C28RyxllXH4I%2B8dk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585562755", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158556275926104897; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_2VPPoqwsc7qTrmUTl7TOqQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - d5c96afbba7d4a8d9767a2520f1014b9
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 00d90bb200263ca8
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=DyhnyQAAAAAA9CNXAAABcSxAexs&oauth_token_secret=ubeISX6MlS1PTPAp8udaQ2yRqHlNWdCf&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 10:05:59 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/access_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="2Wj2SwZSjbQpBx5pgSqAcwXuREAZCW9cYk7IgK79M",
+ oauth_signature="zv4lFCYM8OgJleXMzjSrh6bkzb4%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585442", oauth_token="DyhnyQAAAAAA9CNXAAABcSxAexs", oauth_verifier="15DOeRkjP4JkOSVqULkTKA1SCuIPP105",
+ oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '174'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544330530048; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_r1gFYSkkPVRlfj2/S3iBhA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 4c532e72e52e91a920ec7ede1d738a7d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '437'
+ X-Transaction:
+ - 002d00030028d5ad
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=1205290247124217856-REDACTED&oauth_token_secret=6Izq6rCcuJs07inPgc7oMVbq0sjLzuxFLcRq2gp5ulJQW&user_id=1205290247124217856&screen_name=pennbrooke1
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:03 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account/verify_credentials.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="d8377bbeda339f59394d528d368c5bd6",
+ oauth_signature="665K11LI%2FY0%2BZrf0AD%2BPJnrehVY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585443", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '1928'
+ Content-Type:
+ - application/json;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544430987067; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - lang=en; Path=/
+ - personalization_id="v1_KepQ+bqW3x/y43slZzYqcA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Access-Level:
+ - read-write-directmessages
+ X-Connection-Hash:
+ - fe7eed972598e46753f044b0f5f1c34e
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '75'
+ X-Rate-Limit-Remaining:
+ - '72'
+ X-Rate-Limit-Reset:
+ - '1585585445'
+ X-Response-Time:
+ - '155'
+ X-Transaction:
+ - 00d3169e00a6aa44
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ - BouncerExempt
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":1205290247124217856,"id_str":"1205290247124217856","name":"pennbrooke","screen_name":"pennbrooke1","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":1,"listed_count":0,"created_at":"Fri
+ Dec 13 00:56:10 +0000 2019","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":20,"lang":null,"status":{"created_at":"Thu
+ Mar 12 06:57:32 +0000 2020","id":1237996127103811584,"id_str":"1237996127103811584","text":"zammadzammadzammad","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[],"urls":[]},"source":"\u003ca
+ href=\"https:\/\/zammad.com\/\" rel=\"nofollow\"\u003ezammad\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"lv"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"F5F8FA","profile_background_image_url":null,"profile_background_image_url_https":null,"profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none","suspended":false,"needs_phone_verification":false}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:04 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/subscriptions.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="97f965f030c78cf792bd551bd8252d16",
+ oauth_signature="bTbM1ut0%2Bly3dtA6MqArPRq3wYk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585444", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 409
+ message: Conflict
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '66'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544515442211; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_I7zU3t0hJJakpotS4JM6yQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - b195905c1f696c9a9fc408e990adc77d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '130'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":355,"message":"Subscription already exists."}]}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:05 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/if_twitter_account_has_already_been_added_uses_the_existing_channel.yml b/test/data/vcr_cassettes/requests/external_credentials/if_twitter_account_has_already_been_added_uses_the_existing_channel.yml
new file mode 100644
index 000000000..c2048b994
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/if_twitter_account_has_already_been_added_uses_the_existing_channel.yml
@@ -0,0 +1,312 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="cRQcN4SYlNvQmxLERXdkHw0b8WkgopWyZfshYZ0bQ5c",
+ oauth_signature="1QKjkAywyA9C28RyxllXH4I%2B8dk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585562755", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158556275926104897; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_2VPPoqwsc7qTrmUTl7TOqQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - d5c96afbba7d4a8d9767a2520f1014b9
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 00d90bb200263ca8
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=DyhnyQAAAAAA9CNXAAABcSxAexs&oauth_token_secret=ubeISX6MlS1PTPAp8udaQ2yRqHlNWdCf&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 10:05:59 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/access_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="2Wj2SwZSjbQpBx5pgSqAcwXuREAZCW9cYk7IgK79M",
+ oauth_signature="zv4lFCYM8OgJleXMzjSrh6bkzb4%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585442", oauth_token="DyhnyQAAAAAA9CNXAAABcSxAexs", oauth_verifier="15DOeRkjP4JkOSVqULkTKA1SCuIPP105",
+ oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '174'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544330530048; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_r1gFYSkkPVRlfj2/S3iBhA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 4c532e72e52e91a920ec7ede1d738a7d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '437'
+ X-Transaction:
+ - 002d00030028d5ad
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=REDACTED&oauth_token_secret=6Izq6rCcuJs07inPgc7oMVbq0sjLzuxFLcRq2gp5ulJQW&user_id=1205290247124217856&screen_name=pennbrooke1
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:03 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account/verify_credentials.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="d8377bbeda339f59394d528d368c5bd6",
+ oauth_signature="665K11LI%2FY0%2BZrf0AD%2BPJnrehVY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585443", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '1928'
+ Content-Type:
+ - application/json;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544430987067; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - lang=en; Path=/
+ - personalization_id="v1_KepQ+bqW3x/y43slZzYqcA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Access-Level:
+ - read-write-directmessages
+ X-Connection-Hash:
+ - fe7eed972598e46753f044b0f5f1c34e
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '75'
+ X-Rate-Limit-Remaining:
+ - '72'
+ X-Rate-Limit-Reset:
+ - '1585585445'
+ X-Response-Time:
+ - '155'
+ X-Transaction:
+ - 00d3169e00a6aa44
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ - BouncerExempt
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":1205290247124217856,"id_str":"1205290247124217856","name":"pennbrooke","screen_name":"pennbrooke1","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":1,"listed_count":0,"created_at":"Fri
+ Dec 13 00:56:10 +0000 2019","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":20,"lang":null,"status":{"created_at":"Thu
+ Mar 12 06:57:32 +0000 2020","id":1237996127103811584,"id_str":"1237996127103811584","text":"zammadzammadzammad","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[],"urls":[]},"source":"\u003ca
+ href=\"https:\/\/zammad.com\/\" rel=\"nofollow\"\u003ezammad\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"lv"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"F5F8FA","profile_background_image_url":null,"profile_background_image_url_https":null,"profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none","suspended":false,"needs_phone_verification":false}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:04 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/subscriptions.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="97f965f030c78cf792bd551bd8252d16",
+ oauth_signature="bTbM1ut0%2Bly3dtA6MqArPRq3wYk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585444", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 409
+ message: Conflict
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '66'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544515442211; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_I7zU3t0hJJakpotS4JM6yQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - b195905c1f696c9a9fc408e990adc77d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '130'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":355,"message":"Subscription already exists."}]}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:05 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_and_callback_url_redirects_to_twitter_authorization_url.yml b/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_and_callback_url_redirects_to_twitter_authorization_url.yml
new file mode 100644
index 000000000..5b4400bfa
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_and_callback_url_redirects_to_twitter_authorization_url.yml
@@ -0,0 +1,82 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="RSp3OcV1ODEj0R4YSEi4xX5Bi3TeoGjbw9hoZs1k",
+ oauth_signature="JCzY7lKtru6BqOLGSA7LL46af3U%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584367034", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 16 Mar 2020 13:57:14 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 16 Mar 2020 13:57:14 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158436703465605333; Max-Age=63072000; Expires=Wed, 16 Mar 2022
+ 13:57:14 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_5AZAnySQIfodLKkImyimdg=="; Max-Age=63072000; Expires=Wed,
+ 16 Mar 2022 13:57:14 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - bed6dd1f6adade5c2ef747df5ce32bfa
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 00c8992000427975
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=1rcK1QAAAAABCFc9AAABcOOiYSs&oauth_token_secret=npBw6dAJxQCVpFzUpcmlz0jkScmiysTK&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 16 Mar 2020 13:57:14 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_and_callback_url_requests_oauth_request_token_from_twitter_api.yml b/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_and_callback_url_requests_oauth_request_token_from_twitter_api.yml
new file mode 100644
index 000000000..51ca989e4
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_and_callback_url_requests_oauth_request_token_from_twitter_api.yml
@@ -0,0 +1,82 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="JoMl0wFgjCmgtLpMNWvnxGSBNEJdV8No8LNEczS2d0U",
+ oauth_signature="q%2BvTAhVMi62idkd4vHFk%2Fpaq43o%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584366932", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '128'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 16 Mar 2020 13:55:32 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 16 Mar 2020 13:55:32 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158436693266223710; Max-Age=63072000; Expires=Wed, 16 Mar 2022
+ 13:55:32 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_LovT1kuyT4gkNHPUL+9O6g=="; Max-Age=63072000; Expires=Wed,
+ 16 Mar 2022 13:55:32 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - bfabbced05a4e94816a757d869cfd575
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '180'
+ X-Transaction:
+ - '0083912f0005d95b'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=6BpW6AAAAAABCFc9AAABcOOg0sA&oauth_token_secret=LOd9KByBr5ZAKjSAxGYhsiDmgbsnsRxO&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 16 Mar 2020 13:55:32 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_and_callback_url_saves_request_token_to_session_hash.yml b/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_and_callback_url_saves_request_token_to_session_hash.yml
new file mode 100644
index 000000000..5b4400bfa
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_and_callback_url_saves_request_token_to_session_hash.yml
@@ -0,0 +1,82 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="RSp3OcV1ODEj0R4YSEi4xX5Bi3TeoGjbw9hoZs1k",
+ oauth_signature="JCzY7lKtru6BqOLGSA7LL46af3U%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584367034", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 16 Mar 2020 13:57:14 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 16 Mar 2020 13:57:14 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158436703465605333; Max-Age=63072000; Expires=Wed, 16 Mar 2022
+ 13:57:14 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_5AZAnySQIfodLKkImyimdg=="; Max-Age=63072000; Expires=Wed,
+ 16 Mar 2022 13:57:14 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - bed6dd1f6adade5c2ef747df5ce32bfa
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 00c8992000427975
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=1rcK1QAAAAABCFc9AAABcOOiYSs&oauth_token_secret=npBw6dAJxQCVpFzUpcmlz0jkScmiysTK&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 16 Mar 2020 13:57:14 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_but_misconfigured_callback_url_responds_with_the_appropriate_status_and_error_message.yml b/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_but_misconfigured_callback_url_responds_with_the_appropriate_status_and_error_message.yml
new file mode 100644
index 000000000..a6072546f
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_a_valid_twitter_app_but_misconfigured_callback_url_responds_with_the_appropriate_status_and_error_message.yml
@@ -0,0 +1,78 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="http%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="Rsg8ixONk1XJVdmJAKnkSTVk8YCiynvhdrqXfIhMU",
+ oauth_signature="KuOrQrs1Ah5xW9hHo28%2FQ%2Fi04tg%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584364934", oauth_version="1.0"
+ response:
+ status:
+ code: 403
+ message: Forbidden
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '173'
+ Content-Type:
+ - application/xml;charset=utf-8
+ Date:
+ - Mon, 16 Mar 2020 13:22:15 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 16 Mar 2020 13:22:15 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158436493504625224; Max-Age=63072000; Expires=Wed, 16 Mar 2022
+ 13:22:15 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_Jn76b6m/dKeCo+E7CcsmbQ=="; Max-Age=63072000; Expires=Wed,
+ 16 Mar 2022 13:22:15 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 403 Forbidden
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 0d85fc163803f7e0d987629ca430e656
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '109'
+ X-Transaction:
+ - 001fa76700e52a67
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: Callback
+ URL not approved for this client application. Approved callback URLs can be
+ adjusted in your application settings
+ http_version:
+ recorded_at: Mon, 16 Mar 2020 13:22:15 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_invalid_webhook_registered_to_zammad_responds_200_ok_with_the_new_webhook_id.yml b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_invalid_webhook_registered_to_zammad_responds_200_ok_with_the_new_webhook_id.yml
new file mode 100644
index 000000000..33f586089
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_invalid_webhook_registered_to_zammad_responds_200_ok_with_the_new_webhook_id.yml
@@ -0,0 +1,221 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="csPRCe8Nu9cv8FNuxnLrInhnw96JjKTcZwK0HW8Njk",
+ oauth_signature="snIl5z49RgjhAiQs%2FQxk3kA%2FXtk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946407", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:53:28 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:53:28 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494640855835907; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:53:28 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_0zvtRwIZbniQqVSLo6XdbQ=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:53:28 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - f86b366038f347fcd3bba565fd31387f
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '174'
+ X-Transaction:
+ - '008597c000517be9'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=dMaNHgAAAAAA9CNXAAABcQYq7Hg&oauth_token_secret=d9QXHdi5FXmJjA1NZwKJBvvYh3tyv5IE&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:53:28 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="942e58699c99fd8bd9ba1cd69942f14f",
+ oauth_signature="O3JqHZhT8NsLR7yAA1QHIyxFVBw%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946408", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '159'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:53:29 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:53:29 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494640936571915; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:53:29 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_/ujsZ3ysdevr5v1b89RLmA=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:53:29 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 3a297b509badf9dde9b3bd63225f2460
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '11'
+ X-Rate-Limit-Reset:
+ - '1584946869'
+ X-Response-Time:
+ - '129'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '[{"id":"1241980494134145024","url":"https://zammad.example.com/api/v1/channels_twitter_webhook","valid":false,"created_timestamp":"2020-03-23
+ 06:50:00 +0000"}]'
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:53:29 GMT
+- request:
+ method: put
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks/1241980494134145024.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="0e68c87513ac6d73759d3d581842342a",
+ oauth_signature="yJoLurGrHTs20uGEsm3uDEBgwUE%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946414", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 204
+ message: No Content
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Length:
+ - '0'
+ Date:
+ - Mon, 23 Mar 2020 06:53:36 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:53:36 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494641515025640; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:53:36 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_sOQIzWywRzjCDnBIeqxEvw=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:53:36 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - f79cb739010ea5fa189afc005a998ebd
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '1192'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: ''
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:53:36 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_invalid_webhook_registered_to_zammad_revalidates_by_manually_triggering_a_challenge-response_check.yml b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_invalid_webhook_registered_to_zammad_revalidates_by_manually_triggering_a_challenge-response_check.yml
new file mode 100644
index 000000000..33f586089
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_invalid_webhook_registered_to_zammad_revalidates_by_manually_triggering_a_challenge-response_check.yml
@@ -0,0 +1,221 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="csPRCe8Nu9cv8FNuxnLrInhnw96JjKTcZwK0HW8Njk",
+ oauth_signature="snIl5z49RgjhAiQs%2FQxk3kA%2FXtk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946407", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:53:28 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:53:28 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494640855835907; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:53:28 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_0zvtRwIZbniQqVSLo6XdbQ=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:53:28 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - f86b366038f347fcd3bba565fd31387f
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '174'
+ X-Transaction:
+ - '008597c000517be9'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=dMaNHgAAAAAA9CNXAAABcQYq7Hg&oauth_token_secret=d9QXHdi5FXmJjA1NZwKJBvvYh3tyv5IE&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:53:28 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="942e58699c99fd8bd9ba1cd69942f14f",
+ oauth_signature="O3JqHZhT8NsLR7yAA1QHIyxFVBw%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946408", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '159'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:53:29 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:53:29 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494640936571915; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:53:29 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_/ujsZ3ysdevr5v1b89RLmA=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:53:29 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 3a297b509badf9dde9b3bd63225f2460
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '11'
+ X-Rate-Limit-Reset:
+ - '1584946869'
+ X-Response-Time:
+ - '129'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '[{"id":"1241980494134145024","url":"https://zammad.example.com/api/v1/channels_twitter_webhook","valid":false,"created_timestamp":"2020-03-23
+ 06:50:00 +0000"}]'
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:53:29 GMT
+- request:
+ method: put
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks/1241980494134145024.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="0e68c87513ac6d73759d3d581842342a",
+ oauth_signature="yJoLurGrHTs20uGEsm3uDEBgwUE%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946414", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 204
+ message: No Content
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Length:
+ - '0'
+ Date:
+ - Mon, 23 Mar 2020 06:53:36 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:53:36 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494641515025640; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:53:36 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_sOQIzWywRzjCDnBIeqxEvw=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:53:36 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - f79cb739010ea5fa189afc005a998ebd
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '1192'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: ''
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:53:36 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_valid_webhook_registered_to_zammad_responds_200_ok_with_the_new_webhook_id.yml b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_valid_webhook_registered_to_zammad_responds_200_ok_with_the_new_webhook_id.yml
new file mode 100644
index 000000000..b2fbece3c
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_valid_webhook_registered_to_zammad_responds_200_ok_with_the_new_webhook_id.yml
@@ -0,0 +1,156 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="R8pami8MAZxueiWHbeHGElRu1eKkqlx1EMWzIMBak4",
+ oauth_signature="4YqicQdmoR%2FPy%2BWoNuYM7Ju5i5o%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946227", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:50:27 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:50:27 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494622759890078; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:50:27 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_H5QcZwbsYs17rlHYr0H+vQ=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:50:27 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 83386731bc9de977648afc912027179c
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '173'
+ X-Transaction:
+ - 00f539ea00e120fb
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=cUJTzgAAAAAA9CNXAAABcQYoKZg&oauth_token_secret=VmKRBVKJhSgWG3lDkGEs05S3hUipFCFT&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:50:27 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="7340c22f098c47bf11dd02b86b7ae4ee",
+ oauth_signature="xImjBG5HNm1qIr2W1vfPfNXI2ZU%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946227", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '159'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:50:28 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:50:28 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494622852377372; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:50:28 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_QVDADsPO7IEd2c2pSzqnlQ=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:50:28 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - f55ffd0a92717898db5d39594134bfc7
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '12'
+ X-Rate-Limit-Reset:
+ - '1584946869'
+ X-Response-Time:
+ - '129'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '[{"id":"1241980494134145024","url":"https://zammad.example.com/api/v1/channels_twitter_webhook","valid":true,"created_timestamp":"2020-03-23
+ 06:50:00 +0000"}]'
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:50:28 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_valid_webhook_registered_to_zammad_uses_the_existing_webhook.yml b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_valid_webhook_registered_to_zammad_uses_the_existing_webhook.yml
new file mode 100644
index 000000000..b2fbece3c
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_valid_webhook_registered_to_zammad_uses_the_existing_webhook.yml
@@ -0,0 +1,156 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="R8pami8MAZxueiWHbeHGElRu1eKkqlx1EMWzIMBak4",
+ oauth_signature="4YqicQdmoR%2FPy%2BWoNuYM7Ju5i5o%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946227", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:50:27 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:50:27 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494622759890078; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:50:27 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_H5QcZwbsYs17rlHYr0H+vQ=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:50:27 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 83386731bc9de977648afc912027179c
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '173'
+ X-Transaction:
+ - 00f539ea00e120fb
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=cUJTzgAAAAAA9CNXAAABcQYoKZg&oauth_token_secret=VmKRBVKJhSgWG3lDkGEs05S3hUipFCFT&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:50:27 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="7340c22f098c47bf11dd02b86b7ae4ee",
+ oauth_signature="xImjBG5HNm1qIr2W1vfPfNXI2ZU%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946227", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '159'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:50:28 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:50:28 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494622852377372; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:50:28 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_QVDADsPO7IEd2c2pSzqnlQ=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:50:28 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - f55ffd0a92717898db5d39594134bfc7
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '12'
+ X-Rate-Limit-Reset:
+ - '1584946869'
+ X-Response-Time:
+ - '129'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '[{"id":"1241980494134145024","url":"https://zammad.example.com/api/v1/channels_twitter_webhook","valid":true,"created_timestamp":"2020-03-23
+ 06:50:00 +0000"}]'
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:50:28 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_webhook_registered_to_another_app_deletes_all_existing_webhooks_first.yml b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_webhook_registered_to_another_app_deletes_all_existing_webhooks_first.yml
new file mode 100644
index 000000000..122857e5b
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_webhook_registered_to_another_app_deletes_all_existing_webhooks_first.yml
@@ -0,0 +1,291 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="VRoBaTlqUNONRdoijJHa6EOqLUm3byplijFPiq89rk",
+ oauth_signature="WdhBR4eYTroYsTDILrvXuI0XkiQ%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946494", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '128'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:54:55 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:54:55 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494649546445555; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:54:55 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_YhVmFXgqJqhoo/vskWqjig=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:54:55 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 0024fe0912dac2a5dc844ca38452d061
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '175'
+ X-Transaction:
+ - '0079b5ea00ca607b'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=ROuVpAAAAAAA9CNXAAABcQYsP_I&oauth_token_secret=DxU3Sug0XWisEguI1V1sKLCtagoN4H9n&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:54:55 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="4d73297b8c1c4b53c4da233d5c84450d",
+ oauth_signature="jFTdr8438fxw6izLvwu%2B8vG71wY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946495", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '159'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:54:56 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:54:56 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494649637073312; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:54:56 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_eXer39NQ1Q4OV5hhtjRCfw=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:54:56 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - d3cf054bb409d406e78f3eceb68dbc87
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '10'
+ X-Rate-Limit-Reset:
+ - '1584946869'
+ X-Response-Time:
+ - '120'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '[{"id":"1241981813595049984","url":"https://other-twitter-consumer.example.com/api/v1/channels_twitter_webhook","valid":true,"created_timestamp":"2020-03-23
+ 06:50:00 +0000"}]'
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:54:56 GMT
+- request:
+ method: delete
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks/1241981813595049984.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="e01c43b32c7cc9a40ae38ed9160d4270",
+ oauth_signature="TYA3fOVQFJaroBPv%2BxcexVsf0pA%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946512", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 204
+ message: No Content
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Length:
+ - '0'
+ Date:
+ - Mon, 23 Mar 2020 06:55:13 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:55:13 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494651315115177; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:55:13 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_d2nHwUq5dbpmvAGtFTL49w=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:55:13 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 43d344188e5cd1359cc494ca68e3a148
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '134'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: ''
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:55:13 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: url=https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fchannels_twitter_webhook
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="544efdb5ca2de8d67c7dc24824b454b1",
+ oauth_signature="0InLZ8JHpAiDPZdmAHGXJSEGxiU%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946513", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '157'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:55:14 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:55:14 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494651390957301; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:55:14 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_b5rZAeBdcvz00R6KTtRpFQ=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:55:14 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 3654669d75d05854cb54a51031c58246
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '968'
+ X-Tsa-Request-Body-Time:
+ - '0'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"1241980494134145024","url":"https://zammad.example.com/api/v1/channels_twitter_webhook","valid":true,"created_timestamp":"2020-03-23
+ 06:55:14 +0000"}'
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:55:14 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_webhook_registered_to_another_app_responds_200_ok_with_the_new_webhook_id.yml b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_webhook_registered_to_another_app_responds_200_ok_with_the_new_webhook_id.yml
new file mode 100644
index 000000000..122857e5b
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_an_existing_webhook_registered_to_another_app_responds_200_ok_with_the_new_webhook_id.yml
@@ -0,0 +1,291 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="VRoBaTlqUNONRdoijJHa6EOqLUm3byplijFPiq89rk",
+ oauth_signature="WdhBR4eYTroYsTDILrvXuI0XkiQ%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946494", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '128'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:54:55 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:54:55 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494649546445555; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:54:55 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_YhVmFXgqJqhoo/vskWqjig=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:54:55 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 0024fe0912dac2a5dc844ca38452d061
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '175'
+ X-Transaction:
+ - '0079b5ea00ca607b'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=ROuVpAAAAAAA9CNXAAABcQYsP_I&oauth_token_secret=DxU3Sug0XWisEguI1V1sKLCtagoN4H9n&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:54:55 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="4d73297b8c1c4b53c4da233d5c84450d",
+ oauth_signature="jFTdr8438fxw6izLvwu%2B8vG71wY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946495", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '159'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:54:56 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:54:56 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494649637073312; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:54:56 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_eXer39NQ1Q4OV5hhtjRCfw=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:54:56 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - d3cf054bb409d406e78f3eceb68dbc87
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '10'
+ X-Rate-Limit-Reset:
+ - '1584946869'
+ X-Response-Time:
+ - '120'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '[{"id":"1241981813595049984","url":"https://other-twitter-consumer.example.com/api/v1/channels_twitter_webhook","valid":true,"created_timestamp":"2020-03-23
+ 06:50:00 +0000"}]'
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:54:56 GMT
+- request:
+ method: delete
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks/1241981813595049984.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="e01c43b32c7cc9a40ae38ed9160d4270",
+ oauth_signature="TYA3fOVQFJaroBPv%2BxcexVsf0pA%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946512", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 204
+ message: No Content
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Length:
+ - '0'
+ Date:
+ - Mon, 23 Mar 2020 06:55:13 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:55:13 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494651315115177; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:55:13 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_d2nHwUq5dbpmvAGtFTL49w=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:55:13 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 43d344188e5cd1359cc494ca68e3a148
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '134'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: ''
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:55:13 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: url=https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fchannels_twitter_webhook
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="544efdb5ca2de8d67c7dc24824b454b1",
+ oauth_signature="0InLZ8JHpAiDPZdmAHGXJSEGxiU%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946513", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '157'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:55:14 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:55:14 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494651390957301; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:55:14 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_b5rZAeBdcvz00R6KTtRpFQ=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:55:14 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 3654669d75d05854cb54a51031c58246
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '968'
+ X-Tsa-Request-Body-Time:
+ - '0'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"1241980494134145024","url":"https://zammad.example.com/api/v1/channels_twitter_webhook","valid":true,"created_timestamp":"2020-03-23
+ 06:55:14 +0000"}'
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:55:14 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_invalid_credentials_via_request_params_returns_200_with_remote_twitter_auth_error.yml b/test/data/vcr_cassettes/requests/external_credentials/with_invalid_credential_params_responds_with_the_appropriate_status_and_error_message.yml
similarity index 100%
rename from test/data/vcr_cassettes/requests/external_credentials/with_invalid_credentials_via_request_params_returns_200_with_remote_twitter_auth_error.yml
rename to test/data/vcr_cassettes/requests/external_credentials/with_invalid_credential_params_responds_with_the_appropriate_status_and_error_message.yml
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_invalid_credentials_via_existing_externalcredential_record_returns_200_with_remote_twitter_auth_error.yml b/test/data/vcr_cassettes/requests/external_credentials/with_invalid_credentials_via_existing_externalcredential_record_returns_200_with_remote_twitter_auth_error.yml
deleted file mode 100644
index 92649c91f..000000000
--- a/test/data/vcr_cassettes/requests/external_credentials/with_invalid_credentials_via_existing_externalcredential_record_returns_200_with_remote_twitter_auth_error.yml
+++ /dev/null
@@ -1,76 +0,0 @@
----
-http_interactions:
-- request:
- method: post
- uri: https://api.twitter.com/oauth/request_token
- body:
- encoding: UTF-8
- string: ''
- headers:
- Accept-Encoding:
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
- Accept:
- - "*/*"
- User-Agent:
- - OAuth gem v0.5.3
- Content-Length:
- - '0'
- Authorization:
- - OAuth oauth_callback="http%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
- oauth_consumer_key="123", oauth_nonce="0ZvmCFseUeq6QZxGhuzQxLiyty2UErgeVcdRPOk",
- oauth_signature="Ps3iBseIQuh0ERb%2F7tEfFBERbwA%3D", oauth_signature_method="HMAC-SHA1",
- oauth_timestamp="1543582246", oauth_version="1.0"
- response:
- status:
- code: 401
- message: Authorization Required
- headers:
- Cache-Control:
- - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
- Content-Disposition:
- - attachment; filename=json.json
- Content-Length:
- - '89'
- Content-Type:
- - application/json; charset=utf-8
- Date:
- - Fri, 30 Nov 2018 12:50:47 GMT
- Expires:
- - Tue, 31 Mar 1981 05:00:00 GMT
- Last-Modified:
- - Fri, 30 Nov 2018 12:50:47 GMT
- Pragma:
- - no-cache
- Server:
- - tsa_o
- Set-Cookie:
- - guest_id=v1%3A154358224734601031; Expires=Sun, 29 Nov 2020 12:50:47 GMT; Path=/;
- Domain=.twitter.com
- - personalization_id="v1_QoTam409bMc8TzMu10F/CA=="; Expires=Sun, 29 Nov 2020
- 12:50:47 GMT; Path=/; Domain=.twitter.com
- Status:
- - 401 Unauthorized
- Strict-Transport-Security:
- - max-age=631138519
- Www-Authenticate:
- - OAuth realm="https://api.twitter.com"
- X-Connection-Hash:
- - 2ac9b707f5cdd229664772dc9d4a5a8b
- X-Content-Type-Options:
- - nosniff
- X-Frame-Options:
- - SAMEORIGIN
- X-Response-Time:
- - '120'
- X-Transaction:
- - 00d9dad60073e68c
- X-Twitter-Response-Tags:
- - BouncerCompliant
- X-Xss-Protection:
- - 1; mode=block; report=https://twitter.com/i/xss_report
- body:
- encoding: ASCII-8BIT
- string: '{"errors":[{"code":32,"message":"Could not authenticate you."}]}'
- http_version:
- recorded_at: Fri, 30 Nov 2018 12:50:47 GMT
-recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_invalid_credentials_via_externalcredential_record_returns_500_with_remote_twitter_auth_error.yml b/test/data/vcr_cassettes/requests/external_credentials/with_invalid_twitter_app_configured_with_invalid_credentials_responds_with_the_appropriate_status_and_error_message.yml
similarity index 67%
rename from test/data/vcr_cassettes/requests/external_credentials/with_invalid_credentials_via_externalcredential_record_returns_500_with_remote_twitter_auth_error.yml
rename to test/data/vcr_cassettes/requests/external_credentials/with_invalid_twitter_app_configured_with_invalid_credentials_responds_with_the_appropriate_status_and_error_message.yml
index 6ff025280..fbde2ccfb 100644
--- a/test/data/vcr_cassettes/requests/external_credentials/with_invalid_credentials_via_externalcredential_record_returns_500_with_remote_twitter_auth_error.yml
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_invalid_twitter_app_configured_with_invalid_credentials_responds_with_the_appropriate_status_and_error_message.yml
@@ -17,9 +17,9 @@ http_interactions:
- '0'
Authorization:
- OAuth oauth_callback="http%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
- oauth_consumer_key="123", oauth_nonce="f1YmStPaUKxHSrCJCbN4LEBvGhjPs41P9rFzOrnhqc",
- oauth_signature="mPMYvS8A4FiTPhxPDlFB%2FGF0X2U%3D", oauth_signature_method="HMAC-SHA1",
- oauth_timestamp="1573570318", oauth_version="1.0"
+ oauth_consumer_key="q7K8GEkhyCHs9jHLtkmD9Kod4", oauth_nonce="inxkJCcGw8CXKPAR7zPUyKtg64WHnP8IFy00IhEUdk",
+ oauth_signature="Whmfth%2F6dL9gIR2wtw6Q24kCP5w%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584364824", oauth_version="1.0"
response:
status:
code: 401
@@ -34,20 +34,20 @@ http_interactions:
Content-Type:
- application/json; charset=utf-8
Date:
- - Tue, 12 Nov 2019 14:51:59 GMT
+ - Mon, 16 Mar 2020 13:20:25 GMT
Expires:
- Tue, 31 Mar 1981 05:00:00 GMT
Last-Modified:
- - Tue, 12 Nov 2019 14:51:58 GMT
+ - Mon, 16 Mar 2020 13:20:25 GMT
Pragma:
- no-cache
Server:
- tsa_m
Set-Cookie:
- - guest_id=v1%3A157357031898209376; Max-Age=63072000; Expires=Thu, 11 Nov 2021
- 14:51:58 GMT; Path=/; Domain=.twitter.com
- - personalization_id="v1_jB1SWZRvZIk1S63ok8jVog=="; Max-Age=63072000; Expires=Thu,
- 11 Nov 2021 14:51:58 GMT; Path=/; Domain=.twitter.com
+ - guest_id=v1%3A158436482527178006; Max-Age=63072000; Expires=Wed, 16 Mar 2022
+ 13:20:25 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_xDsuGTHoxq4DzimsOj3SQA=="; Max-Age=63072000; Expires=Wed,
+ 16 Mar 2022 13:20:25 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
Status:
- 401 Unauthorized
Strict-Transport-Security:
@@ -55,15 +55,15 @@ http_interactions:
Www-Authenticate:
- OAuth realm="https://api.twitter.com"
X-Connection-Hash:
- - a4ba44ed62e7eb6cb9503b492304013e
+ - 7b48cea34f4491a7dc48fa31a6b4b056
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Response-Time:
- - '103'
+ - '106'
X-Transaction:
- - '009c9ec5003d9011'
+ - 00f72d7200ca3a92
X-Twitter-Response-Tags:
- BouncerCompliant
X-Xss-Protection:
@@ -72,5 +72,5 @@ http_interactions:
encoding: ASCII-8BIT
string: '{"errors":[{"code":32,"message":"Could not authenticate you."}]}'
http_version:
- recorded_at: Tue, 12 Nov 2019 14:51:59 GMT
+ recorded_at: Mon, 16 Mar 2020 13:20:25 GMT
recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_no_existing_webhooks_registers_a_new_webhook.yml b/test/data/vcr_cassettes/requests/external_credentials/with_no_existing_webhooks_registers_a_new_webhook.yml
new file mode 100644
index 000000000..4dbaab1c9
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_no_existing_webhooks_registers_a_new_webhook.yml
@@ -0,0 +1,227 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="WEdVRwqANFvd88F7XT20hb9Gy2sX9SUOHO2OjuDy5s",
+ oauth_signature="5FxCmPjUhhonf8z91c0zjdva17g%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946195", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '128'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:49:56 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:49:56 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494619670369961; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:49:56 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_gRE63FsGkhU+oWr6ym/cmQ=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:49:56 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - bf1be9b449b09c27118e03154030d2c1
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '182'
+ X-Transaction:
+ - 0041a72a0055a246
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=Zh216AAAAAAA9CNXAAABcQYnsOw&oauth_token_secret=yo7psG4mpdPWyukpnmu1vWRt4Tz8WGtr&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:49:56 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="3e01a769626bdda6a2a486523c5ecc88",
+ oauth_signature="ziL70P7MK8c1fQb48VDq90l7nVo%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946196", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '2'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:49:57 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:49:57 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494619764550785; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:49:57 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_VhuMvUna18W18fWDGh4/7A=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:49:57 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 0fb10d92512f1a9c56d292d6b53ae39d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '13'
+ X-Rate-Limit-Reset:
+ - '1584946869'
+ X-Response-Time:
+ - '127'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: "[]"
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:49:57 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: url=https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fchannels_twitter_webhook
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="30b043964594269685a4f012b7e8dee9",
+ oauth_signature="2Cjq%2BkPsg9t16de7RxT%2BpSHd4Vs%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946198", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '157'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:50:00 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:50:00 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494619932180099; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:50:00 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_j3+Q2dBVsNiOGIBfS4inpg=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:50:00 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 0adde24aa0bdba3982ff7fca82228752
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '1002'
+ X-Tsa-Request-Body-Time:
+ - '0'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"1241980494134145024","url":"https://zammad.example.com/api/v1/channels_twitter_webhook","valid":true,"created_timestamp":"2020-03-23
+ 06:50:00 +0000"}'
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:50:00 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_no_existing_webhooks_responds_200_ok_with_the_new_webhook_id.yml b/test/data/vcr_cassettes/requests/external_credentials/with_no_existing_webhooks_responds_200_ok_with_the_new_webhook_id.yml
new file mode 100644
index 000000000..4dbaab1c9
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_no_existing_webhooks_responds_200_ok_with_the_new_webhook_id.yml
@@ -0,0 +1,227 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="WEdVRwqANFvd88F7XT20hb9Gy2sX9SUOHO2OjuDy5s",
+ oauth_signature="5FxCmPjUhhonf8z91c0zjdva17g%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946195", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '128'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:49:56 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:49:56 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494619670369961; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:49:56 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_gRE63FsGkhU+oWr6ym/cmQ=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:49:56 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - bf1be9b449b09c27118e03154030d2c1
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '182'
+ X-Transaction:
+ - 0041a72a0055a246
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=Zh216AAAAAAA9CNXAAABcQYnsOw&oauth_token_secret=yo7psG4mpdPWyukpnmu1vWRt4Tz8WGtr&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:49:56 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="3e01a769626bdda6a2a486523c5ecc88",
+ oauth_signature="ziL70P7MK8c1fQb48VDq90l7nVo%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946196", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '2'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:49:57 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:49:57 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494619764550785; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:49:57 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_VhuMvUna18W18fWDGh4/7A=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:49:57 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 0fb10d92512f1a9c56d292d6b53ae39d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '13'
+ X-Rate-Limit-Reset:
+ - '1584946869'
+ X-Response-Time:
+ - '127'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: "[]"
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:49:57 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: url=https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fchannels_twitter_webhook
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="30b043964594269685a4f012b7e8dee9",
+ oauth_signature="2Cjq%2BkPsg9t16de7RxT%2BpSHd4Vs%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584946198", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '157'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 23 Mar 2020 06:50:00 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 23 Mar 2020 06:50:00 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158494619932180099; Max-Age=63072000; Expires=Wed, 23 Mar 2022
+ 06:50:00 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_j3+Q2dBVsNiOGIBfS4inpg=="; Max-Age=63072000; Expires=Wed,
+ 23 Mar 2022 06:50:00 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 0adde24aa0bdba3982ff7fca82228752
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '1002'
+ X-Tsa-Request-Body-Time:
+ - '0'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"1241980494134145024","url":"https://zammad.example.com/api/v1/channels_twitter_webhook","valid":true,"created_timestamp":"2020-03-23
+ 06:50:00 +0000"}'
+ http_version:
+ recorded_at: Mon, 23 Mar 2020 06:50:00 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_valid_credential_params_and_callback_url_but_no_dev_env_registered_responds_with_the_appropriate_status_and_error_message.yml b/test/data/vcr_cassettes/requests/external_credentials/with_valid_credential_params_and_callback_url_but_no_dev_env_registered_responds_with_the_appropriate_status_and_error_message.yml
new file mode 100644
index 000000000..d6dff1ab5
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_valid_credential_params_and_callback_url_but_no_dev_env_registered_responds_with_the_appropriate_status_and_error_message.yml
@@ -0,0 +1,366 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="JY7lBkhK76dN4XwmWt0fpW76PVZpkOYNNdkJVQvs",
+ oauth_signature="3LZNJdmWilkaWF8LNJi%2BJ2MoqqY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584809973", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Sat, 21 Mar 2020 16:59:34 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Sat, 21 Mar 2020 16:59:34 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158480997456453257; Max-Age=63072000; Expires=Mon, 21 Mar 2022
+ 16:59:34 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_+mW6Nj+Ef5FKaOmpfa/alw=="; Max-Age=63072000; Expires=Mon,
+ 21 Mar 2022 16:59:34 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - d525a3286fa3056dd107ac6eeb71e366
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 007ea87f00123004
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=DY8E9gAAAAABCFc9AAABcP4JGzI&oauth_token_secret=gAR1aD2RGw3klpbxNtMuwvALohChdLDR&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Sat, 21 Mar 2020 16:59:34 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="f37bedff997ce5964bc6a3b101aba492",
+ oauth_signature="ttsDqMAySZvanN9nc2ht8dKYSmI%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584809974", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 403
+ message: Forbidden
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '48'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Sat, 21 Mar 2020 16:59:35 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Sat, 21 Mar 2020 16:59:35 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158480997539935448; Max-Age=63072000; Expires=Mon, 21 Mar 2022
+ 16:59:35 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_hIU9rfKFHfFl54Xqc4isng=="; Max-Age=63072000; Expires=Mon,
+ 21 Mar 2022 16:59:35 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - dd38c9d0b693ae69215ec1f8b3cfedbc
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '14'
+ X-Rate-Limit-Reset:
+ - '1584810875'
+ X-Response-Time:
+ - '126'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":200,"message":"Forbidden."}]}'
+ http_version:
+ recorded_at: Sat, 21 Mar 2020 16:59:35 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="d1dc6541ff8ee09d0ac42c447199e5b7",
+ oauth_signature="1Ca9FsCYSjLZQASFRKshljunPrk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584809986", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 403
+ message: Forbidden
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '48'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Sat, 21 Mar 2020 16:59:47 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Sat, 21 Mar 2020 16:59:47 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158480998730112300; Max-Age=63072000; Expires=Mon, 21 Mar 2022
+ 16:59:47 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_Fdu/3tNQYPP/xFvfXJbwDg=="; Max-Age=63072000; Expires=Mon,
+ 21 Mar 2022 16:59:47 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - c2d1a9eec6b30f9d082b1da37c2f04d1
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '14'
+ X-Rate-Limit-Reset:
+ - '1584810887'
+ X-Response-Time:
+ - '121'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":200,"message":"Forbidden."}]}'
+ http_version:
+ recorded_at: Sat, 21 Mar 2020 16:59:47 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="081b3d097aca1652183a751202a26335",
+ oauth_signature="VEdsYoj9vXKN4xrHuC1LFbluM5I%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584810017", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 403
+ message: Forbidden
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '48'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Sat, 21 Mar 2020 17:00:18 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Sat, 21 Mar 2020 17:00:18 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158481001864282473; Max-Age=63072000; Expires=Mon, 21 Mar 2022
+ 17:00:18 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_ZI2Mgql0H9p9UFGi5gDuGQ=="; Max-Age=63072000; Expires=Mon,
+ 21 Mar 2022 17:00:18 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 74ac96190171b5ae738b44309f54eded
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '13'
+ X-Rate-Limit-Reset:
+ - '1584810887'
+ X-Response-Time:
+ - '119'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":200,"message":"Forbidden."}]}'
+ http_version:
+ recorded_at: Sat, 21 Mar 2020 17:00:18 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="c0cad1a2a978959c5601510938ee43b5",
+ oauth_signature="EGquSunA7UZQDtWUJ1o0e1jfXiM%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584863384", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 403
+ message: Forbidden
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '48'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Sun, 22 Mar 2020 07:49:45 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Sun, 22 Mar 2020 07:49:45 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158486338550177879; Max-Age=63072000; Expires=Tue, 22 Mar 2022
+ 07:49:45 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_ACZqBomM69SOVn4DsIhWpg=="; Max-Age=63072000; Expires=Tue,
+ 22 Mar 2022 07:49:45 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 1530861f42dc04780e44eca4ac0493c2
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '14'
+ X-Rate-Limit-Reset:
+ - '1584864285'
+ X-Response-Time:
+ - '118'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":200,"message":"Forbidden."}]}'
+ http_version:
+ recorded_at: Sun, 22 Mar 2020 07:49:45 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_valid_credential_params_and_callback_url_but_wrong_dev_env_label_responds_with_the_appropriate_status_and_error_message.yml b/test/data/vcr_cassettes/requests/external_credentials/with_valid_credential_params_and_callback_url_but_wrong_dev_env_label_responds_with_the_appropriate_status_and_error_message.yml
new file mode 100644
index 000000000..a1153723c
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_valid_credential_params_and_callback_url_but_wrong_dev_env_label_responds_with_the_appropriate_status_and_error_message.yml
@@ -0,0 +1,226 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="UUPB8XVJ1NuvAbj3aqyyiIKVMK7ko0BsJsgenHb1g",
+ oauth_signature="w3x2Z7sLFUR0%2FEVnEUgY%2BjFxArQ%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584863417", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Sun, 22 Mar 2020 07:50:18 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Sun, 22 Mar 2020 07:50:18 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158486341853162103; Max-Age=63072000; Expires=Tue, 22 Mar 2022
+ 07:50:18 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_DKWuZi5CRwZ86gs5trb8KQ=="; Max-Age=63072000; Expires=Tue,
+ 22 Mar 2022 07:50:18 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - b8ec73ffd179fea5daaa30f3a077692a
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 00ba19ed00f1eba8
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=FKDDVQAAAAABCFc9AAABcQE4mLA&oauth_token_secret=K4EVN3HlKB5WevblF1xpn9kG89boaVVB&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Sun, 22 Mar 2020 07:50:18 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/foo/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="d29100379bb6bac96644adacff4dca44",
+ oauth_signature="CsldhuESW3DOtaCZulq3qA%2BflGs%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584863418", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 403
+ message: Forbidden
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '48'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Sun, 22 Mar 2020 07:50:19 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Sun, 22 Mar 2020 07:50:19 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158486341964912319; Max-Age=63072000; Expires=Tue, 22 Mar 2022
+ 07:50:19 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_BxIlCjlAW7oHwqZ/pwLaIQ=="; Max-Age=63072000; Expires=Tue,
+ 22 Mar 2022 07:50:19 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - bed4902b98c59d385f9b8367c481a4dc
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '13'
+ X-Rate-Limit-Reset:
+ - '1584864285'
+ X-Response-Time:
+ - '135'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":200,"message":"Forbidden."}]}'
+ http_version:
+ recorded_at: Sun, 22 Mar 2020 07:50:19 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account_activity/all/webhooks.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="29b521a0e7f13264842b631dbf88ad3c",
+ oauth_signature="WFtmIEjdyHHJdidWUh5KuocRDrg%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584863419", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '59'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Sun, 22 Mar 2020 07:50:20 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Sun, 22 Mar 2020 07:50:20 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158486342081149704; Max-Age=63072000; Expires=Tue, 22 Mar 2022
+ 07:50:20 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_hme2WiclptVHO6tR4hvfJA=="; Max-Age=63072000; Expires=Tue,
+ 22 Mar 2022 07:50:20 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 2866e6e58948a650df59bb1a35de93d9
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '15'
+ X-Rate-Limit-Remaining:
+ - '14'
+ X-Rate-Limit-Reset:
+ - '1584864320'
+ X-Response-Time:
+ - '125'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"environments":[{"environment_name":"zammad","webhooks":[]}]}'
+ http_version:
+ recorded_at: Sun, 22 Mar 2020 07:50:21 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_valid_credential_params_but_misconfigured_callback_url_responds_with_the_appropriate_status_and_error_message.yml b/test/data/vcr_cassettes/requests/external_credentials/with_valid_credential_params_but_misconfigured_callback_url_responds_with_the_appropriate_status_and_error_message.yml
new file mode 100644
index 000000000..8a8c84b1d
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_valid_credential_params_but_misconfigured_callback_url_responds_with_the_appropriate_status_and_error_message.yml
@@ -0,0 +1,78 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="http%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="nJCf3pHks6WdvL49c9EwvOldiSNZVcBm78QjTTC8",
+ oauth_signature="b%2B7o2S7eebqcSat9ejl5eg994Yo%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1584809480", oauth_version="1.0"
+ response:
+ status:
+ code: 403
+ message: Forbidden
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '173'
+ Content-Type:
+ - application/xml;charset=utf-8
+ Date:
+ - Sat, 21 Mar 2020 16:51:22 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Sat, 21 Mar 2020 16:51:21 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158480948198632109; Max-Age=63072000; Expires=Mon, 21 Mar 2022
+ 16:51:21 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_huputGsbjXeqeEMv8yWoWA=="; Max-Age=63072000; Expires=Mon,
+ 21 Mar 2022 16:51:21 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 403 Forbidden
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 9b4cca102e32ff639f91393c49da27db
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '108'
+ X-Transaction:
+ - 006ad3bc000880af
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: Callback
+ URL not approved for this client application. Approved callback URLs can be
+ adjusted in your application settings
+ http_version:
+ recorded_at: Sat, 21 Mar 2020 16:51:22 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_and_request_token_but_non-matching_oauth_token_via_params_responds_with_the_appropriate_status_and_error_message.yml b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_and_request_token_but_non-matching_oauth_token_via_params_responds_with_the_appropriate_status_and_error_message.yml
new file mode 100644
index 000000000..b2b188dfd
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_and_request_token_but_non-matching_oauth_token_via_params_responds_with_the_appropriate_status_and_error_message.yml
@@ -0,0 +1,82 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="osQnRbjAXQwlKL3HyiIy9qRRLSsaCfeZEjP9tpCKU2g",
+ oauth_signature="70oe9naxLRBTlWB3iTiDNjl3hYY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585562110", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 09:55:11 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 09:55:11 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158556211133010327; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 09:55:11 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_ZycBeYCs8XZrPuLGIlNJdQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 09:55:11 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 69405d9ca050afeb0102866002c080c4
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - '008c8d0f00cd1be0'
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=scHVjwAAAAABCFc9AAABcSrdzXA&oauth_token_secret=DLhVF0DI6EVecjHobit6rdi4QV2IP55e&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 09:55:11 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_clears_the_request_token_session_variable.yml b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_clears_the_request_token_session_variable.yml
new file mode 100644
index 000000000..c2048b994
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_clears_the_request_token_session_variable.yml
@@ -0,0 +1,312 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="cRQcN4SYlNvQmxLERXdkHw0b8WkgopWyZfshYZ0bQ5c",
+ oauth_signature="1QKjkAywyA9C28RyxllXH4I%2B8dk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585562755", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158556275926104897; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_2VPPoqwsc7qTrmUTl7TOqQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - d5c96afbba7d4a8d9767a2520f1014b9
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 00d90bb200263ca8
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=DyhnyQAAAAAA9CNXAAABcSxAexs&oauth_token_secret=ubeISX6MlS1PTPAp8udaQ2yRqHlNWdCf&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 10:05:59 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/access_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="2Wj2SwZSjbQpBx5pgSqAcwXuREAZCW9cYk7IgK79M",
+ oauth_signature="zv4lFCYM8OgJleXMzjSrh6bkzb4%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585442", oauth_token="DyhnyQAAAAAA9CNXAAABcSxAexs", oauth_verifier="15DOeRkjP4JkOSVqULkTKA1SCuIPP105",
+ oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '174'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544330530048; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_r1gFYSkkPVRlfj2/S3iBhA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 4c532e72e52e91a920ec7ede1d738a7d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '437'
+ X-Transaction:
+ - 002d00030028d5ad
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=REDACTED&oauth_token_secret=6Izq6rCcuJs07inPgc7oMVbq0sjLzuxFLcRq2gp5ulJQW&user_id=1205290247124217856&screen_name=pennbrooke1
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:03 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account/verify_credentials.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="d8377bbeda339f59394d528d368c5bd6",
+ oauth_signature="665K11LI%2FY0%2BZrf0AD%2BPJnrehVY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585443", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '1928'
+ Content-Type:
+ - application/json;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544430987067; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - lang=en; Path=/
+ - personalization_id="v1_KepQ+bqW3x/y43slZzYqcA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Access-Level:
+ - read-write-directmessages
+ X-Connection-Hash:
+ - fe7eed972598e46753f044b0f5f1c34e
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '75'
+ X-Rate-Limit-Remaining:
+ - '72'
+ X-Rate-Limit-Reset:
+ - '1585585445'
+ X-Response-Time:
+ - '155'
+ X-Transaction:
+ - 00d3169e00a6aa44
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ - BouncerExempt
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":1205290247124217856,"id_str":"1205290247124217856","name":"pennbrooke","screen_name":"pennbrooke1","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":1,"listed_count":0,"created_at":"Fri
+ Dec 13 00:56:10 +0000 2019","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":20,"lang":null,"status":{"created_at":"Thu
+ Mar 12 06:57:32 +0000 2020","id":1237996127103811584,"id_str":"1237996127103811584","text":"zammadzammadzammad","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[],"urls":[]},"source":"\u003ca
+ href=\"https:\/\/zammad.com\/\" rel=\"nofollow\"\u003ezammad\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"lv"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"F5F8FA","profile_background_image_url":null,"profile_background_image_url_https":null,"profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none","suspended":false,"needs_phone_verification":false}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:04 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/subscriptions.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="97f965f030c78cf792bd551bd8252d16",
+ oauth_signature="bTbM1ut0%2Bly3dtA6MqArPRq3wYk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585444", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 409
+ message: Conflict
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '66'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544515442211; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_I7zU3t0hJJakpotS4JM6yQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - b195905c1f696c9a9fc408e990adc77d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '130'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":355,"message":"Subscription already exists."}]}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:05 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_creates_a_new_channel.yml b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_creates_a_new_channel.yml
new file mode 100644
index 000000000..c2048b994
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_creates_a_new_channel.yml
@@ -0,0 +1,312 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="cRQcN4SYlNvQmxLERXdkHw0b8WkgopWyZfshYZ0bQ5c",
+ oauth_signature="1QKjkAywyA9C28RyxllXH4I%2B8dk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585562755", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158556275926104897; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_2VPPoqwsc7qTrmUTl7TOqQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - d5c96afbba7d4a8d9767a2520f1014b9
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 00d90bb200263ca8
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=DyhnyQAAAAAA9CNXAAABcSxAexs&oauth_token_secret=ubeISX6MlS1PTPAp8udaQ2yRqHlNWdCf&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 10:05:59 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/access_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="2Wj2SwZSjbQpBx5pgSqAcwXuREAZCW9cYk7IgK79M",
+ oauth_signature="zv4lFCYM8OgJleXMzjSrh6bkzb4%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585442", oauth_token="DyhnyQAAAAAA9CNXAAABcSxAexs", oauth_verifier="15DOeRkjP4JkOSVqULkTKA1SCuIPP105",
+ oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '174'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544330530048; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_r1gFYSkkPVRlfj2/S3iBhA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 4c532e72e52e91a920ec7ede1d738a7d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '437'
+ X-Transaction:
+ - 002d00030028d5ad
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=REDACTED&oauth_token_secret=6Izq6rCcuJs07inPgc7oMVbq0sjLzuxFLcRq2gp5ulJQW&user_id=1205290247124217856&screen_name=pennbrooke1
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:03 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account/verify_credentials.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="d8377bbeda339f59394d528d368c5bd6",
+ oauth_signature="665K11LI%2FY0%2BZrf0AD%2BPJnrehVY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585443", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '1928'
+ Content-Type:
+ - application/json;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544430987067; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - lang=en; Path=/
+ - personalization_id="v1_KepQ+bqW3x/y43slZzYqcA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Access-Level:
+ - read-write-directmessages
+ X-Connection-Hash:
+ - fe7eed972598e46753f044b0f5f1c34e
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '75'
+ X-Rate-Limit-Remaining:
+ - '72'
+ X-Rate-Limit-Reset:
+ - '1585585445'
+ X-Response-Time:
+ - '155'
+ X-Transaction:
+ - 00d3169e00a6aa44
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ - BouncerExempt
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":1205290247124217856,"id_str":"1205290247124217856","name":"pennbrooke","screen_name":"pennbrooke1","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":1,"listed_count":0,"created_at":"Fri
+ Dec 13 00:56:10 +0000 2019","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":20,"lang":null,"status":{"created_at":"Thu
+ Mar 12 06:57:32 +0000 2020","id":1237996127103811584,"id_str":"1237996127103811584","text":"zammadzammadzammad","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[],"urls":[]},"source":"\u003ca
+ href=\"https:\/\/zammad.com\/\" rel=\"nofollow\"\u003ezammad\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"lv"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"F5F8FA","profile_background_image_url":null,"profile_background_image_url_https":null,"profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none","suspended":false,"needs_phone_verification":false}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:04 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/subscriptions.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="97f965f030c78cf792bd551bd8252d16",
+ oauth_signature="bTbM1ut0%2Bly3dtA6MqArPRq3wYk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585444", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 409
+ message: Conflict
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '66'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544515442211; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_I7zU3t0hJJakpotS4JM6yQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - b195905c1f696c9a9fc408e990adc77d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '130'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":355,"message":"Subscription already exists."}]}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:05 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_redirects_to_the_newly_created_channel.yml b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_redirects_to_the_newly_created_channel.yml
new file mode 100644
index 000000000..c2048b994
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_redirects_to_the_newly_created_channel.yml
@@ -0,0 +1,312 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="cRQcN4SYlNvQmxLERXdkHw0b8WkgopWyZfshYZ0bQ5c",
+ oauth_signature="1QKjkAywyA9C28RyxllXH4I%2B8dk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585562755", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158556275926104897; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_2VPPoqwsc7qTrmUTl7TOqQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - d5c96afbba7d4a8d9767a2520f1014b9
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 00d90bb200263ca8
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=DyhnyQAAAAAA9CNXAAABcSxAexs&oauth_token_secret=ubeISX6MlS1PTPAp8udaQ2yRqHlNWdCf&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 10:05:59 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/access_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="2Wj2SwZSjbQpBx5pgSqAcwXuREAZCW9cYk7IgK79M",
+ oauth_signature="zv4lFCYM8OgJleXMzjSrh6bkzb4%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585442", oauth_token="DyhnyQAAAAAA9CNXAAABcSxAexs", oauth_verifier="15DOeRkjP4JkOSVqULkTKA1SCuIPP105",
+ oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '174'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544330530048; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_r1gFYSkkPVRlfj2/S3iBhA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 4c532e72e52e91a920ec7ede1d738a7d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '437'
+ X-Transaction:
+ - 002d00030028d5ad
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=REDACTED&oauth_token_secret=6Izq6rCcuJs07inPgc7oMVbq0sjLzuxFLcRq2gp5ulJQW&user_id=1205290247124217856&screen_name=pennbrooke1
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:03 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account/verify_credentials.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="d8377bbeda339f59394d528d368c5bd6",
+ oauth_signature="665K11LI%2FY0%2BZrf0AD%2BPJnrehVY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585443", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '1928'
+ Content-Type:
+ - application/json;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544430987067; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - lang=en; Path=/
+ - personalization_id="v1_KepQ+bqW3x/y43slZzYqcA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Access-Level:
+ - read-write-directmessages
+ X-Connection-Hash:
+ - fe7eed972598e46753f044b0f5f1c34e
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '75'
+ X-Rate-Limit-Remaining:
+ - '72'
+ X-Rate-Limit-Reset:
+ - '1585585445'
+ X-Response-Time:
+ - '155'
+ X-Transaction:
+ - 00d3169e00a6aa44
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ - BouncerExempt
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":1205290247124217856,"id_str":"1205290247124217856","name":"pennbrooke","screen_name":"pennbrooke1","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":1,"listed_count":0,"created_at":"Fri
+ Dec 13 00:56:10 +0000 2019","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":20,"lang":null,"status":{"created_at":"Thu
+ Mar 12 06:57:32 +0000 2020","id":1237996127103811584,"id_str":"1237996127103811584","text":"zammadzammadzammad","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[],"urls":[]},"source":"\u003ca
+ href=\"https:\/\/zammad.com\/\" rel=\"nofollow\"\u003ezammad\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"lv"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"F5F8FA","profile_background_image_url":null,"profile_background_image_url_https":null,"profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none","suspended":false,"needs_phone_verification":false}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:04 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/subscriptions.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="97f965f030c78cf792bd551bd8252d16",
+ oauth_signature="bTbM1ut0%2Bly3dtA6MqArPRq3wYk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585444", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 409
+ message: Conflict
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '66'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544515442211; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_I7zU3t0hJJakpotS4JM6yQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - b195905c1f696c9a9fc408e990adc77d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '130'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":355,"message":"Subscription already exists."}]}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:05 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_subscribes_to.yml b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_subscribes_to.yml
new file mode 100644
index 000000000..c2048b994
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_subscribes_to.yml
@@ -0,0 +1,312 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="cRQcN4SYlNvQmxLERXdkHw0b8WkgopWyZfshYZ0bQ5c",
+ oauth_signature="1QKjkAywyA9C28RyxllXH4I%2B8dk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585562755", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158556275926104897; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_2VPPoqwsc7qTrmUTl7TOqQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - d5c96afbba7d4a8d9767a2520f1014b9
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 00d90bb200263ca8
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=DyhnyQAAAAAA9CNXAAABcSxAexs&oauth_token_secret=ubeISX6MlS1PTPAp8udaQ2yRqHlNWdCf&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 10:05:59 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/access_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="2Wj2SwZSjbQpBx5pgSqAcwXuREAZCW9cYk7IgK79M",
+ oauth_signature="zv4lFCYM8OgJleXMzjSrh6bkzb4%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585442", oauth_token="DyhnyQAAAAAA9CNXAAABcSxAexs", oauth_verifier="15DOeRkjP4JkOSVqULkTKA1SCuIPP105",
+ oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '174'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544330530048; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_r1gFYSkkPVRlfj2/S3iBhA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 4c532e72e52e91a920ec7ede1d738a7d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '437'
+ X-Transaction:
+ - 002d00030028d5ad
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=REDACTED&oauth_token_secret=6Izq6rCcuJs07inPgc7oMVbq0sjLzuxFLcRq2gp5ulJQW&user_id=1205290247124217856&screen_name=pennbrooke1
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:03 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account/verify_credentials.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="d8377bbeda339f59394d528d368c5bd6",
+ oauth_signature="665K11LI%2FY0%2BZrf0AD%2BPJnrehVY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585443", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '1928'
+ Content-Type:
+ - application/json;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544430987067; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - lang=en; Path=/
+ - personalization_id="v1_KepQ+bqW3x/y43slZzYqcA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Access-Level:
+ - read-write-directmessages
+ X-Connection-Hash:
+ - fe7eed972598e46753f044b0f5f1c34e
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '75'
+ X-Rate-Limit-Remaining:
+ - '72'
+ X-Rate-Limit-Reset:
+ - '1585585445'
+ X-Response-Time:
+ - '155'
+ X-Transaction:
+ - 00d3169e00a6aa44
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ - BouncerExempt
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":1205290247124217856,"id_str":"1205290247124217856","name":"pennbrooke","screen_name":"pennbrooke1","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":1,"listed_count":0,"created_at":"Fri
+ Dec 13 00:56:10 +0000 2019","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":20,"lang":null,"status":{"created_at":"Thu
+ Mar 12 06:57:32 +0000 2020","id":1237996127103811584,"id_str":"1237996127103811584","text":"zammadzammadzammad","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[],"urls":[]},"source":"\u003ca
+ href=\"https:\/\/zammad.com\/\" rel=\"nofollow\"\u003ezammad\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"lv"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"F5F8FA","profile_background_image_url":null,"profile_background_image_url_https":null,"profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none","suspended":false,"needs_phone_verification":false}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:04 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/subscriptions.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="97f965f030c78cf792bd551bd8252d16",
+ oauth_signature="bTbM1ut0%2Bly3dtA6MqArPRq3wYk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585444", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 409
+ message: Conflict
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '66'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544515442211; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_I7zU3t0hJJakpotS4JM6yQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - b195905c1f696c9a9fc408e990adc77d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '130'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":355,"message":"Subscription already exists."}]}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:05 GMT
+recorded_with: VCR 4.0.0
diff --git a/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_subscribes_to_webhooks.yml b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_subscribes_to_webhooks.yml
new file mode 100644
index 000000000..c2048b994
--- /dev/null
+++ b/test/data/vcr_cassettes/requests/external_credentials/with_valid_twitter_app_request_token_and_matching_oauth_token_via_params_subscribes_to_webhooks.yml
@@ -0,0 +1,312 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/request_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_callback="https%3A%2F%2Fzammad.example.com%2Fapi%2Fv1%2Fexternal_credentials%2Ftwitter%2Fcallback",
+ oauth_consumer_key="REDACTED", oauth_nonce="cRQcN4SYlNvQmxLERXdkHw0b8WkgopWyZfshYZ0bQ5c",
+ oauth_signature="1QKjkAywyA9C28RyxllXH4I%2B8dk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585562755", oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '129'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 10:05:59 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158556275926104897; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_2VPPoqwsc7qTrmUTl7TOqQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 10:05:59 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - d5c96afbba7d4a8d9767a2520f1014b9
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '179'
+ X-Transaction:
+ - 00d90bb200263ca8
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=DyhnyQAAAAAA9CNXAAABcSxAexs&oauth_token_secret=ubeISX6MlS1PTPAp8udaQ2yRqHlNWdCf&oauth_callback_confirmed=true
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 10:05:59 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/oauth/access_token
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - OAuth gem v0.5.4
+ Content-Length:
+ - '0'
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="2Wj2SwZSjbQpBx5pgSqAcwXuREAZCW9cYk7IgK79M",
+ oauth_signature="zv4lFCYM8OgJleXMzjSrh6bkzb4%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585442", oauth_token="DyhnyQAAAAAA9CNXAAABcSxAexs", oauth_verifier="15DOeRkjP4JkOSVqULkTKA1SCuIPP105",
+ oauth_version="1.0"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Content-Length:
+ - '174'
+ Content-Security-Policy:
+ - default-src 'none'; connect-src 'self'; font-src https://abs.twimg.com https://abs-0.twimg.com
+ data:; frame-src 'self' twitter:; img-src https://abs.twimg.com https://*.twimg.com
+ https://pbs.twimg.com data:; media-src 'none'; object-src 'none'; script-src
+ https://abs.twimg.com https://abs-0.twimg.com https://twitter.com https://mobile.twitter.com;
+ style-src https://abs.twimg.com https://abs-0.twimg.com; report-uri https://twitter.com/i/csp_report?a=NVQWGYLXFVWG6Z3JNY%3D%3D%3D%3D%3D%3D&ro=false;
+ Content-Type:
+ - text/html;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:03 GMT
+ Ml:
+ - S
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544330530048; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_r1gFYSkkPVRlfj2/S3iBhA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:03 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - 4c532e72e52e91a920ec7ede1d738a7d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '437'
+ X-Transaction:
+ - 002d00030028d5ad
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ X-Ua-Compatible:
+ - IE=edge,chrome=1
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: ASCII-8BIT
+ string: oauth_token=REDACTED&oauth_token_secret=6Izq6rCcuJs07inPgc7oMVbq0sjLzuxFLcRq2gp5ulJQW&user_id=1205290247124217856&screen_name=pennbrooke1
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:03 GMT
+- request:
+ method: get
+ uri: https://api.twitter.com/1.1/account/verify_credentials.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="d8377bbeda339f59394d528d368c5bd6",
+ oauth_signature="665K11LI%2FY0%2BZrf0AD%2BPJnrehVY%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585443", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '1928'
+ Content-Type:
+ - application/json;charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:04 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544430987067; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - lang=en; Path=/
+ - personalization_id="v1_KepQ+bqW3x/y43slZzYqcA=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:04 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Status:
+ - 200 OK
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Access-Level:
+ - read-write-directmessages
+ X-Connection-Hash:
+ - fe7eed972598e46753f044b0f5f1c34e
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Rate-Limit-Limit:
+ - '75'
+ X-Rate-Limit-Remaining:
+ - '72'
+ X-Rate-Limit-Reset:
+ - '1585585445'
+ X-Response-Time:
+ - '155'
+ X-Transaction:
+ - 00d3169e00a6aa44
+ X-Twitter-Response-Tags:
+ - BouncerCompliant
+ - BouncerExempt
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":1205290247124217856,"id_str":"1205290247124217856","name":"pennbrooke","screen_name":"pennbrooke1","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":1,"listed_count":0,"created_at":"Fri
+ Dec 13 00:56:10 +0000 2019","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":20,"lang":null,"status":{"created_at":"Thu
+ Mar 12 06:57:32 +0000 2020","id":1237996127103811584,"id_str":"1237996127103811584","text":"zammadzammadzammad","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[],"urls":[]},"source":"\u003ca
+ href=\"https:\/\/zammad.com\/\" rel=\"nofollow\"\u003ezammad\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"lv"},"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"F5F8FA","profile_background_image_url":null,"profile_background_image_url_https":null,"profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none","suspended":false,"needs_phone_verification":false}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:04 GMT
+- request:
+ method: post
+ uri: https://api.twitter.com/1.1/account_activity/all/zammad/subscriptions.json
+ body:
+ encoding: UTF-8
+ string: ''
+ headers:
+ User-Agent:
+ - TwitterRubyGem/6.2.0
+ Authorization:
+ - OAuth oauth_consumer_key="REDACTED", oauth_nonce="97f965f030c78cf792bd551bd8252d16",
+ oauth_signature="bTbM1ut0%2Bly3dtA6MqArPRq3wYk%3D", oauth_signature_method="HMAC-SHA1",
+ oauth_timestamp="1585585444", oauth_token="REDACTED",
+ oauth_version="1.0"
+ Connection:
+ - close
+ Content-Type:
+ - application/x-www-form-urlencoded
+ Host:
+ - api.twitter.com
+ response:
+ status:
+ code: 409
+ message: Conflict
+ headers:
+ Cache-Control:
+ - no-cache, no-store, must-revalidate, pre-check=0, post-check=0
+ Connection:
+ - close
+ Content-Disposition:
+ - attachment; filename=json.json
+ Content-Length:
+ - '66'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Expires:
+ - Tue, 31 Mar 1981 05:00:00 GMT
+ Last-Modified:
+ - Mon, 30 Mar 2020 16:24:05 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - tsa_m
+ Set-Cookie:
+ - guest_id=v1%3A158558544515442211; Max-Age=63072000; Expires=Wed, 30 Mar 2022
+ 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ - personalization_id="v1_I7zU3t0hJJakpotS4JM6yQ=="; Max-Age=63072000; Expires=Wed,
+ 30 Mar 2022 16:24:05 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
+ Strict-Transport-Security:
+ - max-age=631138519
+ X-Connection-Hash:
+ - b195905c1f696c9a9fc408e990adc77d
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Response-Time:
+ - '130'
+ X-Xss-Protection:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"errors":[{"code":355,"message":"Subscription already exists."}]}'
+ http_version:
+ recorded_at: Mon, 30 Mar 2020 16:24:05 GMT
+recorded_with: VCR 4.0.0