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.
- data/.gitignore +5 -4
- data/.rspec +3 -3
- data/.travis.yml +7 -7
- data/CHANGELOG +11 -1
- data/Gemfile +3 -3
- data/README.md +29 -29
- data/Rakefile +70 -70
- data/jabber4r-revive.gemspec +25 -25
- data/lib/jabber4r.rb +38 -33
- data/lib/jabber4r/bosh.rb +21 -0
- data/lib/jabber4r/bosh/authentication.rb +13 -0
- data/lib/jabber4r/bosh/authentication/non_sasl.rb +219 -0
- data/lib/jabber4r/bosh/authentication/sasl.rb +239 -0
- data/lib/jabber4r/bosh/session.rb +144 -0
- data/lib/jabber4r/connection.rb +259 -258
- data/lib/jabber4r/debugger.rb +60 -60
- data/lib/jabber4r/jid.rb +20 -19
- data/lib/jabber4r/protocol.rb +249 -257
- data/lib/jabber4r/protocol/authentication.rb +14 -0
- data/lib/jabber4r/protocol/authentication/non_sasl.rb +138 -0
- data/lib/jabber4r/protocol/authentication/sasl.rb +88 -0
- data/lib/jabber4r/protocol/iq.rb +259 -259
- data/lib/jabber4r/protocol/message.rb +245 -245
- data/lib/jabber4r/protocol/parsed_xml_element.rb +207 -207
- data/lib/jabber4r/protocol/presence.rb +160 -160
- data/lib/jabber4r/protocol/xml_element.rb +143 -143
- data/lib/jabber4r/rexml_1.8_patch.rb +15 -15
- data/lib/jabber4r/roster.rb +38 -38
- data/lib/jabber4r/session.rb +615 -615
- data/lib/jabber4r/version.rb +10 -3
- data/spec/lib/jabber4r/bosh/authentication/non_sasl_spec.rb +79 -0
- data/spec/lib/jabber4r/bosh/authentication/sasl_spec.rb +42 -0
- data/spec/lib/jabber4r/bosh/session_spec.rb +406 -0
- data/spec/lib/jabber4r/bosh_spec.rb +0 -0
- data/spec/lib/jabber4r/connection_spec.rb +174 -174
- data/spec/lib/jabber4r/debugger_spec.rb +35 -35
- data/spec/lib/jabber4r/jid_spec.rb +197 -197
- data/spec/lib/jabber4r/protocol/authentication/non_sasl_spec.rb +79 -0
- data/spec/lib/jabber4r/protocol/authentication/sasl_spec.rb +42 -0
- data/spec/spec_helper.rb +11 -11
- data/spec/support/mocks/tcp_socket_mock.rb +8 -8
- metadata +61 -45
- data/Gemfile.lock +0 -45
- data/lib/jabber4r/bosh_session.rb +0 -224
- data/spec/lib/jabber4r/bosh_session_spec.rb +0 -150
data/.gitignore
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
.rvmrc
|
2
|
-
|
3
|
-
|
4
|
-
|
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).
|
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"
|
data/jabber4r-revive.gemspec
CHANGED
@@ -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
|
-
|
23
|
-
require "jabber4r/
|
24
|
-
require "jabber4r/
|
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/
|
32
|
-
|
33
|
-
require "jabber4r/
|
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
|