autodiscover 0.1.0 → 1.0.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 +7 -0
- data/.gitignore +19 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/README.md +32 -31
- data/Rakefile +19 -0
- data/autodiscover.gemspec +30 -0
- data/lib/autodiscover.rb +12 -25
- data/lib/autodiscover/client.rb +22 -215
- data/lib/autodiscover/errors.rb +5 -0
- data/lib/autodiscover/pox_request.rb +72 -0
- data/lib/autodiscover/pox_response.rb +32 -0
- data/lib/autodiscover/server_version_parser.rb +45 -0
- data/lib/autodiscover/version.rb +3 -0
- data/test/fixtures/pox_response.xml +93 -0
- data/test/test_helper.rb +12 -0
- data/test/units/client_test.rb +35 -0
- data/test/units/pox_request_test.rb +46 -0
- data/test/units/pox_response_test.rb +54 -0
- data/test/units/server_version_parser_test.rb +18 -0
- metadata +154 -81
- data/lib/autodiscover/credentials.rb +0 -51
- data/lib/autodiscover/services.rb +0 -40
- data/test/unit_test.rb +0 -195
@@ -1,51 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright (c) 2010-2011 WIMM Labs, Inc.
|
3
|
-
#
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
-
# a copy of this software and associated documentation files (the
|
6
|
-
# "Software"), to deal in the Software without restriction, including
|
7
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
-
# the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be
|
13
|
-
# included in all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
-
#++
|
23
|
-
|
24
|
-
module Autodiscover
|
25
|
-
# A Credentials object is used to determine the autodiscover service
|
26
|
-
# endpoint and to authenticate to it.
|
27
|
-
class Credentials
|
28
|
-
# E-mail address for the user.
|
29
|
-
attr_reader :email
|
30
|
-
|
31
|
-
# Password for the account.
|
32
|
-
attr_reader :password
|
33
|
-
|
34
|
-
# SMTP domain determined by the e-mail address.
|
35
|
-
attr_reader :smtp_domain #:nodoc:
|
36
|
-
|
37
|
-
def initialize(address, password)
|
38
|
-
self.email = address
|
39
|
-
@password = password
|
40
|
-
end
|
41
|
-
|
42
|
-
def email=(address) #:nodoc:
|
43
|
-
raise ArgumentError, "No email address specified" unless address
|
44
|
-
@smtp_domain = address[/^.+@(.*)$/, 1]
|
45
|
-
unless @smtp_domain =~ /.+\..+/
|
46
|
-
raise ArgumentError, "Invalid email address: #{address}"
|
47
|
-
end
|
48
|
-
@email = address
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright (c) 2010-2011 WIMM Labs, Inc.
|
3
|
-
#
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
-
# a copy of this software and associated documentation files (the
|
6
|
-
# "Software"), to deal in the Software without restriction, including
|
7
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
-
# the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be
|
13
|
-
# included in all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
-
#++
|
23
|
-
|
24
|
-
module Autodiscover
|
25
|
-
# A Services object contains the endpoint URLs and settings returned
|
26
|
-
# from an \Autodiscover server.
|
27
|
-
class Services
|
28
|
-
# URL for Exchange Web Services API endpoint.
|
29
|
-
attr_reader :ews_url
|
30
|
-
|
31
|
-
# Time to Live (TTL), in hours, during which the settings remain valid.
|
32
|
-
# A value of zero indicates that rediscovery is not required.
|
33
|
-
attr_reader :ttl
|
34
|
-
|
35
|
-
def initialize(settings) #:nodoc:
|
36
|
-
@ews_url = settings['ews_url']
|
37
|
-
@ttl = settings['ttl']
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
data/test/unit_test.rb
DELETED
@@ -1,195 +0,0 @@
|
|
1
|
-
# Prefix LOAD_PATH with lib sub-directory to ensure we're
|
2
|
-
# testing the intended version.
|
3
|
-
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
4
|
-
|
5
|
-
# Load HTTPClient before webmock so the HTTPClient adapter will be used.
|
6
|
-
require 'httpclient'
|
7
|
-
require 'webmock/test_unit'
|
8
|
-
require 'test/unit'
|
9
|
-
require 'autodiscover'
|
10
|
-
|
11
|
-
SETTINGS_AUTODISCOVER_RESPONSE = <<END
|
12
|
-
<?xml version="1.0" encoding="utf-8"?>
|
13
|
-
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
|
14
|
-
<Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
|
15
|
-
<User>
|
16
|
-
<DisplayName>spiff</DisplayName>
|
17
|
-
<LegacyDN>/o=outlook/ou=Exchange Administrative Group (spacecommand)/cn=Recipients/cn=spiff</LegacyDN>
|
18
|
-
<DeploymentId>11111111-2222-3333-4444-555555555555</DeploymentId>
|
19
|
-
</User>
|
20
|
-
<Account>
|
21
|
-
<AccountType>email</AccountType>
|
22
|
-
<Action>settings</Action>
|
23
|
-
<Protocol>
|
24
|
-
<Type>EXPR</Type>
|
25
|
-
<Server>outlook.spacecommand.sol</Server>
|
26
|
-
<SSL>On</SSL>
|
27
|
-
<AuthPackage>Basic</AuthPackage>
|
28
|
-
<EwsUrl>https://ews.spacecommand.sol/EWS/Exchange.asmx</EwsUrl>
|
29
|
-
</Protocol>
|
30
|
-
</Account>
|
31
|
-
</Response>
|
32
|
-
</Autodiscover>
|
33
|
-
END
|
34
|
-
|
35
|
-
REDIRECTURL_AUTODISCOVER_RESPONSE = <<END
|
36
|
-
<?xml version="1.0" encoding="utf-8"?>
|
37
|
-
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
|
38
|
-
<Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
|
39
|
-
<Account>
|
40
|
-
<Action>redirectUrl</Action>
|
41
|
-
<RedirectUrl>https://earthcommand.org/autodiscover/autodiscover.xml</RedirectUrl>
|
42
|
-
</Account>
|
43
|
-
</Response>
|
44
|
-
</Autodiscover>
|
45
|
-
END
|
46
|
-
|
47
|
-
REDIRECTADDR_AUTODISCOVER_RESPONSE = <<END
|
48
|
-
<?xml version="1.0" encoding="utf-8"?>
|
49
|
-
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
|
50
|
-
<Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
|
51
|
-
<Account>
|
52
|
-
<Action>redirectAddr</Action>
|
53
|
-
<RedirectAddr>calvin@spacecommand.sol</RedirectAddr>
|
54
|
-
</Account>
|
55
|
-
</Response>
|
56
|
-
</Autodiscover>
|
57
|
-
END
|
58
|
-
|
59
|
-
class AutodiscoverResponseTest < Test::Unit::TestCase
|
60
|
-
def setup
|
61
|
-
@credentials = Autodiscover::Credentials.new('spiff@spacecommand.sol', 'hobbes')
|
62
|
-
@client = Autodiscover::Client.new
|
63
|
-
WebMock::stub_request(:any, /spacecommand.sol/).to_timeout
|
64
|
-
end
|
65
|
-
|
66
|
-
# Test the cases where the Autodiscover service is configured to listen on
|
67
|
-
# the standard secure endpoint addresses.
|
68
|
-
[ "https://spiff%40spacecommand.sol:hobbes@spacecommand.sol/autodiscover/autodiscover.xml",
|
69
|
-
"https://spiff%40spacecommand.sol:hobbes@autodiscover.spacecommand.sol/autodiscover/autodiscover.xml"
|
70
|
-
].each_with_index do |url, i|
|
71
|
-
define_method "test_standard_secure_urls_#{i}" do
|
72
|
-
WebMock::stub_request(:post, url).to_return(
|
73
|
-
:body => SETTINGS_AUTODISCOVER_RESPONSE,
|
74
|
-
:status => 200,
|
75
|
-
:headers => { 'Content-Length' => SETTINGS_AUTODISCOVER_RESPONSE.size }
|
76
|
-
)
|
77
|
-
response = @client.get_services(@credentials)
|
78
|
-
assert_not_nil response
|
79
|
-
assert_equal 'https://ews.spacecommand.sol/EWS/Exchange.asmx', response.ews_url
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# Test the cases where a standard secure address is used to redirect
|
84
|
-
# to a secure endpoint that the Autodiscover service is available upon.
|
85
|
-
def test_redirect_from_standard_secure_url
|
86
|
-
WebMock::stub_request(:post, /spacecommand.sol/).to_return(
|
87
|
-
:status => 302,
|
88
|
-
:headers => { 'Location' => 'https://earthcommand.org/autodiscover/autodiscover.xml' }
|
89
|
-
)
|
90
|
-
WebMock::stub_request(:post, 'https://spiff%40spacecommand.sol:hobbes@earthcommand.org/autodiscover/autodiscover.xml').to_return(
|
91
|
-
:body => SETTINGS_AUTODISCOVER_RESPONSE,
|
92
|
-
:status => 200,
|
93
|
-
:headers => { 'Content-Length' => SETTINGS_AUTODISCOVER_RESPONSE.size }
|
94
|
-
)
|
95
|
-
response = @client.get_services(@credentials)
|
96
|
-
assert_not_nil response
|
97
|
-
assert_equal 'https://ews.spacecommand.sol/EWS/Exchange.asmx', response.ews_url
|
98
|
-
end
|
99
|
-
|
100
|
-
# Test the cases where the standard insecure redirect address is used to redirect
|
101
|
-
# to a secure endpoint that the Autodiscover service is available upon.
|
102
|
-
def test_standard_redirection_url
|
103
|
-
WebMock::stub_request(:get, "http://autodiscover.spacecommand.sol/autodiscover/autodiscover.xml").to_return(
|
104
|
-
:status => 302,
|
105
|
-
:headers => { 'Location' => 'https://earthcommand.org/autodiscover/autodiscover.xml' }
|
106
|
-
)
|
107
|
-
WebMock::stub_request(:post, 'https://spiff%40spacecommand.sol:hobbes@earthcommand.org/autodiscover/autodiscover.xml').to_return(
|
108
|
-
:body => SETTINGS_AUTODISCOVER_RESPONSE,
|
109
|
-
:status => 200,
|
110
|
-
:headers => { 'Content-Length' => SETTINGS_AUTODISCOVER_RESPONSE.size }
|
111
|
-
)
|
112
|
-
response = @client.get_services(@credentials)
|
113
|
-
assert_not_nil response
|
114
|
-
assert_equal 'https://ews.spacecommand.sol/EWS/Exchange.asmx', response.ews_url
|
115
|
-
end
|
116
|
-
|
117
|
-
# Test the case where a post to a standard secure address returns a redirectUrl response that
|
118
|
-
# redirects to a secure endpoint that returns a valid settings response.
|
119
|
-
def test_redirect_url_response
|
120
|
-
WebMock::stub_request(:post, "https://spiff%40spacecommand.sol:hobbes@spacecommand.sol/autodiscover/autodiscover.xml").to_return(
|
121
|
-
:body => REDIRECTURL_AUTODISCOVER_RESPONSE,
|
122
|
-
:status => 200,
|
123
|
-
:headers => { 'Content-Length' => REDIRECTURL_AUTODISCOVER_RESPONSE.size }
|
124
|
-
)
|
125
|
-
WebMock::stub_request(:post, 'https://spiff%40spacecommand.sol:hobbes@earthcommand.org/autodiscover/autodiscover.xml').to_return(
|
126
|
-
:body => SETTINGS_AUTODISCOVER_RESPONSE,
|
127
|
-
:status => 200,
|
128
|
-
:headers => { 'Content-Length' => SETTINGS_AUTODISCOVER_RESPONSE.size }
|
129
|
-
)
|
130
|
-
response = @client.get_services(@credentials)
|
131
|
-
assert_not_nil response
|
132
|
-
assert_equal 'https://ews.spacecommand.sol/EWS/Exchange.asmx', response.ews_url
|
133
|
-
end
|
134
|
-
|
135
|
-
# Test the case where a post to a standard secure address returns a redirectAddr response that
|
136
|
-
# includes a new email address to use.
|
137
|
-
def test_redirect_addr_response
|
138
|
-
WebMock::stub_request(:post, "https://spiff%40spacecommand.sol:hobbes@autodiscover.spacecommand.sol/autodiscover/autodiscover.xml").to_return(
|
139
|
-
:body => REDIRECTADDR_AUTODISCOVER_RESPONSE,
|
140
|
-
:status => 200,
|
141
|
-
:headers => { 'Content-Length' => REDIRECTURL_AUTODISCOVER_RESPONSE.size }
|
142
|
-
)
|
143
|
-
WebMock::stub_request(:post, 'https://calvin%40spacecommand.sol:hobbes@spacecommand.sol/autodiscover/autodiscover.xml').to_return(
|
144
|
-
:body => SETTINGS_AUTODISCOVER_RESPONSE,
|
145
|
-
:status => 200,
|
146
|
-
:headers => { 'Content-Length' => SETTINGS_AUTODISCOVER_RESPONSE.size }
|
147
|
-
)
|
148
|
-
response = @client.get_services(@credentials)
|
149
|
-
assert_not_nil response
|
150
|
-
assert_equal 'https://ews.spacecommand.sol/EWS/Exchange.asmx', response.ews_url
|
151
|
-
end
|
152
|
-
|
153
|
-
# Test the case where there is an infinite loop of HTTP redirects. A limit should be hit
|
154
|
-
# and a nil result should be returned.
|
155
|
-
def test_http_redirect_limit
|
156
|
-
WebMock::stub_request(:post, /spacecommand.sol/).to_return(
|
157
|
-
:status => 302,
|
158
|
-
:headers => { 'Location' => 'https://spacecommand.sol/autodiscover/autodiscover.xml' }
|
159
|
-
)
|
160
|
-
response = @client.get_services(@credentials)
|
161
|
-
assert_nil response
|
162
|
-
end
|
163
|
-
|
164
|
-
# Test the case where there is an infinite loop created by circular redirectUrl responses.
|
165
|
-
# The redirect limit should be reached and a nil result should be returned.
|
166
|
-
def test_redirect_url_response_limit
|
167
|
-
WebMock::stub_request(:post, "https://spiff%40spacecommand.sol:hobbes@spacecommand.sol/autodiscover/autodiscover.xml").to_return(
|
168
|
-
:body => REDIRECTURL_AUTODISCOVER_RESPONSE,
|
169
|
-
:status => 200,
|
170
|
-
:headers => { 'Content-Length' => REDIRECTURL_AUTODISCOVER_RESPONSE.size }
|
171
|
-
)
|
172
|
-
WebMock::stub_request(:post, 'https://spiff%40spacecommand.sol:hobbes@earthcommand.org/autodiscover/autodiscover.xml').to_return(
|
173
|
-
:body => REDIRECTURL_AUTODISCOVER_RESPONSE,
|
174
|
-
:status => 200,
|
175
|
-
:headers => { 'Content-Length' => SETTINGS_AUTODISCOVER_RESPONSE.size }
|
176
|
-
)
|
177
|
-
response = @client.get_services(@credentials)
|
178
|
-
assert_nil response
|
179
|
-
end
|
180
|
-
|
181
|
-
def test_redirect_addr_response_limit
|
182
|
-
WebMock::stub_request(:post, "https://spiff%40spacecommand.sol:hobbes@spacecommand.sol/autodiscover/autodiscover.xml").to_return(
|
183
|
-
:body => REDIRECTADDR_AUTODISCOVER_RESPONSE,
|
184
|
-
:status => 200,
|
185
|
-
:headers => { 'Content-Length' => REDIRECTURL_AUTODISCOVER_RESPONSE.size }
|
186
|
-
)
|
187
|
-
WebMock::stub_request(:post, 'https://calvin%40spacecommand.sol:hobbes@spacecommand.sol/autodiscover/autodiscover.xml').to_return(
|
188
|
-
:body => REDIRECTADDR_AUTODISCOVER_RESPONSE,
|
189
|
-
:status => 200,
|
190
|
-
:headers => { 'Content-Length' => SETTINGS_AUTODISCOVER_RESPONSE.size }
|
191
|
-
)
|
192
|
-
response = @client.get_services(@credentials)
|
193
|
-
assert_nil response
|
194
|
-
end
|
195
|
-
end
|