zm-ruby-client 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +58 -0
  3. data/Gemfile +8 -0
  4. data/LICENSE +674 -0
  5. data/README.md +47 -0
  6. data/SECURITY.md +21 -0
  7. data/lib/zm/client/account/account.rb +345 -0
  8. data/lib/zm/client/account/account_dls_membership_collection.rb +22 -0
  9. data/lib/zm/client/account/account_dls_owner_collection.rb +22 -0
  10. data/lib/zm/client/account/accounts_builder.rb +19 -0
  11. data/lib/zm/client/account/accounts_collection.rb +48 -0
  12. data/lib/zm/client/account.rb +7 -0
  13. data/lib/zm/client/ace/ace.rb +32 -0
  14. data/lib/zm/client/ace/aces_builder.rb +25 -0
  15. data/lib/zm/client/ace/aces_collection.rb +36 -0
  16. data/lib/zm/client/ace.rb +5 -0
  17. data/lib/zm/client/appointment/appointment.rb +143 -0
  18. data/lib/zm/client/appointment/appointment_jsns_builder.rb +125 -0
  19. data/lib/zm/client/appointment/appointment_jsns_initializer.rb +129 -0
  20. data/lib/zm/client/appointment/appointments_builder.rb +33 -0
  21. data/lib/zm/client/appointment/appointments_collection.rb +106 -0
  22. data/lib/zm/client/appointment.rb +7 -0
  23. data/lib/zm/client/backup/backup.rb +59 -0
  24. data/lib/zm/client/backup/backups_builder.rb +26 -0
  25. data/lib/zm/client/backup/backups_collection.rb +22 -0
  26. data/lib/zm/client/backup.rb +5 -0
  27. data/lib/zm/client/base/account_object.rb +17 -0
  28. data/lib/zm/client/base/admin_object.rb +45 -0
  29. data/lib/zm/client/base/object.rb +80 -0
  30. data/lib/zm/client/base/objects_builder.rb +31 -0
  31. data/lib/zm/client/base/objects_collection.rb +135 -0
  32. data/lib/zm/client/base.rb +7 -0
  33. data/lib/zm/client/cluster/cluster.rb +121 -0
  34. data/lib/zm/client/cluster/cluster_config.rb +100 -0
  35. data/lib/zm/client/cluster.rb +4 -0
  36. data/lib/zm/client/common/message.rb +10 -0
  37. data/lib/zm/client/common/recipients.rb +67 -0
  38. data/lib/zm/client/common/token_metadata.rb +44 -0
  39. data/lib/zm/client/common.rb +5 -0
  40. data/lib/zm/client/config.rb +12 -0
  41. data/lib/zm/client/connector/rest_account.rb +74 -0
  42. data/lib/zm/client/connector/soap_account.rb +563 -0
  43. data/lib/zm/client/connector/soap_admin.rb +532 -0
  44. data/lib/zm/client/connector/soap_base.rb +65 -0
  45. data/lib/zm/client/connector/soap_error.rb +26 -0
  46. data/lib/zm/client/connector/soap_xml_builder.rb +68 -0
  47. data/lib/zm/client/constant.rb +217 -0
  48. data/lib/zm/client/contact/contact.rb +124 -0
  49. data/lib/zm/client/contact/contact_member.rb +73 -0
  50. data/lib/zm/client/contact/contacts_builder.rb +24 -0
  51. data/lib/zm/client/contact/contacts_collection.rb +26 -0
  52. data/lib/zm/client/contact/mod_group_contact.rb +74 -0
  53. data/lib/zm/client/contact.rb +7 -0
  54. data/lib/zm/client/cos/cos.rb +59 -0
  55. data/lib/zm/client/cos/coses_builder.rb +29 -0
  56. data/lib/zm/client/cos/coses_collection.rb +33 -0
  57. data/lib/zm/client/cos.rb +5 -0
  58. data/lib/zm/client/data_source.rb +5 -0
  59. data/lib/zm/client/distributionlist/distributionlist.rb +125 -0
  60. data/lib/zm/client/distributionlist/distributionlists_builder.rb +29 -0
  61. data/lib/zm/client/distributionlist/distributionlists_collection.rb +41 -0
  62. data/lib/zm/client/distributionlist.rb +5 -0
  63. data/lib/zm/client/document/document.rb +51 -0
  64. data/lib/zm/client/document/documents_builder.rb +31 -0
  65. data/lib/zm/client/document/documents_collection.rb +93 -0
  66. data/lib/zm/client/document.rb +5 -0
  67. data/lib/zm/client/domain/domain.rb +85 -0
  68. data/lib/zm/client/domain/domains_builder.rb +32 -0
  69. data/lib/zm/client/domain/domains_collection.rb +36 -0
  70. data/lib/zm/client/domain.rb +5 -0
  71. data/lib/zm/client/folder/folder.rb +215 -0
  72. data/lib/zm/client/folder/folder_grant.rb +58 -0
  73. data/lib/zm/client/folder/folder_retention_policy.rb +48 -0
  74. data/lib/zm/client/folder/folders_builder.rb +58 -0
  75. data/lib/zm/client/folder/folders_collection.rb +95 -0
  76. data/lib/zm/client/folder/mod_document_folder.rb +17 -0
  77. data/lib/zm/client/folder.rb +8 -0
  78. data/lib/zm/client/identity/identities_builder.rb +25 -0
  79. data/lib/zm/client/identity/identities_collection.rb +26 -0
  80. data/lib/zm/client/identity/identity.rb +75 -0
  81. data/lib/zm/client/identity.rb +5 -0
  82. data/lib/zm/client/license/license.rb +29 -0
  83. data/lib/zm/client/license/licenses_collection.rb +28 -0
  84. data/lib/zm/client/license.rb +4 -0
  85. data/lib/zm/client/message/message.rb +225 -0
  86. data/lib/zm/client/message/messages_builder.rb +31 -0
  87. data/lib/zm/client/message/messages_collection.rb +111 -0
  88. data/lib/zm/client/message.rb +5 -0
  89. data/lib/zm/client/mountpoint/mountpoint.rb +95 -0
  90. data/lib/zm/client/mountpoint/mountpoints_builder.rb +38 -0
  91. data/lib/zm/client/mountpoint/mountpoints_collection.rb +61 -0
  92. data/lib/zm/client/mountpoint.rb +5 -0
  93. data/lib/zm/client/mta_queue/mta_queue.rb +60 -0
  94. data/lib/zm/client/mta_queue/mta_queues_builder.rb +26 -0
  95. data/lib/zm/client/mta_queue/mta_queues_collection.rb +95 -0
  96. data/lib/zm/client/mta_queue.rb +5 -0
  97. data/lib/zm/client/mta_queue_item/mta_queue_item.rb +51 -0
  98. data/lib/zm/client/mta_queue_item/mta_queue_items_builder.rb +27 -0
  99. data/lib/zm/client/mta_queue_item/mta_queue_items_collection.rb +99 -0
  100. data/lib/zm/client/mta_queue_item.rb +5 -0
  101. data/lib/zm/client/resource/resource.rb +149 -0
  102. data/lib/zm/client/resource/resources_builder.rb +29 -0
  103. data/lib/zm/client/resource/resources_collection.rb +41 -0
  104. data/lib/zm/client/resource.rb +5 -0
  105. data/lib/zm/client/search_folder/search_folder.rb +63 -0
  106. data/lib/zm/client/search_folder/search_folders_builder.rb +26 -0
  107. data/lib/zm/client/search_folder/search_folders_collection.rb +28 -0
  108. data/lib/zm/client/search_folder.rb +5 -0
  109. data/lib/zm/client/server/server.rb +516 -0
  110. data/lib/zm/client/server/servers_builder.rb +26 -0
  111. data/lib/zm/client/server/servers_collection.rb +37 -0
  112. data/lib/zm/client/server.rb +5 -0
  113. data/lib/zm/client/share/share.rb +60 -0
  114. data/lib/zm/client/share/shares_builder.rb +23 -0
  115. data/lib/zm/client/share/shares_collection.rb +48 -0
  116. data/lib/zm/client/share.rb +5 -0
  117. data/lib/zm/client/signature/signature.rb +62 -0
  118. data/lib/zm/client/signature/signature_jsns_builder.rb +29 -0
  119. data/lib/zm/client/signature/signatures_builder.rb +26 -0
  120. data/lib/zm/client/signature/signatures_collection.rb +28 -0
  121. data/lib/zm/client/signature.rb +6 -0
  122. data/lib/zm/client/tag/tag.rb +45 -0
  123. data/lib/zm/client/tag/tags_builder.rb +25 -0
  124. data/lib/zm/client/tag/tags_collection.rb +26 -0
  125. data/lib/zm/client/tag.rb +5 -0
  126. data/lib/zm/client/task/task.rb +74 -0
  127. data/lib/zm/client/task/tasks_builder.rb +31 -0
  128. data/lib/zm/client/task/tasks_collection.rb +100 -0
  129. data/lib/zm/client/task.rb +5 -0
  130. data/lib/zm/client/upload/upload.rb +154 -0
  131. data/lib/zm/client/upload.rb +3 -0
  132. data/lib/zm/client/version.rb +18 -0
  133. data/lib/zm/client.rb +5 -0
  134. data/lib/zm/modules/common/account_common.rb +71 -0
  135. data/lib/zm/modules/common/cos_common.rb +463 -0
  136. data/lib/zm/modules/common/dl_common.rb +36 -0
  137. data/lib/zm/modules/common/identity_common.rb +19 -0
  138. data/lib/zm/modules/common/resource_common.rb +59 -0
  139. data/lib/zm/modules/common/signature_common.rb +16 -0
  140. data/lib/zm/modules/common/zimbra-attrs.json +1 -0
  141. data/lib/zm/utils/thread_pool.rb +72 -0
  142. data/lib/zm-ruby-client.rb +1 -0
  143. data/test/accounts.rb +62 -0
  144. data/test/cluster_config.rb +30 -0
  145. data/test/coses.rb +26 -0
  146. data/test/domains.rb +70 -0
  147. data/zm-ruby-client.gemspec +24 -0
  148. metadata +244 -0
@@ -0,0 +1,532 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'soap_base'
4
+ require_relative 'soap_error'
5
+ require_relative 'soap_xml_builder'
6
+
7
+ module Zm
8
+ module Client
9
+ class SoapAdminConnector < SoapBaseConnector
10
+
11
+ SOAP_PATH = '/service/admin/soap/'
12
+ ADMINSPACE = 'urn:zimbraAdmin'
13
+ A_NODE_PROC = lambda { |n| { n: n.first, _content: n.last } }
14
+
15
+ attr_accessor :token
16
+
17
+ def initialize(scheme, host, port)
18
+ @verbose = false
19
+ @uri = URI::HTTP.new(scheme, nil, host, port, nil, SOAP_PATH, nil, nil, nil)
20
+ init_curl_client
21
+ end
22
+
23
+ def auth(mail, password)
24
+ body = { Body: { AuthRequest: { _jsns: ADMINSPACE, name: mail, password: password } } }
25
+ res = curl_request(body, AuthError)
26
+ @token = res[BODY][:AuthResponse][:authToken][0][:_content]
27
+ end
28
+
29
+ def noop
30
+ body = init_hash_request(:NoOpRequest)
31
+ curl_request(body)
32
+ end
33
+
34
+ def delegate_auth(name, by = :name, duration = nil)
35
+ req = { duration: duration, account: { by: by, _content: name } }.reject { |_, v| v.nil? }
36
+ body = init_hash_request(:DelegateAuthRequest)
37
+ body[:Body][:DelegateAuthRequest].merge!(req)
38
+ res = curl_request(body)
39
+ res[BODY][:DelegateAuthResponse][:authToken][0][:_content]
40
+ end
41
+
42
+ def get_license
43
+ body = init_hash_request(:GetLicenseRequest)
44
+ curl_request(body)
45
+ end
46
+
47
+ def count_object(type)
48
+ soap_name = :CountObjectsRequest
49
+ body = init_hash_request(soap_name)
50
+ req = { type: type}
51
+ body[:Body][soap_name].merge!(req)
52
+ curl_request(body)
53
+ end
54
+
55
+ def create_gal_sync_account(name, domain_name, type, server_name, folder_name, account_name, attrs = {})
56
+ req = {
57
+ name: name,
58
+ domain: domain_name,
59
+ type: type,
60
+ server: server_name,
61
+ folder: folder_name,
62
+ account: { by: :name, _content: account_name },
63
+ a: attrs.to_a.map(&A_NODE_PROC)
64
+ # a: attrs.to_a.map { |n| { n: n.first, _content: n.last } }
65
+ }.reject { |_, v| v.nil? }
66
+ body = init_hash_request(:CreateGalSyncAccountRequest)
67
+ body[:Body][:CreateGalSyncAccountRequest].merge!(req)
68
+ curl_request(body)
69
+ end
70
+
71
+ def sync_gal_account(gal_account_id, data_source, by = :name, full_sync = 1, reset = 1)
72
+ req = {
73
+ account: {
74
+ id: gal_account_id,
75
+ datasource: {
76
+ by: by,
77
+ fullSync: full_sync,
78
+ reset: reset,
79
+ _content: data_source
80
+ }
81
+ }
82
+ }
83
+ body = init_hash_request(:SyncGalAccountRequest)
84
+ body[:Body][:SyncGalAccountRequest].merge!(req)
85
+ curl_request(body)
86
+ end
87
+
88
+ def get_all_domains
89
+ body = init_hash_request(:GetAllDomainsRequest)
90
+ curl_request(body)
91
+ end
92
+
93
+ def create_data_source(name, account_id, type, attrs = { })
94
+ req = {
95
+ id: account_id,
96
+ dataSource: {
97
+ type: type,
98
+ name: name,
99
+ a: attrs.to_a.map(&A_NODE_PROC)
100
+ # a: attrs.to_a.map { |n| { n: n.first, _content: n.last } }
101
+ }
102
+ }
103
+ body = init_hash_request(:CreateDataSourceRequest)
104
+ body[:Body][:CreateDataSourceRequest].merge!(req)
105
+ curl_request(body)
106
+ end
107
+
108
+ def get_data_sources(id)
109
+ req = { id: id }
110
+ body = init_hash_request(:GetDataSourcesRequest)
111
+ body[:Body][:GetDataSourcesRequest].merge!(req)
112
+ curl_request(body)
113
+ end
114
+
115
+ def delete_data_source(account_id, data_source_id)
116
+ req = { id: account_id, dataSource: { id: data_source_id } }
117
+ body = init_hash_request(:DeleteDataSourceRequest)
118
+ body[:Body][:DeleteDataSourceRequest].merge!(req)
119
+ curl_request(body)
120
+ end
121
+
122
+ def get_all_servers(services = nil)
123
+ req = { service: services }.reject { |_, v| v.nil? }
124
+ body = init_hash_request(:GetAllServersRequest)
125
+ body[:Body][:GetAllServersRequest].merge!(req)
126
+ curl_request(body)
127
+ end
128
+
129
+ def get_server(name, by = :name, attrs = nil)
130
+ req = { server: { by: by, _content: name }, attrs: attrs }
131
+ body = init_hash_request(:GetServerRequest)
132
+ body[:Body][:GetServerRequest].merge!(req)
133
+ curl_request(body)
134
+ end
135
+
136
+ def get_cos(name, by = :name, attrs = nil)
137
+ req = { cos: { by: by, _content: name } }
138
+ req[:attrs] = attrs unless attrs.nil? || attrs.empty?
139
+ body = init_hash_request(:GetCosRequest)
140
+ body[:Body][:GetCosRequest].merge!(req)
141
+ curl_request(body)
142
+ end
143
+
144
+ def create_cos(name, attrs = nil)
145
+ req = { name: name }
146
+ body = init_hash_request(:CreateCosRequest)
147
+ body[:Body][:CreateCosRequest].merge!(req)
148
+ # a: attrs.to_a.map(&A_NODE_PROC)
149
+ # a: attrs.to_a.map { |n| { n: n.first, _content: n.last } }
150
+ # puts SoapXmlBuilder.new(body).to_xml
151
+ # todo ne fonctionne pas !
152
+ curl_xml(SoapXmlBuilder.new(body).to_xml)
153
+ end
154
+
155
+ def modify_cos(id, attrs = nil)
156
+ # req = { _jsns: ADMINSPACE, id: id, a: attrs.to_a.map{ |n| { n: n.first, _content: n.last } } }
157
+ req = { _jsns: ADMINSPACE, id: id }
158
+ body = { Body: { ModifyCosRequest: req } }.merge(hash_header(@token))
159
+ # puts body
160
+ # todo ne fonctionne pas !
161
+ # peut-être seul la version xml fonctionne. Il faudrait créer une fonction qui converti le json en xml
162
+ curl_request(body)
163
+ end
164
+
165
+ def create_account(name, password = nil, attrs = [])
166
+ soap_name = :CreateAccountRequest
167
+ req = { name: name, password: password }.reject { |_, v| v.nil? }
168
+ req[:a] = attrs.map { |i| i.last.is_a?(Array) ? i.last.map{|j|[i.first, j]} : [i] }.flatten(1).map(&A_NODE_PROC)
169
+ # req[:a] = attrs.map{|i|i.last.is_a?(Array) ? i.last.map{|j|[i.first, j]} : [i]}.flatten(1).map { |n| { n: n.first, _content: n.last } }
170
+ body = init_hash_request(soap_name)
171
+ body[:Body][soap_name].merge!(req)
172
+ # puts body
173
+ curl_request(body)
174
+ end
175
+
176
+ def create_resource(name, password = nil, attrs = [])
177
+ soap_name = :CreateCalendarResourceRequest
178
+ req = { name: name, password: password }
179
+ req.reject! { |_, v| v.nil? }
180
+ req[:a] = attrs.map { |i| i.last.is_a?(Array) ? i.last.map{|j|[i.first, j]} : [i] }.flatten(1).map(&A_NODE_PROC)
181
+ body = init_hash_request(soap_name)
182
+ body[:Body][soap_name].merge!(req)
183
+ curl_request(body)
184
+ end
185
+
186
+ def create_distribution_list(name, attrs = [])
187
+ soap_name = :CreateDistributionListRequest
188
+ req = { name: name }
189
+ req[:a] = attrs.map { |i| i.last.is_a?(Array) ? i.last.map{|j|[i.first, j]} : [i] }.flatten(1).map(&A_NODE_PROC)
190
+ body = init_hash_request(soap_name)
191
+ body[:Body][soap_name].merge!(req)
192
+ # puts body
193
+ curl_request(body)
194
+ end
195
+
196
+ def modify_account(id, attrs = [])
197
+ generic_modify(:ModifyAccountRequest, id, attrs)
198
+ end
199
+
200
+ def modify_resource(id, attrs = [])
201
+ generic_modify(:ModifyCalendarResourceRequest, id, attrs)
202
+ end
203
+
204
+ def modify_distribution_list(id, attrs = [])
205
+ generic_modify(:ModifyDistributionListRequest, id, attrs)
206
+ end
207
+
208
+ def generic_modify(soap_name, id, attrs)
209
+ req = {
210
+ id: id,
211
+ a: attrs.map(&A_NODE_PROC)
212
+ }
213
+ body = init_hash_request(soap_name)
214
+ body[:Body][soap_name].merge!(req)
215
+ curl_request(body)
216
+ end
217
+
218
+ def set_password(id, new_password)
219
+ soap_name = :SetPasswordRequest
220
+ req = { id: id, newPassword: new_password }
221
+ body = init_hash_request(soap_name)
222
+ body[:Body][soap_name].merge!(req)
223
+ curl_request(body)
224
+ end
225
+
226
+ def add_account_alias(id, email)
227
+ generic_alias(:AddAccountAliasRequest, id, email)
228
+ end
229
+
230
+ def remove_account_alias(id, email)
231
+ generic_alias(:RemoveAccountAliasRequest, id, email)
232
+ end
233
+
234
+
235
+ def rename_account(id, email)
236
+ generic_rename(:RenameAccountRequest, id, email)
237
+ end
238
+
239
+ def add_distribution_list_members(id, emails)
240
+ generic_members(:AddDistributionListMemberRequest, id, emails)
241
+ end
242
+
243
+ def remove_distribution_list_members(id, emails)
244
+ generic_members(:RemoveDistributionListMemberRequest, id, emails)
245
+ end
246
+
247
+ def generic_members(soap_name, id, emails)
248
+ req = { id: id, dlm: emails.map { |email| {_content: email} } }
249
+ body = init_hash_request(soap_name)
250
+ body[:Body][soap_name].merge!(req)
251
+ curl_request(body)
252
+ end
253
+
254
+ def add_distribution_list_alias(id, email)
255
+ generic_alias(:AddDistributionListAliasRequest, id, email)
256
+ end
257
+
258
+ def remove_distribution_list_alias(id, email)
259
+ generic_alias(:RemoveDistributionListAliasRequest, id, email)
260
+ end
261
+
262
+ def generic_alias(soap_name, id, email)
263
+ req = { id: id, alias: email }
264
+ body = init_hash_request(soap_name)
265
+ body[:Body][soap_name].merge!(req)
266
+ # puts body
267
+ curl_request(body)
268
+ end
269
+
270
+ def rename_distribution_list(id, email)
271
+ generic_rename(:RenameDistributionListRequest, id, email)
272
+ end
273
+
274
+ def generic_rename(soap_name, id, email)
275
+ req = { id: id, newName: email }
276
+ body = init_hash_request(soap_name)
277
+ body[:Body][soap_name].merge!(req)
278
+ curl_request(body)
279
+ end
280
+
281
+ def get_domain(name, by = :name, attrs = nil)
282
+ req = { domain: { by: by, _content: name } }
283
+ req[:_attrs] = attrs unless attrs.nil?
284
+ body = init_hash_request(:GetDomainRequest)
285
+ body[:Body][:GetDomainRequest].merge!(req)
286
+ # TODO: tester param attrs
287
+ # puts body
288
+ curl_request(body)
289
+ end
290
+
291
+ def create_domain(name, attrs = [])
292
+ soap_name = :CreateDomainRequest
293
+ req = {
294
+ name: name,
295
+ a: attrs.map(&A_NODE_PROC)
296
+ }
297
+ body = init_hash_request(soap_name)
298
+ body[:Body][soap_name].merge!(req)
299
+ curl_request(body)
300
+ end
301
+
302
+ def modify_domain(id, attrs = [])
303
+ generic_modify(:ModifyDomainRequest, id, attrs)
304
+ end
305
+
306
+ def get_account(name, by = :name, attrs = nil, applyCos = 1)
307
+ soap_name = :GetAccountRequest
308
+ req = { account: { by: by, _content: name }, applyCos: applyCos }
309
+ req[:attrs] = attrs unless attrs.nil? || attrs.empty?
310
+ body = init_hash_request(soap_name)
311
+ body[:Body][soap_name].merge!(req)
312
+ # puts body
313
+ curl_request(body)
314
+ end
315
+
316
+ def get_account_membership(name, by = :name)
317
+ soap_name = :GetAccountMembershipRequest
318
+ req = { account: { by: by, _content: name } }
319
+ body = init_hash_request(soap_name)
320
+ body[:Body][soap_name].merge!(req)
321
+ curl_request(body)
322
+ end
323
+
324
+ def get_resource(name, by = :name, attrs = nil)
325
+ soap_name = :GetCalendarResourceRequest
326
+ req = { calresource: { by: by, _content: name } }
327
+ req[:attrs] = attrs unless attrs.nil?
328
+ body = init_hash_request(soap_name)
329
+ body[:Body][soap_name].merge!(req)
330
+ # p body
331
+ curl_request(body)
332
+ end
333
+
334
+ def get_distribution_list(name, by = :name, attrs = nil)
335
+ soap_name = :GetDistributionListRequest
336
+ req = { dl: { by: by, _content: name } }
337
+ req[:attrs] = attrs unless attrs.nil?
338
+ body = init_hash_request(soap_name)
339
+ body[:Body][soap_name].merge!(req)
340
+ # p body
341
+ curl_request(body)
342
+ end
343
+
344
+ def delete_account(id)
345
+ generic_delete(:DeleteAccountRequest, id)
346
+ end
347
+
348
+ def delete_resource(id)
349
+ generic_delete(:DeleteCalendarResourceRequest, id)
350
+ end
351
+
352
+ def delete_distribution_list(id)
353
+ generic_delete(:DeleteDistributionListRequest, id)
354
+ end
355
+
356
+ def distribution_list_action(name, by = :name, action = {})
357
+ soap_name = :DistributionListActionRequest
358
+ req = { dl: { by: by, _content: name }, action: action }
359
+ body = init_hash_request(soap_name)
360
+ body[:Body][soap_name][:_jsns] = Zm::Client::SoapAccountConnector::ACCOUNTSPACE
361
+ body[:Body][soap_name].merge!(req)
362
+ # p body
363
+ curl_request(body)
364
+ end
365
+
366
+ def generic_delete(soap_name, id)
367
+ body = init_hash_request(soap_name)
368
+ body[:Body][soap_name][:id] = id
369
+ curl_request(body)
370
+ end
371
+
372
+ def search_directory(query = nil, maxResults = nil, limit = nil, offset = nil, domain = nil, applyCos = nil, applyConfig = nil, sortBy = nil, types = nil, sortAscending = nil, countOnly = nil, attrs = nil)
373
+
374
+ # Désactivé car moins performant !
375
+ # req = Hash[method(__method__).parameters.map{ |p|[p.last, (eval p.last.to_s)] }].select!{ |k,v|!v.nil? }
376
+
377
+ soap_name = :SearchDirectoryRequest
378
+
379
+ req = {
380
+ query: query,
381
+ maxResults: maxResults,
382
+ limit: limit,
383
+ offset: offset,
384
+ domain: domain,
385
+ applyCos: applyCos,
386
+ applyConfig: applyConfig,
387
+ sortBy: sortBy,
388
+ types: types,
389
+ sortAscending: sortAscending,
390
+ countOnly: countOnly,
391
+ attrs: attrs
392
+ }.reject { |_, v| v.nil? }
393
+
394
+ # body = { Body: { SearchDirectoryRequest: { _jsns: ADMINSPACE } } }.merge(hash_header(@token))
395
+ body = init_hash_request(soap_name)
396
+ body[:Body][soap_name].merge!(req)
397
+ # puts body
398
+
399
+ curl_request(body)
400
+ end
401
+
402
+ def get_quota_usage(domain = nil, allServers = nil, limit = nil, offset = nil, sortBy = nil, sortAscending = nil, refresh = nil, target_server_id = nil)
403
+ soap_name = :GetQuotaUsageRequest
404
+ req = {
405
+ domain: domain,
406
+ allServers: allServers,
407
+ limit: limit,
408
+ offset: offset,
409
+ sortBy: sortBy,
410
+ sortAscending: sortAscending,
411
+ refresh: refresh
412
+ }.reject { |_, v| v.nil? }
413
+
414
+ # body = { Body: { GetQuotaUsageRequest: { _jsns: ADMINSPACE } } }.merge(hash_header(@token))
415
+ body = init_hash_request(soap_name, target_server_id)
416
+ body[:Body][soap_name].merge!(req)
417
+ curl_request(body)
418
+ end
419
+
420
+ def get_mailbox(id)
421
+ soap_name = :GetMailboxRequest
422
+ req = {
423
+ mbox: {
424
+ id: id
425
+ }
426
+ }
427
+ body = init_hash_request(soap_name)
428
+ body[:Body][soap_name].merge!(req)
429
+ curl_request(body)
430
+ end
431
+
432
+ def flush_cache(type, all_servers, id = nil)
433
+ soap_name = :FlushCacheRequest
434
+ req = { cache: { type: type, allServers: all_servers } }
435
+ req[:cache].merge!({ entry: { by: :id, _content: id } }) unless id.nil?
436
+ body = init_hash_request(soap_name)
437
+ body[:Body][soap_name].merge!(req)
438
+ curl_request(body)
439
+ end
440
+
441
+ def get_share_info(id)
442
+ soap_name = :GetShareInfoRequest
443
+ req = { owner: { by: :id, _content: id } }
444
+ body = init_hash_request(soap_name)
445
+ body[:Body][soap_name].merge!(req)
446
+ curl_request(body)
447
+ end
448
+
449
+ def move_mailbox(name, src, dest, dest_id)
450
+ soap_name = :MoveMailboxRequest
451
+ req = { account: { name: name, dest: dest, src: src } }
452
+ body = init_hash_request(soap_name, dest_id)
453
+ body[:Body][soap_name].merge!(req)
454
+ curl_request(body)
455
+ end
456
+
457
+ def query_mailbox_move(name, dest_id)
458
+ soap_name = :QueryMailboxMoveRequest
459
+ req = { account: { name: name } }
460
+ body = init_hash_request(soap_name, dest_id)
461
+ body[:Body][soap_name].merge!(req)
462
+ curl_request(body)
463
+ end
464
+
465
+ def get_mail_queue_info(server_name)
466
+ soap_name = :GetMailQueueInfoRequest
467
+ body = init_hash_request(soap_name)
468
+ req = { server: { name: server_name } }
469
+ body[:Body][soap_name].merge!(req)
470
+ # puts body.to_json
471
+ curl_request(body)
472
+ end
473
+
474
+ def get_mail_queue(server_name, queue_name, offset = 0, limit = 1000, fields = {})
475
+ # fields = { fromdomain: 'domain.tld', todomain: 'domain.tld' }
476
+ # AND operator
477
+
478
+ query = {
479
+ offset: offset,
480
+ limit: limit
481
+ }
482
+ query[:field] = fields.map { |k, v| { name: k, match: { value: v } } } unless fields.empty?
483
+ query.reject! { |_, v| v.nil? || v.empty? }
484
+
485
+ soap_name = :GetMailQueueRequest
486
+ body = init_hash_request(soap_name)
487
+ req = {
488
+ server: {
489
+ name: server_name,
490
+ queue: {
491
+ name: queue_name,
492
+ scan: 1,
493
+ query: query
494
+ }
495
+ }
496
+ }
497
+ body[:Body][soap_name].merge!(req)
498
+ # puts body.to_json
499
+ curl_request(body)
500
+ end
501
+
502
+ def mail_queue_action(server_name, queue_name, op, value, by = :id)
503
+ # op: hold|release|delete|requeue
504
+ # by: id|query
505
+ soap_name = :MailQueueActionRequest
506
+ value = [value] unless value.is_a?(Array)
507
+ body = init_hash_request(soap_name)
508
+ req = { server: { name: server_name, queue: { name: queue_name, action: { op: op, by: by, _content: value.join(',') } } } }
509
+ body[:Body][soap_name].merge!(req)
510
+ curl_request(body)
511
+ end
512
+
513
+ def backup_query(dest_id)
514
+ soap_name = :BackupQueryRequest
515
+ body = init_hash_request(soap_name, dest_id)
516
+ req = { query: {} }
517
+ body[:Body][soap_name].merge!(req)
518
+ # puts body
519
+ curl_request(body)
520
+ # curl_xml(SoapXmlBuilder.new(body).to_xml)
521
+ end
522
+
523
+ def init_hash_request(soap_name, target_server = nil)
524
+ {
525
+ Body: {
526
+ soap_name => { _jsns: ADMINSPACE }
527
+ }
528
+ }.merge(hash_header(@token, target_server))
529
+ end
530
+ end
531
+ end
532
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'openssl'
5
+ require 'curb'
6
+ require 'uri'
7
+
8
+ require_relative 'soap_error'
9
+
10
+ module Zm
11
+ module Client
12
+ class SoapBaseConnector
13
+ BASESPACE = 'urn:zimbra'
14
+ HTTP_HEADERS = {
15
+ 'Content-Type' => 'application/json; charset=utf-8'
16
+ }.freeze
17
+ BODY = :Body
18
+
19
+ def verbose!
20
+ @verbose = true
21
+ @curl.verbose = @verbose
22
+ end
23
+
24
+ private
25
+
26
+ def init_curl_client
27
+ @curl = ::Curl::Easy.new(@uri.to_s) do |curl|
28
+ curl.timeout = 300
29
+ curl.enable_cookies = false
30
+ curl.encoding = ''
31
+ curl.headers = HTTP_HEADERS
32
+ curl.ssl_verify_peer = false
33
+ curl.ssl_verify_host = 0
34
+ # curl.verbose = @verbose
35
+ end
36
+ end
37
+
38
+ def curl_request(body, error_handler = SoapError)
39
+ puts body.to_json if @verbose
40
+ @curl.http_post(body.to_json)
41
+
42
+ puts @curl.body_str if @verbose
43
+ soapbody = JSON.parse(@curl.body_str, symbolize_names: true)
44
+ raise(error_handler, soapbody) if @curl.status.to_i >= 400
45
+
46
+ soapbody
47
+ end
48
+
49
+ def curl_xml(xml, error_handler = SoapError)
50
+ # puts xml
51
+ @curl.http_post(xml)
52
+
53
+ soapbody = JSON.parse(@curl.body_str, symbolize_names: true)
54
+ raise(error_handler, soapbody) if @curl.status.to_i >= 400
55
+
56
+ soapbody
57
+ end
58
+
59
+ def hash_header(token, target_server = nil)
60
+ context = { authToken: token, userAgent: { name: :zmsoap }, targetServer: target_server }.delete_if { |_, v| v.nil? }
61
+ { Header: { context: context, _jsns: BASESPACE } }
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Client
5
+ class ZmError < StandardError
6
+ end
7
+
8
+ class SoapError < StandardError
9
+ attr_reader :reason, :code
10
+ def initialize(soapbody)
11
+ @reason = soapbody[:Body][:Fault][:Reason][:Text]
12
+ @code = soapbody[:Body][:Fault][:Detail][:Error][:Code]
13
+ super "[#{@code}] [#{@reason}]"
14
+ end
15
+ end
16
+
17
+ class AuthError < SoapError
18
+ end
19
+
20
+ class RestError < StandardError
21
+ def initialize(restbody)
22
+ super(restbody)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nokogiri'
4
+ # https://stackoverflow.com/questions/11933451/converting-nested-hash-into-xml-using-nokogiri
5
+
6
+ class SoapXmlBuilder
7
+ ATTRS_NODE_PROC = ->(k, _) { k.to_s.start_with?('_') }
8
+
9
+ def initialize(hash)
10
+ @hash = hash
11
+ end
12
+
13
+ def to_xml
14
+ builder = Nokogiri::XML::Builder.new do |xml|
15
+ xml.Envelope('xmlns' => 'http://schemas.xmlsoap.org/soap/envelope/', 'xmlns:urn' => 'urn:zimbra') do
16
+ header(xml)
17
+ body(xml)
18
+ end
19
+ end
20
+ builder.to_xml
21
+ end
22
+
23
+ private
24
+
25
+ def header(xml)
26
+ return unless @hash[:Header]
27
+
28
+ xml.Header do
29
+ xml.context_('xmlns' => 'urn:zimbra') do
30
+ xml.authToken @hash[:Header][:context][:authToken]
31
+ if @hash[:Header][:context][:targetServer]
32
+ xml.targetServer @hash[:Header][:context][:targetServer]
33
+ end
34
+ xml.format('type' => 'js')
35
+ end
36
+ end
37
+ end
38
+
39
+ def body(xml)
40
+ return unless @hash[:Body]
41
+
42
+ xml.Body do
43
+ generate_xml(@hash[:Body], xml)
44
+ end
45
+ end
46
+
47
+ def generate_xml(hash, xml)
48
+ hash.each do |req_name, req_h|
49
+ xml.send(req_name, transform_keys(req_h.select(&ATTRS_NODE_PROC))) do
50
+ req_h.reject(&ATTRS_NODE_PROC).each do |label, value|
51
+ if value.is_a?(Hash)
52
+ generate_xml(value, xml)
53
+ elsif value.is_a?(Array)
54
+ value.each do |el|
55
+ xml.send(label, el.reject(&ATTRS_NODE_PROC), el[:_content])
56
+ end
57
+ else
58
+ xml.send(label, value)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ def transform_keys(hash)
66
+ Hash[hash.map { |k, v| [k.to_s.sub(/\A_/, '').sub('jsns', 'xmlns'), v] }]
67
+ end
68
+ end