jabber4r-revive 0.9.0 → 0.10.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.
Files changed (45) hide show
  1. data/.gitignore +5 -4
  2. data/.rspec +3 -3
  3. data/.travis.yml +7 -7
  4. data/CHANGELOG +11 -1
  5. data/Gemfile +3 -3
  6. data/README.md +29 -29
  7. data/Rakefile +70 -70
  8. data/jabber4r-revive.gemspec +25 -25
  9. data/lib/jabber4r.rb +38 -33
  10. data/lib/jabber4r/bosh.rb +21 -0
  11. data/lib/jabber4r/bosh/authentication.rb +13 -0
  12. data/lib/jabber4r/bosh/authentication/non_sasl.rb +219 -0
  13. data/lib/jabber4r/bosh/authentication/sasl.rb +239 -0
  14. data/lib/jabber4r/bosh/session.rb +144 -0
  15. data/lib/jabber4r/connection.rb +259 -258
  16. data/lib/jabber4r/debugger.rb +60 -60
  17. data/lib/jabber4r/jid.rb +20 -19
  18. data/lib/jabber4r/protocol.rb +249 -257
  19. data/lib/jabber4r/protocol/authentication.rb +14 -0
  20. data/lib/jabber4r/protocol/authentication/non_sasl.rb +138 -0
  21. data/lib/jabber4r/protocol/authentication/sasl.rb +88 -0
  22. data/lib/jabber4r/protocol/iq.rb +259 -259
  23. data/lib/jabber4r/protocol/message.rb +245 -245
  24. data/lib/jabber4r/protocol/parsed_xml_element.rb +207 -207
  25. data/lib/jabber4r/protocol/presence.rb +160 -160
  26. data/lib/jabber4r/protocol/xml_element.rb +143 -143
  27. data/lib/jabber4r/rexml_1.8_patch.rb +15 -15
  28. data/lib/jabber4r/roster.rb +38 -38
  29. data/lib/jabber4r/session.rb +615 -615
  30. data/lib/jabber4r/version.rb +10 -3
  31. data/spec/lib/jabber4r/bosh/authentication/non_sasl_spec.rb +79 -0
  32. data/spec/lib/jabber4r/bosh/authentication/sasl_spec.rb +42 -0
  33. data/spec/lib/jabber4r/bosh/session_spec.rb +406 -0
  34. data/spec/lib/jabber4r/bosh_spec.rb +0 -0
  35. data/spec/lib/jabber4r/connection_spec.rb +174 -174
  36. data/spec/lib/jabber4r/debugger_spec.rb +35 -35
  37. data/spec/lib/jabber4r/jid_spec.rb +197 -197
  38. data/spec/lib/jabber4r/protocol/authentication/non_sasl_spec.rb +79 -0
  39. data/spec/lib/jabber4r/protocol/authentication/sasl_spec.rb +42 -0
  40. data/spec/spec_helper.rb +11 -11
  41. data/spec/support/mocks/tcp_socket_mock.rb +8 -8
  42. metadata +61 -45
  43. data/Gemfile.lock +0 -45
  44. data/lib/jabber4r/bosh_session.rb +0 -224
  45. data/spec/lib/jabber4r/bosh_session_spec.rb +0 -150
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
- .rvmrc
2
-
3
- tmp/
4
- pkg/
1
+ .rvmrc
2
+ Gemfile.lock
3
+
4
+ tmp/
5
+ pkg/
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
- --color
2
- --format progress
3
- --order random
1
+ --color
2
+ --format progress
3
+ --order random
data/.travis.yml CHANGED
@@ -1,8 +1,8 @@
1
- language: ruby
2
- rvm:
3
- - 1.9.2
4
- - 1.9.3
5
- branches:
6
- only:
7
- - master
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ branches:
6
+ only:
7
+ - master
8
8
  script: bundle exec rspec
data/CHANGELOG CHANGED
@@ -1,15 +1,25 @@
1
1
 
2
+ v0.10.0
3
+ - 2013/07/08: fix(changelog) fixed version recognition (Strech (aka Sergey Fedorov))
4
+ - 2013/07/05: feature(bosh) added authentication via sasl and non-sasl technology (Strech (aka Sergey Fedorov))
5
+ - 2013/07/02: fix(rfc) added 'version' attribute to plain open stream tag (Strech (aka Sergey Fedorov))
6
+ - 2013/06/28: chore(gemspec) removed Gemfile.lock (Strech (aka Sergey Fedorov))
7
+ - 2013/06/28: style(protocol) removed debug information (Strech (aka Sergey Fedorov))
8
+ - 2013/06/28: refactor(all) change host to domain (Aelphy)
9
+ - 2013/06/26: style(all) debug methods added (Strech (aka Sergey Fedorov))
10
+
2
11
  v0.9.0
12
+ - 2013/06/26: Release 0.9.0 (Strech (aka Sergey Fedorov))
3
13
  - 2013/06/26: feature(changelog) added changelog file (Strech (aka Sergey Fedorov))
4
14
  - 2013/06/26: Jabber::BoshSession : Modified to_json method (Strech (aka Sergey Fedorov))
5
15
  - 2013/06/25: Jabber::BoshSession : XMPP over BOSH (XEP-0206) (Strech (aka Sergey Fedorov))
6
16
  - 2013/06/20: Jabber::Connection : Change method parse_failure (Strech (aka Sergey Fedorov))
7
17
  - 2013/06/20: Jabber::Connection : Refactoring (Strech (aka Sergey Fedorov))
8
18
  - 2013/06/20: Rspec : Socket mock changed. Jabber::Connection : Specs for #send (Strech (aka Sergey Fedorov))
19
+ - 2013/06/20: Jabber::Connection : add_filter and remove_filter refactoring (Strech (aka Sergey Fedorov))
9
20
  - 2013/06/20: Rspec : Change rspec dummy text (Strech (aka Sergey Fedorov))
10
21
  - 2013/06/20: Jabber::Debugger : Added (Strech (aka Sergey Fedorov))
11
22
  - 2013/06/20: Jabber : Moved up on one level (Strech (aka Sergey Fedorov))
12
- - 2013/06/20: Jabber::Connection : add_filter and remove_filter refactoring (Strech (aka Sergey Fedorov))
13
23
  - 2013/06/20: F (Strech (aka Sergey Fedorov))
14
24
  - 2013/06/20: F (Strech (aka Sergey Fedorov))
15
25
  - 2013/06/19: Jabber::Connection : New method force_close! added (Strech (aka Sergey Fedorov))
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.md CHANGED
@@ -1,29 +1,29 @@
1
- # Jabber4r (revive)
2
-
3
- Original [README](http://rubydoc.info/gems/jabber4r/file/README) and original [jabber4r web-site](http://jabber4r.rubyforge.org/)
4
-
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
8
-
9
- gem 'jabber4r-revive'
10
-
11
- And then execute:
12
-
13
- $ bundle
14
-
15
- Or install it yourself as:
16
-
17
- $ gem install jabber4r-revive
18
-
19
- ## Usage
20
-
21
- TODO: Write usage instructions here
22
-
23
- ## Contributing
24
-
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
1
+ # Jabber4r (revive)
2
+
3
+ Original [README](http://rubydoc.info/gems/jabber4r/file/README) and original [jabber4r web-site](http://jabber4r.rubyforge.org/)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'jabber4r-revive'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install jabber4r-revive
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile CHANGED
@@ -1,71 +1,71 @@
1
- # coding: utf-8
2
-
3
- require "bundler/gem_tasks"
4
- require "pty"
5
-
6
- # ============================== Support =======================================
7
-
8
- ROOT_PATH = File.expand_path("..", __FILE__)
9
- VERSION_PATH = File.join(ROOT_PATH, "lib", "jabber4r", "version.rb")
10
- CHANGELOG_PATH = File.join(ROOT_PATH, "CHANGELOG")
11
-
12
- # get current version from version.rb file
13
- def current_version
14
- version = File.read(VERSION_PATH).gsub(/[^\d\.]+/, "").strip.chomp
15
- end
16
-
17
- # get released version from git
18
- def released_version
19
- /\Av([\d\.]+)\z/ === `git describe --tags --abbrev=0 2>/dev/null || echo 'v0.0.0'`.chomp.strip
20
-
21
- $1
22
- end
23
-
24
- # run +cmd+ in subprocess, redirect its stdout to parent's stdout
25
- def spawn(cmd, stdout = STDOUT)
26
- puts ">> #{cmd}"
27
-
28
- cmd += ' 2>&1'
29
- PTY.spawn cmd do |r, w, pid|
30
- begin
31
- r.sync
32
- r.each_char { |chr| stdout.write(chr) }
33
- rescue Errno::EIO => e
34
- # simply ignoring this
35
- ensure
36
- ::Process.wait pid
37
- end
38
- end
39
- abort "#{cmd} failed" unless $? && $?.exitstatus == 0
40
- end
41
-
42
- # =============================== Tasks ========================================
43
-
44
- namespace :version do
45
- task :current do
46
- puts current_version
47
- end
48
-
49
- desc "Release new version"
50
- task release: [:changelog, :commit, :tag]
51
-
52
- desc "Add new version to git repo"
53
- task :commit do
54
- spawn "git add '#{VERSION_PATH}'"
55
- spawn "git diff --cached --exit-code > /dev/null || git commit -m \"Release #{current_version}\" || echo -n"
56
- end
57
-
58
- desc "Add git tag for new version"
59
- task :tag do
60
- spawn "git tag v#{current_version}"
61
- end
62
-
63
- desc "Generate file CHANGELOG"
64
- task :changelog do
65
- spawn "changelogger changelog '#{ROOT_PATH}' --top_version='v#{current_version}' > '#{CHANGELOG_PATH}'"
66
- spawn "git add '#{CHANGELOG_PATH}'"
67
- end
68
- end
69
-
70
- desc "Show current version"
1
+ # coding: utf-8
2
+
3
+ require "bundler/gem_tasks"
4
+ require "pty"
5
+
6
+ # ============================== Support =======================================
7
+
8
+ ROOT_PATH = File.expand_path("..", __FILE__)
9
+ VERSION_PATH = File.join(ROOT_PATH, "lib", "jabber4r", "version.rb")
10
+ CHANGELOG_PATH = File.join(ROOT_PATH, "CHANGELOG")
11
+
12
+ # get current version from version.rb file
13
+ def current_version
14
+ version = File.read(VERSION_PATH).match(/VERSION \= \"(\d+\.\d+\.\d+)\"/)[1].strip.chomp
15
+ end
16
+
17
+ # get released version from git
18
+ def released_version
19
+ /\Av([\d\.]+)\z/ === `git describe --tags --abbrev=0 2>/dev/null || echo 'v0.0.0'`.chomp.strip
20
+
21
+ $1
22
+ end
23
+
24
+ # run +cmd+ in subprocess, redirect its stdout to parent's stdout
25
+ def spawn(cmd, stdout = STDOUT)
26
+ puts ">> #{cmd}"
27
+
28
+ cmd += ' 2>&1'
29
+ PTY.spawn cmd do |r, w, pid|
30
+ begin
31
+ r.sync
32
+ r.each_char { |chr| stdout.write(chr) }
33
+ rescue Errno::EIO => e
34
+ # simply ignoring this
35
+ ensure
36
+ ::Process.wait pid
37
+ end
38
+ end
39
+ abort "#{cmd} failed" unless $? && $?.exitstatus == 0
40
+ end
41
+
42
+ # =============================== Tasks ========================================
43
+
44
+ namespace :version do
45
+ task :current do
46
+ puts current_version
47
+ end
48
+
49
+ desc "Release new version"
50
+ task release: [:changelog, :commit, :tag]
51
+
52
+ desc "Add new version to git repo"
53
+ task :commit do
54
+ spawn "git add '#{VERSION_PATH}'"
55
+ spawn "git diff --cached --exit-code > /dev/null || git commit -m \"Release #{current_version}\" || echo -n"
56
+ end
57
+
58
+ desc "Add git tag for new version"
59
+ task :tag do
60
+ spawn "git tag v#{current_version}"
61
+ end
62
+
63
+ desc "Generate file CHANGELOG"
64
+ task :changelog do
65
+ spawn "changelogger changelog '#{ROOT_PATH}' --top_version='v#{current_version}' > '#{CHANGELOG_PATH}'"
66
+ spawn "git add '#{CHANGELOG_PATH}'"
67
+ end
68
+ end
69
+
70
+ desc "Show current version"
71
71
  task version: "version:current"
@@ -1,25 +1,25 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "jabber4r/version"
5
-
6
- Gem::Specification.new do |gem|
7
- gem.name = "jabber4r-revive"
8
- gem.version = Jabber::VERSION
9
- gem.authors = ["Richard Kilmer", "Sergey Fedorov"]
10
- gem.email = ["rich@infoether.com", "strech_ftf@mail.ru"]
11
- gem.description = "The purpose of this library is to allow Ruby applications to talk to a Jabber IM system. Jabber is an open-source instant messaging service, which can be learned about at http://www.jabber.org"
12
- gem.summary = "Read more http://jabber4r.rubyforge.org"
13
- gem.homepage = "https://github.com/Strech/jabber4r-revive"
14
-
15
- gem.files = `git ls-files`.split($/)
16
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
- gem.require_paths = ["lib"]
19
-
20
- gem.add_dependency "ox"
21
-
22
- gem.add_development_dependency "rspec"
23
- gem.add_development_dependency "webmock"
24
- gem.add_development_dependency "changelogger"
25
- end
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "jabber4r/version"
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "jabber4r-revive"
8
+ gem.version = Jabber::VERSION
9
+ gem.authors = ["Richard Kilmer", "Sergey Fedorov"]
10
+ gem.email = ["rich@infoether.com", "strech_ftf@mail.ru"]
11
+ gem.description = "The purpose of this library is to allow Ruby applications to talk to a Jabber IM system. Jabber is an open-source instant messaging service, which can be learned about at http://www.jabber.org"
12
+ gem.summary = "Read more http://jabber4r.rubyforge.org"
13
+ gem.homepage = "https://github.com/Strech/jabber4r-revive"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency "ox", "~> 2.0.4"
21
+
22
+ gem.add_development_dependency "rspec", "~> 2.13.0"
23
+ gem.add_development_dependency "webmock", "~> 1.11.0"
24
+ gem.add_development_dependency "changelogger", "~> 0.0.3"
25
+ end
data/lib/jabber4r.rb CHANGED
@@ -1,33 +1,38 @@
1
- # License: see LICENSE.txt
2
- # Jabber4R - Jabber Instant Messaging Library for Ruby
3
- # Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
4
-
5
-
6
- # The Jabber module is the main namespace for all Jabber modules
7
- # and classes.
8
- module Jabber
9
- DEBUG = false
10
-
11
- # Public: Should raise if connection was force closed
12
- class ConnectionForceCloseError < StandardError; end
13
-
14
- # Public: Should raise if received XML data is malformed
15
- class XMLMalformedError < StandardError; end
16
-
17
- # Public: Should raise if authentication failed
18
- class AuthenticationError < StandardError; end
19
- end
20
-
21
- require "jabber4r/debugger"
22
- require "jabber4r/session"
23
- require "jabber4r/bosh_session"
24
- require "jabber4r/protocol"
25
- require "jabber4r/connection"
26
- require "jabber4r/protocol/iq"
27
- require "jabber4r/protocol/presence"
28
- require "jabber4r/protocol/message"
29
- require "jabber4r/protocol/xml_element"
30
- require "jabber4r/protocol/parsed_xml_element"
31
- require "jabber4r/roster"
32
- require "jabber4r/jid"
33
- require "jabber4r/vcard"
1
+ # License: see LICENSE.txt
2
+ # Jabber4R - Jabber Instant Messaging Library for Ruby
3
+ # Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
4
+
5
+
6
+ # The Jabber module is the main namespace for all Jabber modules
7
+ # and classes.
8
+ module Jabber
9
+ DEBUG = false
10
+
11
+ # Public: Should raise if connection was force closed
12
+ class ConnectionForceCloseError < StandardError; end
13
+
14
+ # Public: Should raise if received XML data is malformed
15
+ class XMLMalformedError < StandardError; end
16
+
17
+ # Public: Should raise if authentication failed
18
+ class AuthenticationError < StandardError; end
19
+ end
20
+
21
+ require "jabber4r/debugger"
22
+
23
+ require "jabber4r/protocol"
24
+ require "jabber4r/connection"
25
+
26
+ require "jabber4r/protocol/iq"
27
+ require "jabber4r/protocol/presence"
28
+ require "jabber4r/protocol/message"
29
+ require "jabber4r/protocol/xml_element"
30
+ require "jabber4r/protocol/parsed_xml_element"
31
+ require "jabber4r/protocol/authentication"
32
+
33
+ require "jabber4r/jid"
34
+ require "jabber4r/bosh"
35
+ require "jabber4r/session"
36
+
37
+ require "jabber4r/roster"
38
+ require "jabber4r/vcard"
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+
3
+ # License: see LICENSE
4
+ # Jabber4R - Jabber Instant Messaging Library for Ruby
5
+ # Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
6
+ # Copyright (C) 2013 Sergey Fedorov <strech_ftf@mail.ru>
7
+
8
+ module Jabber
9
+ module Bosh
10
+ # Public: Default connection options
11
+ DEFAULTS = {
12
+ domain: "localhost",
13
+ port: 5280,
14
+ bind_uri: "/http-bind",
15
+ use_sasl: true
16
+ }.freeze
17
+ end
18
+ end
19
+
20
+ require "jabber4r/bosh/authentication"
21
+ require "jabber4r/bosh/session"
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+
3
+ # License: see LICENSE
4
+ # Jabber4R - Jabber Instant Messaging Library for Ruby
5
+ # Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
6
+ # Copyright (C) 2013 Sergey Fedorov <strech_ftf@mail.ru>
7
+
8
+ module Jabber::Bosh
9
+ module Authentication; end
10
+ end
11
+
12
+ require "jabber4r/bosh/authentication/sasl"
13
+ require "jabber4r/bosh/authentication/non_sasl"
@@ -0,0 +1,219 @@
1
+ # coding: utf-8
2
+
3
+ # License: see LICENSE
4
+ # Jabber4R - Jabber Instant Messaging Library for Ruby
5
+ # Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
6
+ # Copyright (C) 2013 Sergey Fedorov <strech_ftf@mail.ru>
7
+
8
+ require "ox"
9
+
10
+ module Jabber::Bosh::Authentication
11
+ # This class provides Non-SASL authentication for BOSH session
12
+ class NonSASL
13
+ # Public: Instance of Jabber::Bosh::Session
14
+ attr_reader :session
15
+
16
+ # Public: Opened stream identifier
17
+ attr_reader :stream_id
18
+
19
+ def initialize(session)
20
+ @session = session
21
+ end
22
+
23
+ def authenticate(jid, password)
24
+ open_stream
25
+
26
+ pass_authentication(jid, password)
27
+ end
28
+
29
+ # Internal: Send open stream command to jabber server
30
+ #
31
+ # Raises XMLMalformedError
32
+ # Returns boolean
33
+ def open_stream
34
+ body = Ox::Element.new("body").tap do |element|
35
+ element[:xmlns] = "http://jabber.org/protocol/httpbind"
36
+ element[:content] = "text/xml; charset=utf-8"
37
+ element[:rid] = session.generate_next_rid
38
+ element[:to] = session.domain
39
+ element[:secure] = true
40
+ element[:wait] = 60
41
+ element[:hold] = 1
42
+ end
43
+
44
+ Jabber.debug(%Q[Open (rid="#{body.rid}") new session])
45
+
46
+ response = session.post(Ox.dump body)
47
+ xml = Ox.parse(response.body.tr("'", '"'))
48
+
49
+ [:sid, :authid].each do |m|
50
+ raise Jabber::XMLMalformedError,
51
+ "Couldn't find <body /> attribute [#{m}]" if xml[m].nil?
52
+ end
53
+
54
+ session.sid, @stream_id = xml.sid, xml.authid
55
+
56
+ true
57
+ end
58
+
59
+ # Internal: Send login request to jabber server
60
+ #
61
+ # jid - Jabber::JID the jid of jabber user
62
+ # password - String the password of jabber user
63
+ #
64
+ # Raises TypeError
65
+ # Raises XMLMalformedError
66
+ # Returns boolean
67
+ def pass_authentication(jid, password)
68
+ raise TypeError,
69
+ "Jabber::JID expected, but #{jid.class} was given" unless jid.is_a?(Jabber::JID)
70
+
71
+ body = Ox::Element.new("body").tap do |element|
72
+ element[:xmlns] = 'http://jabber.org/protocol/httpbind'
73
+ element[:content] = "text/xml; charset=utf-8"
74
+ element[:rid] = session.generate_next_rid
75
+ element[:sid] = session.sid
76
+
77
+ element << Query.new(jid, password, stream_id: stream_id, mechanism: :digest).to_ox
78
+ end
79
+
80
+ Jabber.debug(%Q[Authenticate {Non-SASL} (rid="#{body.rid}" sid="#{body.sid}") in opened session] +
81
+ %Q[ as #{session.jid.node}/#{session.jid.resource}])
82
+
83
+ response = session.post(Ox.dump body)
84
+ xml = Ox.parse(response.body.tr("'", '"'))
85
+
86
+ raise Jabber::XMLMalformedError, "Couldn't find xml tag <iq/>" if xml.locate("iq").empty?
87
+ return false unless xml.iq[:type] == "result"
88
+
89
+ true
90
+ end
91
+
92
+ private
93
+ class Query
94
+ MECHANISMS = [:plain, :digest].freeze
95
+
96
+ attr_reader :jid, :password
97
+ attr_reader :stream_id, :mechanism
98
+
99
+ # Public: Creates new Non-SASL authentication object
100
+ #
101
+ # jid - [Jabber::JID|String] the jid of jabber server user
102
+ # password - String the user password
103
+ # options - Hash the authentication options (default: Empty hash)
104
+ # :stream_id - String the stream identifier (authid)
105
+ # :mechanism - Symbol the name of mechnism to use
106
+ #
107
+ # Examples
108
+ #
109
+ # non_sasl = Jabber::Protocol::Authentication::NonSASL.new("strech@localhost/res-1", "my-pass-phrase")
110
+ # non_sasl.plain? # => true
111
+ # non_sasl.to_xml # =>
112
+ #
113
+ # <iq type="set" id="...">
114
+ # <query xmlns="jabber:iq:auth">
115
+ # <username>strech</username>
116
+ # <password>my-pass-phrase</password>
117
+ # <resource>res-1</resource>
118
+ # </query>
119
+ # </iq>
120
+ def initialize(jid, password, options = {})
121
+ raise TypeError,
122
+ "Class(Jabber::JID) or Class(String) expected," +
123
+ " but #{jid.class} was given" unless jid.is_a?(Jabber::JID) || jid.is_a?(String)
124
+
125
+ @jid = jid.is_a?(Jabber::JID) ? jid : Jabber::JID.new(jid)
126
+ @password = password
127
+
128
+ @mechanism = options.fetch(:mechanism, :plain)
129
+ @stream_id = options.fetch(:stream_id) if digest?
130
+
131
+ raise ArgumentError,
132
+ "Unknown authentication mechanism '#{mechanism}'," +
133
+ " available is [#{MECHANISMS * ", "}]" unless MECHANISMS.include?(mechanism)
134
+ end
135
+
136
+ # Public: Is NonSASL object is for plain authentication
137
+ #
138
+ # Returns boolean
139
+ def plain?
140
+ mechanism == :plain
141
+ end
142
+
143
+ # Public: Is NonSASL object is for digest authentication
144
+ #
145
+ # Returns boolean
146
+ def digest?
147
+ mechanism == :digest
148
+ end
149
+
150
+ # Public: Create XML string from NonSASL object
151
+ #
152
+ # Returns String
153
+ def dump
154
+ Ox.dump(send mechanism)
155
+ end
156
+ alias :to_xml :dump
157
+
158
+ # Public: Create Ox::Element from NonSASL object
159
+ #
160
+ # Returns Ox::Element
161
+ def to_ox
162
+ send(mechanism)
163
+ end
164
+
165
+ private
166
+ # Internal: Make xml object for plain authentication mechanism
167
+ #
168
+ # Returns Ox:Element
169
+ def plain
170
+ query = Ox::Element.new("query").tap do |element|
171
+ element[:xmlns] = "jabber:iq:auth"
172
+
173
+ element << (Ox::Element.new("username") << jid.node)
174
+ element << (Ox::Element.new("password") << password)
175
+ element << (Ox::Element.new("resource") << jid.resource)
176
+ end
177
+
178
+ build_iq(query)
179
+ end
180
+
181
+ # Internal: Make xml object for digest authentication mechanism
182
+ #
183
+ # Returns Ox:Element
184
+ def digest
185
+ query = Ox::Element.new("query").tap do |element|
186
+ element[:xmlns] = "jabber:iq:auth"
187
+
188
+ digest_password = self.class.generate_digest(stream_id, password)
189
+
190
+ element << (Ox::Element.new("username") << jid.node)
191
+ element << (Ox::Element.new("digest") << digest_password)
192
+ element << (Ox::Element.new("resource") << jid.resource)
193
+ end
194
+
195
+ build_iq(query)
196
+ end
197
+
198
+ # Internal: The root iq stanza for authentication
199
+ #
200
+ # Returns Ox:Element
201
+ def build_iq(query)
202
+ Ox::Element.new("iq").tap do |element|
203
+ element[:xmlns] = "jabber:client"
204
+ element[:type] = "set"
205
+ element[:id] = Jabber.gen_random_id
206
+
207
+ element << query
208
+ end
209
+ end
210
+
211
+ # Internal: Generate hex string consist of concatination stream_id and password
212
+ #
213
+ # Returns String
214
+ def self.generate_digest(stream_id, password)
215
+ Digest::SHA1.hexdigest([stream_id, password].join)
216
+ end
217
+ end
218
+ end
219
+ end