microsoft365.rb 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. class ExternalCredential::Microsoft365 < ExternalCredential::MicrosoftBase
  3. def self.channel_area
  4. 'Microsoft365::Account'.freeze
  5. end
  6. def self.error_missing_app_configuration
  7. __('No Microsoft 365 app configured!')
  8. end
  9. def self.authorize_scope
  10. 'https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send offline_access openid profile email'
  11. end
  12. def self.channel_migration_possible?
  13. true
  14. end
  15. def self.channel_options_inbound(user_data, _account_data)
  16. {
  17. adapter: 'imap',
  18. options: {
  19. auth_type: 'XOAUTH2',
  20. host: 'outlook.office365.com',
  21. ssl: 'ssl',
  22. ssl_verify: true,
  23. user: user_data[:preferred_username],
  24. },
  25. }
  26. end
  27. def self.channel_options_outbound(user_data)
  28. {
  29. adapter: 'smtp',
  30. options: {
  31. host: 'smtp.office365.com',
  32. port: 587,
  33. user: user_data[:preferred_username],
  34. authentication: 'xoauth2',
  35. ssl_verify: true
  36. },
  37. }
  38. end
  39. def self.find_migration_channel(user_data)
  40. migrate_channel = nil
  41. Channel.where(area: 'Email::Account').find_each do |channel|
  42. next if channel.options.dig(:inbound, :options, :host)&.downcase != 'outlook.office365.com'
  43. next if channel.options.dig(:outbound, :options, :host)&.downcase != 'smtp.office365.com'
  44. next if channel.options.dig(:outbound, :options, :user)&.downcase != user_data[:preferred_username].downcase && channel.options.dig(:outbound, :email)&.downcase != user_data[:preferred_username].downcase
  45. migrate_channel = channel
  46. break
  47. end
  48. migrate_channel
  49. end
  50. def self.execute_channel_migration(migrate_channel, channel_options)
  51. channel_options[:inbound][:options][:folder] = migrate_channel.options[:inbound][:options][:folder]
  52. channel_options[:inbound][:options][:keep_on_server] = migrate_channel.options[:inbound][:options][:keep_on_server]
  53. backup = {
  54. attributes: {
  55. area: migrate_channel.area,
  56. options: migrate_channel.options,
  57. last_log_in: migrate_channel.last_log_in,
  58. last_log_out: migrate_channel.last_log_out,
  59. status_in: migrate_channel.status_in,
  60. status_out: migrate_channel.status_out,
  61. },
  62. migrated_at: Time.zone.now,
  63. }
  64. migrate_channel.update(
  65. area: channel_area,
  66. options: channel_options.merge(backup_imap_classic: backup),
  67. last_log_in: nil,
  68. last_log_out: nil,
  69. )
  70. migrate_channel
  71. end
  72. end