webmoney 0.0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +35 -0
- data/ext/wmsigner/base64.cpp +144 -0
- data/ext/wmsigner/base64.h +48 -0
- data/ext/wmsigner/cmdbase.cpp +417 -0
- data/ext/wmsigner/cmdbase.h +111 -0
- data/ext/wmsigner/crypto.cpp +155 -0
- data/ext/wmsigner/crypto.h +17 -0
- data/ext/wmsigner/extconf.rb +16 -0
- data/ext/wmsigner/md4.cpp +192 -0
- data/ext/wmsigner/md4.h +41 -0
- data/ext/wmsigner/rsalib1.cpp +838 -0
- data/ext/wmsigner/rsalib1.h +81 -0
- data/ext/wmsigner/signer.cpp +315 -0
- data/ext/wmsigner/signer.h +63 -0
- data/ext/wmsigner/stdafx.cpp +8 -0
- data/ext/wmsigner/stdafx.h +33 -0
- data/ext/wmsigner/wmsigner.cpp +119 -0
- data/lib/WebMoneyCA.crt +90 -0
- data/lib/messenger.rb +37 -0
- data/lib/passport.rb +44 -0
- data/lib/webmoney.rb +237 -0
- data/lib/wmid.rb +14 -0
- data/rakefile +63 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/unit/messenger_spec.rb +23 -0
- data/spec/unit/passport_spec.rb +47 -0
- data/spec/unit/signer_spec.rb +35 -0
- data/spec/unit/time_spec.rb +14 -0
- data/spec/unit/webmoney_spec.rb +111 -0
- data/spec/unit/wmid_spec.rb +30 -0
- data/tools/rakehelp.rb +117 -0
- metadata +102 -0
data/lib/wmid.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Support class
|
2
|
+
class Webmoney
|
3
|
+
class Wmid < String
|
4
|
+
|
5
|
+
def initialize(str)
|
6
|
+
str = str.to_s unless str.kind_of?(String)
|
7
|
+
raise IncorrectWmidError, ': ' + str.to_s unless str =~ /^\d{12}$/
|
8
|
+
super(str)
|
9
|
+
end
|
10
|
+
|
11
|
+
def wmid; self end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
data/rakefile
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'tools/rakehelp'
|
6
|
+
require 'spec/rake/spectask'
|
7
|
+
|
8
|
+
GEM_VERSION="0.0.4.2"
|
9
|
+
|
10
|
+
setup_extension('wmsigner', 'wmsigner')
|
11
|
+
|
12
|
+
desc "Compiles native extensions"
|
13
|
+
task :compile => [:wmsigner]
|
14
|
+
|
15
|
+
task :default => [:compile, :spec]
|
16
|
+
|
17
|
+
Spec::Rake::SpecTask.new do |task|
|
18
|
+
task.libs << 'spec'
|
19
|
+
task.spec_files = Dir.glob( 'spec/**/*_spec.rb' )
|
20
|
+
task.verbose = true
|
21
|
+
end
|
22
|
+
|
23
|
+
gemspec = Gem::Specification.new do |gemspec|
|
24
|
+
gemspec.name = "webmoney"
|
25
|
+
gemspec.version = GEM_VERSION
|
26
|
+
gemspec.author = "Alexander Oryol"
|
27
|
+
gemspec.email = "eagle.alex@gmail.com"
|
28
|
+
gemspec.summary = "Webmoney interfaces and native wmsigner"
|
29
|
+
gemspec.files = %w( rakefile ChangeLog lib/WebMoneyCA.crt ) +
|
30
|
+
Dir.glob( 'lib/*.rb' ) +
|
31
|
+
Dir.glob( 'spec/*.rb' ) +
|
32
|
+
Dir.glob( 'spec/unit/*.rb' ) +
|
33
|
+
Dir.glob( 'ext/**/*.{h,cpp,rb}' ) +
|
34
|
+
Dir.glob( 'tools/*.rb' )
|
35
|
+
gemspec.autorequire = 'webmoney'
|
36
|
+
gemspec.require_path = 'lib'
|
37
|
+
gemspec.add_dependency('hpricot')
|
38
|
+
gemspec.add_dependency('builder')
|
39
|
+
|
40
|
+
if RUBY_PLATFORM.match("win32")
|
41
|
+
gemspec.platform = Gem::Platform::WIN32
|
42
|
+
gemspec.files += []
|
43
|
+
else
|
44
|
+
gemspec.platform = Gem::Platform::RUBY
|
45
|
+
gemspec.extensions = Dir.glob( 'ext/**/extconf.rb' )
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
task :package => [:clean, :compile, :spec]
|
50
|
+
Rake::GemPackageTask.new( gemspec ) do |task|
|
51
|
+
task.gem_spec = gemspec
|
52
|
+
task.need_tar = true
|
53
|
+
end
|
54
|
+
|
55
|
+
setup_clean ["ext/wmsigner/*.{so,o}", "ext/wmsigner/Makefile", "lib/wmsigner.so", "pkg", "*.gem"]
|
56
|
+
|
57
|
+
task :install => [:default, :package] do
|
58
|
+
sh %{ sudo gem install pkg/webmoney-#{GEM_VERSION}.gem }
|
59
|
+
end
|
60
|
+
|
61
|
+
task :uninstall do
|
62
|
+
sh %{ sudo gem uninstall webmoney }
|
63
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'spec'
|
4
|
+
require 'hpricot'
|
5
|
+
require 'ostruct'
|
6
|
+
require 'yaml'
|
7
|
+
require 'time'
|
8
|
+
require File.dirname(__FILE__) + '/../lib/webmoney'
|
9
|
+
|
10
|
+
# Variables may be access, for example WmConfig.wmid
|
11
|
+
config = OpenStruct.new(YAML.load_file("#{ENV['HOME']}/.wm/config.yml"))
|
12
|
+
if ENV['WM_ENV']
|
13
|
+
env_config = config.send(ENV['WM_ENV'])
|
14
|
+
config.common.update(env_config) unless env_config.nil?
|
15
|
+
end
|
16
|
+
::WmConfig = OpenStruct.new(config.common)
|
17
|
+
|
18
|
+
def webmoney
|
19
|
+
Webmoney.new :wmid => WmConfig.wmid, :password => WmConfig.password, :key => WmConfig.key
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
class Webmoney
|
4
|
+
|
5
|
+
describe Messenger, "class" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@wm = webmoney()
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should create instance and send messages" do
|
12
|
+
@wm.messenger.should be_nil
|
13
|
+
@wm.send_message(:wmid => @wm.wmid, :subj => 'FIRST', :text => 'BODY')
|
14
|
+
@wm.messenger.should be_instance_of(Messenger)
|
15
|
+
@wm.send_message(:wmid => @wm.wmid, :subj => 'SECOND', :text => 'SECOUND')
|
16
|
+
sleep(3)
|
17
|
+
end
|
18
|
+
|
19
|
+
# TODO HOW TEST IT FUNCTIONALITY???
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
class Webmoney
|
4
|
+
|
5
|
+
describe Passport, "class" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@wm = webmoney()
|
9
|
+
end
|
10
|
+
|
11
|
+
def make_request(wmid=nil)
|
12
|
+
test_wmid = wmid || @wm.wmid
|
13
|
+
x = Builder::XmlMarkup.new
|
14
|
+
x.request do
|
15
|
+
x.wmid @wm.wmid
|
16
|
+
x.passportwmid test_wmid
|
17
|
+
x.sign @wm.send(:sign, @wm.wmid + test_wmid)
|
18
|
+
x.params { x.dict 0; x.info 1; x.mode 0 }
|
19
|
+
end
|
20
|
+
x.target!
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return empty on incorrect xml" do
|
24
|
+
Passport.new('<response/>').should == ''
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return Passport instance" do
|
28
|
+
Passport.new(@wm.send(:https_request, :get_passport, make_request)).should be_instance_of(Passport)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return correct data" do
|
32
|
+
wmid = '000000000007'
|
33
|
+
p = Passport.new(@wm.send(:https_request, :get_passport, make_request(wmid)))
|
34
|
+
p.wmid.should == wmid
|
35
|
+
p.attestat.should == Webmoney::Passport::REGISTRATOR
|
36
|
+
p.created_at.strftime('%Y-%m-%d %H:%M:%S').should == '2004-02-25 21:54:01'
|
37
|
+
|
38
|
+
wmid = '370860915669'
|
39
|
+
p = Passport.new(@wm.send(:https_request, :get_passport, make_request(wmid)))
|
40
|
+
p.wmid.should == wmid
|
41
|
+
p.attestat.should == Webmoney::Passport::ALIAS
|
42
|
+
p.created_at.strftime('%Y-%m-%d %H:%M:%S').should == '2006-04-19 10:16:30'
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Signer, "class" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@s = Signer.new( WmConfig.wmid, WmConfig.password, WmConfig.key)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should be Signer class" do
|
10
|
+
@s.should be_kind_of(Signer)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should signing string" do
|
14
|
+
@s.sign('Test123').should_not be_nil
|
15
|
+
@s.sign('Test123').should match(/[0-9a-f]{132}/)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should signing empty string" do
|
19
|
+
@s.sign('').should match(/[0-9a-f]{132}/)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should raise error on nil string" do
|
23
|
+
lambda{@s.sign(nil)}.should raise_error(ArgumentError)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should raise error on nil pass" do
|
27
|
+
lambda{Signer.new('405424574082', nil, '')}.should raise_error(ArgumentError)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should raise error on blank key" do
|
31
|
+
lambda{Signer.new('405424574082', 'test', nil)}.should raise_error(ArgumentError)
|
32
|
+
lambda{Signer.new('405424574082', 'test', '')}.should raise_error(ArgumentError)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Time, "class" do
|
4
|
+
it "should test time from_ms" do
|
5
|
+
time = Time.xmlschema("2006-10-10T17:00:45.383")
|
6
|
+
time.strftime('%Y-%m-%d %H:%M:%S').should == '2006-10-10 17:00:45'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should test time from_ms without ending zeros" do
|
10
|
+
time = Time.xmlschema("2006-10-10T17:00:45")
|
11
|
+
time.strftime('%Y-%m-%d %H:%M:%S').should == '2006-10-10 17:00:45'
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
class Webmoney
|
4
|
+
|
5
|
+
describe Webmoney, "class" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@wm = webmoney()
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be instance of Webmoney" do
|
12
|
+
@wm.should be_instance_of(Webmoney)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be classic" do
|
16
|
+
@wm.classic?.should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should return reqn" do
|
20
|
+
t1 = @wm.send(:reqn)
|
21
|
+
sleep(0.1)
|
22
|
+
t2 = @wm.send(:reqn)
|
23
|
+
t1.should match(/^\d{16}$/)
|
24
|
+
(t2 > t1).should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should raise error on incorrect arg" do
|
28
|
+
lambda { @wm.send(:request, :check_sign, 1) }.
|
29
|
+
should raise_error(ArgumentError)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should send request" do
|
33
|
+
r = @wm.send(:https_request, :check_sign, '<w3s.request/>')
|
34
|
+
doc = Hpricot.XML(r.gsub(/w3s\.response/,'w3s_response'))
|
35
|
+
doc.at('w3s_response').should_not be_nil
|
36
|
+
end
|
37
|
+
|
38
|
+
it"should raise error on bad response" do
|
39
|
+
lambda { @wm.send(:https_request,
|
40
|
+
'https://w3s.wmtransfer.com/asp/XMLUnexistantIface.asp', '<w3s.request/>')}.
|
41
|
+
should raise_error(RequestError)
|
42
|
+
@wm.error.should == '404'
|
43
|
+
@wm.errormsg.should match(/^<!DOCTYPE HTML PUBLIC/)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should parse retval and raise error" do
|
47
|
+
lambda { @wm.request(:create_transaction)}.should raise_error(ResultError)
|
48
|
+
@wm.error.should == -3
|
49
|
+
@wm.errormsg.should match(%r{incorrect value of w3s.request/trans/tranid is incorrect})
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should sign string" do
|
53
|
+
@wm.send(:sign, 'Test123').should match(/^[0-9a-f]{132}$/)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should return nil on sign empty string" do
|
57
|
+
@wm.send(:sign, '').should be_nil
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should check_sign" do
|
61
|
+
plan = 'test123'
|
62
|
+
@wm.request(:check_sign,
|
63
|
+
:wmid => @wm.wmid, :plan => plan, :sign => @wm.send(:sign, plan)).
|
64
|
+
should be_true
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should check_sign broken" do
|
68
|
+
plan = 'test123'
|
69
|
+
@wm.request(:check_sign,
|
70
|
+
:wmid => @wm.wmid, :plan => plan, :sign => 'abcd').
|
71
|
+
should be_false
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should check_sign with specials" do
|
75
|
+
plan = '<test>текст</test>'
|
76
|
+
real_plan = Iconv.conv('CP1251', 'UTF-8', plan)
|
77
|
+
@wm.request(:check_sign,
|
78
|
+
:wmid => @wm.wmid, :plan => plan, :sign => @wm.send(:sign, real_plan )).
|
79
|
+
should be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should parse retval and raise error on broken get_passport" do
|
83
|
+
lambda { @wm.request(:get_passport, :wmid => '') }.should raise_error(ResultError)
|
84
|
+
@wm.error.should == 2
|
85
|
+
@wm.errormsg.should match(%r{неверно указан проверяемый WMID})
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should get_passport" do
|
89
|
+
@wm.request(:get_passport, :wmid => @wm.wmid).should be_instance_of(Passport)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should return correct BL" do
|
93
|
+
wmid = '370860915669'
|
94
|
+
@wm.request(:bussines_level, :wmid => wmid).should == 0
|
95
|
+
|
96
|
+
wmid = Wmid.new '000000000007'
|
97
|
+
bl = @wm.request(:bussines_level, :wmid => wmid)
|
98
|
+
(bl > 1000).should be_true
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should send message" do
|
102
|
+
result = @wm.request(:send_message,
|
103
|
+
:wmid => @wm.wmid, :subj => 'Текст', :text => 'Тело <b>сообщения</b>')
|
104
|
+
result.should be_kind_of(Hash)
|
105
|
+
result[:id].should match(/^\d*$/)
|
106
|
+
((result[:date] + 60) > Time.now).should be_true
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
class Webmoney
|
4
|
+
|
5
|
+
describe Wmid, "class" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@t = Wmid.new('123456789012')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be kind of Wmid" do
|
12
|
+
@t.should be_kind_of(Wmid)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be string" do
|
16
|
+
@t.should == '123456789012'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should permit initialize by integer" do
|
20
|
+
Wmid.new(123456789012).should == '123456789012'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should raise error on incorrect wmid" do
|
24
|
+
lambda{Wmid.new('abc')}.
|
25
|
+
should raise_error(IncorrectWmidError)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/tools/rakehelp.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
def make(makedir)
|
2
|
+
Dir.chdir(makedir) do
|
3
|
+
sh(PLATFORM =~ /win32/ ? 'nmake' : 'make')
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
def extconf(dir)
|
9
|
+
Dir.chdir(dir) do ruby "extconf.rb" end
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def setup_tests
|
14
|
+
Rake::TestTask.new do |t|
|
15
|
+
t.libs << "test"
|
16
|
+
t.test_files = FileList['test/test*.rb']
|
17
|
+
t.verbose = true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def setup_clean otherfiles
|
23
|
+
files = ['build/*', '**/*.o', '**/*.so', '**/*.a', 'lib/*-*', '**/*.log'] + otherfiles
|
24
|
+
CLEAN.include(files)
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def setup_rdoc files
|
29
|
+
Rake::RDocTask.new do |rdoc|
|
30
|
+
rdoc.rdoc_dir = 'doc/rdoc'
|
31
|
+
rdoc.options << '--line-numbers'
|
32
|
+
rdoc.rdoc_files.add(files)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def setup_extension(dir, extension)
|
38
|
+
ext = "ext/#{dir}"
|
39
|
+
ext_so = "#{ext}/#{extension}.#{Config::CONFIG['DLEXT']}"
|
40
|
+
ext_files = FileList[
|
41
|
+
"#{ext}/*.cpp",
|
42
|
+
"#{ext}/*.h",
|
43
|
+
"#{ext}/extconf.rb",
|
44
|
+
"#{ext}/Makefile",
|
45
|
+
"lib"
|
46
|
+
]
|
47
|
+
|
48
|
+
task "lib" do
|
49
|
+
directory "lib"
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Builds just the #{extension} extension"
|
53
|
+
task extension.to_sym => ["#{ext}/Makefile", ext_so ]
|
54
|
+
|
55
|
+
file "#{ext}/Makefile" => ["#{ext}/extconf.rb"] do
|
56
|
+
extconf "#{ext}"
|
57
|
+
end
|
58
|
+
|
59
|
+
file ext_so => ext_files do
|
60
|
+
make "#{ext}"
|
61
|
+
cp ext_so, "lib"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def base_gem_spec(pkg_name, pkg_version)
|
67
|
+
rm_rf "test/coverage"
|
68
|
+
pkg_version = pkg_version
|
69
|
+
pkg_name = pkg_name
|
70
|
+
pkg_file_name = "#{pkg_name}-#{pkg_version}"
|
71
|
+
Gem::Specification.new do |s|
|
72
|
+
s.name = pkg_name
|
73
|
+
s.version = pkg_version
|
74
|
+
s.platform = Gem::Platform::RUBY
|
75
|
+
s.has_rdoc = true
|
76
|
+
s.extra_rdoc_files = [ "README" ]
|
77
|
+
|
78
|
+
s.files = %w(COPYING LICENSE README Rakefile) +
|
79
|
+
Dir.glob("{bin,doc/rdoc,test}/**/*") +
|
80
|
+
Dir.glob("ext/**/*.{h,cpp,rb,rl}") +
|
81
|
+
Dir.glob("{examples,tools,lib}/**/*.rb")
|
82
|
+
|
83
|
+
s.require_path = "lib"
|
84
|
+
s.extensions = FileList["ext/**/extconf.rb"].to_a
|
85
|
+
s.bindir = "bin"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def setup_gem(pkg_name, pkg_version)
|
90
|
+
spec = base_gem_spec(pkg_name, pkg_version)
|
91
|
+
yield spec if block_given?
|
92
|
+
|
93
|
+
Rake::GemPackageTask.new(spec) do |p|
|
94
|
+
p.gem_spec = spec
|
95
|
+
p.need_tar = true if RUBY_PLATFORM !~ /mswin/
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def sub_project(project, *targets)
|
100
|
+
targets.each do |target|
|
101
|
+
Dir.chdir "projects/#{project}" do
|
102
|
+
sh %{rake --trace #{target.to_s} }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Conditional require rcov/rcovtask if present
|
108
|
+
begin
|
109
|
+
require 'rcov/rcovtask'
|
110
|
+
|
111
|
+
Rcov::RcovTask.new do |t|
|
112
|
+
t.test_files = FileList['test/test*.rb']
|
113
|
+
t.rcov_opts << "-x /usr"
|
114
|
+
t.output_dir = "test/coverage"
|
115
|
+
end
|
116
|
+
rescue Object
|
117
|
+
end
|