socialcast 1.3.9 → 1.3.10

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: 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