xcapclient 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.
@@ -0,0 +1,49 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <cp:ruleset xmlns:pr="urn:ietf:params:xml:ns:pres-rules" xmlns:cp="urn:ietf:params:xml:ns:common-policy">
3
+ <cp:rule id="pres_whitelist">
4
+ <cp:conditions>
5
+ <cp:identity>
6
+ <cp:one id="sip:alice@example.org"/>
7
+ <cp:one id="sip:bob@example.org"/>
8
+ <cp:one id="sip:carol@example2.net"/>
9
+ </cp:identity>
10
+ </cp:conditions>
11
+ <cp:actions>
12
+ <pr:sub-handling>allow</pr:sub-handling>
13
+ </cp:actions>
14
+ <cp:transformations>
15
+ <pr:provide-services>
16
+ <pr:all-services/>
17
+ </pr:provide-services>
18
+ <pr:provide-persons>
19
+ <pr:all-persons/>
20
+ </pr:provide-persons>
21
+ <pr:provide-devices>
22
+ <pr:all-devices/>
23
+ </pr:provide-devices>
24
+ <pr:provide-all-attributes/>
25
+ </cp:transformations>
26
+ </cp:rule>
27
+ <cp:rule id="pres_blacklist">
28
+ <cp:conditions>
29
+ <cp:identity>
30
+ <cp:one id="sip:bill@microsoft.com"/>
31
+ </cp:identity>
32
+ </cp:conditions>
33
+ <cp:actions>
34
+ <pr:sub-handling>block</pr:sub-handling>
35
+ </cp:actions>
36
+ <cp:transformations/>
37
+ </cp:rule>
38
+ <cp:rule id="pres_polite_blacklist">
39
+ <cp:conditions>
40
+ <cp:identity>
41
+ <cp:one id="sip:steve@apple.com"/>
42
+ </cp:identity>
43
+ </cp:conditions>
44
+ <cp:actions>
45
+ <pr:sub-handling>polite-block</pr:sub-handling>
46
+ </cp:actions>
47
+ <cp:transformations/>
48
+ </cp:rule>
49
+ </cp:ruleset>
@@ -0,0 +1,352 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ # IMPORTANT: Configure these values with your own setting.
5
+ #
6
+ XCAP_ROOT = "https://xcap.example.org/xcap-root"
7
+ USER = "sip:user@example.org"
8
+ AUTH_USER = "user"
9
+ PASSWORD = "xxxx"
10
+ SSL_VERIFY_CERT = false
11
+
12
+
13
+ # Let's check that the user has customized the above settings.
14
+ if USER == "sip:user@example.org"
15
+ STDERR.puts "ERROR: You must configure the settings with your own values. Edit the top lines of this script."
16
+ exit 1
17
+ end
18
+
19
+
20
+ require "test/unit"
21
+ require "rubygems"
22
+ require "xcapclient"
23
+
24
+
25
+ include XCAPClient
26
+
27
+
28
+ # This test unit checks XCAPClient's and XCAP server's behaviour according to specifications in RFC 4825.
29
+ # It's focused on OpenXCAP[http://www.openxcap.org] server. In fact, some tests fail due to known bugs in OpenXCAP.
30
+ #
31
+ class TestXCAPClient < Test::Unit::TestCase
32
+
33
+
34
+ PRES_RULES = File.new(File.join(File.dirname(__FILE__), "PRES_RULES_EXAMPLE.xml")).read
35
+ NS = {"pr"=>"urn:ietf:params:xml:ns:pres-rules", "cp"=>"urn:ietf:params:xml:ns:common-policy"}
36
+
37
+
38
+ def setup
39
+
40
+ xcap_conf = {
41
+ :xcap_root => XCAP_ROOT,
42
+ :user => USER,
43
+ :auth_user => AUTH_USER,
44
+ :password => PASSWORD,
45
+ :ssl_verify_cert => SSL_VERIFY_CERT
46
+ }
47
+
48
+ xcap_apps = {
49
+ "pres-rules" => {
50
+ :xmlns => "urn:ietf:params:xml:ns:pres-rules",
51
+ :mime_type => "application/auth-policy+xml",
52
+ :document_name => "pres-rules"
53
+ }
54
+ }
55
+
56
+ @client = Client.new(xcap_conf, xcap_apps)
57
+ @client.application("pres-rules").document.plain = PRES_RULES
58
+
59
+ @doc = @client.application("pres-rules").document
60
+
61
+ reset_document
62
+
63
+ end
64
+
65
+
66
+ def teardown
67
+ reset_document
68
+ end
69
+
70
+
71
+ def test_01_get
72
+ show "Fetching the document (correct ETag) => 304"
73
+ begin
74
+ assert @client.get("pres-rules")
75
+ rescue => e
76
+ assert_equal( HTTPDocumentNotModified, e.class )
77
+ else
78
+ should_fail
79
+ end
80
+ end
81
+
82
+
83
+ def test_02_get
84
+ show "Fetching the document (wrong ETag) => 200"
85
+ @doc.etag = "wrongETag"
86
+ assert @client.get("pres-rules")
87
+ end
88
+
89
+
90
+ def test_03_put
91
+ show "Replace the document (correct ETag)=> 2XX"
92
+ assert @client.put("pres-rules")
93
+ end
94
+
95
+
96
+ def test_04_put
97
+ show "Replace the document (wrong ETag) => 412"
98
+ begin
99
+ @doc.etag = "wrongETag"
100
+ @client.put("pres-rules")
101
+ rescue => e
102
+ assert_equal( HTTPNoMatchingETag, e.class )
103
+ else
104
+ should_fail
105
+ end
106
+ end
107
+
108
+
109
+ def test_05_put
110
+ show "Replace the document (no ETag) => 200"
111
+ assert @client.put("pres-rules", nil, check_etag=false)
112
+ end
113
+
114
+
115
+ def test_06_delete
116
+ show "Deleting the document (correct ETag) => 200"
117
+ assert @client.delete("pres-rules")
118
+ end
119
+
120
+
121
+ def test_07_delete
122
+ show "Deleting a non existing document (no ETag) => 404"
123
+ @client.delete("pres-rules")
124
+ begin
125
+ @client.delete("pres-rules")
126
+ rescue => e
127
+ assert_equal( HTTPDocumentNotFound, e.class )
128
+ else
129
+ should_fail
130
+ end
131
+ end
132
+
133
+
134
+ def test_08_delete
135
+ show "Deleting the document (wrong ETag) => 412"
136
+ begin
137
+ @doc.etag = "wrongETag"
138
+ @client.delete("pres-rules")
139
+ rescue => e
140
+ assert_equal( HTTPNoMatchingETag, e.class )
141
+ else
142
+ should_fail
143
+ end
144
+ end
145
+
146
+
147
+ def test_09_delete
148
+ show "Deleting the document (no ETag) => 200"
149
+ assert @client.delete("pres-rules", nil, check_etag=false)
150
+ end
151
+
152
+
153
+ def test_10_get_element
154
+ show "Fetching a node (no ETag) => 200"
155
+ assert @client.get_element("pres-rules", nil,
156
+ '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:bob@example.org"]',
157
+ NS,
158
+ check_etag=false)
159
+ end
160
+
161
+
162
+ def test_11_get_element
163
+ show "Fetching a node (correct ETag) => 304"
164
+ begin
165
+ @client.get_element("pres-rules", nil,
166
+ '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
167
+ NS,
168
+ check_etag=true)
169
+ rescue => e
170
+ assert_equal( HTTPDocumentNotModified, e.class )
171
+ else
172
+ should_fail
173
+ end
174
+ end
175
+
176
+
177
+ # NOTE: OpenXCAP doesn't implement fetching element attributes.
178
+ # BUG in OpenXCAP: http://openxcap.org/ticket/122
179
+ def test_12_get_element
180
+ show "Fetching an attribute (no ETag) => 200 (fails in OpenXCAP, bug http://openxcap.org/ticket/122)"
181
+ assert @client.get_element("pres-rules", nil,
182
+ '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]/@id',
183
+ NS,
184
+ check_etag=false)
185
+ end
186
+
187
+
188
+ def test_13_put_element
189
+ show "Creating a node (no ETag) => 201"
190
+ assert @client.put_element("pres-rules", nil,
191
+ '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:new-1@new.net"]',
192
+ '<cp:one id="sip:new-1@new.net"/>',
193
+ NS,
194
+ check_etag=false)
195
+ end
196
+
197
+
198
+ def test_14_put_element
199
+ show "Creating a node (wrong ETag) => 412"
200
+ begin
201
+ @doc.etag = "wrongETag"
202
+ @client.put_element("pres-rules", nil,
203
+ '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:condition/cp:identity/cp:one[@id="sip:new-2@new.net"]',
204
+ '<cp:one id="sip:new-2@new.net"/>',
205
+ NS,
206
+ check_etag=true)
207
+ rescue => e
208
+ assert_equal( HTTPNoMatchingETag, e.class )
209
+ else
210
+ should_fail
211
+ end
212
+ end
213
+
214
+
215
+ def test_15_put_element
216
+ show "Creating a node in wrong position => 409"
217
+ begin
218
+ @client.put_element("pres-rules", nil,
219
+ '/cp:ruleset/cp:rule[@id="non_existing"]/cp:condition/cp:identity/cp:one[@id="sip:new-3@new.net"]',
220
+ '<cp:one id="sip:new-3@new.net"/>',
221
+ NS,
222
+ check_etag=false)
223
+ rescue => e
224
+ assert_equal( HTTPConflictError, e.class )
225
+ else
226
+ should_fail
227
+ end
228
+ end
229
+
230
+
231
+ def test_16_put_element
232
+ show "Creating a node using different NS prefixes than the used in the server document (no ETag) => 409/500"
233
+ begin
234
+ @client.put_element("pres-rules", nil,
235
+ '/ccpp:ruleset/ccpp:rule[@id="pres_whitelist"]/ccpp:conditions/ccpp:identity/ccpp:one[@id="sip:new-4@new.net"]',
236
+ '<ccpp:one id="sip:new-4@new.net"/>',
237
+ {"pprr"=>"urn:ietf:params:xml:ns:pres-rules", "ccpp"=>"urn:ietf:params:xml:ns:common-policy"},
238
+ check_etag=false)
239
+ rescue => e
240
+ assert_equal_options( [ HTTPServerError, HTTPConflictError ], e.class )
241
+ else
242
+ should_fail
243
+ end
244
+ end
245
+
246
+
247
+ # NOTE: This should fail since the selector doesn't match an unique node, but OpenXCAP allows it.
248
+ # BUG in OpenXCAP: http://openxcap.org/ticket/123
249
+ def test_17_put_element
250
+ show "Creating a node using using a non unique selector (no ETag) => 409 (fails in OpenXCAP, bug http://openxcap.org/ticket/123)"
251
+ begin
252
+ @client.put_element("pres-rules", nil,
253
+ '/cp:ruleset/cp:rule/cp:conditions/cp:identity/cp:one[@id="sip:new-5@new.net"]',
254
+ '<cp:one id="sip:new-5@new.net"/>',
255
+ NS,
256
+ check_etag=false)
257
+ rescue
258
+ assert_equal( HTTPConflictError, e.class )
259
+ else
260
+ should_fail
261
+ end
262
+ end
263
+
264
+
265
+ def test_18_delete_element
266
+ show "Deleting an element (no ETag) => 200"
267
+ assert @client.delete_element("pres-rules", nil,
268
+ '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:bob@example.org"]',
269
+ NS,
270
+ check_etag=false)
271
+ end
272
+
273
+
274
+ def test_19_delete_element
275
+ show "Deleting an element (wrong ETag) => 412"
276
+ begin
277
+ @doc.etag = "wrongETag"
278
+ @client.delete_element("pres-rules", nil,
279
+ '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:condition/cp:identity/cp:one[@id="sip:bob@example.org"]',
280
+ NS,
281
+ check_etag=true)
282
+ rescue => e
283
+ assert_equal( HTTPNoMatchingETag, e.class )
284
+ else
285
+ should_fail
286
+ end
287
+ end
288
+
289
+
290
+ def test_20_delete_element
291
+ show "Deleting a no existing element (correct ETag) => 404"
292
+ @client.delete_element("pres-rules", nil,
293
+ '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
294
+ NS)
295
+ begin
296
+ @client.delete_element("pres-rules", nil,
297
+ '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
298
+ NS)
299
+ rescue => e
300
+ assert_equal( HTTPDocumentNotFound, e.class )
301
+ else
302
+ should_fail
303
+ end
304
+ end
305
+
306
+
307
+ # NOTE: OpenXCAP doesn't implement fetching namespaces.
308
+ # BUG in OpenXCAP: http://openxcap.org/ticket/124
309
+ def test_21_get_element_namespaces
310
+ show "Fetching the namespaces associated to a document node => 200 (fails in OpenXCAP, bug http://openxcap.org/ticket/124)"
311
+ assert @client.get_element_namespaces("pres-rules", nil,
312
+ '/ccpp:ruleset/ccpp:rule[@id="pres_whitelist"]/ccpp:conditions/ccpp:identity',
313
+ {"ccpp"=>"urn:ietf:params:xml:ns:common-policy"},
314
+ check_etag=false)
315
+ assert_equal( @client.application("pres-rules").document.last_response.header["Content-Type"], "application/xcap-ns+xml" )
316
+ end
317
+
318
+
319
+ def test_22_get_xcap_auids
320
+ show "Fetching the XCAP server available 'auids' => 200"
321
+ assert @client.get_xcap_auids
322
+ end
323
+
324
+
325
+ def reset_document
326
+ @doc.plain = PRES_RULES
327
+ @doc.etag = nil
328
+ @client.put("pres-rules", nil, check_etag=false) # Upload without cheking ETag.
329
+ end
330
+
331
+
332
+ def show(text)
333
+ puts "\n\n[#{name}] #{text}"
334
+ end
335
+
336
+
337
+ def should_fail
338
+ raise RuntimeError, "It should fail but didn't"
339
+ end
340
+
341
+
342
+ def assert_false(object, message="")
343
+ assert_equal(object, false, message)
344
+ end
345
+
346
+
347
+ def assert_equal_options(options, element)
348
+ assert options.include?(element)
349
+ end
350
+
351
+
352
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xcapclient
3
+ version: !ruby/object:Gem::Version
4
+ version: "1.0"
5
+ platform: ruby
6
+ authors:
7
+ - "I\xC3\xB1aki Baz Castillo"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-31 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: httpclient
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: XCAP (RFC 4825) is a protocol on top of HTTP which allows a client (usually a VoIP/SIP device) to manipulate the contents of Presence Information Data Format (PIDF) based presence documents. These documents are stored in a server in XML format. Ruby xcapclient library implements the XCAP protocol in client side, allowing the applications to get, store, modify and delete XML documents in the server.'
26
+ email: ibc@aliax.net
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.rdoc
33
+ - ERRORS.rdoc
34
+ - LICENSE.txt
35
+ - test/PRES_RULES_EXAMPLE.xml
36
+ files:
37
+ - LICENSE.txt
38
+ - lib/xcapclient/client.rb
39
+ - lib/xcapclient.rb
40
+ - lib/xcapclient/errors.rb
41
+ - lib/xcapclient/application.rb
42
+ - lib/xcapclient/document.rb
43
+ - test/PRES_RULES_EXAMPLE.xml
44
+ - README.rdoc
45
+ - ERRORS.rdoc
46
+ has_rdoc: true
47
+ homepage: http://dev.sipdoc.net/projects/ruby-xcap-client/wiki/
48
+ post_install_message:
49
+ rdoc_options:
50
+ - --main
51
+ - README.rdoc
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 1.8.1
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project: xcapclient
69
+ rubygems_version: 1.3.1
70
+ signing_key:
71
+ specification_version: 2
72
+ summary: XCAP client library
73
+ test_files:
74
+ - test/test_unit_01.rb