-
Notifications
You must be signed in to change notification settings - Fork 172
Expand file tree
/
Copy pathexchange_web_service.rb
More file actions
276 lines (250 loc) · 11.1 KB
/
exchange_web_service.rb
File metadata and controls
276 lines (250 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
=begin
This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=end
module Viewpoint::EWS::SOAP
class ExchangeWebService
include Viewpoint::EWS
include Viewpoint::EWS::SOAP
include Viewpoint::StringUtils
include ExchangeDataServices
include ExchangeNotification
include ExchangeAvailability
include ExchangeUserConfiguration
include ExchangeSynchronization
include ExchangeTimeZones
attr_accessor :server_version, :auto_deepen, :no_auto_deepen_behavior, :connection, :impersonation_type, :impersonation_address
# @param [Viewpoint::EWS::Connection] connection the connection object
# @param [Hash] opts additional options to the web service
# @option opts [String] :server_version what version to target with the
# requests. Must be one of the contants VERSION_2007, VERSION_2007_SP1,
# VERSION_2010, VERSION_2010_SP1, VERSION_2010_SP2, or VERSION_NONE. The
# default is VERSION_2010.
def initialize(connection, opts = {})
super()
@connection = connection
@server_version = opts[:server_version] ? opts[:server_version] : VERSION_2010
@auto_deepen = true
@no_auto_deepen_behavior = :raise
@impersonation_type = ""
@impersonation_address = ""
end
def delete_attachment
action = "#{SOAP_ACTION_PREFIX}/DeleteAttachment"
resp = invoke("#{NS_EWS_MESSAGES}:DeleteAttachment", action) do |delete_attachment|
build_delete_attachment!(delete_attachment)
end
parse_delete_attachment(resp)
end
def create_managed_folder
action = "#{SOAP_ACTION_PREFIX}/CreateManagedFolder"
resp = invoke("#{NS_EWS_MESSAGES}:CreateManagedFolder", action) do |create_managed_folder|
build_create_managed_folder!(create_managed_folder)
end
parse_create_managed_folder(resp)
end
# Retrieves the delegate settings for a specific mailbox.
# @see http://msdn.microsoft.com/en-us/library/bb799735.aspx
#
# @param [String] owner The user that is delegating permissions
def get_delegate(owner)
action = "#{SOAP_ACTION_PREFIX}/GetDelegate"
resp = invoke("#{NS_EWS_MESSAGES}:GetDelegate", action) do |root|
root.set_attr('IncludePermissions', 'true')
build!(root) do
mailbox!(root, {:email_address => {:text => owner}})
end
end
parse_soap_response(resp)
end
# Adds one or more delegates to a principal's mailbox and sets specific access permissions.
# @see http://msdn.microsoft.com/en-us/library/bb856527.aspx
#
# @param [String] owner The user that is delegating permissions
# @param [String] delegate The user that is being given delegate permission
# @param [Hash] permissions A hash of permissions that will be delegated.
# This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
def add_delegate(owner, delegate, permissions)
action = "#{SOAP_ACTION_PREFIX}/AddDelegate"
resp = invoke("#{NS_EWS_MESSAGES}:AddDelegate", action) do |root|
build!(root) do
add_delegate!(owner, delegate, permissions)
end
end
parse_soap_response(resp)
end
# Removes one or more delegates from a user's mailbox.
# @see http://msdn.microsoft.com/en-us/library/bb856564.aspx
#
# @param [String] owner The user that is delegating permissions
# @param [String] delegate The user that is being given delegate permission
def remove_delegate(owner, delegate)
action = "#{SOAP_ACTION_PREFIX}/RemoveDelegate"
resp = invoke("#{NS_EWS_MESSAGES}:RemoveDelegate", action) do |root|
build!(root) do
remove_delegate!(owner, delegate)
end
end
parse_soap_response(resp)
end
# Updates delegate permissions on a principal's mailbox
# @see http://msdn.microsoft.com/en-us/library/bb856529.aspx
#
# @param [String] owner The user that is delegating permissions
# @param [String] delegate The user that is being given delegate permission
# @param [Hash] permissions A hash of permissions that will be delegated.
# This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
def update_delegate(owner, delegate, permissions)
action = "#{SOAP_ACTION_PREFIX}/UpdateDelegate"
resp = invoke("#{NS_EWS_MESSAGES}:UpdateDelegate", action) do |root|
build!(root) do
add_delegate!(owner, delegate, permissions)
end
end
parse_soap_response(resp)
end
# Provides detailed information about the availability of a set of users, rooms, and resources
# within a specified time window.
# @see http://msdn.microsoft.com/en-us/library/aa564001.aspx
# @param [Hash] opts
# @option opts [Hash] :time_zone The TimeZone data
# Example: {:bias => 'UTC offset in minutes',
# :standard_time => {:bias => 480, :time => '02:00:00',
# :day_order => 5, :month => 10, :day_of_week => 'Sunday'},
# :daylight_time => {same options as :standard_time}}
# @option opts [Array<Hash>] :mailbox_data Data for the mailbox to query
# Example: [{:attendee_type => 'Organizer|Required|Optional|Room|Resource',
# :email =>{:name => 'name', :address => 'email', :routing_type => 'SMTP'},
# :exclude_conflicts => true|false }]
# @option opts [Hash] :free_busy_view_options
# Example: {:time_window => {:start_time => DateTime,:end_time => DateTime},
# :merged_free_busy_interval_in_minutes => minute_int,
# :requested_view => None|MergedOnly|FreeBusy|FreeBusyMerged|Detailed
# |DetailedMerged} (optional)
# @option opts [Hash] :suggestions_view_options (optional)
# @todo Finish out :suggestions_view_options
def get_user_availability(opts)
opts = opts.clone
req = build_soap! do |type, builder|
if(type == :header)
else
builder.nbuild.GetUserAvailabilityRequest {|x|
x.parent.default_namespace = @default_ns
builder.time_zone!(opts[:time_zone])
builder.nbuild.MailboxDataArray {
opts[:mailbox_data].each do |mbd|
builder.mailbox_data!(mbd)
end
}
builder.free_busy_view_options!(opts[:free_busy_view_options])
builder.suggestions_view_options!(opts[:suggestions_view_options])
}
end
end
do_soap_request(req, response_class: EwsSoapFreeBusyResponse)
end
# Gets the rooms that are in the specified room distribution list
# @see http://msdn.microsoft.com/en-us/library/aa563465.aspx
# @param [string] roomDistributionList
def get_rooms(roomDistributionList)
req = build_soap! do |type, builder|
if(type == :header)
else
builder.nbuild.GetRooms {|x|
x.parent.default_namespace = @default_ns
builder.room_list!(roomDistributionList)
}
end
end
do_soap_request(req, response_class: EwsSoapRoomResponse)
end
# Gets the room lists that are available within the Exchange organization.
# @see http://msdn.microsoft.com/en-us/library/aa563465.aspx
def get_room_lists
req = build_soap! do |type, builder|
if(type == :header)
else
builder.room_lists!
end
end
do_soap_request(req, response_class: EwsSoapRoomlistResponse)
end
# Resolves a contact's name given an email address.
# @see https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/resolvenames-operation
def resolve_names(name, full_contact_data)
req = build_soap! do |type, builder|
if(type == :header)
else
builder.resolve_names!(name, full_contact_data)
end
end
do_soap_request(req, response_class: EwsSoapResolveNamesResponse)
end
# Send the SOAP request to the endpoint and parse it.
# @param [String] soapmsg an XML formatted string
# @todo make this work for Viewpoint (imported from SPWS)
# @param [Hash] opts misc options
# @option opts [Boolean] :raw_response if true do not parse and return
# the raw response string.
def do_soap_request(soapmsg, opts = {})
@log.debug <<-EOF.gsub(/^ {8}/, '')
Sending SOAP Request:
----------------
#{soapmsg}
----------------
EOF
connection.dispatch(self, soapmsg, opts)
end
# @param [String] response the SOAP response string
# @param [Hash] opts misc options to send to the parser
# @option opts [Class] :response_class the response class
def parse_soap_response(soapmsg, opts = {})
raise EwsError, "Can't parse an empty response. Please check your endpoint." if(soapmsg.nil?)
opts[:response_class] ||= EwsSoapResponse
EwsParser.new(soapmsg).parse(opts)
end
private
# Private Methods (Builders and Parsers)
# Validate or set default values for options parameters.
# @param [Hash] opts The options parameter passed to an EWS operation
# @param [Symbol] key The key in the Hash we are validating
# @param [Boolean] required Whether or not this key is required
# @param [Object] default_val If the key is not required use this as a
# default value for the operation.
def validate_param(opts, key, required, default_val = nil)
if required
raise EwsBadArgumentError, "Required parameter(#{key}) not passed." unless opts.has_key?(key)
opts[key]
else
raise EwsBadArgumentError, "Default value not supplied." unless default_val
opts.has_key?(key) ? opts[key] : default_val
end
end
# Some operations only exist for certain versions of Exchange Server.
# This method should be called with the required version and we'll throw
# an exception of the currently set @server_version does not comply.
def validate_version(exchange_version)
if server_version < exchange_version
msg = 'The operation you are attempting to use is not compatible with'
msg << " your configured Exchange Server version(#{server_version})."
msg << " You must be running at least version (#{exchange_version})."
raise EwsServerVersionError, msg
end
end
# Build the common elements in the SOAP message and yield to any custom elements.
def build_soap!(&block)
opts = { :server_version => server_version, :impersonation_type => impersonation_type, :impersonation_mail => impersonation_address }
opts[:time_zone_context] = @time_zone_context if @time_zone_context
EwsBuilder.new.build!(opts, &block)
end
end # class ExchangeWebService
end # Viewpoint