-
Notifications
You must be signed in to change notification settings - Fork 730
/
channels_email_controller.rb
284 lines (238 loc) · 7.62 KB
/
channels_email_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
class ChannelsEmailController < ApplicationController
prepend_before_action { authentication_check && authorize! }
def index
system_online_service = Setting.get('system_online_service')
account_channel_ids = []
notification_channel_ids = []
email_address_ids = []
not_used_email_address_ids = []
accounts_fixed = []
assets = {}
Channel.order(:id).each do |channel|
if system_online_service && channel.preferences && channel.preferences['online_service_disable']
email_addresses = EmailAddress.where(channel_id: channel.id)
email_addresses.each do |email_address|
accounts_fixed.push email_address
end
next
end
assets = channel.assets(assets)
if channel.area == 'Email::Account'
account_channel_ids.push channel.id
elsif channel.area == 'Email::Notification' && channel.active
notification_channel_ids.push channel.id
end
end
EmailAddress.all.each do |email_address|
next if system_online_service && email_address.preferences && email_address.preferences['online_service_disable']
email_address_ids.push email_address.id
assets = email_address.assets(assets)
if !email_address.channel_id || !email_address.active || !Channel.exists?(id: email_address.channel_id)
not_used_email_address_ids.push email_address.id
end
end
render json: {
accounts_fixed: accounts_fixed,
assets: assets,
account_channel_ids: account_channel_ids,
notification_channel_ids: notification_channel_ids,
email_address_ids: email_address_ids,
not_used_email_address_ids: not_used_email_address_ids,
channel_driver: {
email: EmailHelper.available_driver,
},
config: {
notification_sender: Setting.get('notification_sender'),
}
}
end
def probe
# probe settings based on email and password
result = EmailHelper::Probe.full(
email: params[:email],
password: params[:password],
folder: params[:folder],
)
# verify if user+host already exists
return if result[:result] == 'ok' && account_duplicate?(result)
render json: result
end
def outbound
# verify access
return if params[:channel_id] && !check_access(params[:channel_id])
# connection test
render json: EmailHelper::Probe.outbound(params, params[:email])
end
def inbound
# verify access
return if params[:channel_id] && !check_access(params[:channel_id])
# connection test
result = EmailHelper::Probe.inbound(params)
# check account duplicate
return if account_duplicate?({ setting: { inbound: params } }, params[:channel_id])
render json: result
end
def verify
params.permit!
email = params[:email] || params[:meta][:email]
email = email.downcase
channel_id = params[:channel_id]
# verify access
return if channel_id && !check_access(channel_id)
# check account duplicate
return if account_duplicate?({ setting: { inbound: params[:inbound] } }, channel_id)
# check delivery for 30 sec.
result = EmailHelper::Verify.email(
outbound: params[:outbound].to_h,
inbound: params[:inbound].to_h,
sender: email,
subject: params[:subject],
)
if result[:result] != 'ok'
render json: result
return
end
# fallback
if !params[:group_id]
params[:group_id] = Group.first.id
end
# update account
if channel_id
channel = Channel.find(channel_id)
channel.update!(
options: {
inbound: params[:inbound].to_h,
outbound: params[:outbound].to_h,
},
group_id: params[:group_id],
last_log_in: nil,
last_log_out: nil,
status_in: 'ok',
status_out: 'ok',
)
render json: result
return
end
# create new account
channel = Channel.create(
area: 'Email::Account',
options: {
inbound: params[:inbound].to_h,
outbound: params[:outbound].to_h,
},
group_id: params[:group_id],
last_log_in: nil,
last_log_out: nil,
status_in: 'ok',
status_out: 'ok',
active: true,
)
# remember address && set channel for email address
address = EmailAddress.find_by(email: email)
# on initial setup, use placeholder email address
if Channel.count == 1
address = EmailAddress.first
end
if address
address.update!(
realname: params[:meta][:realname],
email: email,
active: true,
channel_id: channel.id,
)
else
EmailAddress.create(
realname: params[:meta][:realname],
email: email,
active: true,
channel_id: channel.id,
)
end
render json: result
end
def enable
channel = Channel.find_by(id: params[:id], area: 'Email::Account')
channel.active = true
channel.save!
render json: {}
end
def disable
channel = Channel.find_by(id: params[:id], area: 'Email::Account')
channel.active = false
channel.save!
render json: {}
end
def destroy
channel = Channel.find_by(id: params[:id], area: 'Email::Account')
channel.destroy
render json: {}
end
def group
check_access
channel = Channel.find_by(id: params[:id], area: 'Email::Account')
channel.group_id = params[:group_id]
channel.save!
render json: {}
end
def notification
params.permit!
check_online_service
adapter = params[:adapter].downcase
email = Setting.get('notification_sender')
# connection test
result = EmailHelper::Probe.outbound(params, email)
# save settings
if result[:result] == 'ok'
Channel.where(area: 'Email::Notification').each do |channel|
active = false
if adapter.match?(/^#{channel.options[:outbound][:adapter]}$/i)
active = true
channel.options = {
outbound: {
adapter: adapter,
options: params[:options].to_h,
},
}
channel.status_out = 'ok'
channel.last_log_out = nil
end
channel.active = active
channel.save
end
end
render json: result
end
private
def account_duplicate?(result, channel_id = nil)
Channel.where(area: 'Email::Account').each do |channel|
next if !channel.options
next if !channel.options[:inbound]
next if !channel.options[:inbound][:adapter]
next if channel.options[:inbound][:adapter] != result[:setting][:inbound][:adapter]
next if channel.options[:inbound][:options][:host] != result[:setting][:inbound][:options][:host]
next if channel.options[:inbound][:options][:user] != result[:setting][:inbound][:options][:user]
next if channel.options[:inbound][:options][:folder].to_s != result[:setting][:inbound][:options][:folder].to_s
next if channel.id.to_s == channel_id.to_s
render json: {
result: 'duplicate',
message: 'Account already exists!',
}
return true
end
false
end
def check_online_service
return true if !Setting.get('system_online_service')
raise Exceptions::Forbidden
end
def check_access(id = nil)
if !id
id = params[:id]
end
return true if !Setting.get('system_online_service')
channel = Channel.find(id)
return true if channel.preferences && !channel.preferences[:online_service_disable]
raise Exceptions::Forbidden
end
end