zm-ruby-client 3.0.1 → 3.1.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 (229) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +96 -0
  3. data/README.md +128 -27
  4. data/VERSION +1 -1
  5. data/lib/zm/client/account/account.rb +12 -19
  6. data/lib/zm/client/account/account_aliases_collection.rb +6 -4
  7. data/lib/zm/client/account/account_dls_membership_collection.rb +4 -3
  8. data/lib/zm/client/account/account_dls_owner_collection.rb +3 -2
  9. data/lib/zm/client/account/account_jsns_builder.rb +10 -10
  10. data/lib/zm/client/account/accounts_collection.rb +27 -16
  11. data/lib/zm/client/ace/ace.rb +3 -6
  12. data/lib/zm/client/ace/ace_jsns_builder.rb +6 -6
  13. data/lib/zm/client/appointment/appointment.rb +32 -14
  14. data/lib/zm/client/appointment/appointment_jsns_builder.rb +5 -5
  15. data/lib/zm/client/appointment/appointment_jsns_initializer.rb +6 -1
  16. data/lib/zm/client/appointment/appointments_collection.rb +12 -9
  17. data/lib/zm/client/backup/backup.rb +5 -2
  18. data/lib/zm/client/backup/backups_collection.rb +3 -2
  19. data/lib/zm/client/base/account_objects_collection.rb +1 -0
  20. data/lib/zm/client/base/account_search_objects_collection.rb +6 -6
  21. data/lib/zm/client/base/admin_objects_collection.rb +60 -7
  22. data/lib/zm/client/base/base_account_jsns_builder.rb +89 -87
  23. data/lib/zm/client/base/base_jsns_builder.rb +3 -3
  24. data/lib/zm/client/base/base_jsns_initializer.rb +20 -15
  25. data/lib/zm/client/base/mailbox_infos_collection.rb +92 -90
  26. data/lib/zm/client/base/mailbox_object.rb +49 -160
  27. data/lib/zm/client/base/mailbox_prefs_collection.rb +54 -52
  28. data/lib/zm/client/base/object.rb +19 -2
  29. data/lib/zm/client/base/objects_collection.rb +10 -10
  30. data/lib/zm/client/base/zimbra_attribute.rb +28 -42
  31. data/lib/zm/client/base/zimbra_attributes_collection.rb +38 -24
  32. data/lib/zm/client/{cluster/batch_request.rb → batch_request.rb} +1 -1
  33. data/lib/zm/client/cluster/cluster.rb +24 -61
  34. data/lib/zm/client/cluster/cluster_config.rb +35 -15
  35. data/lib/zm/client/contact/contact.rb +15 -13
  36. data/lib/zm/client/contact/contact_jsns_builder.rb +9 -6
  37. data/lib/zm/client/contact/contact_jsns_initializer.rb +2 -2
  38. data/lib/zm/client/contact/contact_member.rb +3 -3
  39. data/lib/zm/client/contact/contact_members_collection.rb +3 -3
  40. data/lib/zm/client/contact/contacts_builder.rb +1 -1
  41. data/lib/zm/client/contact/contacts_collection.rb +2 -2
  42. data/lib/zm/client/contact/group_contact_jsns_builder.rb +18 -14
  43. data/lib/zm/client/contact/mod_group_contact.rb +12 -8
  44. data/lib/zm/client/cos/cos.rb +15 -31
  45. data/lib/zm/client/cos/cos_jsns_builder.rb +21 -21
  46. data/lib/zm/client/cos/coses_collection.rb +11 -6
  47. data/lib/zm/client/datasource/datasource.rb +3 -9
  48. data/lib/zm/client/datasource/datasource_jsns_builder.rb +4 -4
  49. data/lib/zm/client/datasource/datasources_builder.rb +1 -1
  50. data/lib/zm/client/datasource/datasources_collection.rb +2 -2
  51. data/lib/zm/client/deprecated_constants.rb +36 -0
  52. data/lib/zm/client/distributionlist/distributionlist.rb +15 -47
  53. data/lib/zm/client/distributionlist/distributionlist_aces_collection.rb +4 -4
  54. data/lib/zm/client/distributionlist/distributionlist_aliases_collection.rb +7 -5
  55. data/lib/zm/client/distributionlist/distributionlist_jsns_builder.rb +29 -41
  56. data/lib/zm/client/distributionlist/distributionlist_jsns_initializer.rb +14 -3
  57. data/lib/zm/client/distributionlist/distributionlist_members_collection.rb +14 -10
  58. data/lib/zm/client/distributionlist/distributionlist_owners_collection.rb +13 -13
  59. data/lib/zm/client/distributionlist/distributionlists_collection.rb +15 -7
  60. data/lib/zm/client/distributionlist/dls_membership_collection.rb +8 -6
  61. data/lib/zm/client/document/document.rb +5 -11
  62. data/lib/zm/client/document/document_jsns_builder.rb +2 -2
  63. data/lib/zm/client/document/documents_collection.rb +4 -4
  64. data/lib/zm/client/domain/domain.rb +8 -25
  65. data/lib/zm/client/domain/domain_jsns_builder.rb +13 -13
  66. data/lib/zm/client/domain/domains_collection.rb +13 -6
  67. data/lib/zm/client/filter_rules/filter_rules_collection.rb +1 -1
  68. data/lib/zm/client/filter_rules/outgoing_filter_rules_collection.rb +1 -1
  69. data/lib/zm/client/folder/folder.rb +34 -21
  70. data/lib/zm/client/folder/folder_default.rb +39 -0
  71. data/lib/zm/client/folder/folder_grant_jsns_builder.rb +3 -3
  72. data/lib/zm/client/folder/folder_grants_collection.rb +1 -1
  73. data/lib/zm/client/folder/folder_jsns_builder.rb +12 -12
  74. data/lib/zm/client/folder/folder_jsns_initializer.rb +1 -1
  75. data/lib/zm/client/folder/folder_retention_policies_collection.rb +6 -2
  76. data/lib/zm/client/folder/folder_view.rb +15 -0
  77. data/lib/zm/client/folder/folders_jsns_builder.rb +1 -1
  78. data/lib/zm/client/folder/mod_document_folder.rb +16 -12
  79. data/lib/zm/client/identity/identities_collection.rb +1 -1
  80. data/lib/zm/client/identity/identity.rb +3 -9
  81. data/lib/zm/client/identity/identity_jsns_builder.rb +8 -8
  82. data/lib/zm/client/{base/ldap_filter.rb → ldap_filter.rb} +1 -1
  83. data/lib/zm/client/license/licenses_collection.rb +1 -1
  84. data/lib/zm/client/mailbox/mailbox_item_concern.rb +0 -2
  85. data/lib/zm/client/message/message.rb +14 -19
  86. data/lib/zm/client/message/message_attachments_collection.rb +39 -0
  87. data/lib/zm/client/message/message_flags_collection.rb +130 -0
  88. data/lib/zm/client/message/message_jsns_builder.rb +4 -8
  89. data/lib/zm/client/message/message_jsns_initializer.rb +4 -4
  90. data/lib/zm/client/message/message_recipients.rb +19 -43
  91. data/lib/zm/client/message/messages_collection.rb +20 -4
  92. data/lib/zm/client/mountpoint/{mountpoint.rb → mount_point.rb} +4 -10
  93. data/lib/zm/client/mountpoint/{mountpoint_jsns_builder.rb → mount_point_jsns_builder.rb} +3 -3
  94. data/lib/zm/client/mountpoint/{mountpoint_jsns_initializer.rb → mount_point_jsns_initializer.rb} +1 -1
  95. data/lib/zm/client/mountpoint/{mountpoints_builder.rb → mount_points_builder.rb} +1 -1
  96. data/lib/zm/client/mta_queue/mta_queue.rb +4 -16
  97. data/lib/zm/client/mta_queue/mta_queue_action.rb +12 -0
  98. data/lib/zm/client/mta_queue/mta_queue_jsns_builder.rb +7 -7
  99. data/lib/zm/client/mta_queue/mta_queue_name.rb +14 -0
  100. data/lib/zm/client/mta_queue/mta_queues_collection.rb +4 -3
  101. data/lib/zm/client/mta_queue_item/mta_queue_items_collection.rb +1 -0
  102. data/lib/zm/client/recipient.rb +21 -0
  103. data/lib/zm/client/{common/recipients.rb → recipients.rb} +0 -16
  104. data/lib/zm/client/resource/resource.rb +3 -7
  105. data/lib/zm/client/resource/resource_jsns_builder.rb +13 -13
  106. data/lib/zm/client/resource/resources_collection.rb +20 -7
  107. data/lib/zm/client/search_folder/search_folder.rb +4 -11
  108. data/lib/zm/client/search_folder/search_folder_jsns_builder.rb +6 -6
  109. data/lib/zm/client/search_folder/search_folders_collection.rb +1 -1
  110. data/lib/zm/client/server/server.rb +16 -22
  111. data/lib/zm/client/server/server_services.rb +26 -0
  112. data/lib/zm/client/server/servers_collection.rb +6 -6
  113. data/lib/zm/client/share/share.rb +2 -5
  114. data/lib/zm/client/share/shares_builder.rb +1 -1
  115. data/lib/zm/client/share/shares_collection.rb +5 -4
  116. data/lib/zm/client/signature/signature.rb +7 -13
  117. data/lib/zm/client/signature/signature_jsns_builder.rb +13 -13
  118. data/lib/zm/client/signature/signature_jsns_initializer.rb +2 -2
  119. data/lib/zm/client/signature/signatures_collection.rb +1 -1
  120. data/lib/zm/client/tag/account_object_tags_collection.rb +45 -47
  121. data/lib/zm/client/tag/tag.rb +3 -9
  122. data/lib/zm/client/tag/tag_jsns_builder.rb +3 -3
  123. data/lib/zm/client/tag/tags_builder.rb +1 -1
  124. data/lib/zm/client/tag/tags_collection.rb +2 -2
  125. data/lib/zm/client/task/task.rb +2 -2
  126. data/lib/zm/client/task/tasks_collection.rb +2 -2
  127. data/lib/zm/client/token.rb +4 -1
  128. data/lib/zm/client/upload.rb +179 -1
  129. data/lib/zm/client/{common/utils.rb → utils.rb} +6 -3
  130. data/lib/zm/client/zm_logger.rb +1 -1
  131. data/lib/zm/client.rb +227 -10
  132. data/lib/zm/connector/network_error_handler.rb +18 -0
  133. data/lib/zm/{client/connector → connector}/rest_connector.rb +46 -40
  134. data/lib/zm/{client/connector/soap_account.rb → connector/soap_account_connector.rb} +15 -17
  135. data/lib/zm/{client/connector/soap_admin.rb → connector/soap_admin_connector.rb} +3 -5
  136. data/lib/zm/connector/soap_base_connector.rb +115 -0
  137. data/lib/zm/connector.rb +13 -0
  138. data/lib/zm/error/auth_error.rb +8 -0
  139. data/lib/zm/error/connection_error.rb +8 -0
  140. data/lib/zm/error/rest_error.rb +8 -0
  141. data/lib/zm/{client/connector → error}/soap_error.rb +1 -10
  142. data/lib/zm/error/zm_error.rb +8 -0
  143. data/lib/zm/error.rb +11 -0
  144. data/lib/zm/relationship/has_many.rb +22 -0
  145. data/lib/zm/relationship/jsns_builder.rb +21 -0
  146. data/lib/zm/relationship/relationship.rb +113 -0
  147. data/lib/zm/relationship/schema.rb +32 -0
  148. data/lib/zm/relationship.rb +5 -0
  149. data/lib/zm/{client/soap_request → soap_request}/request_methods_admin.rb +11 -5
  150. data/lib/zm/{client/soap_request → soap_request}/request_methods_mailbox.rb +1 -1
  151. data/lib/zm/{client/soap_request/account_soap_constants.rb → soap_request/soap_account_constants.rb} +1 -1
  152. data/lib/zm/{client/soap_request/admin_soap_constants.rb → soap_request/soap_admin_constants.rb} +1 -1
  153. data/lib/zm/{client/soap_request → soap_request}/soap_constants.rb +1 -1
  154. data/lib/zm/{client/soap_request → soap_request}/soap_context.rb +13 -5
  155. data/lib/zm/{client/soap_request → soap_request}/soap_element.rb +1 -1
  156. data/lib/zm/{client/soap_request/mail_soap_constants.rb → soap_request/soap_mail_constants.rb} +1 -1
  157. data/lib/zm/soap_request.rb +14 -0
  158. data/lib/zm/support/cache/entry.rb +3 -3
  159. data/lib/zm/support/cache/file_store.rb +4 -6
  160. data/lib/zm/support/cache/null_store.rb +2 -4
  161. data/lib/zm/support/cache/store.rb +17 -9
  162. data/lib/zm/support/cache.rb +13 -8
  163. data/lib/zm/support.rb +7 -0
  164. data/lib/zm/{modules → utils}/belongs_to_folder.rb +1 -1
  165. data/lib/zm/{modules → utils}/belongs_to_tag.rb +2 -2
  166. data/lib/zm/utils/content_part.rb +9 -0
  167. data/lib/zm/utils/content_type.rb +11 -0
  168. data/lib/zm/{modules → utils}/has_soap_admin_connector.rb +1 -1
  169. data/lib/zm/utils/inspector.rb +26 -0
  170. data/lib/zm/utils/log_filter.rb +30 -0
  171. data/lib/zm/utils/missing_method_static_collection.rb +17 -0
  172. data/lib/zm/utils/regex.rb +11 -0
  173. data/lib/zm/utils/search_utils.rb +13 -0
  174. data/lib/zm/utils.rb +16 -0
  175. data/lib/zm-ruby-client.rb +12 -0
  176. data/sig/zm/client/admin_objects.rbs +261 -0
  177. data/sig/zm/client/base.rbs +191 -0
  178. data/sig/zm/client/cluster.rbs +152 -0
  179. data/sig/zm/client/mailbox.rbs +766 -0
  180. data/sig/zm/error.rbs +23 -0
  181. metadata +99 -91
  182. data/.gitignore +0 -59
  183. data/.rubocop.yml +0 -6
  184. data/.ruby-version +0 -1
  185. data/Gemfile +0 -11
  186. data/SECURITY.md +0 -21
  187. data/bin/console +0 -11
  188. data/lib/zm/client/account.rb +0 -9
  189. data/lib/zm/client/ace.rb +0 -7
  190. data/lib/zm/client/appointment.rb +0 -7
  191. data/lib/zm/client/backup.rb +0 -6
  192. data/lib/zm/client/base.rb +0 -21
  193. data/lib/zm/client/cluster.rb +0 -4
  194. data/lib/zm/client/common/message.rb +0 -10
  195. data/lib/zm/client/common.rb +0 -5
  196. data/lib/zm/client/connector/soap_base.rb +0 -104
  197. data/lib/zm/client/constant.rb +0 -229
  198. data/lib/zm/client/contact.rb +0 -11
  199. data/lib/zm/client/cos.rb +0 -10
  200. data/lib/zm/client/datasource.rb +0 -7
  201. data/lib/zm/client/distributionlist.rb +0 -8
  202. data/lib/zm/client/document.rb +0 -7
  203. data/lib/zm/client/domain.rb +0 -10
  204. data/lib/zm/client/filter_rule.rb +0 -7
  205. data/lib/zm/client/folder.rb +0 -14
  206. data/lib/zm/client/identity.rb +0 -7
  207. data/lib/zm/client/license.rb +0 -5
  208. data/lib/zm/client/message/attachments_collection.rb +0 -55
  209. data/lib/zm/client/message/message_flags.rb +0 -115
  210. data/lib/zm/client/message.rb +0 -10
  211. data/lib/zm/client/mountpoint.rb +0 -7
  212. data/lib/zm/client/mta_queue.rb +0 -7
  213. data/lib/zm/client/mta_queue_item.rb +0 -6
  214. data/lib/zm/client/resource.rb +0 -7
  215. data/lib/zm/client/search_folder.rb +0 -7
  216. data/lib/zm/client/server.rb +0 -7
  217. data/lib/zm/client/share.rb +0 -7
  218. data/lib/zm/client/signature.rb +0 -7
  219. data/lib/zm/client/soap_request.rb +0 -11
  220. data/lib/zm/client/tag.rb +0 -8
  221. data/lib/zm/client/task.rb +0 -6
  222. data/lib/zm/client/upload/upload.rb +0 -160
  223. data/lib/zm/modules/base.rb +0 -9
  224. data/lib/zm/modules/common/zimbra-attrs.json +0 -58
  225. data/lib/zm/modules/inspector.rb +0 -24
  226. data/lib/zm/modules/missing_method_static_collection.rb +0 -13
  227. data/lib/zm/modules/zm_model.rb +0 -43
  228. data/zm-ruby-client.gemspec +0 -27
  229. /data/lib/zm/client/mountpoint/{mountpoints_collection.rb → mount_points_collection.rb} +0 -0
@@ -4,20 +4,17 @@ require 'faraday/multipart'
4
4
  require 'uri'
5
5
 
6
6
  module Zm
7
- module Client
7
+ module Connector
8
8
  class RestConnector
9
+ include NetworkErrorHandler
10
+
9
11
  attr_reader :verbose, :timeout
10
12
  attr_writer :cookies
11
13
 
12
- def initialize(verbose: false, timeout: 300)
14
+ def initialize(verbose: false, timeout: 300, ssl_options: SSL_VERIFY_NONE)
13
15
  @verbose = verbose
14
16
  @timeout = timeout
15
-
16
- @ssl_options = {
17
- verify: false,
18
- verify_hostname: false,
19
- verify_mode: OpenSSL::SSL::VERIFY_NONE
20
- }
17
+ @ssl_options = ssl_options
21
18
 
22
19
  @cookies = nil
23
20
 
@@ -27,41 +24,21 @@ module Zm
27
24
  def download(download_url, dest_file_path)
28
25
  url, path = split_url(download_url)
29
26
 
30
- conn = conn_get(url)
31
-
32
- response = nil
33
-
34
27
  File.open(dest_file_path, 'wb') do |f|
35
- response = conn.get(path) do |request|
36
- request.options.on_data = proc do |chunk, _, _|
37
- f.write chunk
38
- end
39
- end
28
+ stream_get(url, path) { |chunk| f.write(chunk) }
40
29
  end
41
30
 
42
- return unless response.status >= 400
43
-
31
+ nil
32
+ rescue Zm::Error::ConnectionError, Zm::Error::RestError
44
33
  FileUtils.rm_f(dest_file_path)
45
- raise RestError, "Download failure: #{response.body} (status=#{response.status})"
34
+ raise
46
35
  end
47
36
 
48
37
  def read(download_url)
49
38
  url, path = split_url(download_url)
50
39
 
51
- conn = conn_get(url)
52
-
53
40
  data = +''
54
-
55
- response = conn.get(path) do |request|
56
- request.options.on_data = Proc.new do |chunk, _, _|
57
- data.concat(chunk)
58
- end
59
- end
60
-
61
- if response.status >= 400
62
- raise RestError, "Download failure: #{response.body} (status=#{response.status})"
63
- end
64
-
41
+ stream_get(url, path) { |chunk| data.concat(chunk) }
65
42
  data
66
43
  end
67
44
 
@@ -70,20 +47,49 @@ module Zm
70
47
 
71
48
  conn = Faraday.new(**http_options(url)) do |faraday|
72
49
  faraday.request :multipart
73
- faraday.response :logger, nil, { headers: true, bodies: true, errors: true } if @verbose
50
+ add_logger(faraday)
74
51
  end
75
52
 
76
53
  payload = { file: Faraday::Multipart::FilePart.new(src_file_path, nil) }
77
- response = conn.post(path, payload)
54
+ response = handle_network_errors { conn.post(path, payload) }
78
55
 
79
56
  upload_return(response, failure_message: "Upload failure ! #{src_file_path}")
80
57
  end
81
58
 
82
59
  private
83
60
 
61
+ def stream_get(url, path)
62
+ error_body = +''
63
+
64
+ response = handle_network_errors do
65
+ conn_get(url).get(path) do |request|
66
+ request.options.on_data = proc do |chunk, _, env|
67
+ env.status.to_i >= 400 ? error_body.concat(chunk) : yield(chunk)
68
+ end
69
+ end
70
+ end
71
+
72
+ return response if response.status < 400
73
+
74
+ raise Zm::Error::RestError, download_failure_message(response, error_body)
75
+ end
76
+
77
+ def download_failure_message(response, error_body)
78
+ body = error_body.empty? ? response.body.to_s : error_body
79
+ "Download failure: #{extract_title(body) || body[0, 200]} (status=#{response.status})"
80
+ end
81
+
84
82
  def conn_get(url)
85
83
  Faraday.new(**http_options(url)) do |faraday|
86
- faraday.response :logger, nil, { headers: true, bodies: true, errors: true } if @verbose
84
+ add_logger(faraday)
85
+ end
86
+ end
87
+
88
+ def add_logger(faraday)
89
+ return unless @verbose
90
+
91
+ faraday.response(:logger, nil, { headers: true, bodies: true, errors: true }) do |formatter|
92
+ Zm::Utils::LogFilter.apply(formatter)
87
93
  end
88
94
  end
89
95
 
@@ -94,7 +100,7 @@ module Zm
94
100
  extract_title(response.body)
95
101
  ].compact
96
102
 
97
- raise RestError, messages.join("\n")
103
+ raise Zm::Error::RestError, messages.join("\n")
98
104
  end
99
105
 
100
106
  response.body
@@ -103,7 +109,7 @@ module Zm
103
109
  def split_url(url)
104
110
  uri = URI(url)
105
111
  url = "#{uri.scheme}://#{uri.host}:#{uri.port}"
106
- path = [uri.path, uri.query].join('?')
112
+ path = uri.query ? "#{uri.path}?#{uri.query}" : uri.path
107
113
 
108
114
  [url, path]
109
115
  end
@@ -114,8 +120,8 @@ module Zm
114
120
 
115
121
  def http_options(url)
116
122
  {
117
- url: url,
118
- headers: headers,
123
+ url:,
124
+ headers:,
119
125
  request: {
120
126
  timeout: @timeout
121
127
  },
@@ -1,10 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'soap_base'
4
- require_relative 'soap_error'
5
-
6
3
  module Zm
7
- module Client
4
+ module Connector
8
5
  class SoapAccountConnector < SoapBaseConnector
9
6
  class << self
10
7
  def create(config)
@@ -14,6 +11,7 @@ module Zm
14
11
  trans.logger = config.logger
15
12
  trans.cache = config.cache
16
13
  trans.timeout = config.timeout
14
+ trans.ssl_options = config.ssl_options
17
15
  end
18
16
  end
19
17
  end
@@ -27,32 +25,32 @@ module Zm
27
25
  end
28
26
 
29
27
  def initialize(url)
30
- super(url, SoapAccountConstants::ACCOUNT_SERVICE_URI)
28
+ super(url, SoapRequest::SoapAccountConstants::ACCOUNT_SERVICE_URI)
31
29
  end
32
30
 
33
31
  def auth_preauth(content, by, expires, domainkey)
34
32
  ts = (Time.now.to_i * 1000)
35
33
  preauth = compute_preauth(content, by, ts, expires, domainkey)
36
34
 
37
- soap_request = SoapElement.account(SoapAccountConstants::AUTH_REQUEST)
38
- node_account = SoapElement.create(SoapConstants::ACCOUNT)
39
- .add_attribute(SoapConstants::BY, by)
40
- .add_content(content)
35
+ soap_request = SoapRequest::SoapElement.account(Zm::SoapRequest::SoapAccountConstants::AUTH_REQUEST)
36
+ node_account = SoapRequest::SoapElement.create(SoapRequest::SoapConstants::ACCOUNT)
37
+ .add_attribute(SoapRequest::SoapConstants::BY, by)
38
+ .add_content(content)
41
39
  soap_request.add_node(node_account)
42
- node_preauth = SoapElement.create(SoapConstants::PREAUTH)
43
- .add_attribute(SoapConstants::TIMESTAMP, ts)
44
- .add_attribute(SoapConstants::EXPIRES, expires)
45
- .add_content(preauth)
40
+ node_preauth = SoapRequest::SoapElement.create(SoapRequest::SoapConstants::PREAUTH)
41
+ .add_attribute(SoapRequest::SoapConstants::TIMESTAMP, ts)
42
+ .add_attribute(SoapRequest::SoapConstants::EXPIRES, expires)
43
+ .add_content(preauth)
46
44
  soap_request.add_node(node_preauth)
47
45
 
48
46
  do_login(soap_request)
49
47
  end
50
48
 
51
49
  def auth_password(content, by, password)
52
- soap_request = SoapElement.account(SoapAccountConstants::AUTH_REQUEST)
53
- node_account = SoapElement.create(SoapConstants::ACCOUNT)
54
- .add_attribute(SoapConstants::BY, by)
55
- .add_content(content)
50
+ soap_request = SoapRequest::SoapElement.account(Zm::SoapRequest::SoapAccountConstants::AUTH_REQUEST)
51
+ node_account = SoapRequest::SoapElement.create(SoapRequest::SoapConstants::ACCOUNT)
52
+ .add_attribute(SoapRequest::SoapConstants::BY, by)
53
+ .add_content(content)
56
54
  soap_request.add_node(node_account)
57
55
  soap_request.add_attribute('password', password)
58
56
 
@@ -1,10 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'soap_base'
4
- require_relative 'soap_error'
5
-
6
3
  module Zm
7
- module Client
4
+ module Connector
8
5
  class SoapAdminConnector < SoapBaseConnector
9
6
  class << self
10
7
  def create(config)
@@ -14,6 +11,7 @@ module Zm
14
11
  trans.logger = config.logger
15
12
  trans.cache = config.cache
16
13
  trans.timeout = config.timeout
14
+ trans.ssl_options = config.ssl_options
17
15
  end
18
16
  end
19
17
  end
@@ -27,7 +25,7 @@ module Zm
27
25
  end
28
26
 
29
27
  def initialize(url)
30
- super(url, SoapAdminConstants::ADMIN_SERVICE_URI)
28
+ super(url, Zm::SoapRequest::SoapAdminConstants::ADMIN_SERVICE_URI)
31
29
  end
32
30
  end
33
31
  end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Connector
5
+ class SoapBaseConnector
6
+ include NetworkErrorHandler
7
+
8
+ BASESPACE = 'urn:zimbra'
9
+ HTTP_HEADERS = {
10
+ 'Content-Type' => 'application/json; charset=utf-8',
11
+ 'User-Agent' => 'ZmRubyClient'
12
+ }.freeze
13
+ CACHEABLE_REQUEST_REGEX = /\A(?:Get|Search|Count)\w*Request\z/
14
+
15
+ attr_reader :context
16
+ attr_writer :logger, :cache, :timeout, :ssl_options
17
+
18
+ def initialize(url, soap_path)
19
+ @verbose = false
20
+ @timeout = 300
21
+
22
+ @ssl_options = SSL_VERIFY_NONE
23
+
24
+ @url = url
25
+ @soap_path = soap_path
26
+
27
+ @context = Zm::SoapRequest::SoapContext.new
28
+ end
29
+
30
+ def initialize_copy(source)
31
+ super
32
+ @context = @context.dup
33
+ end
34
+
35
+ def verbose!
36
+ @verbose = true
37
+ end
38
+
39
+ def invoke(soap_element, error_handler = Zm::Error::SoapError)
40
+ do_request(envelope(soap_element), error_handler, cacheable: cacheable?(soap_element))[:Body]
41
+ end
42
+
43
+ def target_invoke(soap_element, target_id, error_handler = Zm::Error::SoapError)
44
+ @context.target_server(target_id)
45
+ invoke(soap_element, error_handler)
46
+ ensure
47
+ @context.target_server(nil)
48
+ end
49
+
50
+ def http_client!
51
+ @http_client = Faraday.new(
52
+ url: @url,
53
+ headers: HTTP_HEADERS,
54
+ request: {
55
+ timeout: @timeout
56
+ },
57
+ ssl: @ssl_options
58
+ ) do |faraday|
59
+ faraday.request :json
60
+ if @verbose
61
+ faraday.response(:logger, nil, { headers: true, bodies: true, errors: true }) do |formatter|
62
+ Zm::Utils::LogFilter.apply(formatter)
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def cacheable?(soap_element)
71
+ CACHEABLE_REQUEST_REGEX.match?(soap_element.name)
72
+ end
73
+
74
+ def http_client
75
+ @http_client || http_client!
76
+ end
77
+
78
+ def do_request(body, error_handler = Zm::Error::SoapError, cacheable: false)
79
+ json_body = body.to_json
80
+ @logger.debug { Zm::Utils::LogFilter.filter(json_body) }
81
+
82
+ json_response = if cacheable
83
+ @cache.fetch(json_body) { post(json_body, error_handler) }
84
+ else
85
+ post(json_body, error_handler)
86
+ end
87
+
88
+ JSON.parse(json_response, symbolize_names: true)
89
+ end
90
+
91
+ def post(json_body, error_handler)
92
+ @logger.debug 'Load from remote'
93
+ response = handle_network_errors { http_client.post(@soap_path, json_body) }
94
+ @logger.debug { Zm::Utils::LogFilter.filter(response.body) }
95
+
96
+ raise(error_handler, error_body(response)) if response.status >= 400
97
+
98
+ response.body
99
+ end
100
+
101
+ def error_body(response)
102
+ JSON.parse(response.body, symbolize_names: true)
103
+ rescue JSON::ParserError, TypeError
104
+ { Body: { Fault: { Reason: { Text: "HTTP #{response.status}" }, Detail: { Error: { Code: 'HTTP_ERROR' } } } } }
105
+ end
106
+
107
+ def envelope(soap_element)
108
+ {
109
+ Body: soap_element.to_hash,
110
+ Header: { context: context.to_hash, _jsns: BASESPACE }
111
+ }
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Connector
5
+ SSL_VERIFY_NONE = { verify: false, verify_hostname: false, verify_mode: OpenSSL::SSL::VERIFY_NONE }.freeze
6
+
7
+ autoload :SoapBaseConnector, 'zm/connector/soap_base_connector'
8
+ autoload :SoapAdminConnector, 'zm/connector/soap_admin_connector'
9
+ autoload :SoapAccountConnector, 'zm/connector/soap_account_connector'
10
+ autoload :RestConnector, 'zm/connector/rest_connector'
11
+ autoload :NetworkErrorHandler, 'zm/connector/network_error_handler'
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Error
5
+ class AuthError < SoapError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Error
5
+ class ConnectionError < ZmError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Error
5
+ class RestError < StandardError
6
+ end
7
+ end
8
+ end
@@ -1,10 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zm
4
- module Client
5
- class ZmError < StandardError
6
- end
7
-
4
+ module Error
8
5
  class SoapError < StandardError
9
6
  attr_reader :reason, :code
10
7
 
@@ -14,11 +11,5 @@ module Zm
14
11
  super("[#{@code}] [#{@reason}]")
15
12
  end
16
13
  end
17
-
18
- class AuthError < SoapError
19
- end
20
-
21
- class RestError < StandardError
22
- end
23
14
  end
24
15
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Error
5
+ class ZmError < StandardError
6
+ end
7
+ end
8
+ end
data/lib/zm/error.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Error
5
+ autoload :ZmError, 'zm/error/zm_error'
6
+ autoload :SoapError, 'zm/error/soap_error'
7
+ autoload :AuthError, 'zm/error/auth_error'
8
+ autoload :RestError, 'zm/error/rest_error'
9
+ autoload :ConnectionError, 'zm/error/connection_error'
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Relationship
5
+ class HasMany
6
+ def initialize(name:, klass:)
7
+ @name = name
8
+ @klass = klass
9
+ end
10
+
11
+ attr_reader :name, :klass
12
+
13
+ def generate_relation_method(buffer = +'')
14
+ buffer <<
15
+ 'def ' << @name.name << "\n" \
16
+ 'return @' << @name.name << ' if defined? @' << @name.name << "\n" \
17
+ '@' << @name.name << ' = ' << @klass.name << '.new(self)' << "\n" \
18
+ "end\n"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Relationship
5
+ class JsnsBuilder
6
+ def initialize(klass:)
7
+ @klass = klass
8
+ end
9
+
10
+ attr_reader :name, :klass
11
+
12
+ def generate_relation_method(buffer = +'')
13
+ buffer <<
14
+ 'def jsns_builder' << "\n" \
15
+ 'return @jsns_builder if defined? @jsns_builder' << "\n" \
16
+ '@jsns_builder = ' << @klass.name << '.new(self)' << "\n" \
17
+ "end\n"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Relationship
5
+ autoload :Schema, 'zm/relationship/schema'
6
+ autoload :HasMany, 'zm/relationship/has_many'
7
+ autoload :JsnsBuilder, 'zm/relationship/jsns_builder'
8
+
9
+ def has_many(name, klass: nil)
10
+ klass ||= find_has_many_klass(name.name)
11
+
12
+ new_relation = __relationship_has_many_class__.new(name:, klass:)
13
+
14
+ relationships << new_relation
15
+ __define_relationship_methods__(new_relation)
16
+ include(__relationship_extension__)
17
+ end
18
+
19
+ def has_jsns_builder(klass: nil)
20
+ klass ||= find_jsns_builder_klass(self.name)
21
+
22
+ new_relation = __relationship_jsns_buidler_class__.new(klass:)
23
+
24
+ relationships << new_relation
25
+ __define_relationship_methods__(new_relation)
26
+ include(__relationship_extension__)
27
+ end
28
+
29
+ def __generate_relationship_methods__(new_relation, buffer = +'')
30
+ buffer << "# frozen_string_philosophal: true\n"
31
+
32
+ new_relation.generate_relation_method(buffer)
33
+
34
+ buffer
35
+ end
36
+
37
+ def relationships
38
+ return @relationships if defined?(@relationships)
39
+
40
+ @relationships = if defined?(superclass) && superclass.is_a?(Zm::Relationship)
41
+ superclass.relationships.dup
42
+ else
43
+ Zm::Relationship::Schema.new
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def find_has_many_klass(name)
50
+ parts = name.split('_').map(&:capitalize)
51
+ parts << 'Collection'
52
+ parts.unshift 'Zm::Client::'
53
+ parts.join.to_sym
54
+ end
55
+
56
+ def find_jsns_builder_klass(name)
57
+ (name.dup << 'JsnsBuilder').to_sym
58
+ end
59
+
60
+ def __relationship_has_many_class__
61
+ Zm::Relationship::HasMany
62
+ end
63
+
64
+ def __relationship_jsns_buidler_class__
65
+ Zm::Relationship::JsnsBuilder
66
+ end
67
+
68
+ def __define_relationship_methods__(new_relation)
69
+ code = __generate_relationship_methods__(new_relation)
70
+ __relationship_extension__.module_eval(code)
71
+ end
72
+
73
+ def __relationship_extension__
74
+ if defined?(@__relationship_extension__)
75
+ @__relationship_extension__
76
+ else
77
+ @__relationship_extension__ = Module.new do
78
+ # def cprop?(property_name, klass)
79
+ # property = self.class.philosophal_properties.properties_index[property_name.to_sym]
80
+ # return false unless property
81
+ #
82
+ # klass = klass.class unless klass.is_a?(Class)
83
+ # property.type == klass
84
+ # end
85
+
86
+ # def philosophal_inspect(light = false)
87
+ # keys_map = philosophal_inspect_map
88
+ #
89
+ # if light
90
+ # keys_map.reject! do |_, v|
91
+ # v.nil? || (v.respond_to?(:empty?) && v.empty?)
92
+ # end
93
+ # end
94
+ #
95
+ # keys_str = keys_map.map { |k, v| [k, v.inspect].join(': ') }.join(', ')
96
+ # "#{self.class}:#{format('0x00%x', (object_id << 1))} #{keys_str}"
97
+ # end
98
+ # alias cprop_inspect philosophal_inspect
99
+
100
+ # def philosophal_inspect_map
101
+ # self.class.philosophal_properties.properties_index.values.to_h do |property|
102
+ # [
103
+ # property.name,
104
+ # send(property.name)
105
+ # ]
106
+ # end
107
+ # end
108
+ # alias cprop_inspect_map philosophal_inspect_map
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ module Relationship
5
+ class Schema
6
+ include Enumerable
7
+
8
+ def initialize(properties_index: {})
9
+ @properties_index = properties_index
10
+ @mutex = Mutex.new
11
+ end
12
+
13
+ attr_reader :properties_index
14
+
15
+ def [](key)
16
+ @properties_index[key]
17
+ end
18
+
19
+ def keys
20
+ @properties_index.keys
21
+ end
22
+
23
+ def <<(value)
24
+ @mutex.synchronize do
25
+ @properties_index[value.name] = value
26
+ end
27
+
28
+ self
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zm
4
+ autoload :Relationship, 'zm/relationship/relationship'
5
+ end