xcapclient 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ERRORS.rdoc +123 -0
- data/LICENSE.txt +674 -0
- data/README.rdoc +172 -0
- data/lib/xcapclient/application.rb +62 -0
- data/lib/xcapclient/client.rb +584 -0
- data/lib/xcapclient/document.rb +40 -0
- data/lib/xcapclient/errors.rb +21 -0
- data/lib/xcapclient.rb +30 -0
- data/test/PRES_RULES_EXAMPLE.xml +49 -0
- data/test/test_unit_01.rb +352 -0
- metadata +74 -0
data/README.rdoc
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
= XCAPClient
|
2
|
+
|
3
|
+
* http://dev.sipdoc.net/projects/ruby-xcapclient/wiki/
|
4
|
+
* http://rubyforge.org/projects/xcapclient/
|
5
|
+
|
6
|
+
|
7
|
+
== Description
|
8
|
+
|
9
|
+
XCAP ({RFC 4825}[http://tools.ietf.org/html/rfc4825]) is a protocol on top of HTTP which allows a client to manipulate the contents of Presence Information Data Format (PIDF) based presence documents. These documents are stored in a server in XML format and are fetched, modified, replaced or deleted by the client. The protocol allows multiple clients to manipulate the data, provided that they are authorized to do so. XCAP is already used in SIMPLE-based presence systems for manipulation of presence lists and presence authorization policies.
|
10
|
+
|
11
|
+
XCAPClient library implements the XCAP protocol in client side, allowing the applications to get, store, modify and delete XML documents in the server.
|
12
|
+
|
13
|
+
|
14
|
+
== Features
|
15
|
+
|
16
|
+
The library implements the following features:
|
17
|
+
|
18
|
+
* Fetch, create/replace and delete a document.
|
19
|
+
* Fetch, create/replace and delete a document element (XML node).
|
20
|
+
* Fetch, create/replace and delete an element attribute.
|
21
|
+
* Full configurable parameters allowing customized fields for each XCAP application, such auid, XML namespace, MIME-Type, scope (:user or :global) and default document name ("index" if not set).
|
22
|
+
* Fetch the namespaces and prefixes of a document node as they are used in the server.
|
23
|
+
* Manage of multiple documents per XCAP application.
|
24
|
+
* Fetch the XCAP server auids, extensions and namespaces ("xcap-caps" application).
|
25
|
+
* SSL.
|
26
|
+
* Digest and Basic HTTP authentication.
|
27
|
+
* Raise custom Ruby exception for each HTTP error response.
|
28
|
+
|
29
|
+
|
30
|
+
Ruby XCAPClient works in Ruby 1.8 and 1.9.
|
31
|
+
|
32
|
+
|
33
|
+
== Support
|
34
|
+
|
35
|
+
The XCAPClient mailing list is available here:
|
36
|
+
|
37
|
+
* http://rubyforge.org/mailman/listinfo/xcapclient-devel
|
38
|
+
|
39
|
+
The bug tracker is available here:
|
40
|
+
|
41
|
+
* http://dev.sipdoc.net/projects/ruby-xcapclient/issues
|
42
|
+
|
43
|
+
|
44
|
+
== API
|
45
|
+
|
46
|
+
A developer interested in this library should study the following documents:
|
47
|
+
* XCAPClient::Client
|
48
|
+
* XCAPClient::Application
|
49
|
+
* XCAPClient::Document
|
50
|
+
* ERRORS.rdoc
|
51
|
+
|
52
|
+
|
53
|
+
== Synopsis
|
54
|
+
|
55
|
+
require 'rubygems'
|
56
|
+
require 'xcapclient'
|
57
|
+
|
58
|
+
|
59
|
+
==== Create a client
|
60
|
+
|
61
|
+
xcap_conf = {
|
62
|
+
:xcap_root => "https://xcap.myserver.org/xcap-root",
|
63
|
+
:user => "sip:me@mydomain.org",
|
64
|
+
:auth_user => "me",
|
65
|
+
:password => "xxxxxx",
|
66
|
+
:ssl_verify_cert => true
|
67
|
+
}
|
68
|
+
|
69
|
+
xcap_apps = {
|
70
|
+
"pres-rules" => {
|
71
|
+
:xmlns => "urn:ietf:params:xml:ns:pres-rules",
|
72
|
+
:mime_type => "application/auth-policy+xml",
|
73
|
+
:scope => :user,
|
74
|
+
:document_name => "index"
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
@xcapclient = Client.new(xcap_conf, xcap_apps)
|
79
|
+
|
80
|
+
|
81
|
+
==== Fetch the "pres-rules" document from the server
|
82
|
+
|
83
|
+
@xcapclient.get("pres-rules")
|
84
|
+
|
85
|
+
|
86
|
+
==== Fetch again the "pres-rules" document (now including the stored ETag)
|
87
|
+
|
88
|
+
By default, the methods accesing the XCAP server include the ETag if it's available. Since it was already got on the previous request, it's included in the new request. If the document has not been modified in the server by other client, the server replies "304 Not Modified" and the method generates a XCAPClient::XCAPClientError::HTTPDocumentNotModified exception.
|
89
|
+
|
90
|
+
begin
|
91
|
+
@xcapclient.get("pres-rules")
|
92
|
+
rescue XCAPClientError::HTTPDocumentNotModified
|
93
|
+
puts "The document has not been modified in the server."
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
==== Replace the local document and upload it to the server
|
98
|
+
|
99
|
+
@xcapclient.application("pres-rules").document.reset
|
100
|
+
@xcapclient.application("pres-rules").document.plain = "<?xml version='1.0' encoding='UTF-8'?> ..."
|
101
|
+
@xcapclient.put("pres-rules")
|
102
|
+
|
103
|
+
|
104
|
+
==== Delete the document in the server
|
105
|
+
|
106
|
+
@xcapclient.delete("pres-rules")
|
107
|
+
|
108
|
+
|
109
|
+
==== Create a new document and upload it (a new "vacation-rules" document for "pres-rules" application)
|
110
|
+
|
111
|
+
my_pres_rules_2 = @xcapclient.application("pres-rules).add_document("vacation-rules")
|
112
|
+
my_pres_rules_2.plain = "<?xml version='1.0' encoding='UTF-8'?> ..."
|
113
|
+
@xcapclient.put("pres-rules", my_pres_rules_2)
|
114
|
+
# or
|
115
|
+
@xcapclient.put("pres-rules", "vacation-rules")
|
116
|
+
|
117
|
+
|
118
|
+
==== Fetch an element
|
119
|
+
|
120
|
+
@xcapclient.get_element("pres-rules", nil,
|
121
|
+
'/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
122
|
+
{"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
123
|
+
|
124
|
+
|
125
|
+
==== Add a new element (a new allowed user in "pres-rules" document)
|
126
|
+
|
127
|
+
@xcapclient.put_element("pres-rules", nil,
|
128
|
+
'/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:bob@example.org"]',
|
129
|
+
'<cp:one id="sip:bob@example.org"/>',
|
130
|
+
{"cp"=>"urn:ietf:params:xml:ns:common-policy"})
|
131
|
+
|
132
|
+
|
133
|
+
== ToDo
|
134
|
+
|
135
|
+
* Parse 409 error response ("application/xcap-error+xml") as it contains the explanation of the conflict ({RFC 4825 section 11}[http://tools.ietf.org/html/rfc4825#section-11]).
|
136
|
+
|
137
|
+
|
138
|
+
== Requeriments
|
139
|
+
|
140
|
+
* Ruby 1.8 or 1.9
|
141
|
+
* HTTPClient[http://dev.ctor.org/http-access2]
|
142
|
+
* Nokogiri[http://wiki.github.com/tenderlove/nokogiri] (optional, it provides some non vital features)
|
143
|
+
|
144
|
+
|
145
|
+
== Install
|
146
|
+
|
147
|
+
gem install xcapclient
|
148
|
+
|
149
|
+
|
150
|
+
== Test Unit
|
151
|
+
|
152
|
+
The GEM includes a Test Unit script located in "test" directory name "test_unit_01.rb". It performs various XCAP queries against a XCAP server using the test/PRES_RULES_EXAMPLE.xml document.
|
153
|
+
|
154
|
+
*NOTE:* You must edit the settings with your own values (edit the top lines of the script).
|
155
|
+
|
156
|
+
|
157
|
+
== License
|
158
|
+
|
159
|
+
GNU GENERAL PUBLIC LICENSE
|
160
|
+
Version 3, 29 June 2007
|
161
|
+
|
162
|
+
(see LICENSE.txt)
|
163
|
+
|
164
|
+
|
165
|
+
== Author
|
166
|
+
|
167
|
+
Iñaki Baz Castillo
|
168
|
+
|
169
|
+
* mailto:ibc@aliax.net
|
170
|
+
* http://dev.sipdoc.net
|
171
|
+
|
172
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module XCAPClient
|
2
|
+
|
3
|
+
class Application
|
4
|
+
|
5
|
+
attr_reader :auid, :xmlns, :mime_type, :document_name, :scope
|
6
|
+
|
7
|
+
def initialize(auid, data={}) #:nodoc:
|
8
|
+
|
9
|
+
@auid = auid
|
10
|
+
|
11
|
+
# Check application data.
|
12
|
+
raise ConfigError, "Application `data' must be a hash ('#{@auid}')" unless (Hash === data)
|
13
|
+
|
14
|
+
@xmlns = data[:xmlns].freeze
|
15
|
+
@mime_type = data[:mime_type].freeze
|
16
|
+
@document_name = data[:document_name] || "index"
|
17
|
+
@scope = data[:scope] || :user
|
18
|
+
@scope.freeze
|
19
|
+
|
20
|
+
# Check auid.
|
21
|
+
raise ConfigError, "Application `auid' must be a non empty string ('#{@auid}')" unless String === @auid && ! @auid.empty?
|
22
|
+
|
23
|
+
# Check xmlns.
|
24
|
+
raise ConfigError, "Application `xmlns' must be a non empty string ('#{@auid}')" unless String === @xmlns && ! @xmlns.empty?
|
25
|
+
|
26
|
+
# Check mime-type.
|
27
|
+
raise ConfigError, "Application `mime_type' must be a non empty string ('#{@auid}')" unless String === @mime_type && ! @mime_type.empty?
|
28
|
+
|
29
|
+
# Check document_name
|
30
|
+
raise ConfigError, "Application `document_name' must be a non empty string ('#{@auid}')" unless String === @document_name && ! @document_name.empty?
|
31
|
+
|
32
|
+
# Check scope.
|
33
|
+
raise ConfigError, "Application `scope' must be :user or :global ('#{@auid}')" unless [:user, :global].include?(@scope)
|
34
|
+
|
35
|
+
# Create first document.
|
36
|
+
@documents = {}
|
37
|
+
@documents[@document_name] = Document.new(@document_name)
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
# Get the XCAPClient::Document with name _document_name_ within this application. If the parameter is not set, the default document is got.
|
42
|
+
#
|
43
|
+
def document(document_name=nil)
|
44
|
+
@documents[document_name || @document_name]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Get an Array containing all the documents created for this application.
|
48
|
+
def documents
|
49
|
+
@documents
|
50
|
+
end
|
51
|
+
|
52
|
+
# Creates a new XCAPClient::Document for this application with name _document_name_.
|
53
|
+
def add_document(document_name)
|
54
|
+
raise DocumentError, "document '#{document_name}' already exists" if @documents[document_name]
|
55
|
+
@documents[document_name] = Document.new(document_name)
|
56
|
+
|
57
|
+
return @documents[document_name]
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|