bitballoon 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -46,6 +46,15 @@ If you're not authenticating on behalf of a user you can authorize directly with
46
46
  bitballoon.authorize_from_credentials!
47
47
  ```
48
48
 
49
+ If you already have an OAuth2 `access_token` you can instantiate the client like this:
50
+
51
+ ```ruby
52
+ bitballoon = BitBalloon::Client.new(:access_token => access_token)
53
+ ```
54
+
55
+ And the client will be ready to do requests. This means that once you've gotten a token via `authorize!` or `authorize_from_credentials!` you can store it and reuse it for later sessions.
56
+
57
+
49
58
  Command Line Utility
50
59
  ====================
51
60
 
@@ -9,5 +9,6 @@ require "bitballoon/submissions"
9
9
  require "bitballoon/files"
10
10
  require "bitballoon/snippets"
11
11
  require "bitballoon/deploys"
12
+ require "bitballoon/multipass"
12
13
 
13
14
  module BitBalloon; end
@@ -0,0 +1,70 @@
1
+ # Multipass implementation used for single-sign-on for resellers
2
+ require "openssl"
3
+ require "base64"
4
+ require "time"
5
+ require "json"
6
+
7
+ module BitBalloon
8
+ class Multipass
9
+ def initialize(multipass_secret)
10
+ ### Use the Multipass secret to derive two cryptographic keys,
11
+ ### one for encryption, one for signing
12
+ key_material = OpenSSL::Digest::Digest.new("sha256").digest(multipass_secret)
13
+ @encryption_key = key_material[ 0,16]
14
+ @signature_key = key_material[16,16]
15
+ end
16
+
17
+ def generate_token(customer_data_hash)
18
+ ### Store the current time in ISO8601 format.
19
+ ### The token will only be valid for a small timeframe around this timestamp.
20
+ customer_data_hash["created_at"] = Time.now.iso8601
21
+
22
+ ### Serialize the customer data to JSON and encrypt it
23
+ ciphertext = encrypt(customer_data_hash.to_json)
24
+
25
+ ### Create a signature (message authentication code) of the ciphertext
26
+ ### and encode everything using URL-safe Base64 (RFC 4648)
27
+ sig = sign(ciphertext)
28
+
29
+ Base64.urlsafe_encode64(ciphertext + sign(ciphertext))
30
+ end
31
+
32
+ def decode_token(token)
33
+ decoded_token = Base64.urlsafe_decode64(token)
34
+ ciphertext, signature = [decoded_token[0..-33], decoded_token[-32..-1]]
35
+
36
+ sig = sign(ciphertext)
37
+
38
+ raise "Bad signature" unless sign(ciphertext) == signature
39
+
40
+ JSON.parse(decrypt(ciphertext))
41
+ end
42
+
43
+ private
44
+ def encrypt(plaintext)
45
+ cipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
46
+ cipher.encrypt
47
+ cipher.key = @encryption_key
48
+
49
+ ### Use a random IV
50
+ cipher.iv = iv = cipher.random_iv
51
+
52
+ ### Use IV as first block of ciphertext
53
+ iv + cipher.update(plaintext) + cipher.final
54
+ end
55
+
56
+ def decrypt(ciphertext)
57
+ decipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
58
+ decipher.decrypt
59
+ decipher.key = @encryption_key
60
+
61
+ decipher.iv, encrypted = [ciphertext[0..15], ciphertext[16..-1]]
62
+
63
+ decipher.update(encrypted) + decipher.final
64
+ end
65
+
66
+ def sign(data)
67
+ OpenSSL::HMAC.digest("sha256", @signature_key, data)
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,3 @@
1
1
  module BitBalloon
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+ require 'digest/sha1'
3
+
4
+ class MultipassTest < MiniTest::Unit::TestCase
5
+ def setup
6
+ @mp = BitBalloon::Multipass.new("secret")
7
+ end
8
+
9
+ def test_generate_and_decode_token
10
+ data = {"email" => "test@example.com", "uid" => "1234"}
11
+ token = @mp.generate_token(data)
12
+ assert_equal data, @mp.decode_token(token), "Data should be the same after generating and decoding"
13
+ end
14
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitballoon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-03 00:00:00.000000000 Z
12
+ date: 2013-10-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: oauth2
@@ -116,6 +116,7 @@ files:
116
116
  - lib/bitballoon/form.rb
117
117
  - lib/bitballoon/forms.rb
118
118
  - lib/bitballoon/model.rb
119
+ - lib/bitballoon/multipass.rb
119
120
  - lib/bitballoon/site.rb
120
121
  - lib/bitballoon/sites.rb
121
122
  - lib/bitballoon/snippet.rb
@@ -126,6 +127,7 @@ files:
126
127
  - test/client_test.rb
127
128
  - test/files/site-dir.zip
128
129
  - test/files/site-dir/index.html
130
+ - test/multipass_test.rb
129
131
  - test/sites_test.rb
130
132
  - test/test_helper.rb
131
133
  homepage: https://www.bitballoon.com
@@ -156,6 +158,7 @@ test_files:
156
158
  - test/client_test.rb
157
159
  - test/files/site-dir.zip
158
160
  - test/files/site-dir/index.html
161
+ - test/multipass_test.rb
159
162
  - test/sites_test.rb
160
163
  - test/test_helper.rb
161
164
  has_rdoc: