rack-webmoney 0.0.2
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 +21 -0
- data/Gemfile +3 -0
- data/README.rdoc +81 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/lib/rack/webmoney.rb +253 -0
- data/rack-webmoney.gemspec +49 -0
- metadata +102 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
= Rack::Webmoney
|
2
|
+
|
3
|
+
=== Usage
|
4
|
+
|
5
|
+
You trigger an Webmoney request similar to HTTP authentication. From your app,
|
6
|
+
return a "401 Unauthorized" and a "WWW-Authenticate" header with the identifier you would like to validate.
|
7
|
+
|
8
|
+
On competition, the Webmoney response is automatically verified and assigned to
|
9
|
+
<tt>env["rack.webmoney.response"]</tt>.
|
10
|
+
|
11
|
+
=== Rails 3 Example
|
12
|
+
|
13
|
+
application.rb
|
14
|
+
|
15
|
+
...
|
16
|
+
config.middleware.insert_before(Warden::Manager, Rack::Webmoney,
|
17
|
+
:credentials => {:site_rid => 'your_site_rid', :site_holder_wmid => 'your_site_holder_wmid'},
|
18
|
+
:mode => Rails.env)
|
19
|
+
...
|
20
|
+
|
21
|
+
=== Rack Example
|
22
|
+
|
23
|
+
MyApp = lambda { |env|
|
24
|
+
if resp = env["rack.webmoney.response"]
|
25
|
+
case resp.status
|
26
|
+
when :successful
|
27
|
+
...
|
28
|
+
else
|
29
|
+
...
|
30
|
+
else
|
31
|
+
[401, {"WWW-Authenticate" => 'Webmoney"}, []]
|
32
|
+
end
|
33
|
+
}
|
34
|
+
|
35
|
+
use Rack::Webmoney, :credentials => {:site_rid => 'your_site_rid', :site_holder_wmid => 'your_site_holder_wmid'}, :mode => "development_OR_test_FOR_TESTING"
|
36
|
+
run MyApp
|
37
|
+
|
38
|
+
=== Sinatra Example
|
39
|
+
|
40
|
+
# Session needs to be before Rack::OpenID
|
41
|
+
use Rack::Session::Cookie
|
42
|
+
|
43
|
+
require 'rack/webmoney'
|
44
|
+
use Rack::Webmoney, :credentials => {:site_rid => 'your_site_rid', :site_holder_wmid => 'your_site_holder_wmid'}, :mode => "development_OR_test_FOR_TESTING"
|
45
|
+
|
46
|
+
get '/login' do
|
47
|
+
erb :login
|
48
|
+
end
|
49
|
+
|
50
|
+
post '/login' do
|
51
|
+
if resp = request.env["rack.webmoney.response"]
|
52
|
+
if resp.status == :successful
|
53
|
+
"Welcome: #{resp.display_identifier}"
|
54
|
+
else
|
55
|
+
"#{resp.status}: #{resp.message}"
|
56
|
+
end
|
57
|
+
else
|
58
|
+
headers 'WWW-Authenticate' => Rack::Webmoney.build_header({})
|
59
|
+
throw :halt, [401, 'got webmoney?']
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
use_in_file_templates!
|
64
|
+
|
65
|
+
__END__
|
66
|
+
|
67
|
+
@@ login
|
68
|
+
<form action="/login" method="post">
|
69
|
+
<p>
|
70
|
+
<input style="display:none;" name="auth_provider" type="text" value="webmoney"/>
|
71
|
+
</p>
|
72
|
+
|
73
|
+
<p>
|
74
|
+
<input name="commit" type="submit" value="Sign in" />
|
75
|
+
</p>
|
76
|
+
</form>
|
77
|
+
|
78
|
+
|
79
|
+
== Thank for inspiration goes to:
|
80
|
+
|
81
|
+
rack-openid[http://github.com/josh/rack-openid.git]
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "rack-webmoney"
|
8
|
+
gem.summary = 'Rack Webmoney authentication'
|
9
|
+
gem.description = %q{Rack webmoney authentication}
|
10
|
+
gem.email = ['eagle.anton@gmail.com', 'eagle.alex@gmail.com']
|
11
|
+
gem.homepage = "http://github.com/SkyEagle/rack-webmoney"
|
12
|
+
gem.authors = ['Anton Orel', 'Alexander Orel']
|
13
|
+
gem.add_dependency(%q<rack>, ">= 1.2.1")
|
14
|
+
gem.add_dependency(%q<savon>, ">= 0.7.9")
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
Rake::TestTask.new(:test) do |test|
|
24
|
+
test.libs << 'lib' << 'test'
|
25
|
+
test.pattern = 'test/**/test_*.rb'
|
26
|
+
test.verbose = true
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
require 'rcov/rcovtask'
|
31
|
+
Rcov::RcovTask.new do |test|
|
32
|
+
test.libs << 'test'
|
33
|
+
test.pattern = 'test/**/test_*.rb'
|
34
|
+
test.verbose = true
|
35
|
+
end
|
36
|
+
rescue LoadError
|
37
|
+
task :rcov do
|
38
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
task :test => :check_dependencies
|
43
|
+
|
44
|
+
task :default => :test
|
45
|
+
|
46
|
+
require 'rake/rdoctask'
|
47
|
+
Rake::RDocTask.new do |rdoc|
|
48
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
49
|
+
|
50
|
+
rdoc.rdoc_dir = 'rdoc'
|
51
|
+
rdoc.title = "rack-webmoney #{version}"
|
52
|
+
rdoc.rdoc_files.include('README*')
|
53
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
54
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
@@ -0,0 +1,253 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
require 'rack/request'
|
3
|
+
require 'rack/utils'
|
4
|
+
|
5
|
+
require "savon"
|
6
|
+
|
7
|
+
module Rack #:nodoc:
|
8
|
+
# A Rack middleware that provides a more HTTPish API around Webmoney authentication
|
9
|
+
#
|
10
|
+
# You trigger an Webmoney request similar to HTTP authentication.
|
11
|
+
# From your app, return a "401 Unauthorized" and a "WWW-Authenticate"
|
12
|
+
# header with the identifier you would like to validate.
|
13
|
+
#
|
14
|
+
# On competition, the Webmoney response is automatically verified and
|
15
|
+
# assigned to <tt>env["rack.webmoney.response"]</tt>.
|
16
|
+
class Webmoney
|
17
|
+
class Response
|
18
|
+
ERROR_MESSAGES = {
|
19
|
+
# -2 raised network error
|
20
|
+
:server_not_available => "Sorry, the Webmoney Login server is not available",
|
21
|
+
# -1
|
22
|
+
:internal_error => "Webmoney Login server internal error",
|
23
|
+
# 1
|
24
|
+
:invalid_arguments => "Invalid arguments",
|
25
|
+
# 2
|
26
|
+
:ticket_invalid => "Sorry, invalid authorization ticket",
|
27
|
+
# 3
|
28
|
+
:ticket_expired => "Sorry, authorization ticket expired",
|
29
|
+
# 4
|
30
|
+
:user_not_found => "Sorry, user not found",
|
31
|
+
# 5
|
32
|
+
:holder_not_found => "The holder of a site not found",
|
33
|
+
# 6
|
34
|
+
:website_not_found => "Website Not Found",
|
35
|
+
# 7
|
36
|
+
:url_not_found => "This url is not found, or does not belong to the site",
|
37
|
+
# 8
|
38
|
+
:settings_not_found => "Security Settings for the site could not be found",
|
39
|
+
# 9
|
40
|
+
:invalid_password => "Access service is not authorized. Invalid password.",
|
41
|
+
# 10
|
42
|
+
:not_trusted => "Attempting to gain access to the site, which does not accept you as a trustee",
|
43
|
+
# 11
|
44
|
+
:pwd_access_blocked => "Password access to the service blocked",
|
45
|
+
# 12
|
46
|
+
:user_blocked => "The user is temporarily blocked. Probably made the selection Ticket",
|
47
|
+
# 201
|
48
|
+
:ip_differs => "Ip address in the request differs from the address, which was an authorized user"
|
49
|
+
}
|
50
|
+
|
51
|
+
def initialize(code, info)
|
52
|
+
@code = code
|
53
|
+
@info = info
|
54
|
+
end
|
55
|
+
|
56
|
+
def status
|
57
|
+
@code
|
58
|
+
end
|
59
|
+
|
60
|
+
def successful?
|
61
|
+
@code == :successful
|
62
|
+
end
|
63
|
+
|
64
|
+
def unsuccessful?
|
65
|
+
ERROR_MESSAGES.keys.include?(@code)
|
66
|
+
end
|
67
|
+
|
68
|
+
def message
|
69
|
+
ERROR_MESSAGES[@code]
|
70
|
+
end
|
71
|
+
|
72
|
+
def wmid
|
73
|
+
@info[:wmid]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
#SOAP driver setup
|
78
|
+
#@@driver = SOAP::WSDLDriverFactory.new('https://login.wmtransfer.com/ws/Security.asmx?WSDL').create_rpc_driver
|
79
|
+
#@@driver.options['protocol.http.ssl_config.verify_mode'] = OpenSSL::SSL::VERIFY_PEER
|
80
|
+
|
81
|
+
#
|
82
|
+
# Helper method for building the "WWW-Authenticate" header value.
|
83
|
+
#
|
84
|
+
# Rack::Webmoney.build_header(:site_rid => "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
|
85
|
+
# #=> Webmoney site_rid="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
86
|
+
def self.build_header(params = {})
|
87
|
+
'Webmoney ' + params.map { |key, value|
|
88
|
+
if value.is_a?(Array)
|
89
|
+
"#{key}=\"#{value.join(',')}\""
|
90
|
+
else
|
91
|
+
"#{key}=\"#{value}\""
|
92
|
+
end
|
93
|
+
}.join(', ')
|
94
|
+
end
|
95
|
+
|
96
|
+
# Helper method for parsing "WWW-Authenticate" header values into
|
97
|
+
# a hash.
|
98
|
+
#
|
99
|
+
# Rack::Webmoney.parse_header("Webmoney site_rid="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
|
100
|
+
# #=> {:site_rid => "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}
|
101
|
+
def self.parse_header(str)
|
102
|
+
params = {}
|
103
|
+
if str =~ AUTHENTICATE_REGEXP
|
104
|
+
str = str.gsub(/#{AUTHENTICATE_REGEXP}\s+/, '')
|
105
|
+
str.split(', ').each { |pair|
|
106
|
+
key, *value = pair.split('=')
|
107
|
+
value = value.join('=')
|
108
|
+
value.gsub!(/^\"/, '').gsub!(/\"$/, "")
|
109
|
+
value = value.split(',')
|
110
|
+
params[key] = value.length > 1 ? value : value.first
|
111
|
+
}
|
112
|
+
end
|
113
|
+
params
|
114
|
+
end
|
115
|
+
|
116
|
+
#class TimeoutResponse #:nodoc:
|
117
|
+
#include ::OpenID::Consumer::Response
|
118
|
+
#STATUS = :failure
|
119
|
+
#end
|
120
|
+
|
121
|
+
#class MissingResponse #:nodoc:
|
122
|
+
#include ::OpenID::Consumer::Response
|
123
|
+
#STATUS = :missing
|
124
|
+
#end
|
125
|
+
|
126
|
+
# :stopdoc:
|
127
|
+
|
128
|
+
HTTP_METHODS = %w(GET HEAD PUT POST DELETE OPTIONS)
|
129
|
+
|
130
|
+
RESPONSE = "rack.webmoney.response"
|
131
|
+
AUTHENTICATE_HEADER = "WWW-Authenticate"
|
132
|
+
AUTHENTICATE_REGEXP = /^Webmoney/
|
133
|
+
|
134
|
+
URL_FIELD_SELECTOR = lambda { |field| field.to_s =~ %r{^https://} }
|
135
|
+
|
136
|
+
attr_reader :credentials, :mode
|
137
|
+
|
138
|
+
# :startdoc:
|
139
|
+
|
140
|
+
# Initialize middleware with application
|
141
|
+
#
|
142
|
+
# use Rack::Webmoney, :credentials => {:site_holder_wmid => 'your_site_holder_wmid', :site_rid => 'your_site_rid'}, :mode => Rails.env
|
143
|
+
#
|
144
|
+
def initialize(app, opts ={})
|
145
|
+
@app = app
|
146
|
+
@credentials = opts[:credentials]
|
147
|
+
@mode = opts[:mode]
|
148
|
+
end
|
149
|
+
|
150
|
+
# Standard Rack +call+ dispatch that accepts an +env+ and
|
151
|
+
# returns a <tt>[status, header, body]</tt> response.
|
152
|
+
def call(env)
|
153
|
+
req = Rack::Request.new(env)
|
154
|
+
if req.params["WmLogin_WMID"]
|
155
|
+
complete_authentication(env)
|
156
|
+
end
|
157
|
+
|
158
|
+
status, headers, body = @app.call(env)
|
159
|
+
|
160
|
+
qs = headers[AUTHENTICATE_HEADER]
|
161
|
+
if status.to_i == 401 && qs && qs.match(AUTHENTICATE_REGEXP)
|
162
|
+
begin_authentication(env, qs)
|
163
|
+
else
|
164
|
+
[status, headers, body]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
private
|
169
|
+
def begin_authentication(env, qs)
|
170
|
+
req = Rack::Request.new(env)
|
171
|
+
params = self.class.parse_header(qs)
|
172
|
+
session = env["rack.session"]
|
173
|
+
|
174
|
+
raise RuntimeError, "Rack::Webmoney requires a session" unless session
|
175
|
+
|
176
|
+
redirect_to "https://login.wmtransfer.com/GateKeeper.aspx?RID=#{credentials[:site_rid]}"
|
177
|
+
end
|
178
|
+
|
179
|
+
def complete_authentication(env)
|
180
|
+
req = Rack::Request.new(env)
|
181
|
+
session = env["rack.session"]
|
182
|
+
|
183
|
+
unless session
|
184
|
+
raise RuntimeError, "Rack::Webmoney requires a session"
|
185
|
+
end
|
186
|
+
|
187
|
+
wminfo =
|
188
|
+
{ :ticket => req.params["WmLogin_Ticket"],
|
189
|
+
:url_id => req.params["WmLogin_UrlID"],
|
190
|
+
:expires => req.params["WmLogin_Expires"],
|
191
|
+
:auth_type => req.params["WmLogin_AuthType"],
|
192
|
+
:last_access => req.params["WmLogin_LastAccess"],
|
193
|
+
:created => req.params["WmLogin_Created"],
|
194
|
+
:wmid => req.params["WmLogin_WMID"],
|
195
|
+
:user_ip => req.params["WmLogin_UserAddress"] }
|
196
|
+
|
197
|
+
# work around for local development
|
198
|
+
ip_to_check = %w(development test).include?(mode) ? wminfo[:user_ip] : req.ip
|
199
|
+
|
200
|
+
check_req_params = {
|
201
|
+
:SiteHolderWMID => credentials[:site_holder_wmid],
|
202
|
+
:wmId => wminfo[:wmid],
|
203
|
+
:ticket => wminfo[:ticket],
|
204
|
+
:urlId => wminfo[:url_id],
|
205
|
+
:authType => wminfo[:auth_type],
|
206
|
+
:userAddress => ip_to_check
|
207
|
+
}
|
208
|
+
|
209
|
+
begin
|
210
|
+
soap_client = Savon::Client.new "https://login.wmtransfer.com"
|
211
|
+
response = soap_client.authorize! do |soap| # (!) disable WSDL
|
212
|
+
soap.namespace = "https://login.wmtransfer.com/ws/Security.asmx?WSDL"
|
213
|
+
soap.body = check_req_params
|
214
|
+
end.to_hash['authorizeResult'].to_i
|
215
|
+
rescue Exception => msg
|
216
|
+
response = -2
|
217
|
+
end
|
218
|
+
|
219
|
+
status = case response
|
220
|
+
when 0 then :successful
|
221
|
+
when -2 then :server_not_available
|
222
|
+
when -1 then :internal_error
|
223
|
+
when 1 then :invalid_arguments
|
224
|
+
when 2 then :ticket_invalid
|
225
|
+
when 3 then :ticket_expired
|
226
|
+
when 4 then :user_not_found
|
227
|
+
when 5 then :holder_not_found
|
228
|
+
when 6 then :website_not_found
|
229
|
+
when 7 then :url_not_found
|
230
|
+
when 8 then :settings_not_found
|
231
|
+
when 9 then :invalid_password
|
232
|
+
when 10 then :not_trusted
|
233
|
+
when 11 then :pwd_access_blocked
|
234
|
+
when 12 then :user_blocked
|
235
|
+
when 201 then :ip_differs
|
236
|
+
else
|
237
|
+
"Unknown response code(#{response})"
|
238
|
+
end
|
239
|
+
|
240
|
+
env[RESPONSE] = Response.new(status, wminfo)
|
241
|
+
|
242
|
+
req.params['authenticity_token'] = session['_csrf_token']
|
243
|
+
end
|
244
|
+
|
245
|
+
def redirect_to(url)
|
246
|
+
[303, {"Content-Type" => "text/html", "Location" => url}, []]
|
247
|
+
end
|
248
|
+
|
249
|
+
def logger
|
250
|
+
@logger ||= Rails.logger if defined?(Rails)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{rack-webmoney}
|
8
|
+
s.version = "0.0.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Anton Orel", "Alexander Orel"]
|
12
|
+
s.date = %q{2010-09-01}
|
13
|
+
s.description = %q{Rack webmoney authentication}
|
14
|
+
s.email = ["eagle.anton@gmail.com", "eagle.alex@gmail.com"]
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"Gemfile",
|
21
|
+
"README.rdoc",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"lib/rack/webmoney.rb",
|
25
|
+
"rack-webmoney.gemspec"
|
26
|
+
]
|
27
|
+
s.homepage = %q{http://github.com/SkyEagle/rack-webmoney}
|
28
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
29
|
+
s.require_paths = ["lib"]
|
30
|
+
s.rubygems_version = %q{1.3.7}
|
31
|
+
s.summary = %q{Rack Webmoney authentication}
|
32
|
+
|
33
|
+
if s.respond_to? :specification_version then
|
34
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
35
|
+
s.specification_version = 3
|
36
|
+
|
37
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
38
|
+
s.add_runtime_dependency(%q<rack>, [">= 1.2.1"])
|
39
|
+
s.add_runtime_dependency(%q<savon>, [">= 0.7.9"])
|
40
|
+
else
|
41
|
+
s.add_dependency(%q<rack>, [">= 1.2.1"])
|
42
|
+
s.add_dependency(%q<savon>, [">= 0.7.9"])
|
43
|
+
end
|
44
|
+
else
|
45
|
+
s.add_dependency(%q<rack>, [">= 1.2.1"])
|
46
|
+
s.add_dependency(%q<savon>, [">= 0.7.9"])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-webmoney
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Anton Orel
|
13
|
+
- Alexander Orel
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-09-01 00:00:00 +04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rack
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 2
|
32
|
+
- 1
|
33
|
+
version: 1.2.1
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: savon
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 7
|
47
|
+
- 9
|
48
|
+
version: 0.7.9
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
description: Rack webmoney authentication
|
52
|
+
email:
|
53
|
+
- eagle.anton@gmail.com
|
54
|
+
- eagle.alex@gmail.com
|
55
|
+
executables: []
|
56
|
+
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
extra_rdoc_files:
|
60
|
+
- README.rdoc
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- README.rdoc
|
65
|
+
- Rakefile
|
66
|
+
- VERSION
|
67
|
+
- lib/rack/webmoney.rb
|
68
|
+
- rack-webmoney.gemspec
|
69
|
+
has_rdoc: true
|
70
|
+
homepage: http://github.com/SkyEagle/rack-webmoney
|
71
|
+
licenses: []
|
72
|
+
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options:
|
75
|
+
- --charset=UTF-8
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
version: "0"
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
requirements: []
|
95
|
+
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 1.3.7
|
98
|
+
signing_key:
|
99
|
+
specification_version: 3
|
100
|
+
summary: Rack Webmoney authentication
|
101
|
+
test_files: []
|
102
|
+
|