smime_spec.rb 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Integration SMIME', type: :request do
  4. let(:admin) { create(:admin) }
  5. let(:email_address) { 'smime1@example.com' }
  6. before do
  7. authenticated_as(admin)
  8. end
  9. describe '/integration/smime/certificate' do
  10. let(:endpoint) { '/api/v1/integration/smime/certificate' }
  11. let(:certificate_path) do
  12. Rails.root.join("spec/fixtures/files/smime/#{email_address}.crt")
  13. end
  14. let(:certificate_string) do
  15. File.read(certificate_path)
  16. end
  17. context 'POST requests' do
  18. let(:parsed_certificate) { Certificate::X509::SMIME.new(certificate_string) }
  19. it 'adds certificate by string' do
  20. expect do
  21. post endpoint, params: { data: certificate_string }, as: :json
  22. end.to change(SMIMECertificate, :count).by(1)
  23. expect(response).to have_http_status(:ok)
  24. expect(DateTime.parse(json_response['response'][0]['not_after_at'])).to eq(parsed_certificate.not_after)
  25. end
  26. it 'adds certificate by file' do
  27. expect do
  28. post endpoint, params: { file: Rack::Test::UploadedFile.new(certificate_path, 'text/plain', true) }
  29. end.to change(SMIMECertificate, :count).by(1)
  30. expect(response).to have_http_status(:ok)
  31. expect(DateTime.parse(json_response['response'][0]['not_after_at'])).to eq(parsed_certificate.not_after)
  32. end
  33. end
  34. context 'GET requests' do
  35. let!(:certificate) { create(:smime_certificate, fixture: email_address) }
  36. it 'lists certificates' do
  37. get endpoint, as: :json
  38. expect(response).to have_http_status(:ok)
  39. expect(json_response.first.keys).to match_array %w[
  40. id
  41. subject
  42. doc_hash
  43. fingerprint
  44. modulus
  45. not_before_at
  46. not_after_at
  47. raw
  48. private_key
  49. private_key_secret
  50. created_at
  51. updated_at
  52. subject_alternative_name
  53. ]
  54. expect(json_response.first['subject_alternative_name']).to include(email_address)
  55. expect(json_response.any? { |e| e['id'] == certificate.id }).to be true
  56. end
  57. end
  58. context 'DELETE requests' do
  59. let!(:certificate) { create(:smime_certificate, fixture: email_address) }
  60. it 'deletes certificate' do
  61. expect do
  62. delete endpoint, params: { id: certificate.id }, as: :json
  63. end.to change(SMIMECertificate, :count).by(-1)
  64. expect(response).to have_http_status(:ok)
  65. end
  66. end
  67. end
  68. describe '/integration/smime/private_key' do
  69. let(:endpoint) { '/api/v1/integration/smime/private_key' }
  70. context 'POST requests' do
  71. let(:private_path) do
  72. Rails.root.join("spec/fixtures/files/smime/#{email_address}.key")
  73. end
  74. let(:private_string) { File.read(private_path) }
  75. let(:secret) do
  76. Rails.root.join("spec/fixtures/files/smime/#{email_address}.secret").read.strip
  77. end
  78. let!(:certificate) { create(:smime_certificate, fixture: email_address) }
  79. it 'adds by string' do
  80. expect do
  81. post endpoint, params: { data: private_string, secret: secret }, as: :json
  82. end.to change {
  83. certificate.reload
  84. certificate.private_key
  85. }
  86. expect(response).to have_http_status(:ok)
  87. expect(json_response['result']).to eq('ok')
  88. end
  89. it 'adds by file' do
  90. expect do
  91. post endpoint, params: { file: Rack::Test::UploadedFile.new(private_path, 'text/plain', true), secret: secret }
  92. end.to change {
  93. certificate.reload
  94. certificate.private_key
  95. }
  96. expect(response).to have_http_status(:ok)
  97. expect(json_response['result']).to eq('ok')
  98. end
  99. end
  100. context 'DELETE requests' do
  101. let!(:certificate) { create(:smime_certificate, :with_private, fixture: email_address) }
  102. it 'deletes private key' do
  103. expect do
  104. delete endpoint, params: { id: certificate.id }, as: :json
  105. end.to change {
  106. certificate.reload
  107. certificate.private_key
  108. }.to(nil)
  109. expect(response).to have_http_status(:ok)
  110. end
  111. end
  112. end
  113. describe '/integration/smime' do
  114. let(:endpoint) { '/api/v1/integration/smime' }
  115. context 'POST requests' do
  116. let(:system_email_address) { create(:email_address, email: email_address) }
  117. let(:group) { create(:group, email_address: system_email_address) }
  118. let(:search_query) do
  119. {
  120. article: {
  121. to: email_address,
  122. },
  123. ticket: {
  124. group_id: group.id,
  125. },
  126. }
  127. end
  128. context 'certificate not present' do
  129. it 'does not find non existing certificates' do
  130. post endpoint, params: search_query, as: :json
  131. expect(response).to have_http_status(:ok)
  132. expect(json_response['encryption']['success']).to be(false)
  133. expect(json_response['encryption']['comment']).to eq("Can't find S/MIME encryption certificates for: #{email_address}")
  134. expect(json_response['encryption']['commentPlaceholders']).to eq([])
  135. expect(json_response['encryption']['comment']).to include(email_address)
  136. expect(json_response['sign']['success']).to be(false)
  137. expect(json_response['sign']['comment']).to eq('The certificate for %s was not found.')
  138. expect(json_response['sign']['commentPlaceholders']).to eq([email_address])
  139. end
  140. end
  141. context 'certificate present' do
  142. before do
  143. create(:smime_certificate, :with_private, fixture: email_address)
  144. end
  145. it 'finds existing certificate' do
  146. post endpoint, params: search_query, as: :json
  147. expect(response).to have_http_status(:ok)
  148. expect(json_response['encryption']['success']).to be(true)
  149. expect(json_response['encryption']['comment']).to eq('The certificates for %s were found.')
  150. expect(json_response['encryption']['commentPlaceholders']).to eq([email_address])
  151. expect(json_response['sign']['success']).to be(true)
  152. expect(json_response['sign']['comment']).to eq('The certificate for %s was found.')
  153. expect(json_response['sign']['commentPlaceholders']).to eq([email_address])
  154. end
  155. context 'but expired' do
  156. let(:email_address) { 'expiredsmime1@example.com' }
  157. it 'finds existing certificate with comment' do
  158. post endpoint, params: search_query, as: :json
  159. expect(response).to have_http_status(:ok)
  160. expect(json_response['encryption']['success']).to be(false)
  161. expect(json_response['encryption']['comment']).to eq('There were certificates found for %s, but at least one of them is not valid yet or has expired.')
  162. expect(json_response['encryption']['commentPlaceholders']).to eq([email_address])
  163. expect(json_response['sign']['success']).to be(false)
  164. expect(json_response['sign']['comment']).to eq('The certificate for %s was found, but it is not valid yet or has expired.')
  165. expect(json_response['sign']['commentPlaceholders']).to eq([email_address])
  166. end
  167. end
  168. end
  169. end
  170. end
  171. end