smime_controller.rb 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. class Integration::SMIMEController < ApplicationController
  3. prepend_before_action { authentication_check && authorize! }
  4. def certificate_download
  5. cert = SMIMECertificate.find(params[:id])
  6. send_data(
  7. cert.raw,
  8. filename: "#{cert.doc_hash}.crt",
  9. type: 'text/plain',
  10. disposition: 'attachment'
  11. )
  12. end
  13. def private_key_download
  14. cert = SMIMECertificate.find(params[:id])
  15. send_data(
  16. cert.private_key,
  17. filename: "#{cert.doc_hash}.key",
  18. type: 'text/plain',
  19. disposition: 'attachment'
  20. )
  21. end
  22. def certificate_list
  23. all = SMIMECertificate.all.map do |cert|
  24. cert.attributes.merge({ 'subject_alternative_name' => cert.email_addresses })
  25. end
  26. render json: all
  27. end
  28. def certificate_delete
  29. SMIMECertificate.find(params[:id]).destroy!
  30. render json: {
  31. result: 'ok',
  32. }
  33. end
  34. def certificate_add
  35. string = params[:data]
  36. if string.blank? && params[:file].present?
  37. string = params[:file].read.force_encoding('utf-8')
  38. end
  39. items = SMIMECertificate.create_certificates(string)
  40. render json: {
  41. result: 'ok',
  42. response: items,
  43. }
  44. rescue => e
  45. unprocessable_entity(e)
  46. end
  47. def private_key_delete
  48. SMIMECertificate.find(params[:id]).update!(
  49. private_key: nil,
  50. private_key_secret: nil,
  51. )
  52. render json: {
  53. result: 'ok',
  54. }
  55. end
  56. def private_key_add
  57. string = params[:data]
  58. if string.blank? && params[:file].present?
  59. string = params[:file].read.force_encoding('utf-8')
  60. end
  61. raise __("Parameter 'data' or 'file' required.") if string.blank?
  62. SMIMECertificate.create_certificates(string)
  63. SMIMECertificate.create_private_keys(string, params[:secret])
  64. render json: {
  65. result: 'ok',
  66. }
  67. rescue => e
  68. unprocessable_entity(e)
  69. end
  70. def search
  71. result = {
  72. type: 'S/MIME',
  73. }
  74. result[:encryption] = article_encryption(params[:article])
  75. result[:sign] = article_sign(params[:ticket])
  76. render json: result
  77. end
  78. def article_encryption(article)
  79. result = {
  80. success: false,
  81. comment: 'no recipient found',
  82. }
  83. return result if article.blank?
  84. return result if article[:to].blank? && article[:cc].blank?
  85. recipient = [ article[:to], article[:cc] ].compact.join(',').to_s
  86. recipients = []
  87. begin
  88. list = Mail::AddressList.new(recipient)
  89. list.addresses.each do |address|
  90. recipients.push address.address
  91. end
  92. rescue # rubocop:disable Lint/SuppressedException
  93. end
  94. return result if recipients.blank?
  95. begin
  96. certs = SMIMECertificate.for_recipipent_email_addresses!(recipients)
  97. if certs
  98. if certs.any?(&:expired?)
  99. result[:success] = false
  100. result[:comment] = "certificates found for #{recipients.join(',')} but expired"
  101. else
  102. result[:success] = true
  103. result[:comment] = "certificates found for #{recipients.join(',')}"
  104. end
  105. end
  106. rescue => e
  107. result[:comment] = e.message
  108. end
  109. result
  110. end
  111. def article_sign(ticket)
  112. result = {
  113. success: false,
  114. comment: 'certificate not found',
  115. }
  116. return result if ticket.blank? || !ticket[:group_id]
  117. group = Group.find_by(id: ticket[:group_id])
  118. return result if !group
  119. email_address = group.email_address
  120. begin
  121. list = Mail::AddressList.new(email_address.email)
  122. from = list.addresses.first.to_s
  123. cert = SMIMECertificate.for_sender_email_address(from)
  124. if cert
  125. if cert.expired?
  126. result[:success] = false
  127. result[:comment] = "certificate for #{email_address.email} found but expired"
  128. else
  129. result[:success] = true
  130. result[:comment] = "certificate for #{email_address.email} found"
  131. end
  132. else
  133. result[:success] = false
  134. result[:comment] = "no certificate for #{email_address.email} found"
  135. end
  136. rescue => e
  137. result[:comment] = e.message
  138. end
  139. result
  140. end
  141. end