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 +4 -4
- data/lib/socialcast.rb +14 -3
- data/lib/socialcast/command_line/authenticate.rb +46 -0
- data/lib/socialcast/command_line/cli.rb +30 -9
- data/lib/socialcast/command_line/provision.rb +5 -3
- data/lib/socialcast/command_line/version.rb +1 -1
- data/spec/fixtures/credentials.yml +2 -0
- data/spec/socialcast/command_line/authenticate_spec.rb +29 -0
- data/spec/socialcast/command_line/cli_spec.rb +47 -2
- data/spec/socialcast/socialcast_spec.rb +34 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 788cbe26a9ad449b6b0a366c6d264069586e4653
|
4
|
+
data.tar.gz: 1f21d4c2e36ed4ab2e8809ae8d0aea2d7e38b943
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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, "
|
29
|
-
|
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(
|
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
|
-
|
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 = {
|
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
|
-
|
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',
|
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
|
-
|
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
|
@@ -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(
|
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
|
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 '
|
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 '
|
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.
|
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-
|
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
|