sfdcvp 0.0.1

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 (89) hide show
  1. checksums.yaml +15 -0
  2. data/Changelog.txt +1004 -0
  3. data/README.md +201 -0
  4. data/TODO +17 -0
  5. data/lib/ews/calendar_accessors.rb +34 -0
  6. data/lib/ews/connection.rb +126 -0
  7. data/lib/ews/connection_helper.rb +35 -0
  8. data/lib/ews/convert_accessors.rb +56 -0
  9. data/lib/ews/errors.rb +56 -0
  10. data/lib/ews/ews_client.rb +101 -0
  11. data/lib/ews/exceptions/exceptions.rb +61 -0
  12. data/lib/ews/folder_accessors.rb +264 -0
  13. data/lib/ews/impersonation.rb +30 -0
  14. data/lib/ews/item_accessors.rb +231 -0
  15. data/lib/ews/mailbox_accessors.rb +92 -0
  16. data/lib/ews/message_accessors.rb +93 -0
  17. data/lib/ews/push_subscription_accessors.rb +33 -0
  18. data/lib/ews/room_accessors.rb +48 -0
  19. data/lib/ews/roomlist_accessors.rb +47 -0
  20. data/lib/ews/soap.rb +64 -0
  21. data/lib/ews/soap/builders/ews_builder.rb +1361 -0
  22. data/lib/ews/soap/ews_response.rb +84 -0
  23. data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
  24. data/lib/ews/soap/ews_soap_free_busy_response.rb +119 -0
  25. data/lib/ews/soap/ews_soap_response.rb +103 -0
  26. data/lib/ews/soap/ews_soap_room_response.rb +53 -0
  27. data/lib/ews/soap/ews_soap_roomlist_response.rb +54 -0
  28. data/lib/ews/soap/exchange_availability.rb +61 -0
  29. data/lib/ews/soap/exchange_data_services.rb +780 -0
  30. data/lib/ews/soap/exchange_notification.rb +146 -0
  31. data/lib/ews/soap/exchange_synchronization.rb +93 -0
  32. data/lib/ews/soap/exchange_time_zones.rb +56 -0
  33. data/lib/ews/soap/exchange_user_configuration.rb +33 -0
  34. data/lib/ews/soap/exchange_web_service.rb +264 -0
  35. data/lib/ews/soap/parsers/ews_parser.rb +43 -0
  36. data/lib/ews/soap/parsers/ews_sax_document.rb +70 -0
  37. data/lib/ews/soap/response_message.rb +80 -0
  38. data/lib/ews/soap/responses/create_attachment_response_message.rb +47 -0
  39. data/lib/ews/soap/responses/create_item_response_message.rb +25 -0
  40. data/lib/ews/soap/responses/find_item_response_message.rb +80 -0
  41. data/lib/ews/soap/responses/get_events_response_message.rb +53 -0
  42. data/lib/ews/soap/responses/send_notification_response_message.rb +59 -0
  43. data/lib/ews/soap/responses/subscribe_response_message.rb +35 -0
  44. data/lib/ews/soap/responses/sync_folder_hierarchy_response_message.rb +36 -0
  45. data/lib/ews/soap/responses/sync_folder_items_response_message.rb +36 -0
  46. data/lib/ews/templates/calendar_item.rb +78 -0
  47. data/lib/ews/templates/forward_item.rb +24 -0
  48. data/lib/ews/templates/message.rb +73 -0
  49. data/lib/ews/templates/reply_to_item.rb +25 -0
  50. data/lib/ews/templates/task.rb +74 -0
  51. data/lib/ews/types.rb +194 -0
  52. data/lib/ews/types/attachment.rb +77 -0
  53. data/lib/ews/types/attendee.rb +27 -0
  54. data/lib/ews/types/calendar_folder.rb +50 -0
  55. data/lib/ews/types/calendar_item.rb +129 -0
  56. data/lib/ews/types/contact.rb +7 -0
  57. data/lib/ews/types/contacts_folder.rb +8 -0
  58. data/lib/ews/types/copied_event.rb +51 -0
  59. data/lib/ews/types/created_event.rb +24 -0
  60. data/lib/ews/types/deleted_event.rb +24 -0
  61. data/lib/ews/types/distribution_list.rb +7 -0
  62. data/lib/ews/types/event.rb +62 -0
  63. data/lib/ews/types/export_items_response_message.rb +52 -0
  64. data/lib/ews/types/file_attachment.rb +65 -0
  65. data/lib/ews/types/folder.rb +60 -0
  66. data/lib/ews/types/free_busy_changed_event.rb +24 -0
  67. data/lib/ews/types/generic_folder.rb +420 -0
  68. data/lib/ews/types/item.rb +442 -0
  69. data/lib/ews/types/item_attachment.rb +84 -0
  70. data/lib/ews/types/item_field_uri_map.rb +224 -0
  71. data/lib/ews/types/mailbox_user.rb +156 -0
  72. data/lib/ews/types/meeting_cancellation.rb +7 -0
  73. data/lib/ews/types/meeting_message.rb +7 -0
  74. data/lib/ews/types/meeting_request.rb +7 -0
  75. data/lib/ews/types/meeting_response.rb +7 -0
  76. data/lib/ews/types/message.rb +7 -0
  77. data/lib/ews/types/modified_event.rb +48 -0
  78. data/lib/ews/types/moved_event.rb +51 -0
  79. data/lib/ews/types/new_mail_event.rb +24 -0
  80. data/lib/ews/types/out_of_office.rb +147 -0
  81. data/lib/ews/types/search_folder.rb +8 -0
  82. data/lib/ews/types/status_event.rb +39 -0
  83. data/lib/ews/types/task.rb +37 -0
  84. data/lib/ews/types/tasks_folder.rb +27 -0
  85. data/lib/sfdcvp.rb +109 -0
  86. data/lib/viewpoint/logging.rb +27 -0
  87. data/lib/viewpoint/logging/config.rb +24 -0
  88. data/lib/viewpoint/string_utils.rb +76 -0
  89. metadata +190 -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