ln-xmpp4r 0.5

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 (215) hide show
  1. data/CHANGELOG +91 -0
  2. data/COPYING +340 -0
  3. data/LICENSE +59 -0
  4. data/README.rdoc +113 -0
  5. data/README_ruby19.txt +43 -0
  6. data/Rakefile +252 -0
  7. data/data/doc/xmpp4r/examples/advanced/adventure/README +56 -0
  8. data/data/doc/xmpp4r/examples/advanced/adventure/adventure.rb +23 -0
  9. data/data/doc/xmpp4r/examples/advanced/adventure/adventuremuc.rb +136 -0
  10. data/data/doc/xmpp4r/examples/advanced/adventure/cube.xml +15 -0
  11. data/data/doc/xmpp4r/examples/advanced/adventure/tower.xml +69 -0
  12. data/data/doc/xmpp4r/examples/advanced/adventure/world.rb +424 -0
  13. data/data/doc/xmpp4r/examples/advanced/fileserve.conf +11 -0
  14. data/data/doc/xmpp4r/examples/advanced/fileserve.rb +346 -0
  15. data/data/doc/xmpp4r/examples/advanced/getonline.rb +56 -0
  16. data/data/doc/xmpp4r/examples/advanced/gtkmucclient.rb +315 -0
  17. data/data/doc/xmpp4r/examples/advanced/migrate.rb +88 -0
  18. data/data/doc/xmpp4r/examples/advanced/minimuc.rb +266 -0
  19. data/data/doc/xmpp4r/examples/advanced/pep-aggregator/index.xsl +235 -0
  20. data/data/doc/xmpp4r/examples/advanced/pep-aggregator/pep-aggregator.rb +147 -0
  21. data/data/doc/xmpp4r/examples/advanced/recvfile.rb +84 -0
  22. data/data/doc/xmpp4r/examples/advanced/rosterdiscovery.rb +129 -0
  23. data/data/doc/xmpp4r/examples/advanced/sendfile.conf +10 -0
  24. data/data/doc/xmpp4r/examples/advanced/sendfile.rb +72 -0
  25. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr.rb +51 -0
  26. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_jabber.rb +43 -0
  27. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_test.rb +10 -0
  28. data/data/doc/xmpp4r/examples/advanced/versionpoll.rb +109 -0
  29. data/data/doc/xmpp4r/examples/advanced/xmpping.rb +146 -0
  30. data/data/doc/xmpp4r/examples/advanced/xmppingrc.sample +14 -0
  31. data/data/doc/xmpp4r/examples/basic/change_password.rb +41 -0
  32. data/data/doc/xmpp4r/examples/basic/client.rb +70 -0
  33. data/data/doc/xmpp4r/examples/basic/component.rb +11 -0
  34. data/data/doc/xmpp4r/examples/basic/echo.rb +37 -0
  35. data/data/doc/xmpp4r/examples/basic/jabbersend.rb +41 -0
  36. data/data/doc/xmpp4r/examples/basic/mass_sender.rb +68 -0
  37. data/data/doc/xmpp4r/examples/basic/muc_owner_config.rb +12 -0
  38. data/data/doc/xmpp4r/examples/basic/mucinfo.rb +41 -0
  39. data/data/doc/xmpp4r/examples/basic/mucsimplebot.rb +82 -0
  40. data/data/doc/xmpp4r/examples/basic/register.rb +42 -0
  41. data/data/doc/xmpp4r/examples/basic/remove_registration.rb +18 -0
  42. data/data/doc/xmpp4r/examples/basic/roster.rb +44 -0
  43. data/data/doc/xmpp4r/examples/basic/rosterprint.rb +50 -0
  44. data/data/doc/xmpp4r/examples/basic/rosterrename.rb +34 -0
  45. data/data/doc/xmpp4r/examples/basic/rosterwatch.rb +171 -0
  46. data/data/doc/xmpp4r/examples/basic/send_vcard.rb +67 -0
  47. data/data/doc/xmpp4r/examples/basic/tune_client.rb +56 -0
  48. data/data/doc/xmpp4r/examples/basic/tune_server.rb +58 -0
  49. data/data/doc/xmpp4r/examples/basic/versionbot.rb +75 -0
  50. data/lib/xmpp4r.rb +116 -0
  51. data/lib/xmpp4r/base64.rb +32 -0
  52. data/lib/xmpp4r/bytestreams.rb +15 -0
  53. data/lib/xmpp4r/bytestreams/helper/filetransfer.rb +319 -0
  54. data/lib/xmpp4r/bytestreams/helper/ibb/base.rb +257 -0
  55. data/lib/xmpp4r/bytestreams/helper/ibb/initiator.rb +31 -0
  56. data/lib/xmpp4r/bytestreams/helper/ibb/target.rb +54 -0
  57. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +152 -0
  58. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb +86 -0
  59. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +198 -0
  60. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb +65 -0
  61. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +79 -0
  62. data/lib/xmpp4r/bytestreams/iq/bytestreams.rb +170 -0
  63. data/lib/xmpp4r/bytestreams/iq/si.rb +206 -0
  64. data/lib/xmpp4r/callbacks.rb +133 -0
  65. data/lib/xmpp4r/caps.rb +1 -0
  66. data/lib/xmpp4r/caps/c.rb +67 -0
  67. data/lib/xmpp4r/caps/helper/generator.rb +160 -0
  68. data/lib/xmpp4r/caps/helper/helper.rb +84 -0
  69. data/lib/xmpp4r/client.rb +344 -0
  70. data/lib/xmpp4r/command/helper/responder.rb +53 -0
  71. data/lib/xmpp4r/command/iq/command.rb +154 -0
  72. data/lib/xmpp4r/component.rb +103 -0
  73. data/lib/xmpp4r/connection.rb +223 -0
  74. data/lib/xmpp4r/dataforms.rb +5 -0
  75. data/lib/xmpp4r/dataforms/x/data.rb +297 -0
  76. data/lib/xmpp4r/debuglog.rb +63 -0
  77. data/lib/xmpp4r/delay.rb +5 -0
  78. data/lib/xmpp4r/delay/x/delay.rb +99 -0
  79. data/lib/xmpp4r/discovery.rb +8 -0
  80. data/lib/xmpp4r/discovery/helper/helper.rb +58 -0
  81. data/lib/xmpp4r/discovery/helper/responder.rb +165 -0
  82. data/lib/xmpp4r/discovery/iq/discoinfo.rb +211 -0
  83. data/lib/xmpp4r/discovery/iq/discoitems.rb +147 -0
  84. data/lib/xmpp4r/errors.rb +284 -0
  85. data/lib/xmpp4r/feature_negotiation.rb +5 -0
  86. data/lib/xmpp4r/feature_negotiation/iq/feature.rb +28 -0
  87. data/lib/xmpp4r/framework/base.rb +55 -0
  88. data/lib/xmpp4r/framework/bot.rb +148 -0
  89. data/lib/xmpp4r/httpbinding.rb +5 -0
  90. data/lib/xmpp4r/httpbinding/client.rb +275 -0
  91. data/lib/xmpp4r/idgenerator.rb +37 -0
  92. data/lib/xmpp4r/iq.rb +221 -0
  93. data/lib/xmpp4r/jid.rb +167 -0
  94. data/lib/xmpp4r/last.rb +2 -0
  95. data/lib/xmpp4r/last/helper/helper.rb +37 -0
  96. data/lib/xmpp4r/last/iq/last.rb +67 -0
  97. data/lib/xmpp4r/location.rb +2 -0
  98. data/lib/xmpp4r/location/helper/helper.rb +56 -0
  99. data/lib/xmpp4r/location/location.rb +179 -0
  100. data/lib/xmpp4r/message.rb +180 -0
  101. data/lib/xmpp4r/muc.rb +14 -0
  102. data/lib/xmpp4r/muc/helper/mucbrowser.rb +92 -0
  103. data/lib/xmpp4r/muc/helper/mucclient.rb +462 -0
  104. data/lib/xmpp4r/muc/helper/simplemucclient.rb +332 -0
  105. data/lib/xmpp4r/muc/iq/mucadmin.rb +23 -0
  106. data/lib/xmpp4r/muc/iq/mucadminitem.rb +20 -0
  107. data/lib/xmpp4r/muc/iq/mucowner.rb +15 -0
  108. data/lib/xmpp4r/muc/item.rb +143 -0
  109. data/lib/xmpp4r/muc/x/muc.rb +70 -0
  110. data/lib/xmpp4r/muc/x/mucuserinvite.rb +60 -0
  111. data/lib/xmpp4r/muc/x/mucuseritem.rb +36 -0
  112. data/lib/xmpp4r/presence.rb +232 -0
  113. data/lib/xmpp4r/pubsub.rb +8 -0
  114. data/lib/xmpp4r/pubsub/children/configuration.rb +86 -0
  115. data/lib/xmpp4r/pubsub/children/event.rb +49 -0
  116. data/lib/xmpp4r/pubsub/children/item.rb +35 -0
  117. data/lib/xmpp4r/pubsub/children/items.rb +53 -0
  118. data/lib/xmpp4r/pubsub/children/node_config.rb +48 -0
  119. data/lib/xmpp4r/pubsub/children/publish.rb +38 -0
  120. data/lib/xmpp4r/pubsub/children/retract.rb +41 -0
  121. data/lib/xmpp4r/pubsub/children/subscription.rb +62 -0
  122. data/lib/xmpp4r/pubsub/children/subscription_config.rb +67 -0
  123. data/lib/xmpp4r/pubsub/children/unsubscribe.rb +48 -0
  124. data/lib/xmpp4r/pubsub/helper/nodebrowser.rb +129 -0
  125. data/lib/xmpp4r/pubsub/helper/nodehelper.rb +156 -0
  126. data/lib/xmpp4r/pubsub/helper/oauth_service_helper.rb +90 -0
  127. data/lib/xmpp4r/pubsub/helper/servicehelper.rb +456 -0
  128. data/lib/xmpp4r/pubsub/iq/pubsub.rb +19 -0
  129. data/lib/xmpp4r/query.rb +15 -0
  130. data/lib/xmpp4r/reliable.rb +168 -0
  131. data/lib/xmpp4r/rexmladdons.rb +157 -0
  132. data/lib/xmpp4r/roster.rb +7 -0
  133. data/lib/xmpp4r/roster/helper/roster.rb +522 -0
  134. data/lib/xmpp4r/roster/iq/roster.rb +215 -0
  135. data/lib/xmpp4r/roster/x/roster.rb +138 -0
  136. data/lib/xmpp4r/rpc.rb +2 -0
  137. data/lib/xmpp4r/rpc/helper/client.rb +123 -0
  138. data/lib/xmpp4r/rpc/helper/server.rb +74 -0
  139. data/lib/xmpp4r/rpc/helper/xmlrpcaddons.rb +67 -0
  140. data/lib/xmpp4r/rpc/iq/rpc.rb +23 -0
  141. data/lib/xmpp4r/sasl.rb +248 -0
  142. data/lib/xmpp4r/semaphore.rb +38 -0
  143. data/lib/xmpp4r/stream.rb +599 -0
  144. data/lib/xmpp4r/streamparser.rb +85 -0
  145. data/lib/xmpp4r/test/listener_mocker.rb +118 -0
  146. data/lib/xmpp4r/tune.rb +2 -0
  147. data/lib/xmpp4r/tune/helper/helper.rb +58 -0
  148. data/lib/xmpp4r/tune/tune.rb +113 -0
  149. data/lib/xmpp4r/vcard.rb +6 -0
  150. data/lib/xmpp4r/vcard/helper/vcard.rb +84 -0
  151. data/lib/xmpp4r/vcard/iq/vcard.rb +109 -0
  152. data/lib/xmpp4r/version.rb +7 -0
  153. data/lib/xmpp4r/version/helper/responder.rb +72 -0
  154. data/lib/xmpp4r/version/helper/simpleresponder.rb +44 -0
  155. data/lib/xmpp4r/version/iq/version.rb +105 -0
  156. data/lib/xmpp4r/x.rb +37 -0
  157. data/lib/xmpp4r/xhtml.rb +1 -0
  158. data/lib/xmpp4r/xhtml/html.rb +115 -0
  159. data/lib/xmpp4r/xmpp4r.rb +20 -0
  160. data/lib/xmpp4r/xmppelement.rb +168 -0
  161. data/lib/xmpp4r/xmppstanza.rb +162 -0
  162. data/setup.rb +1586 -0
  163. data/test/bytestreams/tc_ibb.rb +188 -0
  164. data/test/bytestreams/tc_socks5bytestreams.rb +114 -0
  165. data/test/caps/tc_helper.rb +158 -0
  166. data/test/dataforms/tc_data.rb +81 -0
  167. data/test/delay/tc_xdelay.rb +51 -0
  168. data/test/discovery/tc_responder.rb +91 -0
  169. data/test/last/tc_helper.rb +75 -0
  170. data/test/lib/assert_equal_xml.rb +14 -0
  171. data/test/lib/clienttester.rb +149 -0
  172. data/test/muc/tc_muc_mucclient.rb +834 -0
  173. data/test/muc/tc_muc_simplemucclient.rb +114 -0
  174. data/test/muc/tc_mucowner.rb +50 -0
  175. data/test/pubsub/tc_helper.rb +785 -0
  176. data/test/pubsub/tc_nodeconfig.rb +61 -0
  177. data/test/pubsub/tc_subscriptionconfig.rb +41 -0
  178. data/test/reliable/tc_disconnect_cleanup.rb +334 -0
  179. data/test/reliable/tc_disconnect_exception.rb +37 -0
  180. data/test/reliable/tc_listener_mocked_test.rb +68 -0
  181. data/test/reliable/tc_reliable_connection.rb +31 -0
  182. data/test/roster/tc_helper.rb +524 -0
  183. data/test/roster/tc_iqqueryroster.rb +173 -0
  184. data/test/roster/tc_xroster.rb +73 -0
  185. data/test/rpc/tc_helper.rb +96 -0
  186. data/test/tc_callbacks.rb +129 -0
  187. data/test/tc_class_names.rb +146 -0
  188. data/test/tc_client.rb +30 -0
  189. data/test/tc_errors.rb +146 -0
  190. data/test/tc_idgenerator.rb +30 -0
  191. data/test/tc_iq.rb +113 -0
  192. data/test/tc_iqquery.rb +31 -0
  193. data/test/tc_jid.rb +204 -0
  194. data/test/tc_message.rb +131 -0
  195. data/test/tc_presence.rb +150 -0
  196. data/test/tc_rexml.rb +139 -0
  197. data/test/tc_stream.rb +167 -0
  198. data/test/tc_streamComponent.rb +95 -0
  199. data/test/tc_streamError.rb +129 -0
  200. data/test/tc_streamSend.rb +59 -0
  201. data/test/tc_streamparser.rb +125 -0
  202. data/test/tc_xmppstanza.rb +135 -0
  203. data/test/ts_xmpp4r.rb +44 -0
  204. data/test/tune/tc_helper_recv.rb +82 -0
  205. data/test/tune/tc_helper_send.rb +74 -0
  206. data/test/tune/tc_tune.rb +79 -0
  207. data/test/vcard/tc_helper.rb +49 -0
  208. data/test/vcard/tc_iqvcard.rb +62 -0
  209. data/test/version/tc_helper.rb +60 -0
  210. data/test/version/tc_iqqueryversion.rb +97 -0
  211. data/test/xhtml/tc_html.rb +41 -0
  212. data/tools/gen_requires.bash +31 -0
  213. data/tools/xmpp4r-gemspec-test.rb +11 -0
  214. data/xmpp4r.gemspec +238 -0
  215. metadata +280 -0
@@ -0,0 +1,84 @@
1
+ # =XMPP4R - XMPP Library for Ruby
2
+ # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
3
+ # Website::http://home.gna.org/xmpp4r/
4
+
5
+ require 'xmpp4r'
6
+ require 'xmpp4r/discovery'
7
+ require 'xmpp4r/caps/c'
8
+ require 'xmpp4r/caps/helper/generator'
9
+
10
+ module Jabber
11
+ module Caps
12
+ ##
13
+ # A Helper to manage advertising and discovery of entity capabilities.
14
+ #
15
+ # Following XEP-0115 (ver 1.4 http://www.xmpp.org/extensions/xep-0115.html).
16
+ # you can use this Helper to, for example, advertise that your client
17
+ # wishes to receive XEP-0118 User Tune notifications, eg:
18
+ #
19
+ # caps_helper=Jabber::Caps::Helper(cl,
20
+ # [Jabber::Discovery::Identity.new('client',nil,'bot')],
21
+ # [Jabber::Discovery::Feature.new('http://jabber.org/protocol/tune+notify')]
22
+ # )
23
+ class Helper
24
+ attr_accessor :identities, :features, :node
25
+
26
+ ##
27
+ # Construct a new Caps Helper.
28
+ #
29
+ # This will send a <presence> message containing
30
+ # a <c/> (Jabber::Caps::C) stanza to your server.
31
+ # client:: [Jabber::Stream]
32
+ # i:: [Array] of [Jabber::Discovery::Identity] objects that this entity will advertise
33
+ # f:: [Array] of [Jabber::Discovery::Feature] objects that this entity will advertise
34
+ # n:: [String] an identifier representing the software underlying this entity
35
+ def initialize(client,i=[],f=[],n="http://home.gna.org/xmpp4r/##{Jabber::XMPP4R_VERSION}")
36
+ @stream = client
37
+ @identities = i
38
+ @features = f
39
+ @node = n
40
+
41
+ @stream.add_iq_callback(250) do |iq|
42
+ if iq.type == :get and iq.query.kind_of? Jabber::Discovery::IqQueryDiscoInfo
43
+ handle_discoinfo_query(iq)
44
+ true
45
+ else
46
+ false
47
+ end
48
+ end
49
+
50
+ p = Jabber::Presence.new()
51
+ p.add(c)
52
+ @stream.send(p)
53
+ end
54
+
55
+ ##
56
+ # Return a <c/> element for inclusion in your own <presence>
57
+ # stanzas.
58
+ def c
59
+ Jabber::Caps::C.new(node, ver)
60
+ end
61
+
62
+ ##
63
+ # Send actual identities/ features back to a requesting entity
64
+ def handle_discoinfo_query(iq)
65
+ caps_reply = Jabber::XMPPStanza.answer(iq)
66
+ caps_reply.type = :result
67
+ caps_reply.query = Jabber::Discovery::IqQueryDiscoInfo.new
68
+ @identities.each { |i| caps_reply.query.add(i) }
69
+ @features.each { |f| caps_reply.query.add(f) }
70
+
71
+ @stream.send(caps_reply)
72
+ end
73
+
74
+ ##
75
+ # Generate 'ver', an opaque hash used to represent this entity's
76
+ # capabilities
77
+ #
78
+ # See http://www.xmpp.org/extensions/xep-0115.html#ver
79
+ def ver
80
+ Caps::generate_ver(@identities, @features)
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,344 @@
1
+ # =XMPP4R - XMPP Library for Ruby
2
+ # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
3
+ # Website::http://home.gna.org/xmpp4r/
4
+
5
+ require 'resolv'
6
+ require 'xmpp4r/connection'
7
+ require 'xmpp4r/sasl'
8
+
9
+ module Jabber
10
+
11
+ # The client class provides everything needed to build a basic XMPP
12
+ # Client.
13
+ #
14
+ # If you want your connection to survive disconnects and timeouts,
15
+ # catch exception in Stream#on_exception and re-call Client#connect
16
+ # and Client#auth. Don't forget to re-send initial Presence and
17
+ # everything else you need to setup your session.
18
+ class Client < Connection
19
+
20
+ # The client's JID
21
+ attr_reader :jid
22
+
23
+ ##
24
+ # Create a new Client.
25
+ #
26
+ # Remember to *always* put a resource in your JID unless the server can do SASL.
27
+ def initialize(jid)
28
+ super()
29
+ @jid = (jid.kind_of?(JID) ? jid : JID.new(jid.to_s))
30
+ end
31
+
32
+ ##
33
+ # connect to the server
34
+ # (chaining-friendly)
35
+ #
36
+ # If you omit the optional host argument SRV records for your jid will
37
+ # be resolved. If none works, fallback is connecting to the domain part
38
+ # of the jid.
39
+ # host:: [String] Optional c2s host, will be extracted from jid if nil
40
+ # use_ssl:: [Boolean] Optional. Use (old, deprecated) SSL when connecting.
41
+ # return:: self
42
+ def connect(host = nil, port = 5222)
43
+ if host.nil?
44
+ begin
45
+ srv = []
46
+ Resolv::DNS.open { |dns|
47
+ # If ruby version is too old and SRV is unknown, this will raise a NameError
48
+ # which is caught below
49
+ Jabber::debuglog("RESOLVING:\n_xmpp-client._tcp.#{@jid.domain} (SRV)")
50
+ srv = dns.getresources("_xmpp-client._tcp.#{@jid.domain}", Resolv::DNS::Resource::IN::SRV)
51
+ }
52
+ # Sort SRV records: lowest priority first, highest weight first
53
+ srv.sort! { |a,b| (a.priority != b.priority) ? (a.priority <=> b.priority) : (b.weight <=> a.weight) }
54
+
55
+ srv.each { |record|
56
+ begin
57
+ connect(record.target.to_s, record.port)
58
+ # Success
59
+ return self
60
+ rescue SocketError, Errno::ECONNREFUSED
61
+ # Try next SRV record
62
+ end
63
+ }
64
+ rescue NameError
65
+ Jabber::debuglog "Resolv::DNS does not support SRV records. Please upgrade to ruby-1.8.3 or later!"
66
+ end
67
+ # Fallback to normal connect method
68
+ end
69
+
70
+ super(host.nil? ? jid.domain : host, port)
71
+ self
72
+ end
73
+
74
+ ##
75
+ # Close the connection,
76
+ # sends <tt></stream:stream></tt> tag first
77
+ def close
78
+ if @status == CONNECTED
79
+ send("</stream:stream>")
80
+ end
81
+ super
82
+ end
83
+
84
+ ##
85
+ # Start the stream-parser and send the client-specific stream opening element
86
+ def start
87
+ super
88
+ send(generate_stream_start(@jid.domain)) { |e|
89
+ if e.name == 'stream'
90
+ true
91
+ else
92
+ false
93
+ end
94
+ }
95
+ end
96
+
97
+ ##
98
+ # Authenticate with the server
99
+ #
100
+ # Throws ClientAuthenticationFailure
101
+ #
102
+ # Authentication mechanisms are used in the following preference:
103
+ # * SASL DIGEST-MD5
104
+ # * SASL PLAIN
105
+ # * Non-SASL digest
106
+ # password:: [String]
107
+ def auth(password)
108
+ begin
109
+ if @stream_mechanisms.include? 'DIGEST-MD5'
110
+ auth_sasl SASL.new(self, 'DIGEST-MD5'), password
111
+ elsif @stream_mechanisms.include? 'PLAIN'
112
+ auth_sasl SASL.new(self, 'PLAIN'), password
113
+ else
114
+ auth_nonsasl(password)
115
+ end
116
+ rescue
117
+ Jabber::debuglog("#{$!.class}: #{$!}\n#{$!.backtrace.join("\n")}")
118
+ raise ClientAuthenticationFailure.new, $!.to_s
119
+ end
120
+ end
121
+
122
+ ##
123
+ # Resource binding (RFC3920bis-06 - section 8.)
124
+ #
125
+ # XMPP allows to bind to multiple resources
126
+ def bind(desired_resource=nil)
127
+ iq = Iq.new(:set)
128
+ bind = iq.add REXML::Element.new('bind')
129
+ bind.add_namespace @stream_features['bind']
130
+ if desired_resource
131
+ resource = bind.add REXML::Element.new('resource')
132
+ resource.text = desired_resource
133
+ end
134
+
135
+ jid = nil
136
+ send_with_id(iq) do |reply|
137
+ reply_bind = reply.first_element('bind')
138
+ if reply_bind
139
+ reported_jid = reply_bind.first_element('jid')
140
+ if reported_jid and reported_jid.text
141
+ jid = JID.new(reported_jid.text)
142
+ end
143
+ end
144
+ end
145
+ jid
146
+ end
147
+
148
+ ##
149
+ # Resource unbinding (RFC3920bis-06 - section 8.6.3.)
150
+ def unbind(desired_resource)
151
+ iq = Iq.new(:set)
152
+ unbind = iq.add REXML::Element.new('unbind')
153
+ unbind.add_namespace @stream_features['unbind']
154
+ resource = unbind.add REXML::Element.new('resource')
155
+ resource.text = desired_resource
156
+
157
+ send_with_id(iq)
158
+ end
159
+
160
+ ##
161
+ # Use a SASL authentication mechanism and bind to a resource
162
+ #
163
+ # If there was no resource given in the jid, the jid/resource
164
+ # generated by the server will be accepted.
165
+ #
166
+ # This method should not be used directly. Instead, Client#auth
167
+ # may look for the best mechanism suitable.
168
+ # sasl:: Descendant of [Jabber::SASL::Base]
169
+ # password:: [String]
170
+ def auth_sasl(sasl, password)
171
+ sasl.auth(password)
172
+
173
+ # Restart stream after SASL auth
174
+ stop
175
+ start
176
+ # And wait for features - again
177
+ @features_sem.wait
178
+
179
+ # Resource binding (RFC3920 - 7)
180
+ if @stream_features.has_key? 'bind'
181
+ @jid = bind(@jid.resource)
182
+ end
183
+
184
+ # Session starting
185
+ if @stream_features.has_key? 'session'
186
+ iq = Iq.new(:set)
187
+ session = iq.add REXML::Element.new('session')
188
+ session.add_namespace @stream_features['session']
189
+
190
+ send_with_id(iq)
191
+ end
192
+ end
193
+
194
+ ##
195
+ # See Client#auth_anonymous_sasl
196
+ def auth_anonymous
197
+ auth_anonymous_sasl
198
+ end
199
+
200
+
201
+ ##
202
+ # Shortcut for anonymous connection to server
203
+ #
204
+ # Throws ClientAuthenticationFailure
205
+ def auth_anonymous_sasl
206
+ if self.supports_anonymous?
207
+ begin
208
+ auth_sasl SASL.new(self, 'ANONYMOUS'), ""
209
+ rescue
210
+ Jabber::debuglog("#{$!.class}: #{$!}\n#{$!.backtrace.join("\n")}")
211
+ raise ClientAuthenticationFailure, $!.to_s
212
+ end
213
+ else
214
+ raise ClientAuthenticationFailure, 'Anonymous authentication unsupported'
215
+ end
216
+ end
217
+
218
+ ##
219
+ # Reports whether or not anonymous authentication is reported
220
+ # by the client.
221
+ #
222
+ # Returns true or false
223
+ def supports_anonymous?
224
+ @stream_mechanisms.include? 'ANONYMOUS'
225
+ end
226
+
227
+ ##
228
+ # Send auth with given password and wait for result
229
+ # (non-SASL)
230
+ #
231
+ # Throws ServerError
232
+ # password:: [String] the password
233
+ # digest:: [Boolean] use Digest authentication
234
+ def auth_nonsasl(password, digest=true)
235
+ authset = nil
236
+ if digest
237
+ authset = Iq.new_authset_digest(@jid, @streamid.to_s, password)
238
+ else
239
+ authset = Iq.new_authset(@jid, password)
240
+ end
241
+ send_with_id(authset)
242
+ $defout.flush
243
+
244
+ true
245
+ end
246
+
247
+ ##
248
+ # Get instructions and available fields for registration
249
+ # return:: [instructions, fields] Where instructions is a String and fields is an Array of Strings
250
+ def register_info
251
+ instructions = nil
252
+ fields = []
253
+
254
+ reg = Iq.new_registerget
255
+ reg.to = jid.domain
256
+ send_with_id(reg) do |answer|
257
+ if answer.query
258
+ answer.query.each_element { |e|
259
+ if e.namespace == 'jabber:iq:register'
260
+ if e.name == 'instructions'
261
+ instructions = e.text.strip
262
+ else
263
+ fields << e.name
264
+ end
265
+ end
266
+ }
267
+ end
268
+
269
+ true
270
+ end
271
+
272
+ [instructions, fields]
273
+ end
274
+
275
+ ##
276
+ # Register a new user account
277
+ # (may be used instead of Client#auth)
278
+ #
279
+ # This method may raise ServerError if the registration was
280
+ # not successful.
281
+ #
282
+ # password:: String
283
+ # fields:: {String=>String} additional registration information
284
+ #
285
+ # XEP-0077 Defines the following fields for registration information:
286
+ # http://www.xmpp.org/extensions/xep-0077.html
287
+ #
288
+ # 'username' => 'Account name associated with the user'
289
+ # 'nick' => 'Familiar name of the user'
290
+ # 'password' => 'Password or secret for the user'
291
+ # 'name' => 'Full name of the user'
292
+ # 'first' => 'First name or given name of the user'
293
+ # 'last' => 'Last name, surname, or family name of the user'
294
+ # 'email' => 'Email address of the user'
295
+ # 'address' => 'Street portion of a physical or mailing address'
296
+ # 'city' => 'Locality portion of a physical or mailing address'
297
+ # 'state' => 'Region portion of a physical or mailing address'
298
+ # 'zip' => 'Postal code portion of a physical or mailing address'
299
+ # 'phone' => 'Telephone number of the user'
300
+ # 'url' => 'URL to web page describing the user'
301
+ # 'date' => 'Some date (e.g., birth date, hire date, sign-up date)'
302
+ #
303
+ def register(password, fields={})
304
+ reg = Iq.new_register(jid.node, password)
305
+ reg.to = jid.domain
306
+ fields.each { |name,value|
307
+ reg.query.add(REXML::Element.new(name)).text = value
308
+ }
309
+
310
+ send_with_id(reg)
311
+ end
312
+
313
+ ##
314
+ # Remove the registration of a user account
315
+ #
316
+ # *WARNING:* this deletes your roster and everything else
317
+ # stored on the server!
318
+ def remove_registration
319
+ reg = Iq.new_register
320
+ reg.to = jid.domain
321
+ reg.query.add(REXML::Element.new('remove'))
322
+ send_with_id(reg)
323
+ end
324
+
325
+ ##
326
+ # Change the client's password
327
+ #
328
+ # Threading is suggested, as this code waits
329
+ # for an answer.
330
+ #
331
+ # Raises an exception upon error response (ServerError from
332
+ # Stream#send_with_id).
333
+ # new_password:: [String] New password
334
+ def password=(new_password)
335
+ iq = Iq.new_query(:set, @jid.domain)
336
+ iq.query.add_namespace('jabber:iq:register')
337
+ iq.query.add(REXML::Element.new('username')).text = @jid.node
338
+ iq.query.add(REXML::Element.new('password')).text = new_password
339
+
340
+ err = nil
341
+ send_with_id(iq)
342
+ end
343
+ end
344
+ end
@@ -0,0 +1,53 @@
1
+ module Jabber
2
+
3
+ module Command
4
+
5
+ ##
6
+ # The Responder Helper handles the low-level stuff of the
7
+ # Ad-hoc commands (JEP 0050).
8
+ class Responder
9
+
10
+ ##
11
+ # Initialize a Responder
12
+ def initialize(stream)
13
+ @stream = stream
14
+ @commandsdiscocbs = CallbackList.new
15
+ @commandexeccbs = CallbackList.new
16
+
17
+ stream.add_iq_callback(180, self) { |iq|
18
+ iq_callback(iq)
19
+ }
20
+ end
21
+
22
+ ##
23
+ # Add a callback for <query> stanzas asking for the list
24
+ # of ad-hoc commands
25
+ def add_commands_disco_callback(priority = 0, ref = nil, &block)
26
+ @commandsdiscocbs.add(priority, ref, block)
27
+ end
28
+
29
+ ##
30
+ # Add a callback for <command> stanzas asking for the execution
31
+ # of an ad-hoc command
32
+ def add_commands_exec_callback(priority = 0, ref = nil, &block)
33
+ @commandexeccbs.add(priority, ref, block)
34
+ end
35
+
36
+ ##
37
+ # Handles <iq> stanzas and execute callbacks
38
+ def iq_callback(iq)
39
+ if iq.type == :get
40
+ if iq.query.kind_of?(Jabber::Discovery::IqQueryDiscoItems) &&
41
+ iq.query.node == "http://jabber.org/protocol/commands"
42
+ @commandsdiscocbs.process(iq)
43
+ end
44
+ elsif iq.type == :set && iq.command
45
+ @commandexeccbs.process(iq)
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+ end