viewpoint2 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +216 -0
  3. data/lib/ews/calendar_accessors.rb +34 -0
  4. data/lib/ews/connection.rb +130 -0
  5. data/lib/ews/connection_helper.rb +35 -0
  6. data/lib/ews/convert_accessors.rb +56 -0
  7. data/lib/ews/errors.rb +56 -0
  8. data/lib/ews/ews_client.rb +103 -0
  9. data/lib/ews/exceptions/exceptions.rb +61 -0
  10. data/lib/ews/folder_accessors.rb +264 -0
  11. data/lib/ews/impersonation.rb +30 -0
  12. data/lib/ews/item_accessors.rb +231 -0
  13. data/lib/ews/mailbox_accessors.rb +99 -0
  14. data/lib/ews/message_accessors.rb +93 -0
  15. data/lib/ews/push_subscription_accessors.rb +33 -0
  16. data/lib/ews/room_accessors.rb +48 -0
  17. data/lib/ews/roomlist_accessors.rb +47 -0
  18. data/lib/ews/soap.rb +64 -0
  19. data/lib/ews/soap/builders/ews_builder.rb +1351 -0
  20. data/lib/ews/soap/ews_response.rb +84 -0
  21. data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
  22. data/lib/ews/soap/ews_soap_free_busy_response.rb +119 -0
  23. data/lib/ews/soap/ews_soap_response.rb +103 -0
  24. data/lib/ews/soap/ews_soap_room_response.rb +53 -0
  25. data/lib/ews/soap/ews_soap_roomlist_response.rb +54 -0
  26. data/lib/ews/soap/exchange_availability.rb +61 -0
  27. data/lib/ews/soap/exchange_data_services.rb +780 -0
  28. data/lib/ews/soap/exchange_notification.rb +146 -0
  29. data/lib/ews/soap/exchange_synchronization.rb +93 -0
  30. data/lib/ews/soap/exchange_time_zones.rb +56 -0
  31. data/lib/ews/soap/exchange_user_configuration.rb +33 -0
  32. data/lib/ews/soap/exchange_web_service.rb +264 -0
  33. data/lib/ews/soap/parsers/ews_parser.rb +43 -0
  34. data/lib/ews/soap/parsers/ews_sax_document.rb +70 -0
  35. data/lib/ews/soap/response_message.rb +80 -0
  36. data/lib/ews/soap/responses/create_attachment_response_message.rb +47 -0
  37. data/lib/ews/soap/responses/create_item_response_message.rb +25 -0
  38. data/lib/ews/soap/responses/find_item_response_message.rb +80 -0
  39. data/lib/ews/soap/responses/get_events_response_message.rb +53 -0
  40. data/lib/ews/soap/responses/send_notification_response_message.rb +59 -0
  41. data/lib/ews/soap/responses/subscribe_response_message.rb +35 -0
  42. data/lib/ews/soap/responses/sync_folder_hierarchy_response_message.rb +36 -0
  43. data/lib/ews/soap/responses/sync_folder_items_response_message.rb +36 -0
  44. data/lib/ews/templates/calendar_item.rb +79 -0
  45. data/lib/ews/templates/forward_item.rb +24 -0
  46. data/lib/ews/templates/message.rb +76 -0
  47. data/lib/ews/templates/reply_to_item.rb +25 -0
  48. data/lib/ews/templates/task.rb +74 -0
  49. data/lib/ews/types.rb +194 -0
  50. data/lib/ews/types/attachment.rb +77 -0
  51. data/lib/ews/types/attendee.rb +41 -0
  52. data/lib/ews/types/calendar_folder.rb +50 -0
  53. data/lib/ews/types/calendar_item.rb +133 -0
  54. data/lib/ews/types/contact.rb +7 -0
  55. data/lib/ews/types/contacts_folder.rb +8 -0
  56. data/lib/ews/types/copied_event.rb +51 -0
  57. data/lib/ews/types/created_event.rb +24 -0
  58. data/lib/ews/types/deleted_event.rb +24 -0
  59. data/lib/ews/types/distribution_list.rb +7 -0
  60. data/lib/ews/types/event.rb +62 -0
  61. data/lib/ews/types/export_items_response_message.rb +52 -0
  62. data/lib/ews/types/file_attachment.rb +65 -0
  63. data/lib/ews/types/folder.rb +60 -0
  64. data/lib/ews/types/free_busy_changed_event.rb +24 -0
  65. data/lib/ews/types/generic_folder.rb +418 -0
  66. data/lib/ews/types/item.rb +450 -0
  67. data/lib/ews/types/item_attachment.rb +84 -0
  68. data/lib/ews/types/item_field_uri_map.rb +208 -0
  69. data/lib/ews/types/mailbox_user.rb +156 -0
  70. data/lib/ews/types/meeting_cancellation.rb +7 -0
  71. data/lib/ews/types/meeting_message.rb +7 -0
  72. data/lib/ews/types/meeting_request.rb +7 -0
  73. data/lib/ews/types/meeting_response.rb +7 -0
  74. data/lib/ews/types/message.rb +7 -0
  75. data/lib/ews/types/modified_event.rb +48 -0
  76. data/lib/ews/types/moved_event.rb +51 -0
  77. data/lib/ews/types/new_mail_event.rb +24 -0
  78. data/lib/ews/types/out_of_office.rb +147 -0
  79. data/lib/ews/types/post_item.rb +7 -0
  80. data/lib/ews/types/search_folder.rb +8 -0
  81. data/lib/ews/types/status_event.rb +39 -0
  82. data/lib/ews/types/task.rb +104 -0
  83. data/lib/ews/types/tasks_folder.rb +27 -0
  84. data/lib/viewpoint/logging.rb +27 -0
  85. data/lib/viewpoint/logging/config.rb +24 -0
  86. data/lib/viewpoint/string_utils.rb +76 -0
  87. data/lib/viewpoint2.rb +111 -0
  88. metadata +191 -0
@@ -0,0 +1,146 @@
1
+ =begin
2
+ This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ module Viewpoint::EWS::SOAP
20
+
21
+ # Exchange Notification operations as listed in the EWS Documentation.
22
+ # @see http://msdn.microsoft.com/en-us/library/bb409286.aspx
23
+ module ExchangeNotification
24
+ include Viewpoint::EWS::SOAP
25
+
26
+ # Used to subscribe client applications to either push, pull or stream notifications.
27
+ # @see http://msdn.microsoft.com/en-us/library/aa566188(v=EXCHG.140).aspx
28
+ # @param [Array<Hash>] subscriptions An array of Hash objects that describe each
29
+ # subscription.
30
+ # Ex: [ {:pull_subscription_request => {
31
+ # :subscribe_to_all_folders => false,
32
+ # :folder_ids => [ {:id => 'id', :change_key => 'ck'} ],
33
+ # :event_types=> %w{CopiedEvent CreatedEvent},
34
+ # :watermark => 'watermark id',
35
+ # :timeout => intval
36
+ # }},
37
+ # {:push_subscription_request => {
38
+ # :subscribe_to_all_folders => true,
39
+ # :event_types=> %w{CopiedEvent CreatedEvent},
40
+ # :status_frequency => 15,
41
+ # :uRL => 'http://my.endpoint.for.updates/',
42
+ # }},
43
+ # {:streaming_subscription_request => {
44
+ # :subscribe_to_all_folders => false,
45
+ # :folder_ids => [ {:id => 'id', :change_key => 'ck'} ],
46
+ # :event_types=> %w{NewMailEvent DeletedEvent},
47
+ # }},
48
+ # ]
49
+ def subscribe(subscriptions)
50
+ req = build_soap! do |type, builder|
51
+ if(type == :header)
52
+ else
53
+ builder.nbuild.Subscribe {
54
+ builder.nbuild.parent.default_namespace = @default_ns
55
+ subscriptions.each do |sub|
56
+ subtype = sub.keys.first
57
+ if(builder.respond_to?(subtype))
58
+ builder.send subtype, sub[subtype]
59
+ else
60
+ raise EwsBadArgumentError, "Bad subscription type. #{subtype}"
61
+ end
62
+ end
63
+ }
64
+ end
65
+ end
66
+ do_soap_request(req, response_class: EwsResponse)
67
+ end
68
+
69
+ # End a pull notification subscription.
70
+ # @see http://msdn.microsoft.com/en-us/library/aa564263.aspx
71
+ #
72
+ # @param [String] subscription_id The Id of the subscription
73
+ def unsubscribe(subscription_id)
74
+ req = build_soap! do |type, builder|
75
+ if(type == :header)
76
+ else
77
+ builder.nbuild.Unsubscribe {
78
+ builder.nbuild.parent.default_namespace = @default_ns
79
+ builder.subscription_id!(subscription_id)
80
+ }
81
+ end
82
+ end
83
+ do_soap_request(req, response_class: EwsResponse)
84
+ end
85
+
86
+ # Used by pull subscription clients to request notifications from the Client Access server
87
+ # @see http://msdn.microsoft.com/en-us/library/aa566199.aspx GetEvents on MSDN
88
+ #
89
+ # @param [String] subscription_id Subscription identifier
90
+ # @param [String] watermark Event bookmark in the events queue
91
+ def get_events(subscription_id, watermark)
92
+ req = build_soap! do |type, builder|
93
+ if(type == :header)
94
+ else
95
+ builder.nbuild.GetEvents {
96
+ builder.nbuild.parent.default_namespace = @default_ns
97
+ builder.subscription_id!(subscription_id)
98
+ builder.watermark!(watermark, NS_EWS_MESSAGES)
99
+ }
100
+ end
101
+ end
102
+ do_soap_request(req, response_class: EwsResponse)
103
+ end
104
+
105
+
106
+ # ------- convenience methods ------- #
107
+
108
+ # Create a pull subscription to a single folder
109
+ # @param folder [Hash] a hash with the folder :id and :change_key
110
+ # @param evtypes [Array] the events you would like to subscribe to.
111
+ # @param timeout [Fixnum] http://msdn.microsoft.com/en-us/library/aa565201.aspx
112
+ # @param watermark [String] http://msdn.microsoft.com/en-us/library/aa565886.aspx
113
+ def pull_subscribe_folder(folder, evtypes, timeout = nil, watermark = nil)
114
+ timeout ||= 240 # 4 hour default timeout
115
+ psr = {
116
+ :subscribe_to_all_folders => false,
117
+ :folder_ids => [ {:id => folder[:id], :change_key => folder[:change_key]} ],
118
+ :event_types=> evtypes,
119
+ :timeout => timeout
120
+ }
121
+ psr[:watermark] = watermark if watermark
122
+ subscribe([{pull_subscription_request: psr}])
123
+ end
124
+
125
+ # Create a push subscription to a single folder
126
+ # @param folder [Hash] a hash with the folder :id and :change_key
127
+ # @param evtypes [Array] the events you would like to subscribe to.
128
+ # @param url [String,URI] http://msdn.microsoft.com/en-us/library/aa566309.aspx
129
+ # @param watermark [String] http://msdn.microsoft.com/en-us/library/aa565886.aspx
130
+ # @param status_frequency [Fixnum] http://msdn.microsoft.com/en-us/library/aa564048.aspx
131
+ def push_subscribe_folder(folder, evtypes, url, status_frequency = nil, watermark = nil)
132
+ status_frequency ||= 30
133
+ psr = {
134
+ :subscribe_to_all_folders => false,
135
+ :folder_ids => [ {:id => folder[:id], :change_key => folder[:change_key]} ],
136
+ :event_types=> evtypes,
137
+ :status_frequency => status_frequency,
138
+ :uRL => url.to_s
139
+ }
140
+ psr[:watermark] = watermark if watermark
141
+ subscribe([{push_subscription_request: psr}])
142
+ end
143
+
144
+
145
+ end #ExchangeNotification
146
+ end
@@ -0,0 +1,93 @@
1
+ =begin
2
+ This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ module Viewpoint::EWS::SOAP
20
+
21
+ # Exchange Synchronization operations as listed in the EWS Documentation.
22
+ # @see http://msdn.microsoft.com/en-us/library/bb409286.aspx
23
+ module ExchangeSynchronization
24
+ include Viewpoint::EWS::SOAP
25
+
26
+ # Defines a request to synchronize a folder hierarchy on a client
27
+ # @see http://msdn.microsoft.com/en-us/library/aa580990.aspx
28
+ # @param [Hash] opts
29
+ # @option opts [Hash] :folder_shape The folder shape properties
30
+ # Ex: {:base_shape => 'Default', :additional_properties => 'bla bla bla'}
31
+ # @option opts [Hash] :sync_folder_id An optional Hash that represents a FolderId or
32
+ # DistinguishedFolderId.
33
+ # Ex: {:id => :inbox}
34
+ # @option opts [Hash] :sync_state The Base64 sync state id. If this is the
35
+ # first time syncing this does not need to be passed.
36
+ def sync_folder_hierarchy(opts)
37
+ opts = opts.clone
38
+ req = build_soap! do |type, builder|
39
+ if(type == :header)
40
+ else
41
+ builder.nbuild.SyncFolderHierarchy {
42
+ builder.nbuild.parent.default_namespace = @default_ns
43
+ builder.folder_shape!(opts[:folder_shape])
44
+ builder.sync_folder_id!(opts[:sync_folder_id]) if opts[:sync_folder_id]
45
+ builder.sync_state!(opts[:sync_state]) if opts[:sync_state]
46
+ }
47
+ end
48
+ end
49
+ do_soap_request(req, response_class: EwsResponse)
50
+ end
51
+
52
+ # Synchronizes items between the Exchange server and the client
53
+ # @see http://msdn.microsoft.com/en-us/library/aa563967(v=EXCHG.140).aspx
54
+ # @param [Hash] opts
55
+ # @option opts [Hash] :item_shape The item shape properties
56
+ # Ex: {:base_shape => 'Default', :additional_properties => 'bla bla bla'}
57
+ # @option opts [Hash] :sync_folder_id A Hash that represents a FolderId or
58
+ # DistinguishedFolderId. [ Ex: {:id => :inbox} ] OPTIONAL
59
+ # @option opts [String] :sync_state The Base64 sync state id. If this is the
60
+ # first time syncing this does not need to be passed. OPTIONAL on first call
61
+ # @option opts [Array <String>] :ignore An Array of ItemIds for items to ignore
62
+ # during the sync process. Ex: [{:id => 'id1', :change_key => 'ck'}, {:id => 'id2'}]
63
+ # OPTIONAL
64
+ # @option opts [Integer] :max_changes_returned ('required') The amount of items to sync per call.
65
+ # @option opts [String] :sync_scope specifies whether just items or items and folder associated
66
+ # information are returned. OPTIONAL
67
+ # options: 'NormalItems' or 'NormalAndAssociatedItems'
68
+ # @example
69
+ # { :item_shape => {:base_shape => 'Default'},
70
+ # :sync_folder_id => {:id => :inbox},
71
+ # :sync_state => myBase64id,
72
+ # :max_changes_returned => 256 }
73
+ def sync_folder_items(opts)
74
+ opts = opts.clone
75
+ req = build_soap! do |type, builder|
76
+ if(type == :header)
77
+ else
78
+ builder.nbuild.SyncFolderItems {
79
+ builder.nbuild.parent.default_namespace = @default_ns
80
+ builder.item_shape!(opts[:item_shape])
81
+ builder.sync_folder_id!(opts[:sync_folder_id]) if opts[:sync_folder_id]
82
+ builder.sync_state!(opts[:sync_state]) if opts[:sync_state]
83
+ builder.ignore!(opts[:ignore]) if opts[:ignore]
84
+ builder.max_changes_returned!(opts[:max_changes_returned])
85
+ builder.sync_scope!(opts[:sync_scope]) if opts[:sync_scope]
86
+ }
87
+ end
88
+ end
89
+ do_soap_request(req, response_class: EwsResponse)
90
+ end
91
+
92
+ end #ExchangeSynchronization
93
+ end
@@ -0,0 +1,56 @@
1
+ module Viewpoint::EWS::SOAP
2
+
3
+ module ExchangeTimeZones
4
+ include Viewpoint::EWS::SOAP
5
+
6
+ # Request list of server known time zones
7
+ # @param full [Boolean] Request full time zone definition? Returns only name and id if false.
8
+ # @param ids [Array] Returns only the specified time zones instead of all if present
9
+ # @return [Array] Array of Objects responding to #id() and #name()
10
+ # @example Retrieving server zime zones
11
+ # ews_client = Viewpoint::EWSClient.new # ...
12
+ # zones = ews_client.ews.get_time_zones
13
+ # @todo Implement TimeZoneDefinition with sub elements Periods, TransitionsGroups and Transitions
14
+ def get_time_zones(full = false, ids = nil)
15
+ req = build_soap! do |type, builder|
16
+ unless type == :header
17
+ builder.get_server_time_zones!(full: full, ids: ids)
18
+ end
19
+ end
20
+ result = do_soap_request req, response_class: EwsSoapResponse
21
+
22
+ if result.success?
23
+ zones = []
24
+ result.response_messages.each do |message|
25
+ elements = message[:get_server_time_zones_response_message][:elems][:time_zone_definitions][:elems]
26
+ elements.each do |definition|
27
+ data = {
28
+ id: definition[:time_zone_definition][:attribs][:id],
29
+ name: definition[:time_zone_definition][:attribs][:name]
30
+ }
31
+ zones << OpenStruct.new(data)
32
+ end
33
+ end
34
+ zones
35
+ else
36
+ raise EwsError, "Could not get time zones"
37
+ end
38
+ end
39
+
40
+ # Sets the time zone context header
41
+ # @param id [String] Identifier of a Microsoft well known time zone
42
+ # @example Set time zone context for connection
43
+ # ews_client = Viewpoint::EWSClient.new # ...
44
+ # ews_client.set_time_zone 'AUS Central Standard Time'
45
+ # # subsequent request will send the TimeZoneContext header
46
+ # @see EWSClient#set_time_zone
47
+ def set_time_zone_context(id)
48
+ if id
49
+ @time_zone_context = {id: id}
50
+ else
51
+ @time_zone_context = nil
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,33 @@
1
+ module Viewpoint::EWS::SOAP
2
+
3
+ # Exchange User Configuration operations as listed in the EWS Documentation.
4
+ # @see http://msdn.microsoft.com/en-us/library/bb409286.aspx
5
+ module ExchangeUserConfiguration
6
+ include Viewpoint::EWS::SOAP
7
+
8
+ # The GetUserConfiguration operation gets a user configuration object from
9
+ # a folder.
10
+ # @see http://msdn.microsoft.com/en-us/library/aa563465.aspx
11
+ # @param [Hash] opts
12
+ # @option opts [Hash] :user_config_name
13
+ # @option opts [String] :user_config_props
14
+ def get_user_configuration(opts)
15
+ opts = opts.clone
16
+ [:user_config_name, :user_config_props].each do |k|
17
+ validate_param(opts, k, true)
18
+ end
19
+ req = build_soap! do |type, builder|
20
+ if(type == :header)
21
+ else
22
+ builder.nbuild.GetUserConfiguration {|x|
23
+ x.parent.default_namespace = @default_ns
24
+ builder.user_configuration_name!(opts[:user_config_name])
25
+ builder.user_configuration_properties!(opts[:user_config_props])
26
+ }
27
+ end
28
+ end
29
+ do_soap_request(req, response_class: EwsSoapAvailabilityResponse)
30
+ end
31
+
32
+ end #ExchangeUserConfiguration
33
+ end
@@ -0,0 +1,264 @@
1
+ =begin
2
+ This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ module Viewpoint::EWS::SOAP
20
+ class ExchangeWebService
21
+ include Viewpoint::EWS
22
+ include Viewpoint::EWS::SOAP
23
+ include Viewpoint::StringUtils
24
+ include ExchangeDataServices
25
+ include ExchangeNotification
26
+ include ExchangeAvailability
27
+ include ExchangeUserConfiguration
28
+ include ExchangeSynchronization
29
+ include ExchangeTimeZones
30
+
31
+ attr_accessor :server_version, :auto_deepen, :no_auto_deepen_behavior, :connection, :impersonation_type, :impersonation_address
32
+
33
+ # @param [Viewpoint::EWS::Connection] connection the connection object
34
+ # @param [Hash] opts additional options to the web service
35
+ # @option opts [String] :server_version what version to target with the
36
+ # requests. Must be one of the contants VERSION_2007, VERSION_2007_SP1,
37
+ # VERSION_2010, VERSION_2010_SP1, VERSION_2010_SP2, or VERSION_NONE. The
38
+ # default is VERSION_2010.
39
+ def initialize(connection, opts = {})
40
+ super()
41
+ @connection = connection
42
+ @server_version = opts[:server_version] ? opts[:server_version] : VERSION_2010
43
+ @auto_deepen = true
44
+ @no_auto_deepen_behavior = :raise
45
+ @impersonation_type = ""
46
+ @impersonation_address = ""
47
+ end
48
+
49
+ def delete_attachment
50
+ action = "#{SOAP_ACTION_PREFIX}/DeleteAttachment"
51
+ resp = invoke("#{NS_EWS_MESSAGES}:DeleteAttachment", action) do |delete_attachment|
52
+ build_delete_attachment!(delete_attachment)
53
+ end
54
+ parse_delete_attachment(resp)
55
+ end
56
+
57
+ def create_managed_folder
58
+ action = "#{SOAP_ACTION_PREFIX}/CreateManagedFolder"
59
+ resp = invoke("#{NS_EWS_MESSAGES}:CreateManagedFolder", action) do |create_managed_folder|
60
+ build_create_managed_folder!(create_managed_folder)
61
+ end
62
+ parse_create_managed_folder(resp)
63
+ end
64
+
65
+ # Retrieves the delegate settings for a specific mailbox.
66
+ # @see http://msdn.microsoft.com/en-us/library/bb799735.aspx
67
+ #
68
+ # @param [String] owner The user that is delegating permissions
69
+ def get_delegate(owner)
70
+ action = "#{SOAP_ACTION_PREFIX}/GetDelegate"
71
+ resp = invoke("#{NS_EWS_MESSAGES}:GetDelegate", action) do |root|
72
+ root.set_attr('IncludePermissions', 'true')
73
+ build!(root) do
74
+ mailbox!(root, {:email_address => {:text => owner}})
75
+ end
76
+ end
77
+ parse_soap_response(resp)
78
+ end
79
+
80
+ # Adds one or more delegates to a principal's mailbox and sets specific access permissions.
81
+ # @see http://msdn.microsoft.com/en-us/library/bb856527.aspx
82
+ #
83
+ # @param [String] owner The user that is delegating permissions
84
+ # @param [String] delegate The user that is being given delegate permission
85
+ # @param [Hash] permissions A hash of permissions that will be delegated.
86
+ # This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
87
+ def add_delegate(owner, delegate, permissions)
88
+ action = "#{SOAP_ACTION_PREFIX}/AddDelegate"
89
+ resp = invoke("#{NS_EWS_MESSAGES}:AddDelegate", action) do |root|
90
+ build!(root) do
91
+ add_delegate!(owner, delegate, permissions)
92
+ end
93
+ end
94
+ parse_soap_response(resp)
95
+ end
96
+
97
+ # Removes one or more delegates from a user's mailbox.
98
+ # @see http://msdn.microsoft.com/en-us/library/bb856564.aspx
99
+ #
100
+ # @param [String] owner The user that is delegating permissions
101
+ # @param [String] delegate The user that is being given delegate permission
102
+ def remove_delegate(owner, delegate)
103
+ action = "#{SOAP_ACTION_PREFIX}/RemoveDelegate"
104
+ resp = invoke("#{NS_EWS_MESSAGES}:RemoveDelegate", action) do |root|
105
+ build!(root) do
106
+ remove_delegate!(owner, delegate)
107
+ end
108
+ end
109
+ parse_soap_response(resp)
110
+ end
111
+
112
+ # Updates delegate permissions on a principal's mailbox
113
+ # @see http://msdn.microsoft.com/en-us/library/bb856529.aspx
114
+ #
115
+ # @param [String] owner The user that is delegating permissions
116
+ # @param [String] delegate The user that is being given delegate permission
117
+ # @param [Hash] permissions A hash of permissions that will be delegated.
118
+ # This Hash will eventually be passed to add_hierarchy! in the builder so it is in that format.
119
+ def update_delegate(owner, delegate, permissions)
120
+ action = "#{SOAP_ACTION_PREFIX}/UpdateDelegate"
121
+ resp = invoke("#{NS_EWS_MESSAGES}:UpdateDelegate", action) do |root|
122
+ build!(root) do
123
+ add_delegate!(owner, delegate, permissions)
124
+ end
125
+ end
126
+ parse_soap_response(resp)
127
+ end
128
+
129
+ # Provides detailed information about the availability of a set of users, rooms, and resources
130
+ # within a specified time window.
131
+ # @see http://msdn.microsoft.com/en-us/library/aa564001.aspx
132
+ # @param [Hash] opts
133
+ # @option opts [Hash] :time_zone The TimeZone data
134
+ # Example: {:bias => 'UTC offset in minutes',
135
+ # :standard_time => {:bias => 480, :time => '02:00:00',
136
+ # :day_order => 5, :month => 10, :day_of_week => 'Sunday'},
137
+ # :daylight_time => {same options as :standard_time}}
138
+ # @option opts [Array<Hash>] :mailbox_data Data for the mailbox to query
139
+ # Example: [{:attendee_type => 'Organizer|Required|Optional|Room|Resource',
140
+ # :email =>{:name => 'name', :address => 'email', :routing_type => 'SMTP'},
141
+ # :exclude_conflicts => true|false }]
142
+ # @option opts [Hash] :free_busy_view_options
143
+ # Example: {:time_window => {:start_time => DateTime,:end_time => DateTime},
144
+ # :merged_free_busy_interval_in_minutes => minute_int,
145
+ # :requested_view => None|MergedOnly|FreeBusy|FreeBusyMerged|Detailed
146
+ # |DetailedMerged} (optional)
147
+ # @option opts [Hash] :suggestions_view_options (optional)
148
+ # @todo Finish out :suggestions_view_options
149
+ def get_user_availability(opts)
150
+ opts = opts.clone
151
+ req = build_soap! do |type, builder|
152
+ if(type == :header)
153
+ else
154
+ builder.nbuild.GetUserAvailabilityRequest {|x|
155
+ x.parent.default_namespace = @default_ns
156
+ builder.time_zone!(opts[:time_zone])
157
+ builder.nbuild.MailboxDataArray {
158
+ opts[:mailbox_data].each do |mbd|
159
+ builder.mailbox_data!(mbd)
160
+ end
161
+ }
162
+ builder.free_busy_view_options!(opts[:free_busy_view_options])
163
+ builder.suggestions_view_options!(opts[:suggestions_view_options])
164
+ }
165
+ end
166
+ end
167
+
168
+ do_soap_request(req, response_class: EwsSoapFreeBusyResponse)
169
+ end
170
+
171
+ # Gets the rooms that are in the specified room distribution list
172
+ # @see http://msdn.microsoft.com/en-us/library/aa563465.aspx
173
+ # @param [string] roomDistributionList
174
+ def get_rooms(roomDistributionList)
175
+ req = build_soap! do |type, builder|
176
+ if(type == :header)
177
+ else
178
+ builder.nbuild.GetRooms {|x|
179
+ x.parent.default_namespace = @default_ns
180
+ builder.room_list!(roomDistributionList)
181
+ }
182
+ end
183
+ end
184
+ do_soap_request(req, response_class: EwsSoapRoomResponse)
185
+ end
186
+
187
+ # Gets the room lists that are available within the Exchange organization.
188
+ # @see http://msdn.microsoft.com/en-us/library/aa563465.aspx
189
+ def get_room_lists
190
+ req = build_soap! do |type, builder|
191
+ if(type == :header)
192
+ else
193
+ builder.room_lists!
194
+ end
195
+ end
196
+ do_soap_request(req, response_class: EwsSoapRoomlistResponse)
197
+ end
198
+
199
+ # Send the SOAP request to the endpoint and parse it.
200
+ # @param [String] soapmsg an XML formatted string
201
+ # @todo make this work for Viewpoint (imported from SPWS)
202
+ # @param [Hash] opts misc options
203
+ # @option opts [Boolean] :raw_response if true do not parse and return
204
+ # the raw response string.
205
+ def do_soap_request(soapmsg, opts = {})
206
+ @log.debug <<-EOF.gsub(/^ {8}/, '')
207
+ Sending SOAP Request:
208
+ ----------------
209
+ #{soapmsg}
210
+ ----------------
211
+ EOF
212
+ connection.dispatch(self, soapmsg, opts)
213
+ end
214
+
215
+ # @param [String] response the SOAP response string
216
+ # @param [Hash] opts misc options to send to the parser
217
+ # @option opts [Class] :response_class the response class
218
+ def parse_soap_response(soapmsg, opts = {})
219
+ raise EwsError, "Can't parse an empty response. Please check your endpoint." if(soapmsg.nil?)
220
+ opts[:response_class] ||= EwsSoapResponse
221
+ EwsParser.new(soapmsg).parse(opts)
222
+ end
223
+
224
+
225
+ private
226
+ # Private Methods (Builders and Parsers)
227
+
228
+ # Validate or set default values for options parameters.
229
+ # @param [Hash] opts The options parameter passed to an EWS operation
230
+ # @param [Symbol] key The key in the Hash we are validating
231
+ # @param [Boolean] required Whether or not this key is required
232
+ # @param [Object] default_val If the key is not required use this as a
233
+ # default value for the operation.
234
+ def validate_param(opts, key, required, default_val = nil)
235
+ if required
236
+ raise EwsBadArgumentError, "Required parameter(#{key}) not passed." unless opts.has_key?(key)
237
+ opts[key]
238
+ else
239
+ raise EwsBadArgumentError, "Default value not supplied." unless default_val
240
+ opts.has_key?(key) ? opts[key] : default_val
241
+ end
242
+ end
243
+
244
+ # Some operations only exist for certain versions of Exchange Server.
245
+ # This method should be called with the required version and we'll throw
246
+ # an exception of the currently set @server_version does not comply.
247
+ def validate_version(exchange_version)
248
+ if server_version < exchange_version
249
+ msg = 'The operation you are attempting to use is not compatible with'
250
+ msg << " your configured Exchange Server version(#{server_version})."
251
+ msg << " You must be running at least version (#{exchange_version})."
252
+ raise EwsServerVersionError, msg
253
+ end
254
+ end
255
+
256
+ # Build the common elements in the SOAP message and yield to any custom elements.
257
+ def build_soap!(&block)
258
+ opts = { :server_version => server_version, :impersonation_type => impersonation_type, :impersonation_mail => impersonation_address }
259
+ opts[:time_zone_context] = @time_zone_context if @time_zone_context
260
+ EwsBuilder.new.build!(opts, &block)
261
+ end
262
+
263
+ end # class ExchangeWebService
264
+ end # Viewpoint