gitkit-ruby 0.0.1

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/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
@@ -0,0 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ gitkit-ruby (0.0.1)
5
+ addressable (~> 2.2)
6
+ httparty (~> 0.8)
7
+ json (~> 1.4.6)
8
+ rack (~> 1.3)
9
+
10
+ GEM
11
+ remote: http://rubygems.org/
12
+ specs:
13
+ addressable (2.2.6)
14
+ hoe (2.12.4)
15
+ rake (~> 0.8)
16
+ httparty (0.8.1)
17
+ multi_json
18
+ multi_xml
19
+ json (1.4.6)
20
+ multi_json (1.0.3)
21
+ multi_xml (0.4.1)
22
+ rack (1.3.4)
23
+ rack-test (0.6.1)
24
+ rack (>= 1.0)
25
+ rake (0.9.2)
26
+ rr (1.0.4)
27
+ test-unit (1.2.3)
28
+ hoe (>= 1.5.1)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ gitkit-ruby!
35
+ rack-test (~> 0.6)
36
+ rake (~> 0.9)
37
+ rr (~> 1.0)
38
+ test-unit (~> 1.2)
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'bundler'
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ FileList['tasks/**/*.rake'].each { |task| import task }
8
+
9
+ """
10
+ require 'bundle/gem_tasks'
11
+ begin
12
+ gem 'jeweler', '~> 1.6.4'
13
+ require 'jeweler'
14
+
15
+ Jeweler::Tasks.new do |gem|
16
+ gem.name = 'gitkit-ruby'
17
+ gem.summary = 'Rack middleware for Google Identity Toolkit'
18
+ gem.description = gem.summary
19
+ gem.email = 'sqrrrl@gmail.com'
20
+ gem.homepage = 'http://code.google.com/p/%s' % gem.name
21
+ gem.authors = [ 'Steve Bazyl' ]
22
+
23
+ #gem.rubyforge_project = 'gitkit-ruby'
24
+ end
25
+
26
+ Jeweler::GemcutterTasks.new
27
+
28
+ rescue LoadError
29
+ puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler -v 1.6.4'
30
+ end
31
+ """
32
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "google/identity_toolkit/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "gitkit-ruby"
7
+ s.version = Google::IdentityToolkit::VERSION
8
+ s.authors = ["Steven Bazyl"]
9
+ s.email = ["sqrrrl@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Rack middleware for Google Identity Toolkit}
12
+ s.description = %q{Rack middleware for Google Identity Toolkit}
13
+
14
+ s.rubyforge_project = "gitkit-ruby"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency 'rack','~> 1.3'
22
+ s.add_dependency 'json', '~> 1.4.6'
23
+ s.add_dependency 'httparty', '~> 0.8'
24
+ s.add_dependency 'addressable', '~> 2.2'
25
+
26
+ s.add_development_dependency 'rake', '~> 0.9'
27
+ s.add_development_dependency 'rack-test', '~> 0.6'
28
+ s.add_development_dependency 'test-unit', '~> 1.2'
29
+ s.add_development_dependency 'rr', '~> 1.0'
30
+
31
+ end
@@ -0,0 +1,298 @@
1
+ require "rack"
2
+ require "json"
3
+ require "google/identity_toolkit/api"
4
+ require "google/identity_toolkit/helpers"
5
+ require "addressable/uri"
6
+
7
+ module Google
8
+ CONTENT_TYPE = 'Content-Type'
9
+ CONTENT_TYPE_HTML = 'text/html'
10
+ CONTENT_TYPE_JSON = 'application/json'
11
+ STATUS_SUCCESS = 'success'
12
+ STATUS_INVALID_EMAIL = 'invalidAssertionEmail'
13
+ STATUS_ACCOUNT_MISMATCH = 'accountMismatch'
14
+
15
+ ##
16
+ # Rack middleware for using the Google Identity Kit for federated login
17
+ # @see http://code.google.com/apis/identitytoolkit/
18
+ class IdentityToolkit
19
+ attr_accessor :api_key
20
+ attr_accessor :path
21
+ attr_accessor :app
22
+ attr_accessor :api
23
+ attr_accessor :callback_url
24
+ attr_accessor :federated_signup_url
25
+ attr_accessor :signup_url
26
+ attr_accessor :home_url
27
+
28
+ ##
29
+ # Creates the Identity toolkit middleware. Requires defining a block
30
+ # to configure the API and define callback methods for loading & authenticating
31
+ # users.
32
+ #
33
+ # @example
34
+ # use Google::IdentityToolkit, do |toolkit|
35
+ # toolkit.api_key = "..."
36
+ # def fetch_user(email, assertion = nil)
37
+ # # Load the user for the given email, optionally registering
38
+ # # the user if assertion is provided and '
39
+ # end
40
+ #
41
+ # def password_valid?(email, password)
42
+ # # Validates the user id/password
43
+ # end
44
+ # end
45
+ def initialize(app, &block)
46
+ @path = '/_gitkit'
47
+ @callback_url = nil
48
+ @app = app
49
+ instance_eval(&block) if block_given?
50
+ end
51
+
52
+ ##
53
+ # Static method for fetching the API key from thread-local storage. Only valid for threads
54
+ # intercepted by the rack module. Use by helper methods rendering the login button.
55
+ #
56
+ # @return [String] API Key
57
+ def self.api_key
58
+ env[:gitkit_api_key]
59
+ end
60
+
61
+ ##
62
+ # Static method for fetching the current user from thread-local storage. Only valid for threads
63
+ # intercepted by the rack module. Use by helper methods rendering the login button.
64
+ #
65
+ # @return [Hash] Hash representing the user
66
+ def self.current_user
67
+ env[:gitkit_user]
68
+ end
69
+
70
+ ##
71
+ # Static method for fetching the callback URL from thread-local storage. Only valid for threads
72
+ # intercepted by the rack module. Use by helper methods rendering the login button.
73
+ #
74
+ # @return [Hash] Hash representing the user
75
+ def self.callback_url
76
+ env[:gitkit_callback_url]
77
+ end
78
+
79
+ ##
80
+ # Get (and lazy init) the API client
81
+ #
82
+ # @return [Google::IdentityToolkit::Api]
83
+ # API client
84
+ def api
85
+ @api ||= Google::IdentityToolkit::Api.new(@api_key)
86
+ end
87
+
88
+ ##
89
+ # Handles web requests for identity toolkit callbacks
90
+ #
91
+ # @param [Hash] env
92
+ # Rack request context
93
+ # @return [Array]
94
+ # HTTP response
95
+ def call(env)
96
+ request = Rack::Request.new(env)
97
+ env[:gitkit_api_key] = @api_key
98
+ env[:gitkit_callback_url] = callback_url(request)
99
+ env[:gitkit_user] = request.session[:git_user]
100
+ Thread.current[:gitkit_rack_env] = env
101
+ begin
102
+ return @app.call(env) unless request.path == @path
103
+ case request.params['rp_target']
104
+ when "callback"
105
+ body = callback(request)
106
+ [200, {CONTENT_TYPE => CONTENT_TYPE_HTML}, [body]]
107
+ when "login"
108
+ data = login(request)
109
+ [200, {CONTENT_TYPE => CONTENT_TYPE_JSON}, [data.to_json]]
110
+ when "userStatus"
111
+ data = status(request)
112
+ [200, {CONTENT_TYPE => CONTENT_TYPE_JSON}, [data.to_json]]
113
+ end
114
+ ensure
115
+ Thread.current[:gitkit_rack_env] = nil
116
+ end
117
+ end
118
+
119
+ ##
120
+ # Handles IDP responses during login
121
+ #
122
+ # @param [Rack::Request] request
123
+ # current request
124
+ # @return [String]
125
+ # HTML boilerplate to close popup & notify parent window
126
+ def callback(request)
127
+ render_method = !!request.params['mobile'] ? :build_mobile_html : :build_notify_html
128
+ begin
129
+ assertion = api.verify_assertion(request.url, request.body)
130
+ input_email = request.params['rp_input_email']
131
+ email = assertion['verifiedEmail']
132
+ return send(render_method, STATUS_INVALID_EMAIL, {}) if email.nil?
133
+ return send(render_method, STATUS_ACCOUNT_MISMATCH, {
134
+ "inputEmail" => input_email,
135
+ "validatedEmail" => email
136
+ }) unless input_email.nil? or input_email == email
137
+
138
+ user = fetch_user(email, assertion)
139
+ if user.nil?
140
+ # Save the assertion for use in signup page
141
+ request.session[:gitkit_assertion] = assertion unless session.nil?
142
+ send(render_method, STATUS_SUCCESS, {
143
+ "email" => email,
144
+ "registered" => false,
145
+ "displayName" => assertion["displayName"],
146
+ "photoUrl" => assertion["photoUrl"]
147
+ })
148
+ else
149
+ # User exits, login
150
+ upgrade_user(email)
151
+ handle_login(user)
152
+ send(render_method, STATUS_SUCCESS, {
153
+ "email" => email,
154
+ "registered" => true,
155
+ "displayName" => assertion["displayName"],
156
+ "photoUrl" => assertion["photoUrl"]
157
+ })
158
+ end
159
+ rescue Exception => e
160
+ send(render_method, 'invalidAssertion', {})
161
+ end
162
+ end
163
+
164
+ ##
165
+ # Handles authentication requests for non-federated users
166
+ #
167
+ # @param [Rack::Request] request
168
+ # current request
169
+ # @return [Hash]
170
+ # Result of login. Currently just sets the value of :status in the hash
171
+ def login(request)
172
+ user = fetch_user(request.params["email"])
173
+ if user.nil?
174
+ {:status => "emailNotExist"}
175
+ elsif user[:federated]
176
+ {:status => "federated"}
177
+ else
178
+ if password_valid?(request.params["email"], request.params["password"])
179
+ user = fetch_user(request.params["email"])
180
+ handle_login(user)
181
+ {:status => "OK"}
182
+ else
183
+ {:status => "passwordError"}
184
+ end
185
+ end
186
+ end
187
+
188
+ ##
189
+ # Checks the status of a user
190
+ #
191
+ # @param [Rack::Request] request
192
+ # current request
193
+ # @return [Hash]
194
+ # Status of user
195
+ def status(request)
196
+ user = fetch_user(request.params["email"])
197
+ #referrer = request.params["referrer"]
198
+ { "registered" => !!user,
199
+ "legacy" => !(user && user[:federated]) }
200
+ end
201
+
202
+ ##
203
+ # Log the user after either a successful assertion or password validation
204
+ # @param [Hash]
205
+ # User (from find_user)
206
+ # @param [Rack::Request] request
207
+ # Current request
208
+ def handle_login(user)
209
+ unless session.nil?
210
+ request.session[:git_user] = user
211
+ on_login(user)
212
+ end
213
+ end
214
+
215
+ ##
216
+ # Renders boilerplate HTML for closing popups after login
217
+ #
218
+ # @param [String] status
219
+ # Status of callback -- either success, or one of the gitkit supported error messages
220
+ # @param [Hash] data
221
+ # user data from assertion if successful login
222
+ # @return [String] HTML
223
+ def build_notify_html(status, data)
224
+ html = <<-EOF
225
+ <script type='text/javascript' src='https://ajax.googleapis.com/jsapi'></script>
226
+ <script type='text/javascript'>google.load("identitytoolkit", "1.0", {packages: ["notify"]});</script>
227
+ <script type='text/javascript'>
228
+ EOF
229
+ case status
230
+ when STATUS_SUCCESS
231
+ html << "window.google.identitytoolkit.notifyFederatedSuccess(#{data.to_json});"
232
+ else
233
+ html << "window.google.identitytoolkit.notifyFederatedError('#{status}', #{data.to_json});"
234
+ end
235
+ html << "</script>"
236
+ end
237
+
238
+ ##
239
+ # Renders boilerplate HTML for non-poup mobile UI
240
+ #
241
+ # @param [String] status
242
+ # Status of callback -- either success, or one of the gitkit supported error messages
243
+ # @param [Hash] data
244
+ # user data from assertion if successful login
245
+ # @return [String] HTML
246
+ def build_mobile_html(status, data)
247
+ html = "<script type='text/javascript'>"
248
+ if status == STATUS_SUCCESS
249
+ if data["registered"]
250
+ html << "window.location = '#{home_url}';"
251
+ else
252
+ target = Addressable::URI.parse(signup_url)
253
+ target.query_values = target.query_values.merge("email" => data["email"])
254
+ html << "window.location = '#{target}';"
255
+ end
256
+ else
257
+ target = Addressable::URI.parse(login_url)
258
+ target.query_values = target.query_values.merge("error" => status)
259
+ html << "window.location = '#{login_url}';"
260
+ end
261
+ html << "</script>"
262
+ end
263
+
264
+ # Get the callback URL for use in the javascript helpers.
265
+ #
266
+ # @param [Rack::Request] request
267
+ # current request object
268
+ # @return [String]
269
+ # callback URL for verifying assertions
270
+ def callback_url(request = nil)
271
+ return @callback_url unless @callback_url.nil?
272
+ scheme = request.scheme
273
+ if (scheme == 'http' && request.port == 80 ||
274
+ scheme == 'https' && request.port == 443)
275
+ port = ""
276
+ else
277
+ port = ":#{request.port}"
278
+ end
279
+ "#{scheme}://#{request.host}#{port}#{request.script_name}#{@path}"
280
+ end
281
+
282
+ def self.env
283
+ Thread.current[:gitkit_rack_env]
284
+ end
285
+
286
+ def env
287
+ Thread.current[:gitkit_rack_env]
288
+ end
289
+
290
+ def request
291
+ Rack::Request.new(env)
292
+ end
293
+
294
+ def session
295
+ request.session
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,53 @@
1
+ require 'httparty'
2
+ require 'google/identity_toolkit/errors'
3
+ require 'json'
4
+
5
+ module Google
6
+ class IdentityToolkit
7
+
8
+ ##
9
+ # Server API for creating login requests & verifying assertions
10
+ class Api
11
+ include HTTParty
12
+ format :json
13
+ headers "Content-Type" => "application/json"
14
+
15
+ ##
16
+ # Initializes the API
17
+ #
18
+ # @param [String] api_key
19
+ # API key from developer console
20
+ def initialize(api_key)
21
+ @api_key = api_key
22
+ end
23
+
24
+ ##
25
+ # Sends an IDP response for verification, returning an assertion
26
+ # if the response is valid
27
+ #
28
+ # @param [String] request_uri
29
+ # URL of the current request
30
+ # @param [StringIO] body
31
+ # Request body (if post)
32
+ #
33
+ # @return [Hash]
34
+ # Assertion of user identity
35
+ #
36
+ # @raise [ApiError]
37
+ # if assertion not valid
38
+ def verify_assertion(request_uri, body=nil)
39
+ request = {
40
+ "requestUri" => request_uri
41
+ }
42
+ request["postBody"] = body.gets unless body.nil?
43
+ response = Api.post('https://www.googleapis.com/identitytoolkit/v1/relyingparty/verifyAssertion',
44
+ :query => { "key" => @api_key }, :body => request.to_json )
45
+ raise ApiError.new("Error #{response.code} when verifying the assertion") unless response.code == 200
46
+ response.parsed_response
47
+ end
48
+
49
+
50
+ end
51
+ end
52
+
53
+ end
@@ -0,0 +1,11 @@
1
+ module Google
2
+ class IdentityToolkit
3
+ ##
4
+ # General exception for failed API calls when verifiying assertions
5
+ class ApiError < StandardError
6
+ def initialize(s)
7
+ super(s)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,64 @@
1
+ require 'addressable/uri'
2
+
3
+ module Google
4
+ class IdentityToolkit
5
+ module Helpers
6
+
7
+ ##
8
+ # Generate javascript for configuring the identity toolkit button
9
+ #
10
+ # @param [String] element_id
11
+ # Id of element that will contain the login button
12
+ # @param [Hash] options
13
+ # Configuration options
14
+ # @option options [String] :api_key
15
+ # APIKey from developer console
16
+ # @option options [String] :company_name
17
+ # Name of site to display on login pages
18
+ # @option options [String] :base_url
19
+ #
20
+ # @return [String] Block of javascript (must be wrapped in <script> tag)
21
+
22
+ def account_chooser(element_id, options = {})
23
+ callback_url = Addressable::URI.parse(options[:callback_url] || Google::IdentityToolkit.callback_url)
24
+ params = callback_url.query_values || {}
25
+ callback_url.query_values = params.merge("mobile" => "1") if options[:mobile]
26
+ js = <<-EOF
27
+ window.google.identitytoolkit.setConfig({
28
+ developerKey: "#{options[:api_key] || Google::IdentityToolkit.api_key}",
29
+ companyName: "#{options[:site_name]}",
30
+ callbackUrl: "#{callback_url}",
31
+ userStatusUrl: "#{callback_url}",
32
+ loginUrl: "#{callback_url}",
33
+ federatedSignupUrl: "#{options[:federated_signup_url] || options[:signup_url] || '/signup' }",
34
+ signupUrl: "#{options[:signup_url] || '/signup'}",
35
+ homeUrl: "#{options[:home_url] || '/' }",
36
+ logoutUrl: "#{options[:logout_url] || '/logout'}",
37
+ realm: "#{options[:realm]}",
38
+ language: "#{options[:language] || 'en'}",
39
+ idps: ["Gmail", "AOL", "Hotmail", "Yahoo"],
40
+ tryFederatedFirst: #{options[:try_federated_first] || false},
41
+ useCachedUserStatus: #{options[:use_cached_status] || false}
42
+ });
43
+ $('#{element_id}').accountChooser();
44
+ EOF
45
+ end
46
+
47
+ def show_current_user(options={})
48
+ js = ""
49
+ user = options[:user] || Google::IdentityToolkit.current_user
50
+ if user
51
+ js = <<-EOF
52
+ window.google.identitytoolkit.updateSavedAccount({
53
+ email: '#{user[:email]}',
54
+ displayName: '#{user[:display_name]}',
55
+ photoUrl: '#{user[:photo_url]}'
56
+ });
57
+ window.google.identitytoolkit.showSavedAccount('#{user[:email]}');
58
+ EOF
59
+ end
60
+ js
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,5 @@
1
+ module Google
2
+ class IdentityToolkit
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ begin
2
+ require 'rake/testtask'
3
+
4
+ desc "Run basic tests"
5
+ Rake::TestTask.new("test") { |t|
6
+ t.pattern = 'test/*_test.rb'
7
+ t.verbose = true
8
+ t.warning = true
9
+ }
10
+ rescue LoadError
11
+ task :yard do
12
+ abort 'testunit is not available. In order to run yard, you must: gem install testunit'
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ begin
2
+ require 'yard'
3
+
4
+ YARD::Rake::YardocTask.new
5
+ rescue LoadError
6
+ task :yard do
7
+ abort 'YARD is not available. In order to run yard, you must: gem install yard'
8
+ end
9
+ end
@@ -0,0 +1,115 @@
1
+ $: << (File.dirname(__FILE__) + '/../lib')
2
+
3
+ require "rr"
4
+ require "test/unit"
5
+ require 'rack/test'
6
+ require "google/identity_toolkit"
7
+
8
+ module MockCallbacks
9
+ def fetch_user(email, assertion = nil)
10
+ return {"verifiedEmail" => email} if email.start_with?("exist") || email.start_with?("unregistered")
11
+ end
12
+
13
+ def password_valid?(email, password)
14
+ "ok" == password
15
+ end
16
+
17
+ def upgrade_user(user)
18
+ end
19
+
20
+ def on_login(user)
21
+ end
22
+ end
23
+
24
+ class GITKit_Test < Test::Unit::TestCase
25
+ include Rack::Test::Methods
26
+ include RR::Adapters::TestUnit
27
+
28
+ attr_accessor :app
29
+
30
+ def setup
31
+ inner_app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello']] }
32
+ @app = Google::IdentityToolkit.new(inner_app) do |git|
33
+ git.api_key = "AIzaSyBs1gLwB1_QZ-EXgFqBrrLY1MPXzB3G6ZU"
34
+ extend MockCallbacks
35
+ end
36
+ end
37
+
38
+ def teardown
39
+ # Do nothing
40
+ end
41
+
42
+ def test_passthrough
43
+ get '/test'
44
+ assert_equal 'hello', last_response.body
45
+ end
46
+
47
+ def test_valid_login
48
+ post '/_gitkit', "rp_target" => "login", "email" => "exists@bar.com", "password" => "ok"
49
+ data = JSON.parse(last_response.body)
50
+ assert_equal("OK", data["status"])
51
+ end
52
+
53
+ def test_invalid_login
54
+ post '/_gitkit', "rp_target" => "login", "email" => "exists@bar.com", "password" => "badpassword"
55
+ data = JSON.parse(last_response.body)
56
+ assert_equal("passwordError", data["status"])
57
+ end
58
+
59
+ def test_user_exists
60
+ post '/_gitkit', "rp_target" => "userStatus", "email" => "exists@foo.com"
61
+ data = JSON.parse(last_response.body)
62
+ assert_equal(true, data["registered"])
63
+ end
64
+
65
+ def test_user_not_exists
66
+ post '/_gitkit', "rp_target" => "userStatus", "email" => "nobody@foo.com"
67
+ data = JSON.parse(last_response.body)
68
+ assert_equal(false, data["registered"])
69
+ end
70
+
71
+ def test_callback_registered_user
72
+ mock(@app.api).verify_assertion(is_a(String), anything) {
73
+ { "kind" => "identitytoolkit#relyingparty",
74
+ "identifier" => "12345",
75
+ "authority" => "google.com",
76
+ "verifiedEmail" => "existing@foo.com",
77
+ "firstName" => "Test",
78
+ "lastName" => "User",
79
+ "fullName" => "Test User",
80
+ "nickName" => "test",
81
+ "language" => "en",
82
+ "timeZone" => "PST" }
83
+ }
84
+ post '/_gitkit?rp_target=callback', "some long assertion...."
85
+ assert_equal(200, last_response.status)
86
+ assert_match(/.*"registered":true.*/, last_response.body)
87
+ end
88
+
89
+ def test_callback_unregistered_user
90
+ mock(@app.api).verify_assertion(is_a(String), anything) {
91
+ { "kind" => "identitytoolkit#relyingparty",
92
+ "identifier" => "12345",
93
+ "authority" => "google.com",
94
+ "verifiedEmail" => "new@foo.com",
95
+ "firstName" => "Test",
96
+ "lastName" => "User",
97
+ "fullName" => "Test User",
98
+ "nickName" => "test",
99
+ "language" => "en",
100
+ "timeZone" => "PST" }
101
+ }
102
+ post '/_gitkit?rp_target=callback', "some long assertion..."
103
+ assert_equal(200, last_response.status)
104
+ assert_match(/.*"registered":false.*/, last_response.body)
105
+ end
106
+
107
+ def test_callback_invalid_response
108
+ mock(@app.api).verify_assertion(is_a(String), anything) {
109
+ raise ApiError("Invalid assertion")
110
+ }
111
+ post '/_gitkit?rp_target=callback', "garbage"
112
+ assert_equal(200, last_response.status)
113
+ assert_match(/.*notifyFederatedError.*/, last_response.body)
114
+ end
115
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gitkit-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Steven Bazyl
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-16 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: &70358498379620 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70358498379620
25
+ - !ruby/object:Gem::Dependency
26
+ name: json
27
+ requirement: &70358498378900 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.4.6
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70358498378900
36
+ - !ruby/object:Gem::Dependency
37
+ name: httparty
38
+ requirement: &70358498377960 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '0.8'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70358498377960
47
+ - !ruby/object:Gem::Dependency
48
+ name: addressable
49
+ requirement: &70358498376820 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.2'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70358498376820
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &70358498375600 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: '0.9'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70358498375600
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack-test
71
+ requirement: &70358498373840 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: '0.6'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70358498373840
80
+ - !ruby/object:Gem::Dependency
81
+ name: test-unit
82
+ requirement: &70358498371760 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: '1.2'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70358498371760
91
+ - !ruby/object:Gem::Dependency
92
+ name: rr
93
+ requirement: &70358498370780 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ~>
97
+ - !ruby/object:Gem::Version
98
+ version: '1.0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70358498370780
102
+ description: Rack middleware for Google Identity Toolkit
103
+ email:
104
+ - sqrrrl@gmail.com
105
+ executables: []
106
+ extensions: []
107
+ extra_rdoc_files: []
108
+ files:
109
+ - Gemfile
110
+ - Gemfile.lock
111
+ - Rakefile
112
+ - VERSION
113
+ - gitkit-ruby.gemspec
114
+ - lib/google/identity_toolkit.rb
115
+ - lib/google/identity_toolkit/api.rb
116
+ - lib/google/identity_toolkit/errors.rb
117
+ - lib/google/identity_toolkit/helpers.rb
118
+ - lib/google/identity_toolkit/version.rb
119
+ - tasks/test.rake
120
+ - tasks/yard.rake
121
+ - test/gitkit_test.rb
122
+ homepage: ''
123
+ licenses: []
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ segments:
135
+ - 0
136
+ hash: 442708502916154574
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ segments:
144
+ - 0
145
+ hash: 442708502916154574
146
+ requirements: []
147
+ rubyforge_project: gitkit-ruby
148
+ rubygems_version: 1.8.10
149
+ signing_key:
150
+ specification_version: 3
151
+ summary: Rack middleware for Google Identity Toolkit
152
+ test_files:
153
+ - test/gitkit_test.rb