samorau 0.1.1 → 0.2.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/Rakefile CHANGED
@@ -14,8 +14,9 @@ begin
14
14
  gemspec.add_dependency(%q<rest-client>, ["~> 1.2.0"])
15
15
  gemspec.add_dependency(%q<yajl-ruby>, ["~> 0.6"])
16
16
  gemspec.add_dependency(%q<term-ansicolor>, ["~> 1.0"])
17
+ gemspec.add_dependency(%q<launchy>, [">= 0.3.2"])
17
18
 
18
- gemspec.version = '0.1.1'
19
+ gemspec.version = '0.2.0'
19
20
  end
20
21
  rescue LoadError
21
22
  puts "Jeweler not available. Install it with: gem install jeweler"
data/bin/samorau CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'optparse'
4
4
  require 'term/ansicolor'
5
+ require 'launchy'
5
6
  require 'heroku/samorau'
6
7
 
7
8
  fn="addon-manifest.json"
@@ -88,6 +89,10 @@ when "test"
88
89
  id = ARGV.shift || abort("! no id specified; see usage")
89
90
  run ManifestCheck, fn
90
91
  run DeleteCheck, fn, :id => id, :async => async, :env => env
92
+ when "sso"
93
+ id = ARGV.shift || abort("! no id specified; see usage")
94
+ run ManifestCheck, fn
95
+ run SsoCheck, fn, :id => id, :env => env
91
96
  else
92
97
  abort "! Unknown test '#{check}'; see usage"
93
98
  end
@@ -95,6 +100,12 @@ when "run"
95
100
  abort "! missing command to run; see usage" if ARGV.empty?
96
101
  run ManifestCheck, fn
97
102
  run AllCheck, fn, :args => ARGV, :async => async, :env => env
103
+ when "sso"
104
+ id = ARGV.shift || abort("! no id specified; see usage")
105
+ data = Yajl::Parser.parse(resolve_manifest(fn)).merge(:id => id)
106
+ sso = Sso.new(data)
107
+ puts "Opening #{sso.full_url}"
108
+ Launchy.open sso.full_url
98
109
  else
99
110
  abort File.read(__FILE__).split('__END__').last
100
111
  end
@@ -124,6 +135,8 @@ COMMANDS
124
135
 
125
136
  run <command> Provisions a resource and runs command in returned ENV
126
137
 
138
+ sso <id> Launches the browser on a Heroku session for the specified id
139
+
127
140
  TEST TYPES
128
141
 
129
142
  provision
@@ -132,6 +145,9 @@ TEST TYPES
132
145
  deprovision <id>
133
146
  Simulate a deprovision call from Heroku.
134
147
 
148
+ sso <id>
149
+ Simulate a single sign-on call from Heroku.
150
+
135
151
  manifest
136
152
  Confirm that the manifest is valid. Automatically runs before all tests.
137
153
 
@@ -21,6 +21,7 @@ module Heroku
21
21
  "api" => {
22
22
  "username" => "heroku",
23
23
  "password" => generate_password,
24
+ "sso_salt" => generate_password(40),
24
25
  "test" => "http://localhost:4567/",
25
26
  "production" => "https://yourapp.com/",
26
27
  "config_vars" => ["MYADDON_URL"]
@@ -36,8 +37,8 @@ module Heroku
36
37
  }
37
38
  end
38
39
 
39
- def self.generate_password
40
- Array.new(8) { rand(256) }.pack('C*').unpack('H*').first
40
+ def self.generate_password(size=16)
41
+ Array.new(size/2) { rand(256) }.pack('C*').unpack('H*').first
41
42
  end
42
43
 
43
44
  end
@@ -246,6 +247,11 @@ module Heroku
246
247
 
247
248
  module HTTP
248
249
 
250
+ def get(path, params={})
251
+ path = "#{path}?" + params.map { |k, v| "#{k}=#{v}" }.join("&") unless params.empty?
252
+ request(:get, [], path)
253
+ end
254
+
249
255
  def post(credentials, path, payload=nil)
250
256
  request(:post, credentials, path, payload)
251
257
  end
@@ -315,7 +321,7 @@ module Heroku
315
321
  reader, writer = nil
316
322
 
317
323
  payload = {
318
- :id => APPID,
324
+ :heroku_id => APPID,
319
325
  :plan => "Basic",
320
326
  :callback_url => callback
321
327
  }
@@ -421,6 +427,60 @@ module Heroku
421
427
  end
422
428
 
423
429
 
430
+ class Sso
431
+ attr_accessor :id, :url
432
+
433
+ def initialize(data)
434
+ @id = data[:id]
435
+ @salt = data['api']['sso_salt']
436
+ @url = data["api"]["test"].chomp('/')
437
+ end
438
+
439
+ def path
440
+ "/heroku/resources/#{id}"
441
+ end
442
+
443
+ def full_url
444
+ t = Time.now.to_i
445
+ "#{url}#{path}?token=#{make_token(t)}&timestamp=#{t}"
446
+ end
447
+
448
+ def make_token(t)
449
+ Digest::SHA1.hexdigest([@id, @salt, t].join(':'))
450
+ end
451
+ end
452
+
453
+
454
+ class SsoCheck < ApiCheck
455
+ include HTTP
456
+
457
+ def call!
458
+ sso = Sso.new(data)
459
+ t = Time.now.to_i
460
+
461
+ test "GET #{sso.path}"
462
+ check "validates token" do
463
+ code, _ = get(sso.path, { :token => 'invalid', :timestamp => t })
464
+ error("expected 403, got #{code}") if code != 403
465
+ true
466
+ end
467
+
468
+ check "validates timestamp" do
469
+ prev = (Time.now - 60*6).to_i
470
+ code, _ = get(sso.path, { :token => sso.make_token(prev), :timestamp => prev })
471
+ error("expected 403, got #{code}") if code != 403
472
+ true
473
+ end
474
+
475
+ check "logs in" do
476
+ code, _ = get(sso.path, { :token => sso.make_token(t), :timestamp => t })
477
+ error("expected 200, got #{code}") if code != 200
478
+ true
479
+ end
480
+ end
481
+ end
482
+
483
+
424
484
  ##
425
485
  # On Testing:
426
486
  # I've opted to not write tests for this
@@ -435,7 +495,7 @@ module Heroku
435
495
  run CreateCheck, data
436
496
 
437
497
  response = data[:create_response]
438
- id = response["id"]
498
+ data.merge!(:id => response["id"])
439
499
  config = response["config"] || Hash.new
440
500
 
441
501
  if args
@@ -449,7 +509,8 @@ module Heroku
449
509
  screen.message "End of #{args.first}"
450
510
  end
451
511
 
452
- run DeleteCheck, data.merge(:id => id)
512
+ run SsoCheck, data
513
+ run DeleteCheck, data
453
514
  end
454
515
 
455
516
  def run_in_env(env)
data/samorau.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{samorau}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Blake Mizerany", "Pedro Belo", "Adam Wiggins"]
12
- s.date = %q{2010-02-23}
12
+ s.date = %q{2010-03-04}
13
13
  s.default_executable = %q{samorau}
14
14
  s.description = %q{}
15
15
  s.email = %q{pedro@heroku.com}
@@ -32,7 +32,8 @@ Gem::Specification.new do |s|
32
32
  "test/create_response_check_test.rb",
33
33
  "test/delete_check.rb",
34
34
  "test/helper.rb",
35
- "test/manifest_check_test.rb"
35
+ "test/manifest_check_test.rb",
36
+ "test/sso_check_test.rb"
36
37
  ]
37
38
  s.homepage = %q{http://heroku.com}
38
39
  s.rdoc_options = ["--charset=UTF-8"]
@@ -44,7 +45,8 @@ Gem::Specification.new do |s|
44
45
  "test/create_response_check_test.rb",
45
46
  "test/delete_check.rb",
46
47
  "test/helper.rb",
47
- "test/manifest_check_test.rb"
48
+ "test/manifest_check_test.rb",
49
+ "test/sso_check_test.rb"
48
50
  ]
49
51
 
50
52
  if s.respond_to? :specification_version then
@@ -58,6 +60,7 @@ Gem::Specification.new do |s|
58
60
  s.add_runtime_dependency(%q<rest-client>, ["~> 1.2.0"])
59
61
  s.add_runtime_dependency(%q<yajl-ruby>, ["~> 0.6"])
60
62
  s.add_runtime_dependency(%q<term-ansicolor>, ["~> 1.0"])
63
+ s.add_runtime_dependency(%q<launchy>, [">= 0.3.2"])
61
64
  else
62
65
  s.add_dependency(%q<turn>, [">= 0"])
63
66
  s.add_dependency(%q<contest>, [">= 0"])
@@ -65,6 +68,7 @@ Gem::Specification.new do |s|
65
68
  s.add_dependency(%q<rest-client>, ["~> 1.2.0"])
66
69
  s.add_dependency(%q<yajl-ruby>, ["~> 0.6"])
67
70
  s.add_dependency(%q<term-ansicolor>, ["~> 1.0"])
71
+ s.add_dependency(%q<launchy>, [">= 0.3.2"])
68
72
  end
69
73
  else
70
74
  s.add_dependency(%q<turn>, [">= 0"])
@@ -73,6 +77,7 @@ Gem::Specification.new do |s|
73
77
  s.add_dependency(%q<rest-client>, ["~> 1.2.0"])
74
78
  s.add_dependency(%q<yajl-ruby>, ["~> 0.6"])
75
79
  s.add_dependency(%q<term-ansicolor>, ["~> 1.0"])
80
+ s.add_dependency(%q<launchy>, [">= 0.3.2"])
76
81
  end
77
82
  end
78
83
 
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + "/helper"
2
+ require "heroku/samorau"
3
+
4
+ class SsoCheckTest < Test::Unit::TestCase
5
+ include Heroku::Samorau
6
+
7
+ setup do
8
+ @data = Manifest.skeleton.merge :id => 123
9
+ @responses = [
10
+ [403, ""],
11
+ [403, ""],
12
+ [200, ""]
13
+ ]
14
+ end
15
+
16
+ def check ; SsoCheck ; end
17
+
18
+ test "rejects bad token" do
19
+ @responses[0] = [200, ""]
20
+ assert_invalid do |check|
21
+ stub :get, check, @responses
22
+ end
23
+ end
24
+
25
+ test "rejects bad timestamp do" do
26
+ @responses[1] = [200, ""]
27
+ assert_invalid do |check|
28
+ stub :get, check, @responses
29
+ end
30
+ end
31
+
32
+ test "accepts sso otherwise" do
33
+ assert_valid do |check|
34
+ stub :get, check, @responses
35
+ end
36
+ end
37
+
38
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 1
9
- version: 0.1.1
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Blake Mizerany
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-02-23 00:00:00 -08:00
19
+ date: 2010-03-04 00:00:00 -08:00
20
20
  default_executable: samorau
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -96,6 +96,20 @@ dependencies:
96
96
  version: "1.0"
97
97
  type: :runtime
98
98
  version_requirements: *id006
99
+ - !ruby/object:Gem::Dependency
100
+ name: launchy
101
+ prerelease: false
102
+ requirement: &id007 !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ segments:
107
+ - 0
108
+ - 3
109
+ - 2
110
+ version: 0.3.2
111
+ type: :runtime
112
+ version_requirements: *id007
99
113
  description: ""
100
114
  email: pedro@heroku.com
101
115
  executables:
@@ -120,6 +134,7 @@ files:
120
134
  - test/delete_check.rb
121
135
  - test/helper.rb
122
136
  - test/manifest_check_test.rb
137
+ - test/sso_check_test.rb
123
138
  has_rdoc: true
124
139
  homepage: http://heroku.com
125
140
  licenses: []
@@ -156,3 +171,4 @@ test_files:
156
171
  - test/delete_check.rb
157
172
  - test/helper.rb
158
173
  - test/manifest_check_test.rb
174
+ - test/sso_check_test.rb