doyoubuzz-showcase 0.2.0 → 0.3.0

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