socialcast 1.3.9 → 1.3.10

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: e51c9793ebf4ee2583d3ed81fa89daff0b434030
4
- data.tar.gz: e2e52ed618072b8aba3d3b8d66f530220b2bbc27
3
+ metadata.gz: 666669e1a4a45b54b0831459e0e2611f4aff0689
4
+ data.tar.gz: 2de4ab5a30c01bdbc982b42f00a0df9aa2fb3de7
5
5
  SHA512:
6
- metadata.gz: 91ed1ae61a7c01ce7e3d62758873e65588d2a65dced1b6c5745e55fb155d5aa00ca6be823cefd925417351a4b4f4535bc5863f141866d92e695ae285f8fd5243
7
- data.tar.gz: bafba8c661f3f7ff5e5878b15167b6362ac3d558614b7d4fdea7de044847864da7086e76785b1f36f5204a96d587a88eeaeb7ec36a7d16d16dcbc7e40322a549
6
+ metadata.gz: a536bbd57dfe1c7baa506c5be8a2ffed642532fe55576bedcd0854c37ea3895998d82e23abfa172045774c8097e138f80dd326c60ca55ae6fcd04e9cb67b5650
7
+ data.tar.gz: af16fbf3fd088e9a021615703f47ee726544a295aeec3a5f046c7d10b775445e037cadd1e680154c0b05360f8cfd4a3a3b47bc65f5179525757238851a3b4e4e
data/README.md CHANGED
@@ -1,9 +1,50 @@
1
1
  [![Build Status](https://secure.travis-ci.org/socialcast/socialcast-command-line.png?branch=master)](http://travis-ci.org/socialcast/socialcast-command-line)
2
2
  # socialcast-command-line
3
3
 
4
- command line interface to the Socialcast API
4
+ ## Purpose
5
+ Used as a command line interface to interact with the Socialcast API
5
6
  http://www.socialcast.com/resources/api.html
6
7
 
8
+ ## Installing
9
+
10
+ 1. Run: `gem install socialcast`
11
+ 2. Authenticate: `socialcast authenticate`
12
+ * If your account is private cloud or On-Premise you will need to use `socialcast authenticate --domain YOUR_DOMAIN_NAME`
13
+
14
+ ## Available Commands
15
+ ### socialcast info
16
+ Used to tell you information about the currently installed gem.
17
+
18
+ > Example `$ socialcast -v`
19
+
20
+ ### socialcast authenticate
21
+ Used to authenticate your local system to the Socialcast servers. This will create a credentials file stored locally that will be later used to send secure, authenticated requests to Socialcast.
22
+ > Example `$ socialcast authenticate --domain demo.socialcast.com`
23
+
24
+ ### socialcast authenticate_external_system
25
+ Similar to the `socialcast authenticate` command listed above but will allow you to use a provisioning system to authenticate against Socialcast.
26
+
27
+ > Example `$ socialcast authenticate_external_system --domain demo.socialcast.com`
28
+
29
+ *Note: Using an external system is currently limited to the provisioning endpoint*
30
+
31
+ ### socialcast share
32
+ Used to post a message to the stream as the currently authenticated person.
33
+ > Example `$ socialcast share 'Hi Team!'`
34
+
35
+ ### socialcast provision
36
+ Used to sync an LDAP server with your Socialcast community.
37
+
38
+ [For more detailed information](http://developers.socialcast.com/admin/directory-integration-overview/)
39
+
40
+ > Example `$ socialcast provision --config /path/to/ldap.yml`
41
+
42
+ ### socialcast sync_photos
43
+ Used to sync an employees photos stored in LDAP with their Socialcast
44
+ profile photo.
45
+
46
+ > Example `$ socialcast sync_photos --config /path/to/ldap.yml`
47
+
7
48
  ## Contributing
8
49
 
9
50
  * Fork the project.
@@ -11,9 +52,9 @@ http://www.socialcast.com/resources/api.html
11
52
  * Add tests
12
53
  * Send me a pull request. Bonus points for topic branches.
13
54
 
14
- see CONTRIBUTORS.txt for list of contributors
55
+ See [CONTRIBUTORS.txt](https://github.com/socialcast/socialcast-command-line/blob/master/CONTRIBUTORS.txt) for list of contributors
15
56
 
16
57
  ## Copyright
17
58
 
18
- Copyright (c) 2011 Socialcast Inc.
19
- See LICENSE.txt for details.
59
+ Copyright (c) 2011 - 2014 Socialcast Inc.
60
+ See [LICENSE.txt](https://github.com/socialcast/socialcast-command-line/blob/master/LICENSE.txt) for details.
@@ -10,6 +10,20 @@ module Socialcast
10
10
  self.headers = headers
11
11
  end
12
12
 
13
+ def self.current_user
14
+ @current_user ||= find_current_user
15
+ end
16
+
17
+ def self.find_current_user
18
+ response = Socialcast::CommandLine.resource_for_path('/api/userinfo.json').get
19
+ json_body = JSON.parse(response.body)
20
+ if json_body['user']
21
+ json_body['user']
22
+ else
23
+ raise "Unable to find the current user: #{response.body}"
24
+ end
25
+ end
26
+
13
27
  def request
14
28
  @request ||= send_request
15
29
  end
@@ -1,67 +1,95 @@
1
- require 'digest/md5'
2
-
3
1
  module Socialcast
4
2
  module CommandLine
5
3
  class ProvisionPhoto
6
4
  include Socialcast::CommandLine::Provisioner
5
+ attr_accessor :users
6
+ MAX_BATCH_SIZE = 50
7
+
7
8
  def sync
8
9
  @ldap_config['connections'].keys.each do |connection_name|
9
10
  LDAPConnector.attribute_mappings_for(connection_name, @ldap_config).fetch(LDAPConnector::PROFILE_PHOTO_ATTRIBUTE)
10
11
  end
11
12
 
13
+ init_users
14
+
12
15
  each_ldap_connector do |connector|
13
16
  connector.each_photo_hash do |photo_hash|
14
17
  email = photo_hash[LDAPConnector::EMAIL_ATTRIBUTE]
18
+ users[email] = photo_hash[LDAPConnector::PROFILE_PHOTO_ATTRIBUTE]
19
+ handle_batch if users.size >= MAX_BATCH_SIZE
20
+ end
21
+ end
22
+
23
+ handle_batch if users.any?
24
+ end
25
+
26
+ private
27
+
28
+ def init_users
29
+ @users = {}
30
+ end
31
+
32
+ def handle_batch
33
+ users.each_slice(MAX_BATCH_SIZE) do |user_batch|
34
+ search_users_resource = Socialcast::CommandLine.resource_for_path '/api/users/search', http_config
35
+ user_emails_query = user_batch.map { |u| "\"#{u[0]}\"" }.join(" OR ")
36
+ user_search_response = search_users_resource.get(:params => { :q => user_emails_query, :per_page => MAX_BATCH_SIZE }, :accept => :json)
37
+ JSON.parse(user_search_response)['users'].each do |user_hash|
38
+ sync_photo_for(user_hash)
39
+ end
40
+ end
15
41
 
16
- ## GET USER INFO
17
- search_users_resource = Socialcast::CommandLine.resource_for_path '/api/users/search', http_config
18
- user_search_response = search_users_resource.get(:params => { :q => email, :per_page => 1 }, :accept => :json)
19
- user_info = JSON.parse(user_search_response)['users'].first
20
-
21
- is_community_default = user_info && user_info['avatars'] && user_info['avatars']['is_community_default']
22
- next unless is_community_default || @options[:force_sync]
23
-
24
- ## PHOTO URL TO BINARY
25
- if profile_photo_data = photo_hash[LDAPConnector::PROFILE_PHOTO_ATTRIBUTE]
26
- if profile_photo_data.start_with?('http')
27
- begin
28
- profile_photo_data = RestClient.get(profile_photo_data)
29
- rescue => e
30
- puts "Unable to download photo #{profile_photo_data} for #{email}"
31
- puts e.response
32
- next
33
- end
34
- end
35
-
36
- ## FORCE ENCODING
37
- profile_photo_data = profile_photo_data.force_encoding('binary')
38
-
39
- ## CONTENT TYPE
40
- unless content_type = binary_to_content_type(profile_photo_data)
41
- puts "Skipping photo for #{email}: unknown image format (supports .gif, .png, .jpg)"
42
- next
43
- end
44
-
45
- ## WRITE TEMP FILE
46
- tempfile = Tempfile.new(["photo_upload", ".#{content_type}"])
47
- tempfile.write(profile_photo_data)
48
- tempfile.rewind
49
-
50
- puts "Uploading photo for #{email}"
51
-
52
- ## SUBMIT PHOTO
53
- begin
54
- user_resource = Socialcast::CommandLine.resource_for_path "/api/users/#{user_info['id']}", http_config
55
- user_resource.put({ :user => { :profile_photo => { :data => tempfile } } })
56
- ensure
57
- tempfile.unlink
58
- end
42
+ init_users
43
+ end
44
+
45
+ def sync_photo_for(user_hash)
46
+ is_system_default = user_hash && user_hash['avatars'] && user_hash['avatars']['is_system_default']
47
+ is_community_default = user_hash && user_hash['avatars'] && (user_hash['avatars']['id'] == default_profile_photo_id)
48
+ user_email = user_hash && user_hash['contact_info'] && user_hash['contact_info']['email']
49
+ return unless is_system_default || is_community_default || @options[:force_sync]
50
+
51
+ ## PHOTO URL TO BINARY
52
+ if profile_photo_data = users[user_email]
53
+ if profile_photo_data.start_with?('http')
54
+ begin
55
+ profile_photo_data = RestClient.get(profile_photo_data)
56
+ rescue => e
57
+ puts "Unable to download photo #{profile_photo_data} for #{user_email}"
58
+ puts e.response
59
+ return
59
60
  end
60
61
  end
62
+
63
+ ## FORCE ENCODING
64
+ profile_photo_data = profile_photo_data.force_encoding('binary')
65
+
66
+ ## CONTENT TYPE
67
+ unless content_type = binary_to_content_type(profile_photo_data)
68
+ puts "Skipping photo for #{user_email}: unknown image format (supports .gif, .png, .jpg)"
69
+ return
70
+ end
71
+
72
+ ## WRITE TEMP FILE
73
+ tempfile = Tempfile.new(["photo_upload", ".#{content_type}"])
74
+ tempfile.binmode
75
+ tempfile.write(profile_photo_data)
76
+ tempfile.rewind
77
+
78
+ puts "Uploading photo for #{user_email}"
79
+
80
+ ## SUBMIT PHOTO
81
+ begin
82
+ user_resource = Socialcast::CommandLine.resource_for_path "/api/users/#{user_hash['id']}", http_config
83
+ user_resource.put({ :user => { :profile_photo => { :data => tempfile } } })
84
+ ensure
85
+ tempfile.unlink
86
+ end
61
87
  end
62
88
  end
63
89
 
64
- private
90
+ def default_profile_photo_id
91
+ @default_profile_photo_id ||= Socialcast::CommandLine::Authenticate.current_user['community']['default_profile_photo_id']
92
+ end
65
93
 
66
94
  def binary_to_content_type(binary_photo_data)
67
95
  case binary_photo_data
@@ -73,7 +101,6 @@ module Socialcast
73
101
  'jpg'
74
102
  end
75
103
  end
76
-
77
104
  end
78
105
  end
79
106
  end
@@ -1,5 +1,5 @@
1
1
  module Socialcast
2
2
  module CommandLine
3
- VERSION = "1.3.9"
3
+ VERSION = "1.3.10"
4
4
  end
5
5
  end
@@ -27,4 +27,33 @@ describe Socialcast::CommandLine::Authenticate do
27
27
  end
28
28
  end
29
29
 
30
+ describe '.current_user' do
31
+ subject(:current_user) { Socialcast::CommandLine::Authenticate.current_user }
32
+ after do
33
+ Socialcast::CommandLine::Authenticate.instance_variable_set(:@current_user, nil)
34
+ end
35
+ context 'as an unauthenticated user' do
36
+ it { expect { current_user }.to raise_error(RuntimeError, 'Unknown Socialcast credentials. Run `socialcast authenticate` to initialize') }
37
+ end
38
+ context 'with credentials specified out' do
39
+ let(:stubbed_config_dir) { File.join(File.dirname(__FILE__), '..', '..', 'fixtures') }
40
+ let(:current_user_stub) { { :user => { :id => 123 } } }
41
+ let(:current_user_error) { { :error => "Failed to authenticate due to password" } }
42
+ before { Socialcast::CommandLine.stub(:config_dir).and_return(stubbed_config_dir) }
43
+ context 'as a successfull authenticated user' do
44
+ before do
45
+ stub_request(:get, "https://ryan%40socialcast.com:foo@test.staging.socialcast.com/api/userinfo.json").
46
+ to_return(:status => 200, :body => current_user_stub.to_json)
47
+ end
48
+ it { current_user['id'].should == 123 }
49
+ end
50
+ context 'when you not authenticated properly' do
51
+ before do
52
+ stub_request(:get, "https://ryan%40socialcast.com:foo@test.staging.socialcast.com/api/userinfo.json").
53
+ to_return(:status => 200, :body => current_user_error.to_json)
54
+ end
55
+ it { expect { current_user }.to raise_error(RuntimeError) }
56
+ end
57
+ end
58
+ end
30
59
  end
@@ -11,9 +11,12 @@ describe Socialcast::CommandLine::CLI do
11
11
  let(:ldap_with_plugin_mapping_config) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap_with_plugin_mapping.yml')) }
12
12
  let(:ldap_with_profile_photo_config) { YAML.load_file(ldap_with_profile_photo_config_file) }
13
13
  let(:ldap_without_permission_mappings_config) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap_without_permission_mappings.yml')) }
14
+ let(:default_profile_photo_id) { 3 }
15
+ let(:another_profile_photo_id) { 4 }
14
16
 
15
17
  before do
16
18
  Socialcast::CommandLine.stub(:credentials).and_return(credentials)
19
+ Socialcast::CommandLine::ProvisionPhoto.any_instance.stub(:default_profile_photo_id).and_return(default_profile_photo_id)
17
20
  end
18
21
 
19
22
  let(:ldap) do
@@ -155,7 +158,6 @@ describe Socialcast::CommandLine::CLI do
155
158
 
156
159
  context "user does not have a profile photo" do
157
160
  let(:config_file) { ldap_with_profile_photo_config_file }
158
- let(:system_default_photo) { true }
159
161
  let(:photo_data) { "\x89PNGabc".force_encoding('binary') }
160
162
  before do
161
163
  @entry = Net::LDAP::Entry.new("dc=example,dc=com")
@@ -169,7 +171,10 @@ describe Socialcast::CommandLine::CLI do
169
171
  {
170
172
  'id' => 7,
171
173
  'avatars' => {
172
- 'is_community_default' => system_default_photo
174
+ 'id' => default_profile_photo_id
175
+ },
176
+ 'contact_info' => {
177
+ 'email' => 'ryan@example.com'
173
178
  }
174
179
  }
175
180
  ]
@@ -192,7 +197,6 @@ describe Socialcast::CommandLine::CLI do
192
197
 
193
198
  context "unknown image format" do
194
199
  let(:config_file) { ldap_with_profile_photo_config_file }
195
- let(:system_default_photo) { true }
196
200
  let(:photo_data) { "abc" }
197
201
  before do
198
202
  @entry = Net::LDAP::Entry.new("dc=example,dc=com")
@@ -206,7 +210,7 @@ describe Socialcast::CommandLine::CLI do
206
210
  {
207
211
  'id' => 7,
208
212
  'avatars' => {
209
- 'is_community_default' => system_default_photo
213
+ 'id' => default_profile_photo_id
210
214
  }
211
215
  }
212
216
  ]
@@ -225,7 +229,6 @@ describe Socialcast::CommandLine::CLI do
225
229
 
226
230
  context "user already has a profile photo" do
227
231
  let(:config_file) { ldap_with_profile_photo_config_file }
228
- let(:system_default_photo) { false }
229
232
  let(:photo_data) { "\x89PNGabc".force_encoding('binary') }
230
233
  before do
231
234
  @entry = Net::LDAP::Entry.new("dc=example,dc=com")
@@ -239,7 +242,7 @@ describe Socialcast::CommandLine::CLI do
239
242
  {
240
243
  'id' => 7,
241
244
  'avatars' => {
242
- 'is_community_default' => system_default_photo
245
+ 'id' => another_profile_photo_id
243
246
  }
244
247
  }
245
248
  ]
@@ -3,6 +3,12 @@ require 'spec_helper'
3
3
  describe Socialcast::CommandLine::ProvisionPhoto do
4
4
  let!(:ldap_with_profile_photo_config) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap_with_profile_photo.yml')) }
5
5
  let!(:ldap_multiple_connection_mapping_config) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap_with_multiple_connection_mappings.yml')) }
6
+ let(:default_profile_photo_id) { 3 }
7
+ let(:another_profile_photo_id) { 4 }
8
+
9
+ before do
10
+ Socialcast::CommandLine::ProvisionPhoto.any_instance.stub(:default_profile_photo_id).and_return(default_profile_photo_id)
11
+ end
6
12
 
7
13
  let(:ldap) do
8
14
  ldap_instance = double(Net::LDAP, :auth => nil, :encryption => nil)
@@ -11,13 +17,12 @@ describe Socialcast::CommandLine::ProvisionPhoto do
11
17
  ldap_instance
12
18
  end
13
19
 
14
- context '#sync' do
20
+ describe '#sync' do
15
21
  context "with a single ldap connection" do
16
22
  let(:options) { {} }
17
23
  subject(:sync_photos) { Socialcast::CommandLine::ProvisionPhoto.new(ldap_with_profile_photo_config, options).sync }
18
24
  let(:user_search_resource) { double(:user_search_resource) }
19
25
  let(:user_submit_resource) { double(:user_submit_resource) }
20
- let(:is_community_default) { true }
21
26
  let(:data_fingerprint) { '5d41402abc4b2a76b9719d911017c592' }
22
27
  let(:search_api_response) do
23
28
  {
@@ -25,8 +30,10 @@ describe Socialcast::CommandLine::ProvisionPhoto do
25
30
  {
26
31
  'id' => 7,
27
32
  'avatars' => {
28
- 'is_community_default' => is_community_default,
29
- 'data_fingerprint' => data_fingerprint
33
+ 'id' => default_profile_photo_id
34
+ },
35
+ 'contact_info' => {
36
+ 'email' => 'user@example.com'
30
37
  }
31
38
  }
32
39
  ]
@@ -79,7 +86,9 @@ describe Socialcast::CommandLine::ProvisionPhoto do
79
86
  end
80
87
 
81
88
  context 'when there is already a photo set' do
82
- let(:is_community_default) { false }
89
+ before do
90
+ Socialcast::CommandLine::ProvisionPhoto.any_instance.stub(:default_profile_photo_id).and_return(another_profile_photo_id)
91
+ end
83
92
  let(:photo_data) { "\x89PNGabc" }
84
93
  before { user_search_resource.should_receive(:get).and_return(search_api_response.to_json) }
85
94
  context 'for a regular sync' do
@@ -103,25 +112,25 @@ describe Socialcast::CommandLine::ProvisionPhoto do
103
112
 
104
113
  context "with multiple ldap connections" do
105
114
  let(:user_search_resource) { double(:user_search_resource) }
106
- let(:search_api_response1) do
115
+ let(:search_api_response) do
107
116
  {
108
117
  'users' => [
109
118
  {
110
119
  'id' => 7,
111
120
  'avatars' => {
112
- 'is_community_default' => true
121
+ 'id' => default_profile_photo_id
122
+ },
123
+ 'contact_info' => {
124
+ 'email' => 'user@example.com'
113
125
  }
114
- }
115
- ]
116
- }
117
- end
118
- let(:search_api_response2) do
119
- {
120
- 'users' => [
126
+ },
121
127
  {
122
128
  'id' => 8,
123
129
  'avatars' => {
124
- 'is_community_default' => true
130
+ 'id' => default_profile_photo_id
131
+ },
132
+ 'contact_info' => {
133
+ 'email' => 'user2@example.com'
125
134
  }
126
135
  }
127
136
  ]
@@ -131,6 +140,8 @@ describe Socialcast::CommandLine::ProvisionPhoto do
131
140
  let(:sync_photos) { Socialcast::CommandLine::ProvisionPhoto.new(ldap_multiple_connection_mapping_config, {}).sync }
132
141
  let(:binary_photo_data) { "\x89PNGabc".force_encoding('binary') }
133
142
  before do
143
+ stub_const("Socialcast::CommandLine::ProvisionPhoto::MAX_BATCH_SIZE", 2)
144
+
134
145
  ldap_instance1 = double(Net::LDAP, :encryption => nil, :auth => nil)
135
146
  ldap_instance1.should_receive(:open).and_yield(ldap_instance1)
136
147
  Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance1)
@@ -145,8 +156,7 @@ describe Socialcast::CommandLine::ProvisionPhoto do
145
156
 
146
157
  Socialcast::CommandLine.stub(:resource_for_path).with('/api/users/search', anything).and_return(user_search_resource)
147
158
 
148
- user_search_resource.should_receive(:get).once.and_return(search_api_response1.to_json)
149
- user_search_resource.should_receive(:get).once.and_return(search_api_response2.to_json)
159
+ user_search_resource.should_receive(:get).once.with({:params=>{:q=>"\"user@example.com\" OR \"user2@example.com\"", :per_page=>Socialcast::CommandLine::ProvisionPhoto::MAX_BATCH_SIZE}, :accept=>:json}).and_return(search_api_response.to_json)
150
160
 
151
161
  user_resource1 = double(:user_resource)
152
162
  user_resource1.should_receive(:put) do |data|
@@ -168,7 +178,7 @@ describe Socialcast::CommandLine::ProvisionPhoto do
168
178
  end
169
179
  end
170
180
 
171
- context '.binary_to_content_type' do
181
+ describe '.binary_to_content_type' do
172
182
  subject { Socialcast::CommandLine::ProvisionPhoto.new(ldap_with_profile_photo_config, {}).send(:binary_to_content_type, binary_photo_data) }
173
183
  let(:file_dir) { File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'test_images') }
174
184
  let(:binary_photo_data) { File.open(File.join(file_dir, image_name), 'rb') { |file| file.read } }
data/spec/spec_helper.rb CHANGED
@@ -15,23 +15,6 @@ RSpec.configure do |config|
15
15
  Socialcast::CommandLine.stub(:config_dir).and_return(stubbed_credentials)
16
16
  end
17
17
 
18
- def capture_with_status(stream)
19
- exit_status = 0
20
- begin
21
- stream = stream.to_s
22
- eval "$#{stream} = StringIO.new"
23
- begin
24
- yield
25
- rescue SystemExit => system_exit # catch any exit calls
26
- exit_status = system_exit.status
27
- end
28
- result = eval("$#{stream}").string
29
- ensure
30
- eval("$#{stream} = #{stream.upcase}")
31
- end
32
- return result, exit_status
33
- end
34
-
35
18
  def create_entry(cn, entry_attributes)
36
19
  Net::LDAP::Entry.new("cn=#{cn},dc=example,dc=com").tap do |e|
37
20
  entry_attributes.each_pair do |attr, value|
@@ -39,11 +22,4 @@ RSpec.configure do |config|
39
22
  end
40
23
  end
41
24
  end
42
-
43
- def remove_directories(*names)
44
- project_dir = Pathname.new(Dir.pwd)
45
- names.each do |name|
46
- FileUtils.rm_rf(project_dir.join(name)) if FileTest.exists?(project_dir.join(name))
47
- end
48
- end
49
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: socialcast
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.9
4
+ version: 1.3.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Sonnek
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-06-03 00:00:00.000000000 Z
13
+ date: 2014-06-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rest-client