socialcast 1.3.6 → 1.3.7

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: 059c8d71c405b6bd225ddf6bcadd22c55448c244
4
- data.tar.gz: 73dc16b3f63221865f07dd46c74f992d0f8ae96a
3
+ metadata.gz: 788cbe26a9ad449b6b0a366c6d264069586e4653
4
+ data.tar.gz: 1f21d4c2e36ed4ab2e8809ae8d0aea2d7e38b943
5
5
  SHA512:
6
- metadata.gz: 49c4a5675ab1f9832d56aa7ee23678977424020cd002573c72183f1842f6a72adb23ffb1a18464720abcdaf42da17ea5594545866f59174cf86c4746332c1cff
7
- data.tar.gz: 9ca90bb330803ed0dae3fe8ae78b86fccdb1c86c934ed43bf3497c41e455ba494f740abecba293132496149ad6d4eaf292b9d90586239cb7909d90769919b635
6
+ metadata.gz: 90c71da04a539297455463f1b7f81f9b3737c957dd5882acc9539ed52a19f2f43315fcede8e96e38a6b8ce818c91d655d26134e87995715b1444b647e326c777
7
+ data.tar.gz: 7a254b2b4132c6144a58a2d026e8aede0cae18c7a39c4f63c1f680e324578ddd2789c7f099f5cd5308297a56efa60ddfbe50e526d5189449b71afcc8b25a3f98
data/lib/socialcast.rb CHANGED
@@ -3,6 +3,7 @@ require 'fileutils'
3
3
 
4
4
  require_relative 'socialcast/command_line/ldap_connector'
5
5
  require_relative 'socialcast/command_line/provision'
6
+ require_relative 'socialcast/command_line/authenticate'
6
7
  require_relative 'socialcast/command_line/message'
7
8
  require_relative 'socialcast/command_line/cli'
8
9
  require_relative 'socialcast/command_line/version'
@@ -25,8 +26,10 @@ module Socialcast
25
26
  end
26
27
 
27
28
  def self.credentials=(options)
28
- File.open(credentials_file, "w") do |f|
29
- f.write(options.to_yaml)
29
+ File.open(credentials_file, "a+") do |f|
30
+ existing_content = YAML.load(f.read) || {}
31
+ f.truncate(0)
32
+ f.write(existing_content.merge(options).to_yaml)
30
33
  end
31
34
  File.chmod 0600, credentials_file
32
35
  end
@@ -36,7 +39,15 @@ module Socialcast
36
39
  RestClient.log = Logger.new(STDOUT) if debug
37
40
  RestClient.proxy = credentials[:proxy] if credentials[:proxy]
38
41
  url = ['https://', credentials[:domain], path].join
39
- RestClient::Resource.new url, options.merge({ :user => credentials[:user], :password => credentials[:password] })
42
+ RestClient::Resource.new url, options.merge(authentication(options))
43
+ end
44
+
45
+ def self.authentication(options)
46
+ if options[:external_system]
47
+ { :headers => { :Authorization => "SocialcastApiClient #{credentials[:api_client_identifier]}:#{credentials[:api_client_secret]}" } }
48
+ else
49
+ { :user => credentials[:user], :password => credentials[:password] }
50
+ end
40
51
  end
41
52
 
42
53
  end
@@ -0,0 +1,46 @@
1
+ module Socialcast
2
+ module CommandLine
3
+ class Authenticate
4
+ attr_accessor :authenticate_type, :options, :params, :headers
5
+
6
+ def initialize(authenticate_type, options, params, headers = {})
7
+ self.authenticate_type = authenticate_type
8
+ self.options = options
9
+ self.params = params
10
+ self.headers = headers
11
+ end
12
+
13
+ def request
14
+ @request ||= send_request
15
+ end
16
+
17
+ private
18
+
19
+ def send_request
20
+ puts "Authenticating to #{url}"
21
+ RestClient.log = Logger.new($stdout) if options[:trace]
22
+ RestClient.proxy = options[:proxy] if options[:proxy]
23
+ resource = RestClient::Resource.new url, headers
24
+ response = resource.post params, :accept => :json
25
+ puts "API response: #{response.body.to_s}" if options[:trace]
26
+ set_default_credentials
27
+ response
28
+ end
29
+
30
+ def set_default_credentials
31
+ Socialcast::CommandLine.credentials = {
32
+ :domain => domain,
33
+ :proxy => options[:proxy]
34
+ }
35
+ end
36
+
37
+ def url
38
+ @url ||= File.join("https://", domain, 'api', (authenticate_type == :external_system ? 'external_systems/' : ''), 'authentication')
39
+ end
40
+
41
+ def domain
42
+ options[:domain]
43
+ end
44
+ end
45
+ end
46
+ end
@@ -49,23 +49,43 @@ module Socialcast
49
49
  def authenticate
50
50
  user = options[:user] || ask('Socialcast username: ')
51
51
  password = options[:password] || HighLine.new.ask("Socialcast password: ") { |q| q.echo = false }.to_s
52
- domain = options[:domain]
53
52
 
54
- url = ['https://', domain, '/api/authentication'].join
55
- say "Authenticating #{user} to #{url}"
56
53
  params = { :email => user, :password => password }
57
- RestClient.log = Logger.new(STDOUT) if options[:trace]
58
- RestClient.proxy = options[:proxy] if options[:proxy]
59
- resource = RestClient::Resource.new url
60
- response = resource.post params, :accept => :json
61
- say "API response: #{response.body.to_s}" if options[:trace]
54
+ response = Socialcast::CommandLine::Authenticate.new(:user, options, params).request
62
55
  communities = JSON.parse(response.body.to_s)['communities']
63
56
  domain = communities.detect {|c| c['domain'] == domain} ? domain : communities.first['domain']
64
57
 
65
- Socialcast::CommandLine.credentials = {:user => user, :password => password, :domain => domain, :proxy => options[:proxy]}
58
+ Socialcast::CommandLine.credentials = {
59
+ :user => user,
60
+ :password => password,
61
+ :domain => domain
62
+ }
66
63
  say "Authentication successful for #{domain}"
67
64
  end
68
65
 
66
+ desc "authenticate_external_system", "Authenticate using an external system"
67
+ method_option :api_client_identifier, :type => :string, :aliases => '-i', :desc => 'the identifier of the external system'
68
+ method_option :api_client_secret, :type => :string, :aliases => '-s', :desc => 'the secret key of the external system'
69
+ method_option :proxy, :type => :string, :desc => 'HTTP proxy options for connecting to Socialcast server'
70
+ method_option :domain, :type => :string, :default => 'api.socialcast.com', :desc => 'Socialcast community domain'
71
+ def authenticate_external_system
72
+ api_client_identifier = options[:api_client_identifier] || ask("Socialcast external system identifier: ")
73
+ api_client_secret = options[:api_client_secret] || ask("Socialcast external system API secret: ")
74
+
75
+ headers = {
76
+ :headers => {
77
+ :Authorization => "SocialcastApiClient #{api_client_identifier}:#{api_client_secret}"
78
+ }
79
+ }
80
+
81
+ Socialcast::CommandLine::Authenticate.new(:external_system, options, {}, headers).request
82
+
83
+ Socialcast::CommandLine.credentials = {
84
+ :api_client_identifier => api_client_identifier,
85
+ :api_client_secret => api_client_secret,
86
+ }
87
+ end
88
+
69
89
  desc "share MESSAGE", "Posts a new message into socialcast"
70
90
  method_option :url, :type => :string, :desc => '(optional) url to associate to the message'
71
91
  method_option :message_type, :type => :string, :desc => '(optional) force an alternate message_type'
@@ -105,6 +125,7 @@ module Socialcast
105
125
  method_option :skip_emails, :type => :boolean, :desc => 'Do not send signup emails to users'
106
126
  method_option :force, :type => :boolean, :aliases => '-f', :default => false, :desc => 'Proceed with provisioning even if no users are found, which would deactivate all users in the community'
107
127
  method_option :plugins, :type => :array, :desc => "Pass in an array of plugins. Can be either the gem require or the absolute path to a ruby file"
128
+ method_option :external_system, :type => :boolean, :desc => "Use an external system for authentication purposes"
108
129
  def provision
109
130
  config = ldap_config options
110
131
  load_plugins options
@@ -34,7 +34,7 @@ module Socialcast
34
34
  end
35
35
 
36
36
  def provision
37
- http_config = @ldap_config.fetch 'http', {}
37
+ params = @ldap_config.fetch('http', {}).merge(:external_system => !!@options[:external_system])
38
38
 
39
39
  user_whitelist = Set.new
40
40
  output_file = File.join Dir.pwd, @options[:output]
@@ -56,7 +56,7 @@ module Socialcast
56
56
  raise ProvisionError.new "Skipping upload to Socialcast since no users were found"
57
57
  else
58
58
  puts "Uploading dataset to Socialcast..."
59
- resource = Socialcast::CommandLine.resource_for_path '/api/users/provision', http_config
59
+ resource = Socialcast::CommandLine.resource_for_path '/api/users/provision', params
60
60
  begin
61
61
  File.open(output_file, 'r') do |file|
62
62
  request_params = {:file => file}
@@ -65,7 +65,9 @@ module Socialcast
65
65
  resource.post request_params, :accept => :json
66
66
  end
67
67
  rescue RestClient::Unauthorized => e
68
- raise ProvisionError.new "Authenticated user either does not have administration privileges or the community is not configured to allow provisioning. Please contact Socialcast support to if you need help." if e.http_code == 401
68
+ error_message = @options[:external_system] ? "External Provisioning System was not found." : "Authenticated user either does not have administration privileges or the community is not configured to allow provisioning."
69
+ contact_message = "Please contact Socialcast support to if you need help."
70
+ raise ProvisionError.new "#{error_message} #{contact_message}\nResponse from server: #{e.response.body}" if e.http_code == 401
69
71
  end
70
72
  puts "Finished"
71
73
  end
@@ -1,5 +1,5 @@
1
1
  module Socialcast
2
2
  module CommandLine
3
- VERSION = "1.3.6"
3
+ VERSION = "1.3.7"
4
4
  end
5
5
  end
@@ -1,4 +1,6 @@
1
1
  ---
2
2
  :user: ryan@socialcast.com
3
3
  :password: foo
4
+ :api_client_identifier: my_id
5
+ :api_client_secret: mysecret
4
6
  :domain: test.staging.socialcast.com
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Socialcast::CommandLine::Authenticate do
4
+ let(:options) { { :domain => "test.socialcast.local" } }
5
+ let(:params) { { } }
6
+ subject { Socialcast::CommandLine::Authenticate.new(authenticate_type, options, params) }
7
+
8
+ describe '#request' do
9
+ before do
10
+ RestClient::Resource.should_receive(:new).with(url, {}).and_call_original
11
+ RestClient::Resource.any_instance.should_receive(:post).with(subject.params, :accept => :json)
12
+ subject.request
13
+ end
14
+ context 'for a regular user' do
15
+ let(:authenticate_type) { :user }
16
+ let(:url) { "https://test.socialcast.local/api/authentication" }
17
+ # See expectations
18
+ it 'hits the API to try authentication for a regular user' do end
19
+ end
20
+
21
+ context 'for an external system' do
22
+ let(:url) { "https://test.socialcast.local/api/external_systems/authentication" }
23
+ let(:authenticate_type) { :external_system }
24
+ # See expectations
25
+ it 'hits the API to try authentication for an external system' do end
26
+ end
27
+ end
28
+
29
+ end
@@ -34,6 +34,51 @@ describe Socialcast::CommandLine::CLI do
34
34
  end
35
35
  end
36
36
 
37
+ describe '#authenticate' do
38
+ let(:user) { 'mike@socialcast.com' }
39
+ let(:password) { 'password' }
40
+ let(:domain) { 'api.socialcast.com' }
41
+ before do
42
+ Socialcast::CommandLine.should_receive(:credentials=).with({
43
+ :domain => 'api.socialcast.com',
44
+ :proxy => nil
45
+ })
46
+ Socialcast::CommandLine.should_receive(:credentials=).with({
47
+ :user => user,
48
+ :password => password,
49
+ :domain => domain
50
+ })
51
+ stub_request(:post, "https://api.socialcast.com/api/authentication").
52
+ with(:body => {"email"=>"mike@socialcast.com", "password"=>"password"}).
53
+ to_return(:status => 200, :body => { :communities => [{ :domain => domain }] }.to_json, :headers => {})
54
+ Socialcast::CommandLine::CLI.start ['authenticate', "--user=#{user}", "--password=#{password}"]
55
+ end
56
+ ## See expectations
57
+ it 'authenticates with the API and sets the given credentials' do end
58
+ end
59
+
60
+ describe '#authenticate_external_system' do
61
+ let(:api_client_identifier) { 'my-client-id' }
62
+ let(:api_client_secret) { 'my-client-secret' }
63
+ let(:domain) { 'api.socialcast.com' }
64
+ before do
65
+ Socialcast::CommandLine.should_receive(:credentials=).with({
66
+ :domain => 'api.socialcast.com',
67
+ :proxy => nil
68
+ })
69
+ Socialcast::CommandLine.should_receive(:credentials=).with({
70
+ :api_client_identifier => api_client_identifier,
71
+ :api_client_secret => api_client_secret,
72
+ })
73
+ stub_request(:post, "https://api.socialcast.com/api/external_systems/authentication").
74
+ with(:headers => {'Authorization'=>'SocialcastApiClient my-client-id:my-client-secret'}).
75
+ to_return(:status => 200, :body => "", :headers => {})
76
+ Socialcast::CommandLine::CLI.start ['authenticate_external_system', "--api_client_identifier=#{api_client_identifier}", "--api_client_secret=#{api_client_secret}"]
77
+ end
78
+ ## See expectations
79
+ it 'authenticates with the API and sets the given credentials for an authenticated system' do end
80
+ end
81
+
37
82
  describe '#share' do
38
83
  # Expects -u=emily@socialcast.com -p=demo --domain=demo.socialcast.com
39
84
  context 'with a basic message' do
@@ -252,9 +297,9 @@ describe Socialcast::CommandLine::CLI do
252
297
 
253
298
  File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
254
299
  rest_client_resource = double(:rest_client_resource)
255
- rest_client_resource.stub(:post).and_raise(RestClient::Unauthorized.new(mock('Unauthorized HTTP Response', :code => '401')))
300
+ rest_client_resource.stub(:post).and_raise(RestClient::Unauthorized.new(double('Unauthorized HTTP Response', :code => '401', :body => 'Unauthorized HTTP Response')))
256
301
  Socialcast::CommandLine.stub(:resource_for_path).and_return(rest_client_resource)
257
- Kernel.should_receive(:abort).with("Authenticated user either does not have administration privileges or the community is not configured to allow provisioning. Please contact Socialcast support to if you need help.").once
302
+ Kernel.should_receive(:abort).with("Authenticated user either does not have administration privileges or the community is not configured to allow provisioning. Please contact Socialcast support to if you need help.\nResponse from server: Unauthorized HTTP Response").once
258
303
 
259
304
  Socialcast::CommandLine::CLI.start ['provision', '-f']
260
305
  end
@@ -5,8 +5,9 @@ describe Socialcast::CommandLine do
5
5
  let(:custom_file) { File.join(File.dirname(__FILE__), '..', 'fixtures', 'custom_credentials.yml') }
6
6
  let(:stubbed_credentials) { File.join(File.dirname(__FILE__), '..', 'fixtures') }
7
7
  before { Socialcast::CommandLine.stub(:config_dir).and_return(stubbed_credentials) }
8
+ let!(:orig_credentials) { Socialcast::CommandLine.credentials }
8
9
 
9
- describe '#credentials_file' do
10
+ describe '.credentials_file' do
10
11
  subject { Socialcast::CommandLine.credentials_file }
11
12
  context 'with ENV variable' do
12
13
  before { ENV['SC_CREDENTIALS_FILE'] = custom_file }
@@ -18,7 +19,7 @@ describe Socialcast::CommandLine do
18
19
  end
19
20
  end
20
21
 
21
- describe '#credentials' do
22
+ describe '.credentials' do
22
23
  subject { Socialcast::CommandLine.credentials }
23
24
  describe 'with ENV variable' do
24
25
  before { ENV['SC_CREDENTIALS_FILE'] = custom_file }
@@ -30,4 +31,35 @@ describe Socialcast::CommandLine do
30
31
  end
31
32
  end
32
33
 
34
+ describe '.credentials=' do
35
+ let(:options) { { :user => 'mike@socialcast.com', :password => 'mypassword' } }
36
+ before { Socialcast::CommandLine.credentials = options }
37
+ after { Socialcast::CommandLine.credentials = orig_credentials }
38
+ subject { Socialcast::CommandLine.credentials }
39
+ context 'modifies the credentials file with the options content' do
40
+ it { subject[:user].should == 'mike@socialcast.com' }
41
+ end
42
+ context 'only changes the content provided' do
43
+ let(:options) { { :api_client_secret => 'mysecret', :api_client_identifier => 'my_id' } }
44
+ it { subject[:api_client_identifier].should == 'my_id' }
45
+ it { subject[:user].should == 'ryan@socialcast.com' }
46
+ end
47
+ end
48
+
49
+ describe '.resource_for_path' do
50
+ let(:path) { '/mypath' }
51
+ let(:url) { "https://test.staging.socialcast.com#{path}" }
52
+ before do
53
+ RestClient::Resource.should_receive(:new).with(url, options)
54
+ Socialcast::CommandLine.resource_for_path(path, options)
55
+ end
56
+ context 'when using basic auth' do
57
+ let(:options) { { :user => Socialcast::CommandLine.credentials[:user], :password => Socialcast::CommandLine.credentials[:password] } }
58
+ it 'sends user email and password' do end
59
+ end
60
+ context 'when using an external system' do
61
+ let(:options) { { :external_system => true, :headers => { :Authorization=>"SocialcastApiClient my_id:mysecret" } } }
62
+ it 'sends external system credentials' do end
63
+ end
64
+ end
33
65
  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.6
4
+ version: 1.3.7
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-05-28 00:00:00.000000000 Z
13
+ date: 2014-06-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rest-client
@@ -217,6 +217,7 @@ files:
217
217
  - bin/socialcast
218
218
  - config/ldap.yml
219
219
  - lib/socialcast.rb
220
+ - lib/socialcast/command_line/authenticate.rb
220
221
  - lib/socialcast/command_line/cli.rb
221
222
  - lib/socialcast/command_line/ldap_connector.rb
222
223
  - lib/socialcast/command_line/message.rb
@@ -244,6 +245,7 @@ files:
244
245
  - spec/fixtures/ldap_with_unique_identifier.yml
245
246
  - spec/fixtures/ldap_without_account_type_or_roles.yml
246
247
  - spec/fixtures/ldap_without_permission_mappings.yml
248
+ - spec/socialcast/command_line/authenticate_spec.rb
247
249
  - spec/socialcast/command_line/cli_spec.rb
248
250
  - spec/socialcast/command_line/ldap_connector_spec.rb
249
251
  - spec/socialcast/command_line/provision_spec.rb
@@ -295,6 +297,7 @@ test_files:
295
297
  - spec/fixtures/ldap_with_unique_identifier.yml
296
298
  - spec/fixtures/ldap_without_account_type_or_roles.yml
297
299
  - spec/fixtures/ldap_without_permission_mappings.yml
300
+ - spec/socialcast/command_line/authenticate_spec.rb
298
301
  - spec/socialcast/command_line/cli_spec.rb
299
302
  - spec/socialcast/command_line/ldap_connector_spec.rb
300
303
  - spec/socialcast/command_line/provision_spec.rb