blinkbox-user 0.5.3

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YmI2Njc0ZDI4ZjhlN2ZkYzUzMDNhMjk2NmFlNGY5YWI1MWFlNzc3Zg==
5
+ data.tar.gz: !binary |-
6
+ ZWQ0Y2JmYjk5MGE2MmYyNDIzYWUwODZjYTU3Mzk5YjY5M2I2NmFjMw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YTFhMzg4YjU3MmM4MGViNWUwN2E0ZDU4NjkyMjRhNmZhNTgwMTAzYzYwMDBl
10
+ NTJhODc2ODlkNzMwYTc0NGMyNWU3NzVjYTdjYWNiZTFlN2Y0NWVlOTAxYjFl
11
+ YWY3ZTMwNjM2ZDgwNWMxNmE0ZTYyOTNmYmY1ZGRhMjBiMjlhZmE=
12
+ data.tar.gz: !binary |-
13
+ MTdiNmM0YzI2ZjY2ODI1OTYxN2I2NTEwNjVmZmYwNmMyNmExMDkxNmE3ZTg1
14
+ ZTQyYTU5MTY0ZDUwZTk1M2Y0NjZlYzEwM2ZlNGNiYmNhNWFlZmQ4NDAyZGI2
15
+ NmFmZGRiZDM3YmZlY2EyNzk0MmMyODNjNjEwY2M4MDMzY2VmMzQ=
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.3
@@ -0,0 +1,112 @@
1
+ require 'blinkbox/user/device'
2
+ require 'blinkbox/user/zuul_client'
3
+ require 'blinkbox/user/credit_card_service_client'
4
+ require 'blinkbox/user/braintree_encode'
5
+ require 'yaml'
6
+ require 'blinkbox/user/braintree_keys'
7
+
8
+ module Blinkbox
9
+ class User
10
+ attr_accessor :username, :password, :grant_type, :first_name, :last_name, :allow_marketing_communications, :accepted_terms_and_conditions
11
+
12
+ def initialize(params, auth_client = ZuulClient, cc_service_client = CreditCardServiceClient)
13
+ @grant_type = params[:grant_type] || "password"
14
+ @username = params[:username]
15
+ @password = params[:password]
16
+
17
+ # Default parameters only used when attempting to register
18
+ @first_name = params[:first_name] || "Testy"
19
+ @last_name = params[:last_name] || "McTesterson"
20
+ @accepted_terms_and_conditions = params[:accepted_terms_and_conditions] || true
21
+ @allow_marketing_communications = params[:allow_marketing_communications] || false
22
+
23
+ auth_server_uri = params[:server_uri] || "https://auth.dev.bbbtest2.com"
24
+ @auth_client = auth_client.new(auth_server_uri, params[:proxy_uri])
25
+
26
+ credit_card_service_uri = params[:credit_card_service_uri] || "https://api.dev.bbbtest2.com"
27
+ @cc_service_client = cc_service_client.new(credit_card_service_uri, params[:proxy_uri])
28
+ end
29
+
30
+ def register(client_options = {})
31
+ @auth_client.register_user(self, client_options)
32
+ end
33
+
34
+ def authenticate
35
+ @auth_client.authenticate(user_credentials)
36
+ res = @auth_client.last_response(:format => "json")
37
+
38
+ res.keys.each do |key|
39
+ instance_eval %Q{
40
+ @#{key} = "#{res[key]}"
41
+ User.class_eval{ attr_reader key.to_sym }
42
+ }
43
+ end
44
+ end
45
+
46
+ def get_devices
47
+ @auth_client.get_clients_info @access_token
48
+ @device_clients = []
49
+ @auth_client.last_response(:format => "json")['clients'].each do |dc|
50
+ @device_clients.push(Device.new(dc))
51
+ end
52
+ @device_clients
53
+ end
54
+
55
+ def register_device(params)
56
+ @auth_client.register_client(Blinkbox::Device.new(params), @access_token)
57
+ end
58
+
59
+ def deregister_device(device)
60
+ @auth_client.deregister_client(device.id, @access_token)
61
+ end
62
+
63
+ def deregister_all_devices
64
+ get_devices.each do |device|
65
+ deregister_device(device)
66
+ end
67
+ end
68
+
69
+ def add_default_credit_card(opts = {})
70
+ # setting up defaults
71
+ opts[:braintree_env] ||= ENV['SERVER'] || 'dev_int'
72
+ opts[:card_type] ||= 'mastercard'
73
+
74
+ braintree_public_key = BRAINTREE_KEYS[opts[:braintree_env].to_sym]
75
+
76
+ card_number_map = {
77
+ 'mastercard' => '5555555555554444',
78
+ 'visa' => '4111111111111111',
79
+ 'amex' => '378282246310005',
80
+ 'discover' => '6011111111111117',
81
+ 'jcb' => '3530111333300000'
82
+ }
83
+ card_number = card_number_map[opts[:card_type]]
84
+ fail "Unrecognised card_type: #{opts[:card_type]}. Please use one of #{card_number_map.keys}" if card_number.nil?
85
+
86
+ cvv = opts[:card_type].eql?('amex') ? '1234' : '123'
87
+
88
+ @encrypted_card_number ||= BraintreeEncryption.encrypt(card_number, braintree_public_key)
89
+ @encrypted_cvv ||= BraintreeEncryption.encrypt(cvv, braintree_public_key)
90
+ @encrypted_expiration_month ||= BraintreeEncryption.encrypt('8', braintree_public_key)
91
+ @encrypted_expiration_year ||= BraintreeEncryption.encrypt('2020', braintree_public_key)
92
+
93
+ card_details = {
94
+ default: true,
95
+ number: @encrypted_card_number,
96
+ cvv: @encrypted_cvv,
97
+ expirationMonth: @encrypted_expiration_month,
98
+ expirationYear: @encrypted_expiration_year,
99
+ cardholderName: 'Jimmy Jib',
100
+ billingAddress: { line1: "48 dollis rd", locality: "London", postcode: "n3 1rd" }
101
+ }
102
+
103
+ @cc_service_client.add_credit_card(@access_token, card_details)
104
+ end
105
+
106
+ private
107
+
108
+ def user_credentials
109
+ { grant_type: @grant_type, username: @username, password: @password }
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,33 @@
1
+ require "base64" # gem: rubysl-base64
2
+ require "openssl"
3
+ require "securerandom"
4
+
5
+ module BraintreeEncryption
6
+ def self.encrypt(value, public_key)
7
+ # reverse engineered from https://github.com/braintree/braintree.js/blob/master/lib/braintree.js
8
+ # this may need to be updated if braintree change their client-side encryption scripts
9
+
10
+ return nil if value.nil?
11
+ return "" if value.respond_to?(:empty?) && value.empty?
12
+
13
+ fail "The Braintree client key is not configured" if public_key.nil?
14
+ raw_key = Base64.strict_decode64(public_key)
15
+ rsa = OpenSSL::PKey::RSA.new(raw_key)
16
+
17
+ aes = OpenSSL::Cipher::AES256.new(:CBC).encrypt
18
+ aes_key, aes_iv = aes.random_key, aes.random_iv
19
+ encrypted_value = aes.update(value.to_s) + aes.final
20
+ ciphertext = aes_iv + encrypted_value
21
+ encoded_ciphertext = Base64.strict_encode64(ciphertext)
22
+
23
+ hmac_key = SecureRandom.random_bytes(32)
24
+ hmac = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, hmac_key, ciphertext)
25
+ signature = Base64.strict_encode64(hmac)
26
+
27
+ combined_key = aes_key + hmac_key
28
+ encoded_key = Base64.strict_encode64(combined_key)
29
+ encrypted_key = Base64.strict_encode64(rsa.public_encrypt(encoded_key))
30
+
31
+ "$bt4|javascript_1_3_9$#{encrypted_key}$#{encoded_ciphertext}$#{signature}"
32
+ end
33
+ end
@@ -0,0 +1,4 @@
1
+ BRAINTREE_KEYS = {
2
+ dev_int: "snip",
3
+ qa: "snip"
4
+ }
@@ -0,0 +1,47 @@
1
+ require 'httparty'
2
+ require 'multi_json'
3
+ require 'net/http/capture'
4
+
5
+ module Blinkbox
6
+ class CreditCardServiceClient
7
+ include HTTParty
8
+ attr_accessor :headers
9
+
10
+ def initialize(server_uri, proxy_uri = nil)
11
+ self.class.base_uri(server_uri.to_s)
12
+ self.class.http_proxy(proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password) if proxy_uri
13
+ self.class.debug_output($stderr) if ENV['DEBUG']
14
+ @headers = {}
15
+ end
16
+
17
+ def use_proxy(proxy_uri)
18
+ proxy_uri = URI.parse(proxy_uri) if proxy_uri.is_a?(String)
19
+ self.class.http_proxy(proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
20
+ end
21
+
22
+ def add_credit_card(access_token, card_details = {})
23
+ response = nil
24
+ 10.times do
25
+ response = http_post("/service/my/creditcards", card_details, access_token)
26
+ break if response.successful?
27
+ end
28
+ fail 'Adding credit card failed' unless response.successful?
29
+
30
+ #return details of the newly added card
31
+ MultiJson.load(response.body)
32
+ end
33
+
34
+ private
35
+
36
+ def http_post(uri, body, access_token = nil)
37
+ http_send(:post, uri, body, access_token)
38
+ end
39
+
40
+ def http_send(verb, uri, post_body, access_token = nil)
41
+ headers = { "Content-Type" => "application/vnd.blinkboxbooks.data.v1+json" }.merge(@headers)
42
+ headers["Authorization"] = "Bearer #{access_token}" if access_token
43
+ self.class.send(verb, uri.to_s, headers: headers, body: post_body.to_json)
44
+ HttpCapture::RESPONSES.last
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,16 @@
1
+ module Blinkbox
2
+ class Device
3
+ def initialize(hash)
4
+ hash.keys.each do |key|
5
+ instance_eval %Q{
6
+ @#{key} = "#{hash[key]}"
7
+ Device.class_eval{ attr_reader key.to_sym }
8
+ }
9
+ end
10
+ end
11
+
12
+ def id
13
+ @client_id ? @client_id.split(':').last : nil
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,175 @@
1
+ require 'httparty'
2
+ require 'multi_json'
3
+ require 'net/http/capture'
4
+
5
+ module Blinkbox
6
+ class ZuulClient
7
+ include HTTParty
8
+ attr_accessor :headers
9
+
10
+ def initialize(server_uri, proxy_uri = nil)
11
+ self.class.base_uri(server_uri.to_s)
12
+ self.class.http_proxy(proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password) if proxy_uri
13
+ self.class.debug_output($stderr) if ENV['DEBUG']
14
+ @headers = {}
15
+ end
16
+
17
+ def use_proxy(proxy_uri)
18
+ proxy_uri = URI.parse(proxy_uri) if proxy_uri.is_a?(String)
19
+ self.class.http_proxy(proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
20
+ end
21
+
22
+ def authenticate(params)
23
+ http_post "/oauth2/token", params
24
+ end
25
+
26
+ def get_client_info(client_id, access_token)
27
+ http_get "/clients/#{client_id}", {}, access_token
28
+ end
29
+
30
+ def get_clients_info(access_token)
31
+ http_get "/clients", {}, access_token
32
+ end
33
+
34
+ def get_user_info(user_id, access_token)
35
+ http_get "/users/#{user_id}", {}, access_token
36
+ end
37
+
38
+ def get_access_token_info(access_token)
39
+ http_get "/session", {}, access_token
40
+ end
41
+
42
+ def extend_elevated_session(access_token)
43
+ http_post "/session", {}, access_token
44
+ end
45
+
46
+ def register_client(client, access_token)
47
+ params = {
48
+ client_name: client.name,
49
+ client_brand: client.brand,
50
+ client_model: client.model,
51
+ client_os: client.os
52
+ }
53
+ http_post "/clients", params, access_token
54
+ end
55
+
56
+ def change_password(params, access_token)
57
+ http_post "/password/change", params, access_token
58
+ end
59
+
60
+ def reset_password(params)
61
+ http_post "/password/reset", params
62
+ end
63
+
64
+ def validate_password_reset_token(params)
65
+ http_post "/password/reset/validate-token", params
66
+ end
67
+
68
+ def deregister_client(client_id, access_token)
69
+ http_delete "/clients/#{client_id}", {}, access_token
70
+ end
71
+
72
+ def register_user(user, client_options = {})
73
+ params = {
74
+ grant_type: "urn:blinkbox:oauth:grant-type:registration",
75
+ username: user.username,
76
+ password: user.password,
77
+ first_name: user.first_name,
78
+ last_name: user.last_name,
79
+ accepted_terms_and_conditions: user.accepted_terms_and_conditions,
80
+ allow_marketing_communications: user.allow_marketing_communications
81
+ }
82
+ params.merge!(client_options)
83
+ response = http_post("/oauth2/token", params)
84
+ response.successful? ? MultiJson.load(response.body) : response
85
+ end
86
+
87
+ def register_user_with_client(user, client)
88
+ client_params = {
89
+ client_name: client.name,
90
+ client_brand: client.brand,
91
+ client_model: client.model,
92
+ client_os: client.os
93
+ }
94
+ register_user(user, client_params)
95
+ end
96
+
97
+ def revoke(refresh_token, access_token = nil)
98
+ http_post "/tokens/revoke", { refresh_token: refresh_token }, access_token
99
+ end
100
+
101
+ def update_client(client, access_token)
102
+ params = {}
103
+ params[:client_name] = client.name if client.name_changed?
104
+ params[:client_brand] = client.brand if client.brand_changed?
105
+ params[:client_model] = client.model if client.model_changed?
106
+ params[:client_os] = client.os if client.os_changed?
107
+ http_patch "/clients/#{client.local_id}", params, access_token
108
+ end
109
+
110
+ def update_user(user, access_token)
111
+ params = {}
112
+ params[:username] = user.username if user.username_changed?
113
+ params[:password] = user.password if user.password_changed?
114
+ params[:first_name] = user.first_name if user.first_name_changed?
115
+ params[:last_name] = user.last_name if user.last_name_changed?
116
+ params[:accepted_terms_and_conditions] = user.accepted_terms_and_conditions if user.accepted_terms_and_conditions_changed?
117
+ params[:allow_marketing_communications] = user.allow_marketing_communications if user.allow_marketing_communications_changed?
118
+ http_patch "/users/#{user.local_id}", params, access_token
119
+ end
120
+
121
+ def admin_find_user(params = {}, access_token)
122
+ http_get "/admin/users", params, access_token
123
+ end
124
+
125
+ def admin_get_user_info(user_id, access_token)
126
+ http_get "/admin/users/#{user_id}", {}, access_token
127
+ end
128
+
129
+ def last_response(params = {})
130
+ res = HttpCapture::RESPONSES.last
131
+ return nil if res.body.empty?
132
+ fail "Requires format parameter" if !params[:format]
133
+ case params[:format]
134
+ when "json"
135
+ MultiJson.load(res.body)
136
+ else
137
+ res
138
+ end
139
+ end
140
+
141
+ private
142
+
143
+ def http_get(uri, params = {}, access_token = nil)
144
+ http_call(:get, uri, params, access_token)
145
+ end
146
+
147
+ def http_delete(uri, params = {}, access_token = nil)
148
+ http_call(:delete, uri, params, access_token)
149
+ end
150
+
151
+ def http_call(verb, uri, params = {}, access_token = nil)
152
+ headers = { "Accept" => "application/json" }.merge(@headers)
153
+ headers["Authorization"] = "Bearer #{access_token}" if access_token
154
+ self.class.send(verb, uri.to_s, headers: headers, query: params)
155
+ HttpCapture::RESPONSES.last
156
+ end
157
+
158
+ def http_patch(uri, body_params, access_token = nil)
159
+ http_send(:patch, uri, body_params, access_token)
160
+ end
161
+
162
+ def http_post(uri, body_params, access_token = nil)
163
+ http_send(:post, uri, body_params, access_token)
164
+ end
165
+
166
+ def http_send(verb, uri, body_params, access_token = nil)
167
+ headers = { "Accept" => "application/json", "Content-Type" => "application/x-www-form-urlencoded" }.merge(@headers)
168
+ headers["Authorization"] = "Bearer #{access_token}" if access_token
169
+ body_params.reject! { |_, v| v.nil? }
170
+ body_params = URI.encode_www_form(body_params) unless body_params.is_a?(String)
171
+ self.class.send(verb, uri.to_s, headers: headers, body: body_params)
172
+ HttpCapture::RESPONSES.last
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,7 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Blinkbox::CreditCardServiceClient.new(SERVER_URI, nil) do
4
+ it { is_expected.to respond_to(:use_proxy).with(1).argument }
5
+ it { is_expected.to respond_to(:add_credit_card).with(1).argument }
6
+ it { is_expected.to respond_to(:add_credit_card).with(2).arguments }
7
+ end
@@ -0,0 +1,45 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Blinkbox::User do
4
+ before :each do
5
+ @user = described_class.new({ :grant_type => "password", :username => "test", :password => "password" }, MockClient)
6
+ end
7
+
8
+ it "should list a user's devices" do
9
+ expect(@user).to respond_to(:get_devices)
10
+ end
11
+
12
+ it "should be able to unregister all of a user's devices" do
13
+ expect(@user).to respond_to(:deregister_all_devices)
14
+ end
15
+
16
+ it "should allow for devices to be registered for a user" do
17
+ expect(@user).to respond_to(:register_device).with(1).argument
18
+ end
19
+
20
+ it "should allow for devices to be deregistered for a user" do
21
+ expect(@user).to respond_to(:deregister_device).with(1).argument
22
+ end
23
+
24
+ it "should be able to add a default credit card for a user" do
25
+ expect(@user).to respond_to(:add_default_credit_card).with(0).argument
26
+ end
27
+
28
+ it "should be able to add a default credit card of a specified type for a user" do
29
+ expect(@user).to respond_to(:add_default_credit_card).with(1).arguments
30
+ end
31
+
32
+ it "Should store authentication data" do
33
+ @user.authenticate
34
+ expect(@user.access_token).to eq(MockClient::TESTDATA[:access_token])
35
+ expect(@user.token_type).to eq(MockClient::TESTDATA[:token_type])
36
+ expect(@user.expires_in).to eq(MockClient::TESTDATA[:expires_in].to_s)
37
+ expect(@user.user_id).to eq(MockClient::TESTDATA[:user_id])
38
+ expect(@user.refresh_token).to eq(MockClient::TESTDATA[:refresh_token])
39
+ expect(@user.user_id).to eq(MockClient::TESTDATA[:user_id])
40
+ expect(@user.user_uri).to eq(MockClient::TESTDATA[:user_uri])
41
+ expect(@user.user_username).to eq(MockClient::TESTDATA[:user_username])
42
+ expect(@user.user_first_name).to eq(MockClient::TESTDATA[:user_first_name])
43
+ expect(@user.user_last_name).to eq(MockClient::TESTDATA[:user_last_name])
44
+ end
45
+ end
@@ -0,0 +1,19 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Blinkbox::ZuulClient.new(SERVER_URI, nil) do
4
+ it { is_expected.to respond_to(:get_client_info).with(2).arguments }
5
+ it { is_expected.to respond_to(:get_clients_info).with(1).argument }
6
+ it { is_expected.to respond_to(:authenticate).with(1).argument }
7
+ it { is_expected.to respond_to(:use_proxy).with(1).argument }
8
+ it { is_expected.to respond_to(:get_user_info).with(2).arguments }
9
+ it { is_expected.to respond_to(:get_access_token_info).with(1).argument }
10
+ it { is_expected.to respond_to(:extend_elevated_session).with(1).argument }
11
+ it { is_expected.to respond_to(:register_client).with(2).arguments }
12
+ it { is_expected.to respond_to(:change_password).with(2).arguments }
13
+ it { is_expected.to respond_to(:reset_password).with(1).argument }
14
+ it { is_expected.to respond_to(:validate_password_reset_token).with(1).argument }
15
+ it { is_expected.to respond_to(:deregister_client).with(2).arguments }
16
+ it { is_expected.to respond_to(:revoke).with(2).arguments }
17
+ it { is_expected.to respond_to(:update_client).with(2).arguments }
18
+ it { is_expected.to respond_to(:update_user).with(2).arguments }
19
+ end
@@ -0,0 +1,36 @@
1
+ $LOAD_PATH.unshift File.join(__dir__, "../lib")
2
+ require 'blinkbox/user'
3
+
4
+ SERVER_URI = 'https://auth.blinkboxbooks.com'
5
+
6
+ class MockClient
7
+ TESTDATA = {
8
+ :access_token => "eyJraWQiOiJibGlua2JveC9wbGF0L2VuYy9yc2EvMSIsImN0eSI6IkpXVCIsImVuYyI6IkExMjhHQ0 \
9
+ 0iLCJhbGciOiJSU0EtT0FFUCJ9.RDGUMvxMG44WKImdMAFFWypaKCmFOCwCqDq24yJobqOjrmfR7V4ZErJTO-xWueqQX5SxzgRui \
10
+ ARNVch5SdfWZZZqkAVupeiQ7_dvffeEdEGm8RtGiCs9f37s9TNayCQOgWiC4aGEQ2JQ20rt2pLF9SkXmuTqLgVRQCZdrAwtzC90G \
11
+ SVRhAI39nIzsBnxhYxGsv12N9-89g1F6q8NTtih19A3jWBKIhFRp4dC21T1vQDw-k6hiPDqbo9G8msC9-U9aoXZToh9y2YjPxAus \
12
+ rXCPlOTX9r6tMW1RtTFHHDiI48EA7z23ItqhhaiweZVnwjGl3RPWPAwgxgGFyhOcWD10w.Ul73uvPewy1LUqZQ.n0hxUwxsf2fIZ \
13
+ 11xl8nprsbxr8naI51cdroNOylsrSRrVy551_1e0d0DsmoSfmvOkECOLFNaxeC2qDBQYKH7pCpOWmtOuxpWdBvxGC_MV9-z_kapr \
14
+ UrdmJMSxLkM7Ehh9Z1n254wv-zUS8vJ8Dr-e3DwMIKA81OhoGJtNAg6cphGFFFfPmaEOfeP1oHp-SuDYCi6CJSrJRM-TO4HvJqbX \
15
+ QaHqGSdLAvkTe_fGpDofwpGqEUV7bf7gY_U7cvB-5l3gYmkLFs8Ic-xI6a8lhISXrJLup_Pr5pfHTKuRPdYBWY187K_-lDeF0zJA \
16
+ XOxnfdUhGcrxEM.ObXF30ih4PvbRqv_qzoYdQ",
17
+ :token_type => "bearer",
18
+ :expires_in => 1800,
19
+ :refresh_token => "kWLx_RPKbZUYjH8bk8gHm3LKpkuR2MfMXy25ATmv2pc",
20
+ :user_id => "urn:blinkbox:zuul:user:10921",
21
+ :user_uri => "/users/10921",
22
+ :user_username => "calabash_test@gmail.com",
23
+ :user_first_name => "Firstname",
24
+ :user_last_name => "Lastname"
25
+ }
26
+
27
+ def initialize(*)
28
+ end
29
+
30
+ def authenticate(*)
31
+ end
32
+
33
+ def last_response(*)
34
+ TESTDATA
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: blinkbox-user
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.3
5
+ platform: ruby
6
+ authors:
7
+ - blinkbox books
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: http_capture
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: multi_json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '10.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '10.1'
97
+ description: blinkbox ruby user management api
98
+ email:
99
+ - alexjo@blinkbox.com
100
+ - mustaqila@blinkbox.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - VERSION
106
+ - lib/blinkbox/user.rb
107
+ - lib/blinkbox/user/braintree_encode.rb
108
+ - lib/blinkbox/user/braintree_keys.rb
109
+ - lib/blinkbox/user/credit_card_service_client.rb
110
+ - lib/blinkbox/user/device.rb
111
+ - lib/blinkbox/user/zuul_client.rb
112
+ - spec/blinkbox/creditcardserviceclient_spec.rb
113
+ - spec/blinkbox/user_spec.rb
114
+ - spec/blinkbox/zuulclient_spec.rb
115
+ - spec/spec_helper.rb
116
+ homepage: https://git.mobcastdev.com/TEST/blinkbox-user
117
+ licenses:
118
+ - MIT
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.4.5
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: blinkbox ruby user management api
140
+ test_files:
141
+ - spec/blinkbox/creditcardserviceclient_spec.rb
142
+ - spec/blinkbox/user_spec.rb
143
+ - spec/blinkbox/zuulclient_spec.rb
144
+ - spec/spec_helper.rb