socialcast 1.3.6 → 1.3.7
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 +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
|