# Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ require 'rails_helper' RSpec.describe 'Idoit', type: :request do let!(:admin) do create(:admin, groups: Group.all) end let!(:agent) do create(:agent, groups: Group.all) end let!(:customer) do create(:customer) end let!(:token) do 'some_token' end let!(:endpoint) do 'https://idoit.example.com/i-doit/' end def read_message(file) Rails.root.join('test', 'data', 'idoit', "#{file}.json").read end before do Setting.set('idoit_integration', true) Setting.set('idoit_config', { api_token: token, endpoint: endpoint, client_id: '', }) end describe 'request handling' do it 'does unclear urls' do params = { api_token: token, endpoint: endpoint, client_id: '', } authenticated_as(agent) post '/api/v1/integration/idoit/verify', params: params, as: :json expect(response).to have_http_status(:forbidden) expect(json_response).to be_a(Hash) expect(json_response).not_to be_blank expect(json_response['error']).to eq('User authorization failed.') stub_request(:post, "#{endpoint}src/jsonrpc.php") .with(body: "{\"method\":\"cmdb.object_types\",\"params\":{\"apikey\":\"#{token}\"},\"version\":\"2.0\",\"id\":42}") .to_return(status: 200, body: read_message('object_types_response'), headers: {}) params = { api_token: token, endpoint: endpoint, client_id: '', } authenticated_as(admin) post '/api/v1/integration/idoit/verify', params: params, as: :json expect(response).to have_http_status(:ok) expect(json_response).to be_a(Hash) expect(json_response).not_to be_blank expect(json_response['result']).to eq('ok') expect(json_response['response']).to be_truthy expect(json_response['response']['jsonrpc']).to eq('2.0') expect(json_response['response']['result']).to be_truthy params = { api_token: token, endpoint: " #{endpoint}/", client_id: '', } post '/api/v1/integration/idoit/verify', params: params, as: :json expect(response).to have_http_status(:ok) expect(json_response).to be_a(Hash) expect(json_response).not_to be_blank expect(json_response['result']).to eq('ok') expect(json_response['response']).to be_truthy expect(json_response['response']['jsonrpc']).to eq('2.0') expect(json_response['response']['result']).to be_truthy end it 'does list all object types' do stub_request(:post, "#{endpoint}src/jsonrpc.php") .with(body: "{\"method\":\"cmdb.object_types\",\"params\":{\"apikey\":\"#{token}\"},\"version\":\"2.0\",\"id\":42}") .to_return(status: 200, body: read_message('object_types_response'), headers: {}) params = { method: 'cmdb.object_types', } authenticated_as(agent) post '/api/v1/integration/idoit', params: params, as: :json expect(response).to have_http_status(:ok) expect(json_response).to be_a(Hash) expect(json_response).not_to be_blank expect(json_response['result']).to eq('ok') expect(json_response['response']).to be_truthy expect(json_response['response']['jsonrpc']).to eq('2.0') expect(json_response['response']['result']).to be_truthy expect(json_response['response']['result'][0]['id']).to eq('1') expect(json_response['response']['result'][0]['title']).to eq('System service') params = { method: 'cmdb.object_types', } authenticated_as(admin) post '/api/v1/integration/idoit', params: params, as: :json expect(response).to have_http_status(:ok) expect(json_response).to be_a(Hash) expect(json_response).not_to be_blank expect(json_response['result']).to eq('ok') expect(json_response['response']).to be_truthy expect(json_response['response']['jsonrpc']).to eq('2.0') expect(json_response['response']['result']).to be_truthy expect(json_response['response']['result'][0]['id']).to eq('1') expect(json_response['response']['result'][0]['title']).to eq('System service') end it 'does query objects' do stub_request(:post, "#{endpoint}src/jsonrpc.php") .with(body: "{\"method\":\"cmdb.objects\",\"params\":{\"apikey\":\"#{token}\",\"filter\":{\"ids\":[\"33\"]}},\"version\":\"2.0\",\"id\":42}") .to_return(status: 200, body: read_message('object_types_filter_response'), headers: {}) params = { method: 'cmdb.objects', filter: { ids: ['33'] }, } authenticated_as(agent) post '/api/v1/integration/idoit', params: params, as: :json expect(response).to have_http_status(:ok) expect(json_response).to be_a(Hash) expect(json_response).not_to be_blank expect(json_response['result']).to eq('ok') expect(json_response['response']).to be_truthy expect(json_response['response']['jsonrpc']).to eq('2.0') expect(json_response['response']['result']).to be_truthy expect(json_response['response']['result'][0]['id']).to eq('26') expect(json_response['response']['result'][0]['title']).to eq('demo.example.com') expect(json_response['response']['result'][0]['type_title']).to eq('Virtual server') expect(json_response['response']['result'][0]['cmdb_status_title']).to eq('in operation') end end describe 'SSL verification' do describe '.verify' do def request(verify: false) params = { api_token: token, endpoint: endpoint, client_id: '', verify_ssl: verify } authenticated_as(admin) post '/api/v1/integration/idoit/verify', params: params, as: :json expect(response).to have_http_status(:ok) end it 'does verify SSL' do allow(UserAgent).to receive(:get_http) request(verify: true) expect(UserAgent).to have_received(:get_http).with(URI::HTTPS, hash_including(verify_ssl: true)).once end it 'does not verify SSL' do allow(UserAgent).to receive(:get_http) request expect(UserAgent).to have_received(:get_http).with(URI::HTTPS, hash_including(verify_ssl: false)).once end end describe '.query' do def request(verify: false) Setting.set('idoit_config', Setting.get('idoit_config').merge(verify_ssl: verify)) stub_request(:post, "#{endpoint}src/jsonrpc.php") .with(body: "{\"method\":\"cmdb.object_types\",\"params\":{\"apikey\":\"#{token}\"},\"version\":\"2.0\",\"id\":42}") .to_return(status: 200, body: read_message('object_types_response'), headers: {}) params = { method: 'cmdb.objects', filter: { ids: ['33'] }, } authenticated_as(agent) post '/api/v1/integration/idoit', params: params, as: :json expect(response).to have_http_status(:ok) end it 'does verify SSL' do allow(UserAgent).to receive(:get_http) request(verify: true) expect(UserAgent).to have_received(:get_http).with(URI::HTTPS, hash_including(verify_ssl: true)).once end it 'does not verify SSL' do allow(UserAgent).to receive(:get_http) request expect(UserAgent).to have_received(:get_http).with(URI::HTTPS, hash_including(verify_ssl: false)).once end end end end