doyoubuzz-showcase 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 70f12625b52caebe5f3d707d714cd2c0f95ea309
4
- data.tar.gz: 80838e39ed9189bb9e2393d2f6756ae9bd024dc0
3
+ metadata.gz: dab8e4fc67a92861f80a0962dc11196af652b45f
4
+ data.tar.gz: 0da1bb56b4b0767aa2dab2fdfc4c4a9e90133408
5
5
  SHA512:
6
- metadata.gz: 1894f5dd1110f31614346d605307da9dc82e102d2423d8c49d7399473b7e94b344acb3adea419fff5db23f655a1d955bc96716ac3cdc4993da386260d79b5ac8
7
- data.tar.gz: c7443d57d9b68d1c2cc462af7d69109f8793906c6e29bd8e93b50b17995d91c8a2b6783bb26216899b2b6421390b7dfc62b837686419b40d31d16274f63436b3
6
+ metadata.gz: cc792af5f1ad68ebef798ce0953cc9e4c67527d6554a9a05a914c993f6bf1e5c77982b12c8fdb0a1c00557461021fc543d7a8b7199ec12044194273e9ba76559
7
+ data.tar.gz: 8c46d78bb80288218b1a6fc12c2f3581d735a95a6973d8a530cb8aae156381c99fc3546f550425d99e7231fb27132f143429c521d086f515da60923332cb48bf
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --format documentation
@@ -2,7 +2,7 @@ language: ruby
2
2
 
3
3
  rvm:
4
4
  - 2.1.0
5
- - 2.0.0
6
- - 1.9.3
5
+ - 2.2.3
6
+ - 2.3.0
7
7
 
8
- script: bundle exec rspec spec
8
+ script: bundle exec rspec spec
data/Gemfile CHANGED
@@ -1,12 +1,12 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Developpement dependencies
4
- gem 'rspec', '~> 3.1'
5
- gem 'webmock', '~> 1.20'
6
- gem 'vcr', '~> 2.9'
4
+ gem 'rspec', '~> 3.1'
5
+ gem 'webmock', '~> 1.20'
6
+ gem 'vcr', '~> 2.9'
7
7
 
8
8
  # CI
9
- gem 'coveralls', :require => false
9
+ gem 'coveralls', require: false
10
10
 
11
11
  # Specify the gem's dependencies in doyoubuzz-showcase.gemspec
12
12
  gemspec
data/README.md CHANGED
@@ -11,6 +11,7 @@ The `doyoubuzz-showcase` gem is a thin ruby wrapper for the DoYouBuzz Showcase A
11
11
 
12
12
  - httparty
13
13
  - hashie
14
+ - ruby >= 2.1.0
14
15
 
15
16
  ## Installation
16
17
 
@@ -4,23 +4,23 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'doyoubuzz/showcase/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "doyoubuzz-showcase"
7
+ spec.name = 'doyoubuzz-showcase'
8
8
  spec.version = Doyoubuzz::VERSION
9
- spec.authors = ["David RUYER"]
10
- spec.email = ["david.ruyer@gmail.com"]
11
- spec.description = %q{Wrapper around the DoYouBuzz showcase API}
12
- spec.summary = %q{Wrapper around the DoYouBuzz showcase API}
13
- spec.homepage = ""
14
- spec.license = "MIT"
9
+ spec.authors = ['David RUYER']
10
+ spec.email = ['david.ruyer@gmail.com']
11
+ spec.description = 'Wrapper around the DoYouBuzz showcase API'
12
+ spec.summary = 'Wrapper around the DoYouBuzz showcase API'
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
21
+ spec.add_development_dependency 'bundler', '~> 1.3'
22
+ spec.add_development_dependency 'rake'
23
23
 
24
- spec.add_dependency "httparty", "~> 0.13"
25
- spec.add_dependency "hashie", ">= 2.1.2"
24
+ spec.add_dependency 'httparty', '~> 0.13'
25
+ spec.add_dependency 'hashie', '>= 3.5.0'
26
26
  end
@@ -1,3 +1,4 @@
1
+ require 'logger'
1
2
  require 'httparty'
2
3
  require 'hashie/mash'
3
4
 
@@ -9,6 +10,8 @@ module Doyoubuzz
9
10
  include HTTParty
10
11
  base_uri 'http://showcase.doyoubuzz.com/api/v1'
11
12
 
13
+ Hashie.logger = ::Logger.new(STDOUT)
14
+
12
15
  # Construction with mandatory api key and api secret
13
16
  def initialize(api_key, api_secret)
14
17
  @api_key = api_key
@@ -16,68 +19,58 @@ module Doyoubuzz
16
19
  end
17
20
 
18
21
  # HTTP calls => forwarded to #call_api with the verb as the first argument
19
- [:get, :post, :put, :delete].each do |verb|
20
- define_method(verb) do |method, params = {}|
22
+ %i(get post put delete).each do |verb|
23
+ define_method(verb) do |method, params={}|
21
24
  call_api(verb, method, params)
22
25
  end
23
26
  end
24
27
 
25
- # SSO redirection
26
- def sso_redirect_url(application_name, timestamp, sso_key, user_attributes)
27
- # Check mandatory attributes are given
28
- missing_attributes = [:email, :external_id, :firstname, :lastname].reject{|key| user_attributes[key]}
29
-
30
- if missing_attributes.length > 0
31
- raise ArgumentError, "Missing mandatory attributes for SSO : #{missing_attributes.join(', ')}"
32
- end
33
-
34
- params = sign_sso_params(user_attributes.merge(timestamp: timestamp), sso_key)
35
-
36
- "http://showcase.doyoubuzz.com/p/fr/#{application_name}/sso?#{URI.encode_www_form(params)}"
37
- end
38
-
39
-
40
28
  private
41
29
 
42
30
  # The actual api call
43
31
  def call_api(verb, method, params)
44
- res = self.class.send(verb, method, build_request_parameters(params, verb))
45
- return process_response(res)
32
+ res = self.class.send(
33
+ verb,
34
+ method,
35
+ build_request_parameters(params, verb)
36
+ )
37
+
38
+ process_response(res)
46
39
  end
47
40
 
48
41
  # Process the HTTParty response, checking for errors
49
42
  def process_response(res)
50
- if !res.success?
51
- raise Error.new(res.code, res.body)
52
- end
43
+ raise Error.new(res.code, res.body) unless res.success?
44
+
45
+ object = res.parsed_response
53
46
 
54
- if res.is_a? Hash
55
- return Hashie::Mash.new(res)
56
- elsif res.is_a? Array
57
- return res.map{|item| Hashie::Mash.new(item)}
58
- else
59
- return res
47
+ case object
48
+ when Hash then mash(object)
49
+ when Array then object.map(&method(:mash))
50
+ else object
60
51
  end
61
52
  end
62
53
 
54
+ def mash(object)
55
+ Hashie::Mash.new(object)
56
+ end
57
+
63
58
  # Build the request parameters
64
59
  def build_request_parameters(params, verb)
65
- additional_parameters = {:apikey => @api_key, :timestamp => Time.now.to_i}
60
+ additional_parameters = { apikey: @api_key, timestamp: Time.now.to_i }
66
61
 
67
62
  # GET, DELETE requests : the parameters are in the request query
68
- if [:get, :delete].include? verb
69
- return {:query => sign_api_params(params.merge additional_parameters)}
63
+ if %i(get delete).include?(verb)
64
+ return { query: sign_api_params(params.merge(additional_parameters)) }
65
+ end
70
66
 
71
67
  # Otherwise, they are in the body
72
- else
73
- return {:body => params, :query => sign_api_params(additional_parameters)}
74
- end
68
+ { body: params, query: sign_api_params(additional_parameters) }
75
69
  end
76
70
 
77
-
78
71
  # The arguments processing and signing
79
72
  def sign_api_params(params)
80
- ordered_params_values = params.sort.map{|k,v|v}
73
+ ordered_params_values = params.sort.map { |_, v| v }
81
74
  concatenated_params_string = ordered_params_values.join
82
75
  concatenated_params_string << @api_secret
83
76
 
@@ -85,17 +78,5 @@ module Doyoubuzz
85
78
  params.merge(hash: hash)
86
79
  end
87
80
 
88
- # Different ordering
89
- def sign_sso_params(params, sso_key)
90
- # Custom ordering
91
- tosign = params.values_at(:email, :firstname, :lastname, :external_id, :"group[]", :user_type, :timestamp).compact.join
92
- tosign += sso_key
93
-
94
- hash = Digest::MD5.hexdigest(tosign)
95
-
96
- params.merge(hash: hash)
97
- end
98
-
99
-
100
81
  end
101
82
  end
@@ -0,0 +1,52 @@
1
+ module Doyoubuzz
2
+ class Showcase
3
+ class SSO
4
+
5
+ BASE_URL = 'http://showcase.doyoubuzz.com'.freeze
6
+
7
+ def initialize(application, key)
8
+ @application = application
9
+ @key = key
10
+ end
11
+
12
+ def redirect_url(locale: 'fr', timestamp:, user_attributes:)
13
+ enforce_sso_attributes(user_attributes)
14
+
15
+ params = sign_params(user_attributes.merge(timestamp: timestamp))
16
+ encoded_params = URI.encode_www_form(params)
17
+
18
+ "#{BASE_URL}/p/#{locale}/#{application}/sso?#{encoded_params}"
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :application, :key
24
+
25
+ def enforce_sso_attributes(attributes)
26
+ required = %i(email external_id firstname lastname)
27
+ missing = required.reject { |key| attributes[key] }
28
+
29
+ raise(
30
+ ArgumentError,
31
+ "Missing mandatory attributes for SSO : #{missing.join(', ')}"
32
+ ) if missing.any?
33
+ end
34
+
35
+ def sign_params(params)
36
+ # Custom ordering
37
+ tosign = params.values_at(
38
+ :email,
39
+ :firstname,
40
+ :lastname,
41
+ :external_id,
42
+ :"group[]",
43
+ :user_type,
44
+ :timestamp
45
+ ).compact.join + key
46
+
47
+ params.merge(hash: Digest::MD5.hexdigest(tosign))
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -1,3 +1,3 @@
1
1
  module Doyoubuzz
2
- VERSION = "0.2.0"
2
+ VERSION = '0.3.0'
3
3
  end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ require 'doyoubuzz/showcase/sso'
4
+
5
+ RSpec.describe Doyoubuzz::Showcase::SSO, type: :type do
6
+ let(:application) { 'example_application' }
7
+ let(:key) { 'vpsdihgfdso' }
8
+
9
+ subject { described_class.new(application, key) }
10
+
11
+ describe '#new' do
12
+ it 'requires an application name and an sso key' do
13
+ expect { described_class.new }.to raise_error(ArgumentError)
14
+ expect { described_class.new(application, key) }.not_to raise_error
15
+ end
16
+ end
17
+
18
+ describe '#redirect_url' do
19
+ let(:timestamp) { 1370534334 }
20
+ let(:user_attributes) do
21
+ {
22
+ email: 'email@host.tld',
23
+ firstname: 'John',
24
+ lastname: 'Doe',
25
+ external_id: 12345
26
+ }
27
+ end
28
+
29
+ it 'verifies all the mandatory user attributes are given' do
30
+ user_attributes.keys.each do |mandatory_key|
31
+ incomplete_attributes = user_attributes.reject { |k, _| k == mandatory_key }
32
+
33
+ expect do
34
+ subject.redirect_url(
35
+ timestamp: timestamp,
36
+ user_attributes: incomplete_attributes
37
+ )
38
+ end.to raise_error(
39
+ ArgumentError,
40
+ "Missing mandatory attributes for SSO : #{mandatory_key}"
41
+ )
42
+ end
43
+ end
44
+
45
+ it 'computes the right url' do
46
+ expect(
47
+ subject.redirect_url(
48
+ timestamp: timestamp,
49
+ user_attributes: user_attributes
50
+ )
51
+ ).to eq('http://showcase.doyoubuzz.com/p/fr/example_application/sso?email=email%40host.tld&firstname=John&lastname=Doe&external_id=12345&timestamp=1370534334&hash=94a0adad0a9bafdf511326cae3bf7626')
52
+ end
53
+
54
+ it 'handles locales properly' do
55
+ expect(
56
+ subject.redirect_url(
57
+ locale: 'en',
58
+ timestamp: timestamp,
59
+ user_attributes: user_attributes
60
+ )
61
+ ).to eq('http://showcase.doyoubuzz.com/p/en/example_application/sso?email=email%40host.tld&firstname=John&lastname=Doe&external_id=12345&timestamp=1370534334&hash=94a0adad0a9bafdf511326cae3bf7626')
62
+ end
63
+ end
64
+ end
@@ -2,115 +2,99 @@ require 'spec_helper'
2
2
 
3
3
  require 'doyoubuzz/showcase'
4
4
 
5
- describe Doyoubuzz::Showcase do
6
-
7
- let(:api_key){ 'an_api_key' }
8
- let(:api_secret){ 'an_api_secret' }
9
- let(:showcase){ Doyoubuzz::Showcase.new(api_key, api_secret) }
5
+ RSpec.describe Doyoubuzz::Showcase do
6
+ let(:api_key) { 'an_api_key' }
7
+ let(:api_secret) { 'an_api_secret' }
8
+ let(:showcase) { Doyoubuzz::Showcase.new(api_key, api_secret) }
10
9
 
11
10
  describe '#new' do
12
- it 'should require an api key and secret key' do
13
- expect{ Doyoubuzz::Showcase.new }.to raise_error ArgumentError
11
+ it 'requires an api key and secret key' do
12
+ expect { Doyoubuzz::Showcase.new }.to raise_error ArgumentError
14
13
 
15
- expect{ Doyoubuzz::Showcase.new(api_key, api_secret) }.to_not raise_error
14
+ expect { Doyoubuzz::Showcase.new(api_key, api_secret) }.to_not raise_error
16
15
  end
17
16
  end
18
17
 
19
18
  describe '#call' do
20
- let(:arguments){ {:foo => 'bar', :zab => 'baz'} }
21
- let(:timestamp){ 1370534334 }
19
+ let(:arguments) { { foo: 'bar', zab: 'baz' } }
20
+ let(:timestamp) { 1370534334 }
22
21
 
23
- # The timestamp is important in the request generation and the VCR handling. Here it is set at a fixed date
24
- before(:each) do
22
+ # The timestamp is important in the request generation and the VCR
23
+ # handling. Here it is set at a fixed date
24
+ before do
25
25
  time = Time.at(timestamp)
26
26
  allow(Time).to receive(:now).and_return time
27
27
  end
28
28
 
29
- it "should generate a valid signed api call" do
30
- allow(showcase).to receive(:process_response) # We only want to check the sent parameters here
31
- showcase.class.should_receive(:get).with("/path", {:query => {:foo => "bar", :zab => "baz", :apikey => "an_api_key", :timestamp => timestamp, :hash => "757b04a866f1d02f077471589341ff7a"}})
29
+ it 'generates a valid signed api call' do
30
+ # We only want to check the sent parameters here
31
+ allow(showcase).to receive(:process_response)
32
+ expect(showcase.class).to receive(:get).with(
33
+ '/path',
34
+ query: {
35
+ foo: 'bar',
36
+ zab: 'baz',
37
+ apikey: 'an_api_key',
38
+ timestamp: timestamp,
39
+ hash: '757b04a866f1d02f077471589341ff7a'
40
+ }
41
+ )
32
42
 
33
43
  showcase.get('/path', arguments)
34
44
  end
35
45
 
36
- it "should put the parameters in the body for PUT requests" do
37
- allow(showcase).to receive(:process_response) # We only want to check the sent parameters here
38
- showcase.class.should_receive(:put).with("/path", {:query => {:apikey => "an_api_key", :timestamp => timestamp, :hash => "11a68a1bb9e23c681438efb714c9ad4d"}, :body => {:foo => "bar", :zab => "baz"}})
46
+ it 'puts the parameters in the body for PUT requests' do
47
+ # We only want to check the sent parameters here
48
+ allow(showcase).to receive(:process_response)
49
+ expect(showcase.class).to receive(:put).with(
50
+ '/path',
51
+ query: {
52
+ apikey: 'an_api_key',
53
+ timestamp: timestamp,
54
+ hash: '11a68a1bb9e23c681438efb714c9ad4d'
55
+ },
56
+ body: { foo: 'bar', zab: 'baz' }
57
+ )
39
58
 
40
59
  showcase.put('/path', arguments)
41
60
  end
42
61
 
43
- it "should handle HTTP verbs" do
44
- expect(showcase).to respond_to :get
45
- expect(showcase).to respond_to :post
46
- expect(showcase).to respond_to :put
47
- expect(showcase).to respond_to :delete
62
+ it 'handles HTTP verbs' do
63
+ expect(showcase).to respond_to(:get)
64
+ expect(showcase).to respond_to(:post)
65
+ expect(showcase).to respond_to(:put)
66
+ expect(showcase).to respond_to(:delete)
48
67
  end
49
68
 
50
- it "should return an explorable hash" do
51
- VCR.use_cassette("good_call") do
69
+ it 'returns an explorable hash' do
70
+ VCR.use_cassette('good_call') do
52
71
  res = showcase.get('/users')
53
72
 
54
- res.keys.should == ["users", "total", "next"]
55
- res["users"]["items"].first.keys.should == ["username", "email", "firstname", "lastname", "id"]
56
- res.users.items.first.username.should == "lvrmterjwea"
73
+ expect(res.keys).to eq(%w(users total next))
74
+ expect(res['users']['items'].first.keys).
75
+ to eq(%w(username email firstname lastname id))
76
+ expect(res.users.items.first.username).
77
+ to eq('lvrmterjwea')
57
78
  end
58
79
  end
59
80
 
60
-
61
- it "should handle array responses" do
62
- VCR.use_cassette("good_call") do
81
+ it 'handles array responses' do
82
+ VCR.use_cassette('good_call') do
63
83
  res = showcase.get('/tags')
64
84
 
65
- res.should be_a Array
66
- res.first.should be_a Hashie::Mash
85
+ expect(res).to be_an(Array)
86
+ expect(res.first).to be_a(Hashie::Mash)
67
87
  end
68
88
  end
69
89
 
70
-
71
- it "should raise an exception on a failed call" do
72
- VCR.use_cassette("failed_call") do
73
- expect{ res = showcase.get('/users') }.to raise_error do |error|
74
- error.should be_a(Doyoubuzz::Showcase::Error)
75
- error.status.should == 403
76
- error.message.should == "Forbidden"
77
- error.inspect.should == "#<Doyoubuzz::Showcase::Error 403: Forbidden>"
90
+ it 'raises an exception on a failed call' do
91
+ VCR.use_cassette('failed_call') do
92
+ expect { showcase.get('/users') }.to raise_error do |error|
93
+ expect(error).to be_a(Doyoubuzz::Showcase::Error)
94
+ expect(error.status).to eq(403)
95
+ expect(error.message).to eq('Forbidden')
78
96
  end
79
97
  end
80
98
  end
81
-
82
99
  end
83
-
84
-
85
- describe '#sso_redirect_url' do
86
-
87
- let(:company_name){ 'my_company' }
88
- let(:timestamp){ 1370534334 }
89
- let(:user_attributes){
90
- {
91
- email: 'email@host.tld',
92
- firstname: 'John',
93
- lastname: 'Doe',
94
- external_id: 12345
95
- }
96
- }
97
- let(:sso_key){ 'vpsdihgfdso' }
98
-
99
- it "should verify all the mandatory user attributes are given" do
100
-
101
- user_attributes.keys.each do |mandatory_key|
102
-
103
- incomplete_attributes = user_attributes.dup.tap{|attrs|attrs.delete mandatory_key}
104
- expect { showcase.sso_redirect_url(company_name, timestamp, sso_key, incomplete_attributes) }.to raise_error ArgumentError, "Missing mandatory attributes for SSO : #{mandatory_key}"
105
-
106
- end
107
-
108
- end
109
-
110
- it "should compute the right url" do
111
- showcase.sso_redirect_url(company_name, timestamp, sso_key, user_attributes).should == 'http://showcase.doyoubuzz.com/p/fr/my_company/sso?email=email%40host.tld&firstname=John&lastname=Doe&external_id=12345&timestamp=1370534334&hash=94a0adad0a9bafdf511326cae3bf7626'
112
- end
113
-
114
- end
115
-
116
- end
100
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doyoubuzz-showcase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David RUYER
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-09 00:00:00.000000000 Z
11
+ date: 2017-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 2.1.2
61
+ version: 3.5.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 2.1.2
68
+ version: 3.5.0
69
69
  description: Wrapper around the DoYouBuzz showcase API
70
70
  email:
71
71
  - david.ruyer@gmail.com
@@ -85,9 +85,11 @@ files:
85
85
  - doyoubuzz-showcase.gemspec
86
86
  - lib/doyoubuzz/showcase.rb
87
87
  - lib/doyoubuzz/showcase/error.rb
88
+ - lib/doyoubuzz/showcase/sso.rb
88
89
  - lib/doyoubuzz/showcase/version.rb
89
90
  - spec/fixtures/vcr_cassettes/failed_call.yml
90
91
  - spec/fixtures/vcr_cassettes/good_call.yml
92
+ - spec/showcase/sso_spec.rb
91
93
  - spec/showcase_spec.rb
92
94
  - spec/spec_helper.rb
93
95
  homepage: ''
@@ -110,13 +112,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
112
  version: '0'
111
113
  requirements: []
112
114
  rubyforge_project:
113
- rubygems_version: 2.2.2
115
+ rubygems_version: 2.4.5.1
114
116
  signing_key:
115
117
  specification_version: 4
116
118
  summary: Wrapper around the DoYouBuzz showcase API
117
119
  test_files:
118
120
  - spec/fixtures/vcr_cassettes/failed_call.yml
119
121
  - spec/fixtures/vcr_cassettes/good_call.yml
122
+ - spec/showcase/sso_spec.rb
120
123
  - spec/showcase_spec.rb
121
124
  - spec/spec_helper.rb
122
- has_rdoc: