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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +96 -0
- data/README.md +128 -27
- data/VERSION +1 -1
- data/lib/zm/client/account/account.rb +12 -19
- data/lib/zm/client/account/account_aliases_collection.rb +6 -4
- data/lib/zm/client/account/account_dls_membership_collection.rb +4 -3
- data/lib/zm/client/account/account_dls_owner_collection.rb +3 -2
- data/lib/zm/client/account/account_jsns_builder.rb +10 -10
- data/lib/zm/client/account/accounts_collection.rb +27 -16
- data/lib/zm/client/ace/ace.rb +3 -6
- data/lib/zm/client/ace/ace_jsns_builder.rb +6 -6
- data/lib/zm/client/appointment/appointment.rb +32 -14
- data/lib/zm/client/appointment/appointment_jsns_builder.rb +5 -5
- data/lib/zm/client/appointment/appointment_jsns_initializer.rb +6 -1
- data/lib/zm/client/appointment/appointments_collection.rb +12 -9
- data/lib/zm/client/backup/backup.rb +5 -2
- data/lib/zm/client/backup/backups_collection.rb +3 -2
- data/lib/zm/client/base/account_objects_collection.rb +1 -0
- data/lib/zm/client/base/account_search_objects_collection.rb +6 -6
- data/lib/zm/client/base/admin_objects_collection.rb +60 -7
- data/lib/zm/client/base/base_account_jsns_builder.rb +89 -87
- data/lib/zm/client/base/base_jsns_builder.rb +3 -3
- data/lib/zm/client/base/base_jsns_initializer.rb +20 -15
- data/lib/zm/client/base/mailbox_infos_collection.rb +92 -90
- data/lib/zm/client/base/mailbox_object.rb +49 -160
- data/lib/zm/client/base/mailbox_prefs_collection.rb +54 -52
- data/lib/zm/client/base/object.rb +19 -2
- data/lib/zm/client/base/objects_collection.rb +10 -10
- data/lib/zm/client/base/zimbra_attribute.rb +28 -42
- data/lib/zm/client/base/zimbra_attributes_collection.rb +38 -24
- data/lib/zm/client/{cluster/batch_request.rb → batch_request.rb} +1 -1
- data/lib/zm/client/cluster/cluster.rb +24 -61
- data/lib/zm/client/cluster/cluster_config.rb +35 -15
- data/lib/zm/client/contact/contact.rb +15 -13
- data/lib/zm/client/contact/contact_jsns_builder.rb +9 -6
- data/lib/zm/client/contact/contact_jsns_initializer.rb +2 -2
- data/lib/zm/client/contact/contact_member.rb +3 -3
- data/lib/zm/client/contact/contact_members_collection.rb +3 -3
- data/lib/zm/client/contact/contacts_builder.rb +1 -1
- data/lib/zm/client/contact/contacts_collection.rb +2 -2
- data/lib/zm/client/contact/group_contact_jsns_builder.rb +18 -14
- data/lib/zm/client/contact/mod_group_contact.rb +12 -8
- data/lib/zm/client/cos/cos.rb +15 -31
- data/lib/zm/client/cos/cos_jsns_builder.rb +21 -21
- data/lib/zm/client/cos/coses_collection.rb +11 -6
- data/lib/zm/client/datasource/datasource.rb +3 -9
- data/lib/zm/client/datasource/datasource_jsns_builder.rb +4 -4
- data/lib/zm/client/datasource/datasources_builder.rb +1 -1
- data/lib/zm/client/datasource/datasources_collection.rb +2 -2
- data/lib/zm/client/deprecated_constants.rb +36 -0
- data/lib/zm/client/distributionlist/distributionlist.rb +15 -47
- data/lib/zm/client/distributionlist/distributionlist_aces_collection.rb +4 -4
- data/lib/zm/client/distributionlist/distributionlist_aliases_collection.rb +7 -5
- data/lib/zm/client/distributionlist/distributionlist_jsns_builder.rb +29 -41
- data/lib/zm/client/distributionlist/distributionlist_jsns_initializer.rb +14 -3
- data/lib/zm/client/distributionlist/distributionlist_members_collection.rb +14 -10
- data/lib/zm/client/distributionlist/distributionlist_owners_collection.rb +13 -13
- data/lib/zm/client/distributionlist/distributionlists_collection.rb +15 -7
- data/lib/zm/client/distributionlist/dls_membership_collection.rb +8 -6
- data/lib/zm/client/document/document.rb +5 -11
- data/lib/zm/client/document/document_jsns_builder.rb +2 -2
- data/lib/zm/client/document/documents_collection.rb +4 -4
- data/lib/zm/client/domain/domain.rb +8 -25
- data/lib/zm/client/domain/domain_jsns_builder.rb +13 -13
- data/lib/zm/client/domain/domains_collection.rb +13 -6
- data/lib/zm/client/filter_rules/filter_rules_collection.rb +1 -1
- data/lib/zm/client/filter_rules/outgoing_filter_rules_collection.rb +1 -1
- data/lib/zm/client/folder/folder.rb +34 -21
- data/lib/zm/client/folder/folder_default.rb +39 -0
- data/lib/zm/client/folder/folder_grant_jsns_builder.rb +3 -3
- data/lib/zm/client/folder/folder_grants_collection.rb +1 -1
- data/lib/zm/client/folder/folder_jsns_builder.rb +12 -12
- data/lib/zm/client/folder/folder_jsns_initializer.rb +1 -1
- data/lib/zm/client/folder/folder_retention_policies_collection.rb +6 -2
- data/lib/zm/client/folder/folder_view.rb +15 -0
- data/lib/zm/client/folder/folders_jsns_builder.rb +1 -1
- data/lib/zm/client/folder/mod_document_folder.rb +16 -12
- data/lib/zm/client/identity/identities_collection.rb +1 -1
- data/lib/zm/client/identity/identity.rb +3 -9
- data/lib/zm/client/identity/identity_jsns_builder.rb +8 -8
- data/lib/zm/client/{base/ldap_filter.rb → ldap_filter.rb} +1 -1
- data/lib/zm/client/license/licenses_collection.rb +1 -1
- data/lib/zm/client/mailbox/mailbox_item_concern.rb +0 -2
- data/lib/zm/client/message/message.rb +14 -19
- data/lib/zm/client/message/message_attachments_collection.rb +39 -0
- data/lib/zm/client/message/message_flags_collection.rb +130 -0
- data/lib/zm/client/message/message_jsns_builder.rb +4 -8
- data/lib/zm/client/message/message_jsns_initializer.rb +4 -4
- data/lib/zm/client/message/message_recipients.rb +19 -43
- data/lib/zm/client/message/messages_collection.rb +20 -4
- data/lib/zm/client/mountpoint/{mountpoint.rb → mount_point.rb} +4 -10
- data/lib/zm/client/mountpoint/{mountpoint_jsns_builder.rb → mount_point_jsns_builder.rb} +3 -3
- data/lib/zm/client/mountpoint/{mountpoint_jsns_initializer.rb → mount_point_jsns_initializer.rb} +1 -1
- data/lib/zm/client/mountpoint/{mountpoints_builder.rb → mount_points_builder.rb} +1 -1
- data/lib/zm/client/mta_queue/mta_queue.rb +4 -16
- data/lib/zm/client/mta_queue/mta_queue_action.rb +12 -0
- data/lib/zm/client/mta_queue/mta_queue_jsns_builder.rb +7 -7
- data/lib/zm/client/mta_queue/mta_queue_name.rb +14 -0
- data/lib/zm/client/mta_queue/mta_queues_collection.rb +4 -3
- data/lib/zm/client/mta_queue_item/mta_queue_items_collection.rb +1 -0
- data/lib/zm/client/recipient.rb +21 -0
- data/lib/zm/client/{common/recipients.rb → recipients.rb} +0 -16
- data/lib/zm/client/resource/resource.rb +3 -7
- data/lib/zm/client/resource/resource_jsns_builder.rb +13 -13
- data/lib/zm/client/resource/resources_collection.rb +20 -7
- data/lib/zm/client/search_folder/search_folder.rb +4 -11
- data/lib/zm/client/search_folder/search_folder_jsns_builder.rb +6 -6
- data/lib/zm/client/search_folder/search_folders_collection.rb +1 -1
- data/lib/zm/client/server/server.rb +16 -22
- data/lib/zm/client/server/server_services.rb +26 -0
- data/lib/zm/client/server/servers_collection.rb +6 -6
- data/lib/zm/client/share/share.rb +2 -5
- data/lib/zm/client/share/shares_builder.rb +1 -1
- data/lib/zm/client/share/shares_collection.rb +5 -4
- data/lib/zm/client/signature/signature.rb +7 -13
- data/lib/zm/client/signature/signature_jsns_builder.rb +13 -13
- data/lib/zm/client/signature/signature_jsns_initializer.rb +2 -2
- data/lib/zm/client/signature/signatures_collection.rb +1 -1
- data/lib/zm/client/tag/account_object_tags_collection.rb +45 -47
- data/lib/zm/client/tag/tag.rb +3 -9
- data/lib/zm/client/tag/tag_jsns_builder.rb +3 -3
- data/lib/zm/client/tag/tags_builder.rb +1 -1
- data/lib/zm/client/tag/tags_collection.rb +2 -2
- data/lib/zm/client/task/task.rb +2 -2
- data/lib/zm/client/task/tasks_collection.rb +2 -2
- data/lib/zm/client/token.rb +4 -1
- data/lib/zm/client/upload.rb +179 -1
- data/lib/zm/client/{common/utils.rb → utils.rb} +6 -3
- data/lib/zm/client/zm_logger.rb +1 -1
- data/lib/zm/client.rb +227 -10
- data/lib/zm/connector/network_error_handler.rb +18 -0
- data/lib/zm/{client/connector → connector}/rest_connector.rb +46 -40
- data/lib/zm/{client/connector/soap_account.rb → connector/soap_account_connector.rb} +15 -17
- data/lib/zm/{client/connector/soap_admin.rb → connector/soap_admin_connector.rb} +3 -5
- data/lib/zm/connector/soap_base_connector.rb +115 -0
- data/lib/zm/connector.rb +13 -0
- data/lib/zm/error/auth_error.rb +8 -0
- data/lib/zm/error/connection_error.rb +8 -0
- data/lib/zm/error/rest_error.rb +8 -0
- data/lib/zm/{client/connector → error}/soap_error.rb +1 -10
- data/lib/zm/error/zm_error.rb +8 -0
- data/lib/zm/error.rb +11 -0
- data/lib/zm/relationship/has_many.rb +22 -0
- data/lib/zm/relationship/jsns_builder.rb +21 -0
- data/lib/zm/relationship/relationship.rb +113 -0
- data/lib/zm/relationship/schema.rb +32 -0
- data/lib/zm/relationship.rb +5 -0
- data/lib/zm/{client/soap_request → soap_request}/request_methods_admin.rb +11 -5
- data/lib/zm/{client/soap_request → soap_request}/request_methods_mailbox.rb +1 -1
- data/lib/zm/{client/soap_request/account_soap_constants.rb → soap_request/soap_account_constants.rb} +1 -1
- data/lib/zm/{client/soap_request/admin_soap_constants.rb → soap_request/soap_admin_constants.rb} +1 -1
- data/lib/zm/{client/soap_request → soap_request}/soap_constants.rb +1 -1
- data/lib/zm/{client/soap_request → soap_request}/soap_context.rb +13 -5
- data/lib/zm/{client/soap_request → soap_request}/soap_element.rb +1 -1
- data/lib/zm/{client/soap_request/mail_soap_constants.rb → soap_request/soap_mail_constants.rb} +1 -1
- data/lib/zm/soap_request.rb +14 -0
- data/lib/zm/support/cache/entry.rb +3 -3
- data/lib/zm/support/cache/file_store.rb +4 -6
- data/lib/zm/support/cache/null_store.rb +2 -4
- data/lib/zm/support/cache/store.rb +17 -9
- data/lib/zm/support/cache.rb +13 -8
- data/lib/zm/support.rb +7 -0
- data/lib/zm/{modules → utils}/belongs_to_folder.rb +1 -1
- data/lib/zm/{modules → utils}/belongs_to_tag.rb +2 -2
- data/lib/zm/utils/content_part.rb +9 -0
- data/lib/zm/utils/content_type.rb +11 -0
- data/lib/zm/{modules → utils}/has_soap_admin_connector.rb +1 -1
- data/lib/zm/utils/inspector.rb +26 -0
- data/lib/zm/utils/log_filter.rb +30 -0
- data/lib/zm/utils/missing_method_static_collection.rb +17 -0
- data/lib/zm/utils/regex.rb +11 -0
- data/lib/zm/utils/search_utils.rb +13 -0
- data/lib/zm/utils.rb +16 -0
- data/lib/zm-ruby-client.rb +12 -0
- data/sig/zm/client/admin_objects.rbs +261 -0
- data/sig/zm/client/base.rbs +191 -0
- data/sig/zm/client/cluster.rbs +152 -0
- data/sig/zm/client/mailbox.rbs +766 -0
- data/sig/zm/error.rbs +23 -0
- metadata +99 -91
- data/.gitignore +0 -59
- data/.rubocop.yml +0 -6
- data/.ruby-version +0 -1
- data/Gemfile +0 -11
- data/SECURITY.md +0 -21
- data/bin/console +0 -11
- data/lib/zm/client/account.rb +0 -9
- data/lib/zm/client/ace.rb +0 -7
- data/lib/zm/client/appointment.rb +0 -7
- data/lib/zm/client/backup.rb +0 -6
- data/lib/zm/client/base.rb +0 -21
- data/lib/zm/client/cluster.rb +0 -4
- data/lib/zm/client/common/message.rb +0 -10
- data/lib/zm/client/common.rb +0 -5
- data/lib/zm/client/connector/soap_base.rb +0 -104
- data/lib/zm/client/constant.rb +0 -229
- data/lib/zm/client/contact.rb +0 -11
- data/lib/zm/client/cos.rb +0 -10
- data/lib/zm/client/datasource.rb +0 -7
- data/lib/zm/client/distributionlist.rb +0 -8
- data/lib/zm/client/document.rb +0 -7
- data/lib/zm/client/domain.rb +0 -10
- data/lib/zm/client/filter_rule.rb +0 -7
- data/lib/zm/client/folder.rb +0 -14
- data/lib/zm/client/identity.rb +0 -7
- data/lib/zm/client/license.rb +0 -5
- data/lib/zm/client/message/attachments_collection.rb +0 -55
- data/lib/zm/client/message/message_flags.rb +0 -115
- data/lib/zm/client/message.rb +0 -10
- data/lib/zm/client/mountpoint.rb +0 -7
- data/lib/zm/client/mta_queue.rb +0 -7
- data/lib/zm/client/mta_queue_item.rb +0 -6
- data/lib/zm/client/resource.rb +0 -7
- data/lib/zm/client/search_folder.rb +0 -7
- data/lib/zm/client/server.rb +0 -7
- data/lib/zm/client/share.rb +0 -7
- data/lib/zm/client/signature.rb +0 -7
- data/lib/zm/client/soap_request.rb +0 -11
- data/lib/zm/client/tag.rb +0 -8
- data/lib/zm/client/task.rb +0 -6
- data/lib/zm/client/upload/upload.rb +0 -160
- data/lib/zm/modules/base.rb +0 -9
- data/lib/zm/modules/common/zimbra-attrs.json +0 -58
- data/lib/zm/modules/inspector.rb +0 -24
- data/lib/zm/modules/missing_method_static_collection.rb +0 -13
- data/lib/zm/modules/zm_model.rb +0 -43
- data/zm-ruby-client.gemspec +0 -27
- /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
|
|
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
|
-
|
|
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
|
-
|
|
43
|
-
|
|
31
|
+
nil
|
|
32
|
+
rescue Zm::Error::ConnectionError, Zm::Error::RestError
|
|
44
33
|
FileUtils.rm_f(dest_file_path)
|
|
45
|
-
raise
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
118
|
-
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
|
|
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
|
-
|
|
40
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
55
|
-
|
|
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
|
|
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
|
data/lib/zm/connector.rb
ADDED
|
@@ -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
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Zm
|
|
4
|
-
module
|
|
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
|
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
|