samorau 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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