socialcast 1.3.7 → 1.3.8
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 +3 -1
- data/lib/socialcast/command_line/cli.rb +5 -4
- data/lib/socialcast/command_line/provision_photo.rb +79 -0
- data/lib/socialcast/command_line/provision_user.rb +66 -0
- data/lib/socialcast/command_line/provisioner.rb +51 -0
- data/lib/socialcast/command_line/version.rb +1 -1
- data/spec/fixtures/test_images/test-gif-image.gif +0 -0
- data/spec/fixtures/test_images/test-jpg-image.jpg +0 -0
- data/spec/fixtures/test_images/test-png-image.png +0 -0
- data/spec/fixtures/test_images/test-tiff-image.tiff +0 -0
- data/spec/socialcast/command_line/authenticate_spec.rb +3 -2
- data/spec/socialcast/command_line/cli_spec.rb +4 -4
- data/spec/socialcast/command_line/provision_photo_spec.rb +117 -0
- data/spec/socialcast/command_line/{provision_spec.rb → provision_user_spec.rb} +21 -97
- data/spec/spec_helper.rb +13 -0
- metadata +16 -4
- data/lib/socialcast/command_line/provision.rb +0 -166
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43487693be70d4bd0315db025f57e8a2c492fcc7
|
4
|
+
data.tar.gz: a527ada1136ef1d6e3f2fd80ae8fb4e69cd493e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f23a5a4c44d39c83c2a8b1b41868ecf7c25938141129b55993cd619e832ae44d835bfa022fb2700a5d68b595108a204c26ae3b4745855fc169453ed73684975
|
7
|
+
data.tar.gz: f9703ae386594ee84cac91e11625d2d0589a5697c8ab103b433b3ef1af37826ee7f5b00a915378de274eb77c06afc5b52b8d6bbc6835875cca6d0369f0d470a9
|
data/lib/socialcast.rb
CHANGED
@@ -2,8 +2,10 @@ require 'yaml'
|
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
4
|
require_relative 'socialcast/command_line/ldap_connector'
|
5
|
-
require_relative 'socialcast/command_line/
|
5
|
+
require_relative 'socialcast/command_line/provisioner'
|
6
6
|
require_relative 'socialcast/command_line/authenticate'
|
7
|
+
require_relative 'socialcast/command_line/provision_user'
|
8
|
+
require_relative 'socialcast/command_line/provision_photo'
|
7
9
|
require_relative 'socialcast/command_line/message'
|
8
10
|
require_relative 'socialcast/command_line/cli'
|
9
11
|
require_relative 'socialcast/command_line/version'
|
@@ -118,7 +118,7 @@ module Socialcast
|
|
118
118
|
|
119
119
|
desc 'provision', 'provision users from ldap compatible user repository'
|
120
120
|
method_option :config, :default => 'ldap.yml', :aliases => '-c', :desc => 'Path to ldap config file'
|
121
|
-
method_option :output, :default => Socialcast::CommandLine::
|
121
|
+
method_option :output, :default => Socialcast::CommandLine::ProvisionUser::DEFAULT_OUTPUT_FILE, :aliases => '-o', :desc => 'Name of the output file'
|
122
122
|
method_option :setup, :type => :boolean, :desc => 'Create an example ldap config file and exit'
|
123
123
|
method_option :delete_users_file, :type => :boolean, :desc => 'Delete the output file'
|
124
124
|
method_option :test, :type => :boolean, :desc => 'Do not persist changes'
|
@@ -130,18 +130,19 @@ module Socialcast
|
|
130
130
|
config = ldap_config options
|
131
131
|
load_plugins options
|
132
132
|
|
133
|
-
Socialcast::CommandLine::
|
133
|
+
Socialcast::CommandLine::ProvisionUser.new(config, options).provision
|
134
134
|
|
135
|
-
rescue Socialcast::CommandLine::
|
135
|
+
rescue Socialcast::CommandLine::ProvisionUser::ProvisionError => e
|
136
136
|
Kernel.abort e.message
|
137
137
|
end
|
138
138
|
|
139
139
|
desc 'sync_photos', 'Upload default avatar photos from LDAP repository'
|
140
140
|
method_option :config, :default => 'ldap.yml', :aliases => '-c'
|
141
|
+
method_option :force_sync, :default => false, :aliases => '-f', :desc => 'Pushes all photos from LDAP to socialcast'
|
141
142
|
def sync_photos
|
142
143
|
config = ldap_config options
|
143
144
|
|
144
|
-
Socialcast::CommandLine::
|
145
|
+
Socialcast::CommandLine::ProvisionPhoto.new(config, options).sync
|
145
146
|
end
|
146
147
|
|
147
148
|
no_tasks do
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module Socialcast
|
4
|
+
module CommandLine
|
5
|
+
class ProvisionPhoto
|
6
|
+
include Socialcast::CommandLine::Provisioner
|
7
|
+
def sync
|
8
|
+
each_ldap_connector do |connector|
|
9
|
+
|
10
|
+
connector.attribute_mappings.fetch('profile_photo')
|
11
|
+
|
12
|
+
each_ldap_entry do |entry|
|
13
|
+
attr_mappings = connector.attribute_mappings
|
14
|
+
email = connector.grab(entry, attr_mappings['email'])
|
15
|
+
|
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
|
+
return unless is_community_default || @options[:force_sync]
|
23
|
+
|
24
|
+
## PHOTO URL TO BINARY
|
25
|
+
if profile_photo_data = connector.grab(entry, attr_mappings['profile_photo'])
|
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
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def binary_to_content_type(binary_photo_data)
|
67
|
+
case binary_photo_data
|
68
|
+
when Regexp.new("^GIF8", nil, 'n')
|
69
|
+
'gif'
|
70
|
+
when Regexp.new('^\x89PNG', nil, 'n')
|
71
|
+
'png'
|
72
|
+
when Regexp.new("^\xff\xd8\xff\xe0\x00\x10JFIF", nil, 'n'), Regexp.new("^\xff\xd8\xff\xe1(.*){2}Exif", nil, 'n')
|
73
|
+
'jpg'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
require 'builder'
|
3
|
+
require 'set'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module Socialcast
|
7
|
+
module CommandLine
|
8
|
+
class ProvisionUser
|
9
|
+
include Socialcast::CommandLine::Provisioner
|
10
|
+
|
11
|
+
def each_user_hash
|
12
|
+
each_ldap_connector do |connector|
|
13
|
+
connector.each_user_hash do |user_hash|
|
14
|
+
yield user_hash
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch_user_hash(identifier, options = {})
|
20
|
+
each_ldap_connector do |connector|
|
21
|
+
user_hash = connector.fetch_user_hash(identifier, options)
|
22
|
+
return user_hash if user_hash
|
23
|
+
end
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def provision
|
28
|
+
user_whitelist = Set.new
|
29
|
+
output_file = File.join Dir.pwd, @options[:output]
|
30
|
+
params = http_config.merge(:external_system => !!@options[:external_system])
|
31
|
+
|
32
|
+
Zlib::GzipWriter.open(output_file) do |gz|
|
33
|
+
xml = Builder::XmlMarkup.new(:target => gz, :indent => 1)
|
34
|
+
xml.instruct!
|
35
|
+
xml.export do |export|
|
36
|
+
export.users(:type => "array") do |users|
|
37
|
+
each_user_hash do |user_hash|
|
38
|
+
users << user_hash.to_xml(:skip_instruct => true, :root => 'user')
|
39
|
+
user_whitelist << [user_hash['contact_info']['email'], user_hash['unique_identifier'], user_hash['employee_number']]
|
40
|
+
end
|
41
|
+
end # users
|
42
|
+
end # export
|
43
|
+
end # gzip
|
44
|
+
|
45
|
+
if user_whitelist.empty? && !@options[:force]
|
46
|
+
raise ProvisionError.new "Skipping upload to Socialcast since no users were found"
|
47
|
+
else
|
48
|
+
puts "Uploading dataset to Socialcast..."
|
49
|
+
resource = Socialcast::CommandLine.resource_for_path '/api/users/provision', params
|
50
|
+
begin
|
51
|
+
File.open(output_file, 'r') do |file|
|
52
|
+
request_params = {:file => file}
|
53
|
+
request_params[:skip_emails] = 'true' if (@ldap_config['options']["skip_emails"] || @options[:skip_emails])
|
54
|
+
request_params[:test] = 'true' if (@ldap_config['options']["test"] || @options[:test])
|
55
|
+
resource.post request_params, :accept => :json
|
56
|
+
end
|
57
|
+
rescue RestClient::Unauthorized => e
|
58
|
+
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
|
59
|
+
end
|
60
|
+
puts "Finished"
|
61
|
+
end
|
62
|
+
File.delete(output_file) if (@ldap_config['options']['delete_users_file'] || @options[:delete_users_file])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Socialcast
|
2
|
+
module CommandLine
|
3
|
+
module Provisioner
|
4
|
+
class ProvisionError < StandardError; end
|
5
|
+
|
6
|
+
DEFAULT_OUTPUT_FILE = 'users.xml.gz'
|
7
|
+
|
8
|
+
def initialize(ldap_config, options = {})
|
9
|
+
@ldap_config = ldap_config.dup
|
10
|
+
@options = options.dup
|
11
|
+
|
12
|
+
@options[:output] ||= DEFAULT_OUTPUT_FILE
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def http_config
|
18
|
+
@http_config ||= @ldap_config.fetch 'http', {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def ldap_connector(connection_name)
|
22
|
+
@connectors ||= {}
|
23
|
+
|
24
|
+
unless @connectors[connection_name]
|
25
|
+
@connectors[connection_name] = Socialcast::CommandLine::LDAPConnector.new(connection_name, @ldap_config)
|
26
|
+
end
|
27
|
+
|
28
|
+
@connectors[connection_name]
|
29
|
+
end
|
30
|
+
|
31
|
+
def each_ldap_connector
|
32
|
+
@ldap_config['connections'].keys.each do |connection_name|
|
33
|
+
yield ldap_connector(connection_name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def each_ldap_entry(&block)
|
38
|
+
count = 0
|
39
|
+
|
40
|
+
each_ldap_connector do |connector|
|
41
|
+
connector.each_ldap_entry do |entry|
|
42
|
+
yield entry, connector.connection_name
|
43
|
+
count += 1
|
44
|
+
puts "Scanned #{count} users" if ((count % 100) == 0)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
puts "Finished scanning #{count} users"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -3,13 +3,14 @@ require 'spec_helper'
|
|
3
3
|
describe Socialcast::CommandLine::Authenticate do
|
4
4
|
let(:options) { { :domain => "test.socialcast.local" } }
|
5
5
|
let(:params) { { } }
|
6
|
-
subject { Socialcast::CommandLine::Authenticate.new(authenticate_type, options, params) }
|
6
|
+
subject(:authenticate) { Socialcast::CommandLine::Authenticate.new(authenticate_type, options, params) }
|
7
7
|
|
8
8
|
describe '#request' do
|
9
9
|
before do
|
10
10
|
RestClient::Resource.should_receive(:new).with(url, {}).and_call_original
|
11
11
|
RestClient::Resource.any_instance.should_receive(:post).with(subject.params, :accept => :json)
|
12
|
-
|
12
|
+
authenticate.should_receive(:set_default_credentials).and_return(true)
|
13
|
+
authenticate.request
|
13
14
|
end
|
14
15
|
context 'for a regular user' do
|
15
16
|
let(:authenticate_type) { :user }
|
@@ -162,7 +162,7 @@ describe Socialcast::CommandLine::CLI do
|
|
162
162
|
{
|
163
163
|
'id' => 7,
|
164
164
|
'avatars' => {
|
165
|
-
'
|
165
|
+
'is_community_default' => system_default_photo
|
166
166
|
}
|
167
167
|
}
|
168
168
|
]
|
@@ -199,7 +199,7 @@ describe Socialcast::CommandLine::CLI do
|
|
199
199
|
{
|
200
200
|
'id' => 7,
|
201
201
|
'avatars' => {
|
202
|
-
'
|
202
|
+
'is_community_default' => system_default_photo
|
203
203
|
}
|
204
204
|
}
|
205
205
|
]
|
@@ -232,7 +232,7 @@ describe Socialcast::CommandLine::CLI do
|
|
232
232
|
{
|
233
233
|
'id' => 7,
|
234
234
|
'avatars' => {
|
235
|
-
'
|
235
|
+
'is_community_default' => system_default_photo
|
236
236
|
}
|
237
237
|
}
|
238
238
|
]
|
@@ -299,7 +299,7 @@ describe Socialcast::CommandLine::CLI do
|
|
299
299
|
rest_client_resource = double(:rest_client_resource)
|
300
300
|
rest_client_resource.stub(:post).and_raise(RestClient::Unauthorized.new(double('Unauthorized HTTP Response', :code => '401', :body => 'Unauthorized HTTP Response')))
|
301
301
|
Socialcast::CommandLine.stub(:resource_for_path).and_return(rest_client_resource)
|
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
|
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.").once
|
303
303
|
|
304
304
|
Socialcast::CommandLine::CLI.start ['provision', '-f']
|
305
305
|
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Socialcast::CommandLine::ProvisionPhoto do
|
4
|
+
let(:ldap_with_profile_photo) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap_with_profile_photo.yml')) }
|
5
|
+
|
6
|
+
context '#sync' do
|
7
|
+
let(:options) { {} }
|
8
|
+
subject(:sync_photos) { Socialcast::CommandLine::ProvisionPhoto.new(ldap_with_profile_photo, options).sync }
|
9
|
+
let(:user_search_resource) { double(:user_search_resource) }
|
10
|
+
let(:user_submit_resource) { double(:user_submit_resource) }
|
11
|
+
let(:is_community_default) { true }
|
12
|
+
let(:data_fingerprint) { '5d41402abc4b2a76b9719d911017c592' }
|
13
|
+
let(:search_api_response) do
|
14
|
+
{
|
15
|
+
'users' => [
|
16
|
+
{
|
17
|
+
'id' => 7,
|
18
|
+
'avatars' => {
|
19
|
+
'is_community_default' => is_community_default,
|
20
|
+
'data_fingerprint' => data_fingerprint
|
21
|
+
}
|
22
|
+
}
|
23
|
+
]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
before do
|
27
|
+
entry = create_entry :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name', :jpegPhoto => photo_data
|
28
|
+
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', 'jpegPhoto', 'memberof'])).and_yield(entry)
|
29
|
+
Socialcast::CommandLine.stub(:resource_for_path).with('/api/users/search', anything).and_return(user_search_resource)
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'for when it does successfully post the photo' do
|
33
|
+
before do
|
34
|
+
user_search_resource.should_receive(:get).and_return(search_api_response.to_json)
|
35
|
+
user_resource = double(:user_resource)
|
36
|
+
user_resource.should_receive(:put) do |data|
|
37
|
+
uploaded_data = data[:user][:profile_photo][:data]
|
38
|
+
uploaded_data.path.should =~ /\.png\Z/
|
39
|
+
end
|
40
|
+
Socialcast::CommandLine.stub(:resource_for_path).with('/api/users/7', anything).and_return(user_resource)
|
41
|
+
end
|
42
|
+
context 'for a binary file' do
|
43
|
+
let(:photo_data) { "\x89PNGabc" }
|
44
|
+
before do
|
45
|
+
RestClient.should_not_receive(:get)
|
46
|
+
sync_photos
|
47
|
+
end
|
48
|
+
it 'uses the original binary to upload the photo' do end
|
49
|
+
end
|
50
|
+
context 'for an image file' do
|
51
|
+
let(:photo_data) { "http://socialcast.com/someimage.png" }
|
52
|
+
before do
|
53
|
+
RestClient.should_receive(:get).with(photo_data).and_return("\x89PNGabc")
|
54
|
+
sync_photos
|
55
|
+
end
|
56
|
+
it 'downloads the image form the web to upload the photo' do end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'for when it does not successfully post the photo' do
|
61
|
+
context 'for an image file' do
|
62
|
+
let(:photo_data) { "http://socialcast.com/someimage.png" }
|
63
|
+
before do
|
64
|
+
user_search_resource.should_receive(:get).and_return(search_api_response.to_json)
|
65
|
+
RestClient.should_receive(:get).with(photo_data).and_raise(RestClient::ResourceNotFound)
|
66
|
+
sync_photos
|
67
|
+
end
|
68
|
+
it 'tries to download the image from the web and rescues 404' do end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when their is already a photo set' do
|
73
|
+
let(:is_community_default) { false }
|
74
|
+
let(:photo_data) { "\x89PNGabc" }
|
75
|
+
before { user_search_resource.should_receive(:get).and_return(search_api_response.to_json) }
|
76
|
+
context 'for a regular sync' do
|
77
|
+
before do
|
78
|
+
sync_photos
|
79
|
+
Socialcast::CommandLine.should_not_receive(:resource_for_path)
|
80
|
+
end
|
81
|
+
it 'does not post the new photo' do end
|
82
|
+
end
|
83
|
+
context 'when they do a force sync' do
|
84
|
+
let(:options) { { :force_sync => true } }
|
85
|
+
before do
|
86
|
+
Socialcast::CommandLine.should_receive(:resource_for_path).with('/api/users/7', {}).and_return(user_submit_resource)
|
87
|
+
user_submit_resource.should_receive(:put).and_return(true)
|
88
|
+
sync_photos
|
89
|
+
end
|
90
|
+
it 'submits the photo anyways' do end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
context '.binary_to_content_type' do
|
97
|
+
subject { Socialcast::CommandLine::ProvisionPhoto.new(ldap_with_profile_photo, {}).send(:binary_to_content_type, binary_photo_data) }
|
98
|
+
let(:file_dir) { File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'test_images') }
|
99
|
+
let(:binary_photo_data) { File.open(File.join(file_dir, image_name), 'rb') { |file| file.read } }
|
100
|
+
context 'with a jpg' do
|
101
|
+
let(:image_name) { 'test-jpg-image.jpg' }
|
102
|
+
it { should == 'jpg' }
|
103
|
+
end
|
104
|
+
context 'with a gif' do
|
105
|
+
let(:image_name) { 'test-gif-image.gif' }
|
106
|
+
it { should == 'gif' }
|
107
|
+
end
|
108
|
+
context 'with a png' do
|
109
|
+
let(:image_name) { 'test-png-image.png' }
|
110
|
+
it { should == 'png' }
|
111
|
+
end
|
112
|
+
context 'with a tiff' do
|
113
|
+
let(:image_name) { 'test-tiff-image.tiff' }
|
114
|
+
it { should be_nil }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Socialcast::CommandLine::
|
3
|
+
describe Socialcast::CommandLine::ProvisionUser do
|
4
4
|
let!(:credentials) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'credentials.yml')) }
|
5
5
|
let!(:ldap_default_config) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap.yml')) }
|
6
6
|
let!(:ldap_blank_basedn_config) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap_with_blank_basedn.yml')) }
|
@@ -13,17 +13,8 @@ describe Socialcast::CommandLine::Provision do
|
|
13
13
|
let!(:ldap_with_manager_attribute_config) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap_with_manager_attribute.yml')) }
|
14
14
|
let!(:ldap_with_roles_without_account_type_config) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap_with_roles_without_account_type.yml')) }
|
15
15
|
let!(:ldap_with_unique_identifier_config) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap_with_unique_identifier.yml')) }
|
16
|
-
let!(:ldap_with_profile_photo) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap_with_profile_photo.yml')) }
|
17
16
|
let!(:ldap_without_account_type_or_roles_config) { YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'ldap_without_account_type_or_roles.yml')) }
|
18
17
|
|
19
|
-
def create_entry(entry_attributes)
|
20
|
-
Net::LDAP::Entry.new("dc=example,dc=com").tap do |e|
|
21
|
-
entry_attributes.each_pair do |attr, value|
|
22
|
-
e[attr] = value
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
18
|
describe "#provision" do
|
28
19
|
let(:result) { '' }
|
29
20
|
|
@@ -39,7 +30,7 @@ describe Socialcast::CommandLine::Provision do
|
|
39
30
|
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', 'isMemberOf'])).and_yield(entry)
|
40
31
|
RestClient::Resource.any_instance.should_receive(:post).once.with(hash_including(:file => result), { :accept => :json })
|
41
32
|
|
42
|
-
Socialcast::CommandLine::
|
33
|
+
Socialcast::CommandLine::ProvisionUser.new(ldap_default_config, {}).provision
|
43
34
|
end
|
44
35
|
it "puts the user in the output file" do
|
45
36
|
result.should =~ /user@example.com/
|
@@ -51,7 +42,7 @@ describe Socialcast::CommandLine::Provision do
|
|
51
42
|
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'uid', 'isMemberOf'])).and_yield(entry)
|
52
43
|
RestClient::Resource.any_instance.should_receive(:post).once.with(hash_including(:file => result), { :accept => :json })
|
53
44
|
|
54
|
-
Socialcast::CommandLine::
|
45
|
+
Socialcast::CommandLine::ProvisionUser.new(ldap_with_unique_identifier_config, {}).provision
|
55
46
|
end
|
56
47
|
it "puts the user in the output file" do
|
57
48
|
result.should =~ /userID/
|
@@ -65,8 +56,8 @@ describe Socialcast::CommandLine::Provision do
|
|
65
56
|
end
|
66
57
|
it "does not put the user in the output file" do
|
67
58
|
expect do
|
68
|
-
Socialcast::CommandLine::
|
69
|
-
end.to raise_error(Socialcast::CommandLine::
|
59
|
+
Socialcast::CommandLine::ProvisionUser.new(ldap_default_config, {}).provision
|
60
|
+
end.to raise_error(Socialcast::CommandLine::ProvisionUser::ProvisionError, "Skipping upload to Socialcast since no users were found")
|
70
61
|
end
|
71
62
|
end
|
72
63
|
context "attribute mappings" do
|
@@ -99,7 +90,7 @@ describe Socialcast::CommandLine::Provision do
|
|
99
90
|
entry = create_entry :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name'
|
100
91
|
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', 'isMemberOf'])).and_yield(entry)
|
101
92
|
|
102
|
-
Socialcast::CommandLine::
|
93
|
+
Socialcast::CommandLine::ProvisionUser.new(ldap_default_config, {}).provision
|
103
94
|
end
|
104
95
|
let(:expected_attribute_xml) do
|
105
96
|
%Q[<first-name>first name</first-name>
|
@@ -114,7 +105,7 @@ describe Socialcast::CommandLine::Provision do
|
|
114
105
|
|
115
106
|
context "with mappings at the connection level" do
|
116
107
|
before do
|
117
|
-
provision_instance = Socialcast::CommandLine::
|
108
|
+
provision_instance = Socialcast::CommandLine::ProvisionUser.new(ldap_multiple_connection_mapping_config, {})
|
118
109
|
|
119
110
|
ldap_instance1 = double(Net::LDAP, :encryption => nil, :auth => nil)
|
120
111
|
Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance1)
|
@@ -148,7 +139,7 @@ describe Socialcast::CommandLine::Provision do
|
|
148
139
|
entry = create_entry :mail => 'user@example.com', :custom_ldap1 => 'custom value 1', :custom_ldap2 => 'custom value 2'
|
149
140
|
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['custom_ldap1', 'custom_ldap2', 'mail', 'isMemberOf'])).and_yield(entry)
|
150
141
|
|
151
|
-
Socialcast::CommandLine::
|
142
|
+
Socialcast::CommandLine::ProvisionUser.new(ldap_with_custom_attributes_config, {}).provision
|
152
143
|
end
|
153
144
|
let(:expected_attribute_xml) do
|
154
145
|
%Q[<contact-info>
|
@@ -172,7 +163,7 @@ describe Socialcast::CommandLine::Provision do
|
|
172
163
|
|
173
164
|
context "with manager" do
|
174
165
|
before do
|
175
|
-
provision_instance = Socialcast::CommandLine::
|
166
|
+
provision_instance = Socialcast::CommandLine::ProvisionUser.new(ldap_with_manager_attribute_config, {})
|
176
167
|
|
177
168
|
ldap_instance = double(Net::LDAP, :encryption => nil, :auth => nil)
|
178
169
|
Net::LDAP.should_receive(:new).once.and_return(ldap_instance)
|
@@ -205,7 +196,7 @@ describe Socialcast::CommandLine::Provision do
|
|
205
196
|
entry = create_entry :test_ldap_attribute_mapping => 'user@example.com'
|
206
197
|
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['test_ldap_attribute_mapping', 'isMemberOf'])).and_yield(entry)
|
207
198
|
|
208
|
-
Socialcast::CommandLine::
|
199
|
+
Socialcast::CommandLine::ProvisionUser.new(ldap_with_class_ldap_attribute_config, {}).provision
|
209
200
|
end
|
210
201
|
after do
|
211
202
|
Object.send(:remove_const, :TestLdapAttributeMapping)
|
@@ -255,7 +246,7 @@ describe Socialcast::CommandLine::Provision do
|
|
255
246
|
let(:ldap_groups) { ["cn=External,dc=example,dc=com", "cn=SbiAdmins,dc=example,dc=com", "cn=TownHallAdmins,dc=example,dc=com"] }
|
256
247
|
before do
|
257
248
|
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', ldap_group_attribute])).and_yield(entry)
|
258
|
-
Socialcast::CommandLine::
|
249
|
+
Socialcast::CommandLine::ProvisionUser.new(ldap_default_config, {}).provision
|
259
250
|
end
|
260
251
|
let(:expected_permission_xml) do
|
261
252
|
%Q[<account-type>external</account-type>]
|
@@ -267,7 +258,7 @@ describe Socialcast::CommandLine::Provision do
|
|
267
258
|
let(:ldap_groups) { ["cn=SbiAdmins,dc=example,dc=com", "cn=TownHallAdmins,dc=example,dc=com"] }
|
268
259
|
before do
|
269
260
|
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', ldap_group_attribute])).and_yield(entry)
|
270
|
-
Socialcast::CommandLine::
|
261
|
+
Socialcast::CommandLine::ProvisionUser.new(ldap_default_config, {}).provision
|
271
262
|
end
|
272
263
|
let(:expected_permission_xml) do
|
273
264
|
%Q[<account-type>member</account-type>
|
@@ -283,7 +274,7 @@ describe Socialcast::CommandLine::Provision do
|
|
283
274
|
let(:ldap_groups) { ["cn=SbiAdmins,dc=example,dc=com", "cn=TownHallAdmins,dc=example,dc=com"] }
|
284
275
|
before do
|
285
276
|
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', ldap_group_attribute])).and_yield(entry)
|
286
|
-
Socialcast::CommandLine::
|
277
|
+
Socialcast::CommandLine::ProvisionUser.new(ldap_with_account_type_without_roles_config, {}).provision
|
287
278
|
end
|
288
279
|
let(:expected_permission_xml) do
|
289
280
|
%Q[<account-type>member</account-type>]
|
@@ -295,7 +286,7 @@ describe Socialcast::CommandLine::Provision do
|
|
295
286
|
let(:ldap_groups) { ["cn=SbiAdmins,dc=example,dc=com", "cn=TownHallAdmins,dc=example,dc=com"] }
|
296
287
|
before do
|
297
288
|
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', ldap_group_attribute])).and_yield(entry)
|
298
|
-
Socialcast::CommandLine::
|
289
|
+
Socialcast::CommandLine::ProvisionUser.new(ldap_with_roles_without_account_type_config, {}).provision
|
299
290
|
end
|
300
291
|
let(:expected_permission_xml) do
|
301
292
|
%Q[<account-type>member</account-type>
|
@@ -311,7 +302,7 @@ describe Socialcast::CommandLine::Provision do
|
|
311
302
|
let(:ldap_groups) { ["cn=SbiAdmins,dc=example,dc=com", "cn=TownHallAdmins,dc=example,dc=com"] }
|
312
303
|
before do
|
313
304
|
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', ldap_group_attribute])).and_yield(entry)
|
314
|
-
Socialcast::CommandLine::
|
305
|
+
Socialcast::CommandLine::ProvisionUser.new(ldap_without_account_type_or_roles_config, {}).provision
|
315
306
|
end
|
316
307
|
let(:expected_permission_xml) do
|
317
308
|
%Q[<account-type>member</account-type>]
|
@@ -323,7 +314,7 @@ describe Socialcast::CommandLine::Provision do
|
|
323
314
|
let(:ldap_group_attribute) { 'memberOf' }
|
324
315
|
let(:ldap_groups) { }
|
325
316
|
before do
|
326
|
-
provision_instance = Socialcast::CommandLine::
|
317
|
+
provision_instance = Socialcast::CommandLine::ProvisionUser.new(ldap_multiple_connection_permission_mapping_config, {})
|
327
318
|
|
328
319
|
ldap_instance1 = double(Net::LDAP, :encryption => nil, :auth => nil)
|
329
320
|
Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance1)
|
@@ -355,7 +346,7 @@ describe Socialcast::CommandLine::Provision do
|
|
355
346
|
before do
|
356
347
|
RestClient::Resource.any_instance.should_receive(:post).once.with(hash_including(:file => result), { :accept => :json })
|
357
348
|
|
358
|
-
provision_instance = Socialcast::CommandLine::
|
349
|
+
provision_instance = Socialcast::CommandLine::ProvisionUser.new(ldap_blank_basedn_config, {})
|
359
350
|
|
360
351
|
root_entry = create_entry(:namingcontexts => ['dc=foo,dc=com', 'dc=bar,dc=com'])
|
361
352
|
ldap_instance = double(Net::LDAP, :encryption => nil, :auth => nil)
|
@@ -375,7 +366,7 @@ describe Socialcast::CommandLine::Provision do
|
|
375
366
|
end
|
376
367
|
|
377
368
|
describe "#each_user_hash" do
|
378
|
-
let(:provision_instance) { Socialcast::CommandLine::
|
369
|
+
let(:provision_instance) { Socialcast::CommandLine::ProvisionUser.new(ldap_default_config) }
|
379
370
|
before do
|
380
371
|
entry = create_entry :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name'
|
381
372
|
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', 'isMemberOf'])).and_yield(entry)
|
@@ -398,7 +389,7 @@ describe Socialcast::CommandLine::Provision do
|
|
398
389
|
|
399
390
|
describe "#fetch_user_hash" do
|
400
391
|
context "when the first connector returns the entry" do
|
401
|
-
let(:provision_instance) { Socialcast::CommandLine::
|
392
|
+
let(:provision_instance) { Socialcast::CommandLine::ProvisionUser.new(ldap_multiple_connection_mapping_config, {}) }
|
402
393
|
let(:entry) { create_entry :mailCon => 'user@example.com' }
|
403
394
|
before do
|
404
395
|
filter = Net::LDAP::Filter.construct('(&(mail=*)(mailCon=user@example.com))')
|
@@ -418,7 +409,7 @@ describe Socialcast::CommandLine::Provision do
|
|
418
409
|
end
|
419
410
|
end
|
420
411
|
context "when another connector returns the entry" do
|
421
|
-
let(:provision_instance) { Socialcast::CommandLine::
|
412
|
+
let(:provision_instance) { Socialcast::CommandLine::ProvisionUser.new(ldap_multiple_connection_mapping_config, {}) }
|
422
413
|
let(:entry) { create_entry :mailCon2 => 'user@example.com', :firstName => 'first name' }
|
423
414
|
before do
|
424
415
|
ldap_instance1 = double(Net::LDAP, :auth => nil)
|
@@ -448,7 +439,7 @@ describe Socialcast::CommandLine::Provision do
|
|
448
439
|
end
|
449
440
|
end
|
450
441
|
context "when no connectors return the entry" do
|
451
|
-
let(:provision_instance) { Socialcast::CommandLine::
|
442
|
+
let(:provision_instance) { Socialcast::CommandLine::ProvisionUser.new(ldap_multiple_connection_mapping_config, {}) }
|
452
443
|
before do
|
453
444
|
ldap_instance1 = double(Net::LDAP, :auth => nil)
|
454
445
|
Net::LDAP.should_receive(:new).once.ordered.and_return(ldap_instance1)
|
@@ -467,71 +458,4 @@ describe Socialcast::CommandLine::Provision do
|
|
467
458
|
end
|
468
459
|
end
|
469
460
|
end
|
470
|
-
|
471
|
-
describe '#sync_photos' do
|
472
|
-
let(:user_search_resource) { double(:user_search_resource) }
|
473
|
-
let(:search_api_response) do
|
474
|
-
{
|
475
|
-
'users' => [
|
476
|
-
{
|
477
|
-
'id' => 7,
|
478
|
-
'avatars' => {
|
479
|
-
'is_system_default' => true
|
480
|
-
}
|
481
|
-
}
|
482
|
-
]
|
483
|
-
}
|
484
|
-
end
|
485
|
-
before do
|
486
|
-
entry = create_entry :mail => 'user@example.com', :givenName => 'first name', :sn => 'last name', :jpegPhoto => photo_data
|
487
|
-
Net::LDAP.any_instance.should_receive(:search).once.with(hash_including(:attributes => ['givenName', 'sn', 'mail', 'jpegPhoto', 'memberof'])).and_yield(entry)
|
488
|
-
|
489
|
-
Socialcast::CommandLine.stub(:resource_for_path).with('/api/users/search', anything).and_return(user_search_resource)
|
490
|
-
end
|
491
|
-
let(:sync_photos) { Socialcast::CommandLine::Provision.new(ldap_with_profile_photo, {}).sync_photos }
|
492
|
-
|
493
|
-
context 'for when it does successfully post the photo' do
|
494
|
-
before do
|
495
|
-
user_search_resource.should_receive(:get).and_return(search_api_response.to_json)
|
496
|
-
user_resource = double(:user_resource)
|
497
|
-
user_resource.should_receive(:put) do |data|
|
498
|
-
uploaded_data = data[:user][:profile_photo][:data]
|
499
|
-
uploaded_data.path.should =~ /\.png\Z/
|
500
|
-
end
|
501
|
-
Socialcast::CommandLine.stub(:resource_for_path).with('/api/users/7', anything).and_return(user_resource)
|
502
|
-
end
|
503
|
-
context 'for a binary file' do
|
504
|
-
let(:photo_data) { "\x89PNGabc" }
|
505
|
-
before do
|
506
|
-
RestClient.should_not_receive(:get)
|
507
|
-
sync_photos
|
508
|
-
end
|
509
|
-
it 'uses the original binary to upload the photo' do end
|
510
|
-
end
|
511
|
-
context 'for an image file' do
|
512
|
-
let(:photo_data) { "http://socialcast.com/someimage.png" }
|
513
|
-
context 'when it successfully downloads' do
|
514
|
-
before do
|
515
|
-
RestClient.should_receive(:get).with(photo_data).and_return("\x89PNGabc")
|
516
|
-
sync_photos
|
517
|
-
end
|
518
|
-
it 'downloads the image form the web to upload the photo' do end
|
519
|
-
end
|
520
|
-
end
|
521
|
-
end
|
522
|
-
|
523
|
-
context 'for when it does not successfully post the photo' do
|
524
|
-
context 'for an image file' do
|
525
|
-
let(:photo_data) { "http://socialcast.com/someimage.png" }
|
526
|
-
before do
|
527
|
-
user_search_resource.should_not_receive(:get)
|
528
|
-
RestClient.should_receive(:get).with(photo_data).and_raise(RestClient::ResourceNotFound)
|
529
|
-
sync_photos
|
530
|
-
end
|
531
|
-
it 'tries to download the image from the web and rescues 404' do end
|
532
|
-
end
|
533
|
-
end
|
534
|
-
|
535
|
-
end
|
536
|
-
|
537
461
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -10,6 +10,11 @@ require_relative '../lib/socialcast'
|
|
10
10
|
RSpec.configure do |config|
|
11
11
|
config.mock_with :rspec
|
12
12
|
|
13
|
+
config.before do
|
14
|
+
stubbed_credentials = File.join(File.dirname(__FILE__), '..', 'fixtures')
|
15
|
+
Socialcast::CommandLine.stub(:config_dir).and_return(stubbed_credentials)
|
16
|
+
end
|
17
|
+
|
13
18
|
def capture_with_status(stream)
|
14
19
|
exit_status = 0
|
15
20
|
begin
|
@@ -27,6 +32,14 @@ RSpec.configure do |config|
|
|
27
32
|
return result, exit_status
|
28
33
|
end
|
29
34
|
|
35
|
+
def create_entry(entry_attributes)
|
36
|
+
Net::LDAP::Entry.new("dc=example,dc=com").tap do |e|
|
37
|
+
entry_attributes.each_pair do |attr, value|
|
38
|
+
e[attr] = value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
30
43
|
def remove_directories(*names)
|
31
44
|
project_dir = Pathname.new(Dir.pwd)
|
32
45
|
names.each do |name|
|
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.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Sonnek
|
@@ -221,7 +221,9 @@ files:
|
|
221
221
|
- lib/socialcast/command_line/cli.rb
|
222
222
|
- lib/socialcast/command_line/ldap_connector.rb
|
223
223
|
- lib/socialcast/command_line/message.rb
|
224
|
-
- lib/socialcast/command_line/
|
224
|
+
- lib/socialcast/command_line/provision_photo.rb
|
225
|
+
- lib/socialcast/command_line/provision_user.rb
|
226
|
+
- lib/socialcast/command_line/provisioner.rb
|
225
227
|
- lib/socialcast/command_line/version.rb
|
226
228
|
- socialcast.gemspec
|
227
229
|
- spec/fixtures/credentials.yml
|
@@ -245,10 +247,15 @@ files:
|
|
245
247
|
- spec/fixtures/ldap_with_unique_identifier.yml
|
246
248
|
- spec/fixtures/ldap_without_account_type_or_roles.yml
|
247
249
|
- spec/fixtures/ldap_without_permission_mappings.yml
|
250
|
+
- spec/fixtures/test_images/test-gif-image.gif
|
251
|
+
- spec/fixtures/test_images/test-jpg-image.jpg
|
252
|
+
- spec/fixtures/test_images/test-png-image.png
|
253
|
+
- spec/fixtures/test_images/test-tiff-image.tiff
|
248
254
|
- spec/socialcast/command_line/authenticate_spec.rb
|
249
255
|
- spec/socialcast/command_line/cli_spec.rb
|
250
256
|
- spec/socialcast/command_line/ldap_connector_spec.rb
|
251
|
-
- spec/socialcast/command_line/
|
257
|
+
- spec/socialcast/command_line/provision_photo_spec.rb
|
258
|
+
- spec/socialcast/command_line/provision_user_spec.rb
|
252
259
|
- spec/socialcast/socialcast_spec.rb
|
253
260
|
- spec/spec_helper.rb
|
254
261
|
homepage: http://github.com/socialcast/socialcast-command-line
|
@@ -297,9 +304,14 @@ test_files:
|
|
297
304
|
- spec/fixtures/ldap_with_unique_identifier.yml
|
298
305
|
- spec/fixtures/ldap_without_account_type_or_roles.yml
|
299
306
|
- spec/fixtures/ldap_without_permission_mappings.yml
|
307
|
+
- spec/fixtures/test_images/test-gif-image.gif
|
308
|
+
- spec/fixtures/test_images/test-jpg-image.jpg
|
309
|
+
- spec/fixtures/test_images/test-png-image.png
|
310
|
+
- spec/fixtures/test_images/test-tiff-image.tiff
|
300
311
|
- spec/socialcast/command_line/authenticate_spec.rb
|
301
312
|
- spec/socialcast/command_line/cli_spec.rb
|
302
313
|
- spec/socialcast/command_line/ldap_connector_spec.rb
|
303
|
-
- spec/socialcast/command_line/
|
314
|
+
- spec/socialcast/command_line/provision_photo_spec.rb
|
315
|
+
- spec/socialcast/command_line/provision_user_spec.rb
|
304
316
|
- spec/socialcast/socialcast_spec.rb
|
305
317
|
- spec/spec_helper.rb
|
@@ -1,166 +0,0 @@
|
|
1
|
-
require 'zlib'
|
2
|
-
require 'builder'
|
3
|
-
require 'set'
|
4
|
-
require 'fileutils'
|
5
|
-
|
6
|
-
module Socialcast
|
7
|
-
module CommandLine
|
8
|
-
class Provision
|
9
|
-
DEFAULT_OUTPUT_FILE = 'users.xml.gz'
|
10
|
-
|
11
|
-
class ProvisionError < StandardError; end
|
12
|
-
|
13
|
-
def initialize(ldap_config, options = {})
|
14
|
-
@ldap_config = ldap_config.dup
|
15
|
-
@options = options.dup
|
16
|
-
|
17
|
-
@options[:output] ||= DEFAULT_OUTPUT_FILE
|
18
|
-
end
|
19
|
-
|
20
|
-
def each_user_hash
|
21
|
-
each_ldap_connector do |connector|
|
22
|
-
connector.each_user_hash do |user_hash|
|
23
|
-
yield user_hash
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def fetch_user_hash(identifier, options = {})
|
29
|
-
each_ldap_connector do |connector|
|
30
|
-
user_hash = connector.fetch_user_hash(identifier, options)
|
31
|
-
return user_hash if user_hash
|
32
|
-
end
|
33
|
-
nil
|
34
|
-
end
|
35
|
-
|
36
|
-
def provision
|
37
|
-
params = @ldap_config.fetch('http', {}).merge(:external_system => !!@options[:external_system])
|
38
|
-
|
39
|
-
user_whitelist = Set.new
|
40
|
-
output_file = File.join Dir.pwd, @options[:output]
|
41
|
-
|
42
|
-
Zlib::GzipWriter.open(output_file) do |gz|
|
43
|
-
xml = Builder::XmlMarkup.new(:target => gz, :indent => 1)
|
44
|
-
xml.instruct!
|
45
|
-
xml.export do |export|
|
46
|
-
export.users(:type => "array") do |users|
|
47
|
-
each_user_hash do |user_hash|
|
48
|
-
users << user_hash.to_xml(:skip_instruct => true, :root => 'user')
|
49
|
-
user_whitelist << [user_hash['contact_info']['email'], user_hash['unique_identifier'], user_hash['employee_number']]
|
50
|
-
end
|
51
|
-
end # users
|
52
|
-
end # export
|
53
|
-
end # gzip
|
54
|
-
|
55
|
-
if user_whitelist.empty? && !@options[:force]
|
56
|
-
raise ProvisionError.new "Skipping upload to Socialcast since no users were found"
|
57
|
-
else
|
58
|
-
puts "Uploading dataset to Socialcast..."
|
59
|
-
resource = Socialcast::CommandLine.resource_for_path '/api/users/provision', params
|
60
|
-
begin
|
61
|
-
File.open(output_file, 'r') do |file|
|
62
|
-
request_params = {:file => file}
|
63
|
-
request_params[:skip_emails] = 'true' if (@ldap_config['options']["skip_emails"] || @options[:skip_emails])
|
64
|
-
request_params[:test] = 'true' if (@ldap_config['options']["test"] || @options[:test])
|
65
|
-
resource.post request_params, :accept => :json
|
66
|
-
end
|
67
|
-
rescue RestClient::Unauthorized => e
|
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
|
71
|
-
end
|
72
|
-
puts "Finished"
|
73
|
-
end
|
74
|
-
File.delete(output_file) if (@ldap_config['options']['delete_users_file'] || @options[:delete_users_file])
|
75
|
-
end
|
76
|
-
|
77
|
-
def sync_photos
|
78
|
-
http_config = @ldap_config.fetch 'http', {}
|
79
|
-
|
80
|
-
each_ldap_connector do |connector|
|
81
|
-
connector.attribute_mappings.fetch('profile_photo')
|
82
|
-
end
|
83
|
-
|
84
|
-
search_users_resource = Socialcast::CommandLine.resource_for_path '/api/users/search', http_config
|
85
|
-
|
86
|
-
each_ldap_connector do |connector|
|
87
|
-
each_ldap_entry do |entry|
|
88
|
-
attr_mappings = connector.attribute_mappings
|
89
|
-
email = connector.grab(entry, attr_mappings['email'])
|
90
|
-
if profile_photo_data = connector.grab(entry, attr_mappings['profile_photo'])
|
91
|
-
if profile_photo_data.start_with?('http')
|
92
|
-
begin
|
93
|
-
profile_photo_data = RestClient.get(profile_photo_data)
|
94
|
-
rescue => e
|
95
|
-
puts "Unable to download photo #{profile_photo_data} for #{email}"
|
96
|
-
puts e.response
|
97
|
-
next
|
98
|
-
end
|
99
|
-
end
|
100
|
-
profile_photo_data = profile_photo_data.force_encoding('binary')
|
101
|
-
|
102
|
-
user_search_response = search_users_resource.get(:params => { :q => email, :per_page => 1 }, :accept => :json)
|
103
|
-
user_info = JSON.parse(user_search_response)['users'].first
|
104
|
-
if user_info && user_info['avatars'] && user_info['avatars']['is_system_default']
|
105
|
-
puts "Uploading photo for #{email}"
|
106
|
-
|
107
|
-
user_resource = Socialcast::CommandLine.resource_for_path "/api/users/#{user_info['id']}", http_config
|
108
|
-
content_type = case profile_photo_data
|
109
|
-
when Regexp.new("\AGIF8", nil, 'n')
|
110
|
-
'gif'
|
111
|
-
when Regexp.new('\A\x89PNG', nil, 'n')
|
112
|
-
'png'
|
113
|
-
when Regexp.new("\A\xff\xd8\xff\xe0\x00\x10JFIF", nil, 'n'), Regexp.new("\A\xff\xd8\xff\xe1(.*){2}Exif", nil, 'n')
|
114
|
-
'jpg'
|
115
|
-
else
|
116
|
-
puts "Skipping photo for #{email}: unknown image format (supports .gif, .png, .jpg)"
|
117
|
-
next
|
118
|
-
end
|
119
|
-
|
120
|
-
tempfile = Tempfile.new(["photo_upload", ".#{content_type}"])
|
121
|
-
tempfile.write(profile_photo_data)
|
122
|
-
tempfile.rewind
|
123
|
-
begin
|
124
|
-
user_resource.put({ :user => { :profile_photo => { :data => tempfile } } })
|
125
|
-
ensure
|
126
|
-
tempfile.unlink
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
private
|
135
|
-
|
136
|
-
def ldap_connector(connection_name)
|
137
|
-
@connectors ||= {}
|
138
|
-
|
139
|
-
unless @connectors[connection_name]
|
140
|
-
@connectors[connection_name] = Socialcast::CommandLine::LDAPConnector.new(connection_name, @ldap_config)
|
141
|
-
end
|
142
|
-
|
143
|
-
@connectors[connection_name]
|
144
|
-
end
|
145
|
-
|
146
|
-
def each_ldap_connector
|
147
|
-
@ldap_config['connections'].keys.each do |connection_name|
|
148
|
-
yield ldap_connector(connection_name)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def each_ldap_entry(&block)
|
153
|
-
count = 0
|
154
|
-
|
155
|
-
each_ldap_connector do |connector|
|
156
|
-
connector.each_ldap_entry do |entry|
|
157
|
-
yield entry, connector.connection_name
|
158
|
-
count += 1
|
159
|
-
puts "Scanned #{count} users" if ((count % 100) == 0)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
puts "Finished scanning #{count} users"
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|