socialcast 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/bin/socialcast +2 -1
- data/config/ldap.yml +6 -1
- data/lib/socialcast/cli.rb +144 -67
- data/lib/socialcast/version.rb +1 -1
- data/socialcast.gemspec +3 -3
- data/spec/cli_spec.rb +212 -101
- data/spec/fixtures/ldap_with_profile_photo.yml +16 -0
- metadata +10 -33
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
Y2Q0N2I4MGQyYzQ1MzBlYmExMmY5NjcyZDQ2YzNmMWZkYTNmZWFlZg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
N2Q1OWJjZmNhYTE4MmRlNzg5MmFmZGIxNTg4M2YyZTdjZjIyMzlhYw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OGE0ZWRiY2IwMGNlNjQ2NzE2MTc4NzE4ZWQ4NmFiNzEzZWMxNjc2MWNmOWFj
|
10
|
+
ZGU1YzZjZjM5ZmE1ZTgzMjI2OWI5ZWQzODk0YzQyY2FhOTdlMWFmMTIxYjRi
|
11
|
+
Y2RjNWM2OWYyYmJhMzEyMWI5ODI4MzJiMjM4MmUyMDBhNTRhMmY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
M2Q1ZjdjODVlY2I1MmRmOGVjMmE0ZjAzMzkxYWU0YTI3OWY1OGVjODNjZWI1
|
14
|
+
ZWFhNTAyYzU5ODAyNTdjMjAwZTNiNGFkMDYxNjNhYmI4YjQ5MjVlZDBhNzcz
|
15
|
+
NWQ1NzdjODQ2MjcwMzQ0MTVkNWI5Y2UwMTk3YjkxZjZjZTRmZmQ=
|
data/bin/socialcast
CHANGED
data/config/ldap.yml
CHANGED
@@ -30,10 +30,12 @@ mappings:
|
|
30
30
|
first_name: givenName
|
31
31
|
last_name: sn
|
32
32
|
email: mail
|
33
|
+
|
33
34
|
# only use employee_number if the email is unknown
|
34
35
|
# employee_number: emp_id
|
35
36
|
# only use unique_identifier if you do not wish to use email as the main user identification method
|
36
37
|
# unique_identifier: samaccountname
|
38
|
+
|
37
39
|
# To combine multiple ldap attributes into one Socialcast attribute use the following pattern
|
38
40
|
# The key is the socialcast attribute and the value is a hash. The hash requires a key of value
|
39
41
|
# which will use the other keys to interpolate the values.
|
@@ -42,6 +44,7 @@ mappings:
|
|
42
44
|
# city: city
|
43
45
|
# state: state
|
44
46
|
# zip: zipcode
|
47
|
+
|
45
48
|
# To populate the Socialcast org chart functionality you have two options.
|
46
49
|
# If using AD you will most likely need to use the manager option. It works by
|
47
50
|
# doing an additional ldap query for each user to find the email address for the
|
@@ -51,8 +54,10 @@ mappings:
|
|
51
54
|
# mapped is the manager's email address. No additional queries will be performed.
|
52
55
|
# This normally requires changes to your LDAP schema.
|
53
56
|
# manager_email: manager_email
|
54
|
-
|
55
57
|
|
58
|
+
# For the sync_photos command add mapping for the profile_photo attribute to an LDAP attribute
|
59
|
+
# profile_photo: jpegPhoto
|
60
|
+
# profile_photo: photo
|
56
61
|
|
57
62
|
# Map LDAP Group Memberships to Socialcast Permissions
|
58
63
|
permission_mappings:
|
data/lib/socialcast/cli.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
|
3
5
|
require "thor"
|
@@ -102,83 +104,31 @@ module Socialcast
|
|
102
104
|
method_option :sanity_check, :type => :boolean, :default => false
|
103
105
|
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."
|
104
106
|
def provision
|
105
|
-
|
106
|
-
|
107
|
-
if options[:setup]
|
108
|
-
create_file config_file do
|
109
|
-
File.read File.join(File.dirname(__FILE__), '..', '..', 'config', 'ldap.yml')
|
110
|
-
end
|
111
|
-
return
|
112
|
-
end
|
113
|
-
|
114
|
-
fail "Unable to load configuration file: #{config_file}" unless File.exists?(config_file)
|
115
|
-
say "Using configuration file: #{config_file}"
|
116
|
-
|
117
|
-
config = load_configuration config_file
|
118
|
-
http_config = config.fetch('http', {})
|
119
|
-
|
120
|
-
Array.wrap(options[:plugins]).each do |plugin|
|
121
|
-
begin
|
122
|
-
require plugin
|
123
|
-
rescue LoadError => e
|
124
|
-
fail "Unable to load #{plugin}: #{e}"
|
125
|
-
end
|
126
|
-
end
|
107
|
+
config = ldap_config options
|
108
|
+
load_plugins options
|
127
109
|
|
128
|
-
|
110
|
+
http_config = config.fetch 'http', {}
|
129
111
|
mappings = config.fetch 'mappings', {}
|
130
|
-
required_mappings.each do |field|
|
131
|
-
unless mappings.has_key? field
|
132
|
-
fail "Missing required mapping: #{field}"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
112
|
permission_mappings = config.fetch 'permission_mappings', {}
|
137
|
-
|
138
|
-
attributes = mappings.values.map do |mapping_value|
|
139
|
-
mapping_value = begin
|
140
|
-
mapping_value.camelize.constantize
|
141
|
-
rescue NameError
|
142
|
-
mapping_value
|
143
|
-
end
|
144
|
-
case mapping_value
|
145
|
-
when Hash
|
146
|
-
dup_mapping_value = mapping_value.dup
|
147
|
-
dup_mapping_value.delete("value")
|
148
|
-
dup_mapping_value.values
|
149
|
-
when String
|
150
|
-
mapping_value
|
151
|
-
when Class, Module
|
152
|
-
fail "Please add the attributes method to #{mapping_value}" unless mapping_value.respond_to?(:attributes)
|
153
|
-
mapping_value.attributes
|
154
|
-
end
|
155
|
-
end.flatten
|
156
|
-
attributes << membership_attribute
|
113
|
+
|
157
114
|
user_identifier_list = %w{email unique_identifier employee_number}
|
158
115
|
user_whitelist = Set.new
|
159
|
-
count = 0
|
160
116
|
output_file = File.join Dir.pwd, options[:output]
|
117
|
+
|
161
118
|
Zlib::GzipWriter.open(output_file) do |gz|
|
162
119
|
xml = Builder::XmlMarkup.new(:target => gz, :indent => 1)
|
163
120
|
xml.instruct!
|
164
121
|
xml.export do |export|
|
165
122
|
export.users(:type => "array") do |users|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
entry.build_xml_from_mappings user, ldap, mappings, permission_mappings
|
172
|
-
end
|
173
|
-
user_whitelist << user_identifier_list.map { |identifier| entry.grab(mappings[identifier]) }
|
174
|
-
count += 1
|
175
|
-
say "Scanned #{count} users" if ((count % 100) == 0)
|
176
|
-
end # search
|
123
|
+
each_ldap_entry(config) do |ldap, entry|
|
124
|
+
users.user do |user|
|
125
|
+
entry.build_xml_from_mappings user, ldap, mappings, permission_mappings
|
126
|
+
end
|
127
|
+
user_whitelist << user_identifier_list.map { |identifier| entry.grab(mappings[identifier]) }
|
177
128
|
end # connections
|
178
129
|
end # users
|
179
130
|
end # export
|
180
131
|
end # gzip
|
181
|
-
say "Finished scanning #{count} users"
|
182
132
|
|
183
133
|
if options[:sanity_check]
|
184
134
|
say "Sanity checking users currently marked as needing to be terminated"
|
@@ -191,13 +141,13 @@ module Socialcast
|
|
191
141
|
combined_filters.compact!
|
192
142
|
filter = ((combined_filters.size > 1) ? '(|%s)' : '%s') % combined_filters.join(' ')
|
193
143
|
filter = Net::LDAP::Filter.construct(filter) & Net::LDAP::Filter.construct(connection["filter"])
|
194
|
-
ldap_result = ldap.search(:return_result => true, :base => connection["basedn"], :filter => filter, :attributes =>
|
195
|
-
abort("Found user marked for termination that should not be terminated: #{user_identifiers}") unless ldap_result.blank?
|
144
|
+
ldap_result = ldap.search(:return_result => true, :base => connection["basedn"], :filter => filter, :attributes => ldap_search_attributes(config))
|
145
|
+
Kernel.abort("Found user marked for termination that should not be terminated: #{user_identifiers}") unless ldap_result.blank?
|
196
146
|
end
|
197
147
|
end
|
198
148
|
end
|
199
149
|
|
200
|
-
if
|
150
|
+
if user_whitelist.empty? && !options[:force]
|
201
151
|
Kernel.abort("Skipping upload to Socialcast since no users were found")
|
202
152
|
else
|
203
153
|
say "Uploading dataset to Socialcast..."
|
@@ -217,10 +167,134 @@ module Socialcast
|
|
217
167
|
File.delete(output_file) if (config['options']['delete_users_file'] || options[:delete_users_file])
|
218
168
|
end
|
219
169
|
|
170
|
+
desc 'sync_photos', 'Upload default avatar photos from LDAP repository'
|
171
|
+
method_option :config, :default => 'ldap.yml', :aliases => '-c'
|
172
|
+
def sync_photos
|
173
|
+
config = ldap_config options
|
174
|
+
http_config = config.fetch 'http', {}
|
175
|
+
mappings = config.fetch 'mappings', {}
|
176
|
+
profile_photo_field = mappings.fetch('profile_photo')
|
177
|
+
|
178
|
+
search_users_resource = Socialcast.resource_for_path '/api/users/search', http_config
|
179
|
+
|
180
|
+
each_ldap_entry(config) do |ldap, entry|
|
181
|
+
email = entry.grab(mappings['email'])
|
182
|
+
if profile_photo_data = entry.grab(mappings['profile_photo'])
|
183
|
+
profile_photo_data = profile_photo_data.force_encoding('binary')
|
184
|
+
|
185
|
+
user_search_response = search_users_resource.get(:params => { :q => email, :per_page => 1 }, :accept => :json)
|
186
|
+
user_info = JSON.parse(user_search_response)['users'].first
|
187
|
+
if user_info && user_info['avatars'] && user_info['avatars']['is_system_default']
|
188
|
+
say "Uploading photo for #{email}"
|
189
|
+
|
190
|
+
user_resource = Socialcast.resource_for_path "/api/users/#{user_info['id']}", http_config
|
191
|
+
content_type = case profile_photo_data
|
192
|
+
when Regexp.new("\AGIF8", nil, 'n')
|
193
|
+
'gif'
|
194
|
+
when Regexp.new('\A\x89PNG', nil, 'n')
|
195
|
+
'png'
|
196
|
+
when Regexp.new("\A\xff\xd8\xff\xe0\x00\x10JFIF", nil, 'n'), Regexp.new("\A\xff\xd8\xff\xe1(.*){2}Exif", nil, 'n')
|
197
|
+
'jpg'
|
198
|
+
else
|
199
|
+
say "Skipping photo for #{email}: unknown image format (supports .gif, .png, .jpg)"
|
200
|
+
next
|
201
|
+
end
|
202
|
+
|
203
|
+
tempfile = Tempfile.new(["photo_upload", ".#{content_type}"])
|
204
|
+
tempfile.write(profile_photo_data)
|
205
|
+
tempfile.rewind
|
206
|
+
begin
|
207
|
+
user_resource.put({ :user => { :profile_photo => { :data => tempfile } } })
|
208
|
+
ensure
|
209
|
+
tempfile.unlink
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
220
217
|
no_tasks do
|
221
|
-
def
|
222
|
-
|
218
|
+
def load_plugins(options)
|
219
|
+
Array.wrap(options[:plugins]).each do |plugin|
|
220
|
+
begin
|
221
|
+
require plugin
|
222
|
+
rescue LoadError => e
|
223
|
+
fail "Unable to load #{plugin}: #{e}"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def ldap_config(options)
|
229
|
+
config_file = File.expand_path options[:config]
|
230
|
+
|
231
|
+
if options[:setup]
|
232
|
+
create_file config_file do
|
233
|
+
File.read File.join(File.dirname(__FILE__), '..', '..', 'config', 'ldap.yml')
|
234
|
+
end
|
235
|
+
say "Created config file: #{config_file}"
|
236
|
+
Kernel.exit 0
|
237
|
+
end
|
238
|
+
|
239
|
+
fail "Unable to load configuration file: #{config_file}" unless File.exists?(config_file)
|
240
|
+
say "Using configuration file: #{config_file}"
|
241
|
+
config = YAML.load_file config_file
|
242
|
+
|
243
|
+
mappings = config.fetch 'mappings', {}
|
244
|
+
required_mappings = %w{email first_name last_name}
|
245
|
+
required_mappings.each do |field|
|
246
|
+
unless mappings.has_key? field
|
247
|
+
fail "Missing required mapping: #{field}"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
config
|
223
252
|
end
|
253
|
+
|
254
|
+
def ldap_search_attributes(config)
|
255
|
+
mappings = config.fetch 'mappings', {}
|
256
|
+
permission_mappings = config.fetch 'permission_mappings', {}
|
257
|
+
|
258
|
+
membership_attribute = permission_mappings.fetch 'attribute_name', 'memberof'
|
259
|
+
attributes = mappings.values.map do |mapping_value|
|
260
|
+
mapping_value = begin
|
261
|
+
mapping_value.camelize.constantize
|
262
|
+
rescue NameError
|
263
|
+
mapping_value
|
264
|
+
end
|
265
|
+
case mapping_value
|
266
|
+
when Hash
|
267
|
+
dup_mapping_value = mapping_value.dup
|
268
|
+
dup_mapping_value.delete("value")
|
269
|
+
dup_mapping_value.values
|
270
|
+
when String
|
271
|
+
mapping_value
|
272
|
+
when Class, Module
|
273
|
+
fail "Please add the attributes method to #{mapping_value}" unless mapping_value.respond_to?(:attributes)
|
274
|
+
mapping_value.attributes
|
275
|
+
end
|
276
|
+
end.flatten
|
277
|
+
attributes << membership_attribute
|
278
|
+
end
|
279
|
+
|
280
|
+
def each_ldap_entry(config, &block)
|
281
|
+
count = 0
|
282
|
+
mappings = config.fetch 'mappings', {}
|
283
|
+
|
284
|
+
ldap_connections(config) do |key, connection, ldap|
|
285
|
+
ldap.search(:return_result => false, :filter => connection["filter"], :base => connection["basedn"], :attributes => ldap_search_attributes(config)) do |entry|
|
286
|
+
|
287
|
+
if entry.grab(mappings["email"]).present? || (mappings.has_key?("unique_identifier") && entry.grab(mappings["unique_identifier"]).present?)
|
288
|
+
yield ldap, entry
|
289
|
+
end
|
290
|
+
|
291
|
+
count += 1
|
292
|
+
say "Scanned #{count} users" if ((count % 100) == 0)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
say "Finished scanning #{count} users"
|
296
|
+
end
|
297
|
+
|
224
298
|
def ldap_connections(config)
|
225
299
|
config["connections"].each_pair do |key, connection|
|
226
300
|
say "Connecting to #{key} at #{[connection["host"], connection["port"]].join(':')}"
|
@@ -229,12 +303,14 @@ module Socialcast
|
|
229
303
|
yield key, connection, ldap
|
230
304
|
end
|
231
305
|
end
|
306
|
+
|
232
307
|
def create_ldap_instance(connection)
|
233
308
|
ldap = Net::LDAP.new :host => connection["host"], :port => connection["port"], :base => connection["basedn"]
|
234
309
|
ldap.encryption connection['encryption'].to_sym if connection['encryption']
|
235
310
|
ldap.auth connection["username"], connection["password"]
|
236
311
|
ldap
|
237
312
|
end
|
313
|
+
|
238
314
|
def current_socialcast_users(http_config)
|
239
315
|
current_socialcast_list = Set.new
|
240
316
|
request_params = {:per_page => 500}
|
@@ -253,6 +329,7 @@ module Socialcast
|
|
253
329
|
end
|
254
330
|
current_socialcast_list
|
255
331
|
end
|
332
|
+
|
256
333
|
def create_socialcast_user_index_request(http_config, request_params)
|
257
334
|
path_template = "/api/users?per_page=%{per_page}&page=%{page}"
|
258
335
|
Socialcast.resource_for_path((path_template % request_params), http_config)
|
data/lib/socialcast/version.rb
CHANGED
data/socialcast.gemspec
CHANGED
@@ -6,9 +6,9 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "socialcast"
|
7
7
|
s.version = Socialcast::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Ryan Sonnek","Sean Cashin"]
|
10
|
-
s.email = ["
|
11
|
-
s.homepage = "http://github.com/
|
9
|
+
s.authors = ["Ryan Sonnek","Sean Cashin","Lars Klevan"]
|
10
|
+
s.email = ["sean@socialcast.com"]
|
11
|
+
s.homepage = "http://github.com/socialcast/socialcast-command-line"
|
12
12
|
s.summary = %q{command line interface to socialcast api}
|
13
13
|
s.description = %q{publish messages to your stream from a command line interface}
|
14
14
|
|
data/spec/cli_spec.rb
CHANGED
@@ -62,12 +62,126 @@ describe Socialcast::CLI do
|
|
62
62
|
# See expectations
|
63
63
|
end
|
64
64
|
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#sync_photos' do
|
68
|
+
context "with no profile_photo mapping" do
|
69
|
+
let(:config_file) { File.join(File.dirname(__FILE__), 'fixtures', 'ldap.yml') }
|
70
|
+
it "reports an error" do
|
71
|
+
lambda { Socialcast::CLI.start ['sync_photos', '-c', config_file] }.should raise_error KeyError
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "user does not have a profile photo" do
|
76
|
+
let(:config_file) { File.join(File.dirname(__FILE__), 'fixtures', 'ldap_with_profile_photo.yml') }
|
77
|
+
let(:system_default_photo) { true }
|
78
|
+
let(:photo_data) { "\x89PNGabc" }
|
79
|
+
before do
|
80
|
+
@entry = Net::LDAP::Entry.new("dc=example,dc=com")
|
81
|
+
@entry[:mail] = 'ryan@example.com'
|
82
|
+
@entry[:jpegPhoto] = photo_data
|
83
|
+
Net::LDAP.any_instance.stub(:search).and_yield(@entry)
|
84
|
+
|
85
|
+
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
86
|
+
user_search_resource = double(:user_search_resource)
|
87
|
+
search_api_response = {
|
88
|
+
'users' => [
|
89
|
+
{
|
90
|
+
'id' => 7,
|
91
|
+
'avatars' => {
|
92
|
+
'is_system_default' => system_default_photo
|
93
|
+
}
|
94
|
+
}
|
95
|
+
]
|
96
|
+
}
|
97
|
+
user_search_resource.should_receive(:get).and_return(search_api_response.to_json)
|
98
|
+
Socialcast.stub(:resource_for_path).with('/api/users/search', anything).and_return(user_search_resource)
|
99
|
+
|
100
|
+
user_resource = double(:user_resource)
|
101
|
+
user_resource.should_receive(:put) do |data|
|
102
|
+
uploaded_data = data[:user][:profile_photo][:data]
|
103
|
+
uploaded_data.read.force_encoding('binary').should == photo_data
|
104
|
+
uploaded_data.path.should =~ /\.png\Z/
|
105
|
+
end
|
106
|
+
Socialcast.stub(:resource_for_path).with('/api/users/7', anything).and_return(user_resource)
|
107
|
+
|
108
|
+
Socialcast::CLI.start ['sync_photos', '-c', config_file]
|
109
|
+
end
|
110
|
+
it "syncs the profile photo" do; end
|
111
|
+
end
|
65
112
|
|
113
|
+
context "unknown image format" do
|
114
|
+
let(:config_file) { File.join(File.dirname(__FILE__), 'fixtures', 'ldap_with_profile_photo.yml') }
|
115
|
+
let(:system_default_photo) { true }
|
116
|
+
let(:photo_data) { "abc" }
|
117
|
+
before do
|
118
|
+
@entry = Net::LDAP::Entry.new("dc=example,dc=com")
|
119
|
+
@entry[:mail] = 'ryan@example.com'
|
120
|
+
@entry[:jpegPhoto] = photo_data
|
121
|
+
Net::LDAP.any_instance.stub(:search).and_yield(@entry)
|
122
|
+
|
123
|
+
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
124
|
+
user_search_resource = double(:user_search_resource)
|
125
|
+
search_api_response = {
|
126
|
+
'users' => [
|
127
|
+
{
|
128
|
+
'id' => 7,
|
129
|
+
'avatars' => {
|
130
|
+
'is_system_default' => system_default_photo
|
131
|
+
}
|
132
|
+
}
|
133
|
+
]
|
134
|
+
}
|
135
|
+
user_search_resource.should_receive(:get).and_return(search_api_response.to_json)
|
136
|
+
Socialcast.stub(:resource_for_path).with('/api/users/search', anything).and_return(user_search_resource)
|
137
|
+
|
138
|
+
user_resource = double(:user_resource)
|
139
|
+
user_resource.should_not_receive(:put)
|
140
|
+
Socialcast.stub(:resource_for_path).with('/api/users/7', anything).and_return(user_resource)
|
141
|
+
|
142
|
+
Socialcast::CLI.start ['sync_photos', '-c', config_file]
|
143
|
+
end
|
144
|
+
it "does not sync the profile photo" do; end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "user already has a profile photo" do
|
148
|
+
let(:config_file) { File.join(File.dirname(__FILE__), 'fixtures', 'ldap_with_profile_photo.yml') }
|
149
|
+
let(:system_default_photo) { false }
|
150
|
+
let(:photo_data) { "\x89PNGabc" }
|
151
|
+
before do
|
152
|
+
@entry = Net::LDAP::Entry.new("dc=example,dc=com")
|
153
|
+
@entry[:mail] = 'ryan@example.com'
|
154
|
+
@entry[:jpegPhoto] = "\x89PNGabc"
|
155
|
+
Net::LDAP.any_instance.stub(:search).and_yield(@entry)
|
156
|
+
|
157
|
+
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
158
|
+
user_search_resource = double(:user_search_resource)
|
159
|
+
search_api_response = {
|
160
|
+
'users' => [
|
161
|
+
{
|
162
|
+
'id' => 7,
|
163
|
+
'avatars' => {
|
164
|
+
'is_system_default' => system_default_photo
|
165
|
+
}
|
166
|
+
}
|
167
|
+
]
|
168
|
+
}
|
169
|
+
user_search_resource.should_receive(:get).and_return(search_api_response.to_json)
|
170
|
+
Socialcast.stub(:resource_for_path).with('/api/users/search', anything).and_return(user_search_resource)
|
171
|
+
|
172
|
+
user_resource = double(:user_resource)
|
173
|
+
user_resource.should_not_receive(:put)
|
174
|
+
Socialcast.stub(:resource_for_path).with('/api/users/7', anything).and_return(user_resource)
|
175
|
+
|
176
|
+
Socialcast::CLI.start ['sync_photos', '-c', config_file]
|
177
|
+
end
|
178
|
+
it "does not sync the profile photo" do; end
|
179
|
+
end
|
66
180
|
end
|
67
181
|
|
68
182
|
describe '#provision' do
|
69
183
|
before do
|
70
|
-
Socialcast::CLI.instance_eval do # to supress warning from stubbing
|
184
|
+
Socialcast::CLI.instance_eval do # to supress warning from stubbing ldap_config
|
71
185
|
@no_tasks = true
|
72
186
|
end
|
73
187
|
end
|
@@ -78,16 +192,14 @@ describe Socialcast::CLI do
|
|
78
192
|
@result = ''
|
79
193
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
80
194
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
81
|
-
Socialcast::CLI.any_instance.should_receive(:
|
82
|
-
File.should_receive(:exists?).with('/my/path/to/ldap.yml').and_return(true)
|
195
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_without_permission_mappings.yml')))
|
83
196
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
84
197
|
|
85
198
|
RestClient::Resource.any_instance.should_not_receive(:post)
|
86
|
-
Kernel.should_receive(:abort).once
|
87
|
-
|
88
|
-
Socialcast::CLI.start ['provision', '-c', '/my/path/to/ldap.yml']
|
89
199
|
end
|
90
|
-
it 'does not post to Socialcast and
|
200
|
+
it 'does not post to Socialcast and raises error' do
|
201
|
+
lambda { Socialcast::CLI.start ['provision'] }.should raise_error SystemExit
|
202
|
+
end
|
91
203
|
end
|
92
204
|
context 'with 0 users found in ldap and force option passed' do
|
93
205
|
before do
|
@@ -96,17 +208,15 @@ describe Socialcast::CLI do
|
|
96
208
|
@result = ''
|
97
209
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
98
210
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
99
|
-
Socialcast::CLI.any_instance.should_receive(:
|
100
|
-
File.should_receive(:exists?).with('/my/path/to/ldap.yml').and_return(true)
|
211
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_without_permission_mappings.yml')))
|
101
212
|
|
102
213
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
103
214
|
|
104
215
|
RestClient::Resource.any_instance.should_receive(:post).once
|
105
|
-
Kernel.should_not_receive(:abort)
|
106
216
|
|
107
|
-
Socialcast::CLI.start ['provision', '-
|
217
|
+
Socialcast::CLI.start ['provision', '-f']
|
108
218
|
end
|
109
|
-
it 'does post to Socialcast and does not
|
219
|
+
it 'does post to Socialcast and does not raise error' do end # see expectations
|
110
220
|
end
|
111
221
|
context 'with socialcast returning 401' do
|
112
222
|
before do
|
@@ -115,8 +225,7 @@ describe Socialcast::CLI do
|
|
115
225
|
@result = ''
|
116
226
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
117
227
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
118
|
-
Socialcast::CLI.any_instance.should_receive(:
|
119
|
-
File.should_receive(:exists?).with('/my/path/to/ldap.yml').and_return(true)
|
228
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_without_permission_mappings.yml')))
|
120
229
|
|
121
230
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
122
231
|
rest_client_resource = double(:rest_client_resource)
|
@@ -124,7 +233,7 @@ describe Socialcast::CLI do
|
|
124
233
|
Socialcast.stub(:resource_for_path).and_return(rest_client_resource)
|
125
234
|
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
|
126
235
|
|
127
|
-
Socialcast::CLI.start ['provision', '-
|
236
|
+
Socialcast::CLI.start ['provision', '-f']
|
128
237
|
end
|
129
238
|
it "raises Kernel abort" do end # see expectations
|
130
239
|
end
|
@@ -137,8 +246,7 @@ describe Socialcast::CLI do
|
|
137
246
|
@result = ''
|
138
247
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
139
248
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
140
|
-
Socialcast::CLI.any_instance.should_receive(:
|
141
|
-
File.should_receive(:exists?).with('/my/path/to/ldap.yml').and_return(true)
|
249
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).with(hash_including('config' => '/my/path/to/ldap.yml')).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_without_permission_mappings.yml')))
|
142
250
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
143
251
|
RestClient::Resource.any_instance.stub(:post)
|
144
252
|
|
@@ -155,8 +263,7 @@ describe Socialcast::CLI do
|
|
155
263
|
@result = ''
|
156
264
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
157
265
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
158
|
-
Socialcast::CLI.any_instance.should_receive(:
|
159
|
-
File.should_receive(:exists?).with('/my/path/to/ldap.yml').and_return(true)
|
266
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_without_permission_mappings.yml')))
|
160
267
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
161
268
|
RestClient::Resource.any_instance.stub(:post)
|
162
269
|
|
@@ -174,12 +281,11 @@ describe Socialcast::CLI do
|
|
174
281
|
@result = ''
|
175
282
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
176
283
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
177
|
-
Socialcast::CLI.any_instance.should_receive(:
|
178
|
-
File.should_receive(:exists?).with('/my/path/to/ldap.yml').and_return(true)
|
284
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_with_plugin_mapping.yml')))
|
179
285
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
180
286
|
RestClient::Resource.any_instance.stub(:post)
|
181
287
|
|
182
|
-
Socialcast::CLI.start ['provision', '
|
288
|
+
Socialcast::CLI.start ['provision', '--plugins', [File.join(File.dirname(__FILE__), 'fixtures', 'fake_attribute_map')]]
|
183
289
|
end
|
184
290
|
it 'successfully processes' do
|
185
291
|
@result.should =~ %r{rybn@exbmple.com}
|
@@ -195,48 +301,17 @@ describe Socialcast::CLI do
|
|
195
301
|
@result = ''
|
196
302
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
197
303
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
198
|
-
Socialcast::CLI.any_instance.should_receive(:
|
304
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_without_permission_mappings.yml')))
|
199
305
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
200
306
|
|
201
307
|
RestClient::Resource.any_instance.stub(:post)
|
202
308
|
|
203
|
-
Socialcast::CLI.start ['provision'
|
309
|
+
Socialcast::CLI.start ['provision']
|
204
310
|
end
|
205
311
|
it 'excludes roles element' do
|
206
312
|
@result.should_not =~ %r{roles}
|
207
313
|
end
|
208
314
|
end
|
209
|
-
context "with a user marked for termination that shouldn't be and sanity_check option passed" do
|
210
|
-
before do
|
211
|
-
@entry = Net::LDAP::Entry.new("cn=Ryan,dc=example,dc=com")
|
212
|
-
@entry[:mail] = 'ryan@example.com'
|
213
|
-
@valid_entry = Net::LDAP::Entry.new("cn=Sean,dc=example,dc=com")
|
214
|
-
@valid_entry[:mail] = 'sean@example.com'
|
215
|
-
ldap_search_block = double("ldapsearchblock")
|
216
|
-
ldap_search_block.should_receive(:search).and_yield(@entry)
|
217
|
-
ldap_return = double("ldapreturn")
|
218
|
-
ldap_return.should_receive(:search).with(include(:filter=>Net::LDAP::Filter.construct("(&(mail=sean@example.com)(mail=*))"))).and_return(@valid_entry)
|
219
|
-
|
220
|
-
Socialcast::CLI.any_instance.should_receive(:create_ldap_instance).and_return(ldap_search_block, ldap_return)
|
221
|
-
|
222
|
-
@result = ''
|
223
|
-
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
224
|
-
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
225
|
-
Socialcast::CLI.any_instance.should_receive(:load_configuration).with(/ldap.yml/).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap.yml')))
|
226
|
-
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
227
|
-
|
228
|
-
Socialcast::CLI.any_instance.should_receive(:create_socialcast_user_index_request).and_return(
|
229
|
-
double("request1", :get => {"users" => [{"contact_info" => {"email" => @entry[:mail][0]}}]}.to_json),
|
230
|
-
double("request2", :get => {"users" => [{"contact_info" => {"email" => @valid_entry[:mail][0]}}]}.to_json),
|
231
|
-
double("empty_request", :get => {"users" => []}.to_json)
|
232
|
-
)
|
233
|
-
|
234
|
-
RestClient::Resource.any_instance.should_receive(:post).never
|
235
|
-
end
|
236
|
-
it 'does not post to Socialcast and throws Kernel.abort' do
|
237
|
-
lambda { Socialcast::CLI.start ['provision', '-c', 'spec/fixtures/ldap.yml', '--sanity_check', true] }.should raise_error SystemExit
|
238
|
-
end
|
239
|
-
end
|
240
315
|
context 'with external group member' do
|
241
316
|
before do
|
242
317
|
@entry = Net::LDAP::Entry.new("dc=example,dc=com")
|
@@ -248,12 +323,12 @@ describe Socialcast::CLI do
|
|
248
323
|
@result = ''
|
249
324
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
250
325
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
251
|
-
Socialcast::CLI.any_instance.should_receive(:
|
326
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap.yml')))
|
252
327
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
253
328
|
|
254
329
|
RestClient::Resource.any_instance.stub(:post)
|
255
330
|
|
256
|
-
Socialcast::CLI.start ['provision'
|
331
|
+
Socialcast::CLI.start ['provision']
|
257
332
|
end
|
258
333
|
it 'sets account-type to external' do
|
259
334
|
@result.should =~ %r{<account-type>external</account-type>}
|
@@ -270,12 +345,12 @@ describe Socialcast::CLI do
|
|
270
345
|
@result = ''
|
271
346
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
272
347
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
273
|
-
Socialcast::CLI.any_instance.should_receive(:
|
348
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_with_array_permission_mapping.yml')))
|
274
349
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
275
350
|
|
276
351
|
RestClient::Resource.any_instance.stub(:post)
|
277
352
|
|
278
|
-
Socialcast::CLI.start ['provision'
|
353
|
+
Socialcast::CLI.start ['provision']
|
279
354
|
end
|
280
355
|
it 'sets account-type to external' do
|
281
356
|
@result.should =~ %r{<account-type>external</account-type>}
|
@@ -293,12 +368,12 @@ describe Socialcast::CLI do
|
|
293
368
|
@result = ''
|
294
369
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
295
370
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
296
|
-
Socialcast::CLI.any_instance.should_receive(:
|
371
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap.yml')))
|
297
372
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
298
373
|
|
299
374
|
RestClient::Resource.any_instance.stub(:post)
|
300
375
|
|
301
|
-
Socialcast::CLI.start ['provision'
|
376
|
+
Socialcast::CLI.start ['provision']
|
302
377
|
end
|
303
378
|
it 'sets account-type to member' do
|
304
379
|
@result.should =~ %r{<account-type>member</account-type>}
|
@@ -318,7 +393,7 @@ describe Socialcast::CLI do
|
|
318
393
|
@result = ''
|
319
394
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
320
395
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
321
|
-
Socialcast::CLI.any_instance.should_receive(:
|
396
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_with_array_permission_mapping.yml')))
|
322
397
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
323
398
|
|
324
399
|
RestClient::Resource.any_instance.stub(:post)
|
@@ -343,12 +418,12 @@ describe Socialcast::CLI do
|
|
343
418
|
@result = ''
|
344
419
|
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
345
420
|
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
346
|
-
Socialcast::CLI.any_instance.should_receive(:
|
421
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_with_array_permission_mapping.yml')))
|
347
422
|
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
348
423
|
|
349
424
|
RestClient::Resource.any_instance.stub(:post)
|
350
425
|
|
351
|
-
Socialcast::CLI.start ['provision'
|
426
|
+
Socialcast::CLI.start ['provision']
|
352
427
|
end
|
353
428
|
it 'sets account-type to member' do
|
354
429
|
@result.should =~ %r{<account-type>member</account-type>}
|
@@ -357,53 +432,89 @@ describe Socialcast::CLI do
|
|
357
432
|
@result.should =~ %r{<role>sbi_admin</role>}
|
358
433
|
end
|
359
434
|
end
|
360
|
-
end
|
361
|
-
context 'with ldap.yml configuration including template value' do
|
362
|
-
before do
|
363
|
-
@entry = Net::LDAP::Entry.new("dc=example,dc=com")
|
364
|
-
@entry[:mail] = 'ryan@example.com'
|
365
|
-
@entry[:l] = 'San Francisco'
|
366
|
-
@entry[:co] = 'USA'
|
367
435
|
|
368
|
-
|
436
|
+
context 'with ldap.yml configuration including template value' do
|
437
|
+
before do
|
438
|
+
@entry = Net::LDAP::Entry.new("dc=example,dc=com")
|
439
|
+
@entry[:mail] = 'ryan@example.com'
|
440
|
+
@entry[:l] = 'San Francisco'
|
441
|
+
@entry[:co] = 'USA'
|
442
|
+
|
443
|
+
Net::LDAP.any_instance.stub(:search).and_yield(@entry)
|
444
|
+
|
445
|
+
@result = ''
|
446
|
+
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
447
|
+
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
448
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_with_interpolated_values.yml')))
|
449
|
+
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
369
450
|
|
370
|
-
|
371
|
-
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
372
|
-
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
373
|
-
Socialcast::CLI.any_instance.should_receive(:load_configuration).with(/ldap.yml/).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_with_interpolated_values.yml')))
|
374
|
-
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
451
|
+
RestClient::Resource.any_instance.stub(:post)
|
375
452
|
|
376
|
-
|
453
|
+
Socialcast::CLI.start ['provision']
|
454
|
+
end
|
377
455
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
@result.should =~ %r{<location>San Francisco, USA</location>}
|
456
|
+
it 'formats l and co according to template' do
|
457
|
+
@result.should =~ %r{<location>San Francisco, USA</location>}
|
458
|
+
end
|
382
459
|
end
|
383
|
-
end
|
384
|
-
context 'with ldap.yml configuration including manager attribute mapping' do
|
385
|
-
before do
|
386
|
-
@entry = Net::LDAP::Entry.new("dc=example,dc=com")
|
387
|
-
@entry[:mail] = 'ryan@example.com'
|
388
|
-
@entry[:manager] = 'cn=bossman,dc=example,dc=com'
|
389
|
-
@manager_email = 'bossman@example.com'
|
390
460
|
|
391
|
-
|
392
|
-
|
461
|
+
context 'with ldap.yml configuration including manager attribute mapping' do
|
462
|
+
before do
|
463
|
+
@entry = Net::LDAP::Entry.new("dc=example,dc=com")
|
464
|
+
@entry[:mail] = 'ryan@example.com'
|
465
|
+
@entry[:manager] = 'cn=bossman,dc=example,dc=com'
|
466
|
+
@manager_email = 'bossman@example.com'
|
393
467
|
|
394
|
-
|
395
|
-
|
396
|
-
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
397
|
-
Socialcast::CLI.any_instance.should_receive(:load_configuration).with(/ldap.yml/).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_with_manager_attribute.yml')))
|
398
|
-
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
468
|
+
@entry.stub(:dereference_mail).with(kind_of(Net::LDAP), "manager", "mail").and_return(@manager_email)
|
469
|
+
Net::LDAP.any_instance.stub(:search).and_yield(@entry)
|
399
470
|
|
400
|
-
|
471
|
+
@result = ''
|
472
|
+
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
473
|
+
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
474
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_with_manager_attribute.yml')))
|
475
|
+
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
401
476
|
|
402
|
-
|
477
|
+
RestClient::Resource.any_instance.stub(:post)
|
478
|
+
|
479
|
+
Socialcast::CLI.start ['provision', '-c', 'spec/fixtures/ldap.yml']
|
480
|
+
end
|
481
|
+
|
482
|
+
it 'adds a manager_email entry of bossman@example.com' do
|
483
|
+
@result.should =~ /<email>ryan@example.com<\/email>/
|
484
|
+
@result.should =~ /<label>manager_email<\/label>\s*<value>bossman@example.com<\/value>/
|
485
|
+
end
|
403
486
|
end
|
404
|
-
|
405
|
-
|
406
|
-
|
487
|
+
|
488
|
+
context "with a user marked for termination that shouldn't be and sanity_check option passed" do
|
489
|
+
before do
|
490
|
+
@entry = Net::LDAP::Entry.new("cn=Ryan,dc=example,dc=com")
|
491
|
+
@entry[:mail] = 'ryan@example.com'
|
492
|
+
@valid_entry = Net::LDAP::Entry.new("cn=Sean,dc=example,dc=com")
|
493
|
+
@valid_entry[:mail] = 'sean@example.com'
|
494
|
+
ldap_search_block = double("ldapsearchblock")
|
495
|
+
ldap_search_block.should_receive(:search).and_yield(@entry)
|
496
|
+
ldap_return = double("ldapreturn")
|
497
|
+
ldap_return.should_receive(:search).with(include(:filter => Net::LDAP::Filter.construct("(&(mail=sean@example.com)(mail=*))"))).and_return(@valid_entry)
|
498
|
+
|
499
|
+
Socialcast::CLI.any_instance.should_receive(:create_ldap_instance).and_return(ldap_search_block, ldap_return)
|
500
|
+
|
501
|
+
@result = ''
|
502
|
+
Zlib::GzipWriter.stub(:open).and_yield(@result)
|
503
|
+
Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
|
504
|
+
Socialcast::CLI.any_instance.should_receive(:ldap_config).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap.yml')))
|
505
|
+
File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
|
506
|
+
|
507
|
+
Socialcast::CLI.any_instance.should_receive(:create_socialcast_user_index_request).and_return(
|
508
|
+
double("request1", :get => {"users" => [{"contact_info" => {"email" => @entry[:mail][0]}}]}.to_json),
|
509
|
+
double("request2", :get => {"users" => [{"contact_info" => {"email" => @valid_entry[:mail][0]}}]}.to_json),
|
510
|
+
double("empty_request", :get => {"users" => []}.to_json)
|
511
|
+
)
|
512
|
+
|
513
|
+
RestClient::Resource.any_instance.should_receive(:post).never
|
514
|
+
end
|
515
|
+
it 'does not post to Socialcast and throws Kernel.abort' do
|
516
|
+
lambda { Socialcast::CLI.start ['provision', '--sanity_check', true] }.should raise_error SystemExit
|
517
|
+
end
|
407
518
|
end
|
408
519
|
end
|
409
520
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
---
|
2
|
+
connections:
|
3
|
+
example_connection_1:
|
4
|
+
username: "cn=Directory Manager"
|
5
|
+
password: "test"
|
6
|
+
host: localhost
|
7
|
+
port: 1389
|
8
|
+
basedn: "dc=example,dc=com"
|
9
|
+
filter: "(mail=*)"
|
10
|
+
|
11
|
+
# LDAP attribute mappings
|
12
|
+
mappings:
|
13
|
+
first_name: givenName
|
14
|
+
last_name: sn
|
15
|
+
email: mail
|
16
|
+
profile_photo: jpegPhoto
|
metadata
CHANGED
@@ -1,21 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: socialcast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
5
|
-
prerelease:
|
4
|
+
version: 1.2.3
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Ryan Sonnek
|
9
8
|
- Sean Cashin
|
9
|
+
- Lars Klevan
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-12-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rest-client
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
18
|
requirements:
|
20
19
|
- - ! '>='
|
21
20
|
- !ruby/object:Gem::Version
|
@@ -23,7 +22,6 @@ dependencies:
|
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
24
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
25
|
requirements:
|
28
26
|
- - ! '>='
|
29
27
|
- !ruby/object:Gem::Version
|
@@ -31,7 +29,6 @@ dependencies:
|
|
31
29
|
- !ruby/object:Gem::Dependency
|
32
30
|
name: json
|
33
31
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
32
|
requirements:
|
36
33
|
- - ! '>='
|
37
34
|
- !ruby/object:Gem::Version
|
@@ -39,7 +36,6 @@ dependencies:
|
|
39
36
|
type: :runtime
|
40
37
|
prerelease: false
|
41
38
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
39
|
requirements:
|
44
40
|
- - ! '>='
|
45
41
|
- !ruby/object:Gem::Version
|
@@ -47,7 +43,6 @@ dependencies:
|
|
47
43
|
- !ruby/object:Gem::Dependency
|
48
44
|
name: thor
|
49
45
|
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
46
|
requirements:
|
52
47
|
- - ! '>='
|
53
48
|
- !ruby/object:Gem::Version
|
@@ -55,7 +50,6 @@ dependencies:
|
|
55
50
|
type: :runtime
|
56
51
|
prerelease: false
|
57
52
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
53
|
requirements:
|
60
54
|
- - ! '>='
|
61
55
|
- !ruby/object:Gem::Version
|
@@ -63,7 +57,6 @@ dependencies:
|
|
63
57
|
- !ruby/object:Gem::Dependency
|
64
58
|
name: highline
|
65
59
|
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
60
|
requirements:
|
68
61
|
- - ! '>='
|
69
62
|
- !ruby/object:Gem::Version
|
@@ -71,7 +64,6 @@ dependencies:
|
|
71
64
|
type: :runtime
|
72
65
|
prerelease: false
|
73
66
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
67
|
requirements:
|
76
68
|
- - ! '>='
|
77
69
|
- !ruby/object:Gem::Version
|
@@ -79,7 +71,6 @@ dependencies:
|
|
79
71
|
- !ruby/object:Gem::Dependency
|
80
72
|
name: socialcast-net-ldap
|
81
73
|
requirement: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
74
|
requirements:
|
84
75
|
- - ! '>='
|
85
76
|
- !ruby/object:Gem::Version
|
@@ -87,7 +78,6 @@ dependencies:
|
|
87
78
|
type: :runtime
|
88
79
|
prerelease: false
|
89
80
|
version_requirements: !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
81
|
requirements:
|
92
82
|
- - ! '>='
|
93
83
|
- !ruby/object:Gem::Version
|
@@ -95,7 +85,6 @@ dependencies:
|
|
95
85
|
- !ruby/object:Gem::Dependency
|
96
86
|
name: activeresource
|
97
87
|
requirement: !ruby/object:Gem::Requirement
|
98
|
-
none: false
|
99
88
|
requirements:
|
100
89
|
- - ! '>='
|
101
90
|
- !ruby/object:Gem::Version
|
@@ -103,7 +92,6 @@ dependencies:
|
|
103
92
|
type: :runtime
|
104
93
|
prerelease: false
|
105
94
|
version_requirements: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
95
|
requirements:
|
108
96
|
- - ! '>='
|
109
97
|
- !ruby/object:Gem::Version
|
@@ -111,7 +99,6 @@ dependencies:
|
|
111
99
|
- !ruby/object:Gem::Dependency
|
112
100
|
name: rspec
|
113
101
|
requirement: !ruby/object:Gem::Requirement
|
114
|
-
none: false
|
115
102
|
requirements:
|
116
103
|
- - ! '>='
|
117
104
|
- !ruby/object:Gem::Version
|
@@ -119,7 +106,6 @@ dependencies:
|
|
119
106
|
type: :development
|
120
107
|
prerelease: false
|
121
108
|
version_requirements: !ruby/object:Gem::Requirement
|
122
|
-
none: false
|
123
109
|
requirements:
|
124
110
|
- - ! '>='
|
125
111
|
- !ruby/object:Gem::Version
|
@@ -127,7 +113,6 @@ dependencies:
|
|
127
113
|
- !ruby/object:Gem::Dependency
|
128
114
|
name: webmock
|
129
115
|
requirement: !ruby/object:Gem::Requirement
|
130
|
-
none: false
|
131
116
|
requirements:
|
132
117
|
- - ! '>='
|
133
118
|
- !ruby/object:Gem::Version
|
@@ -135,7 +120,6 @@ dependencies:
|
|
135
120
|
type: :development
|
136
121
|
prerelease: false
|
137
122
|
version_requirements: !ruby/object:Gem::Requirement
|
138
|
-
none: false
|
139
123
|
requirements:
|
140
124
|
- - ! '>='
|
141
125
|
- !ruby/object:Gem::Version
|
@@ -143,7 +127,6 @@ dependencies:
|
|
143
127
|
- !ruby/object:Gem::Dependency
|
144
128
|
name: rake
|
145
129
|
requirement: !ruby/object:Gem::Requirement
|
146
|
-
none: false
|
147
130
|
requirements:
|
148
131
|
- - '='
|
149
132
|
- !ruby/object:Gem::Version
|
@@ -151,14 +134,13 @@ dependencies:
|
|
151
134
|
type: :development
|
152
135
|
prerelease: false
|
153
136
|
version_requirements: !ruby/object:Gem::Requirement
|
154
|
-
none: false
|
155
137
|
requirements:
|
156
138
|
- - '='
|
157
139
|
- !ruby/object:Gem::Version
|
158
140
|
version: 0.9.2.2
|
159
141
|
description: publish messages to your stream from a command line interface
|
160
142
|
email:
|
161
|
-
-
|
143
|
+
- sean@socialcast.com
|
162
144
|
executables:
|
163
145
|
- socialcast
|
164
146
|
extensions: []
|
@@ -193,38 +175,32 @@ files:
|
|
193
175
|
- spec/fixtures/ldap_with_interpolated_values.yml
|
194
176
|
- spec/fixtures/ldap_with_manager_attribute.yml
|
195
177
|
- spec/fixtures/ldap_with_plugin_mapping.yml
|
178
|
+
- spec/fixtures/ldap_with_profile_photo.yml
|
196
179
|
- spec/fixtures/ldap_without_permission_mappings.yml
|
197
180
|
- spec/net_ldap_ext_spec.rb
|
198
181
|
- spec/spec_helper.rb
|
199
|
-
homepage: http://github.com/
|
182
|
+
homepage: http://github.com/socialcast/socialcast-command-line
|
200
183
|
licenses: []
|
184
|
+
metadata: {}
|
201
185
|
post_install_message:
|
202
186
|
rdoc_options: []
|
203
187
|
require_paths:
|
204
188
|
- lib
|
205
189
|
required_ruby_version: !ruby/object:Gem::Requirement
|
206
|
-
none: false
|
207
190
|
requirements:
|
208
191
|
- - ! '>='
|
209
192
|
- !ruby/object:Gem::Version
|
210
193
|
version: '0'
|
211
|
-
segments:
|
212
|
-
- 0
|
213
|
-
hash: 4299609609478338183
|
214
194
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
215
|
-
none: false
|
216
195
|
requirements:
|
217
196
|
- - ! '>='
|
218
197
|
- !ruby/object:Gem::Version
|
219
198
|
version: '0'
|
220
|
-
segments:
|
221
|
-
- 0
|
222
|
-
hash: 4299609609478338183
|
223
199
|
requirements: []
|
224
200
|
rubyforge_project: socialcast
|
225
|
-
rubygems_version: 1.
|
201
|
+
rubygems_version: 2.1.7
|
226
202
|
signing_key:
|
227
|
-
specification_version:
|
203
|
+
specification_version: 4
|
228
204
|
summary: command line interface to socialcast api
|
229
205
|
test_files:
|
230
206
|
- spec/cli_spec.rb
|
@@ -236,6 +212,7 @@ test_files:
|
|
236
212
|
- spec/fixtures/ldap_with_interpolated_values.yml
|
237
213
|
- spec/fixtures/ldap_with_manager_attribute.yml
|
238
214
|
- spec/fixtures/ldap_with_plugin_mapping.yml
|
215
|
+
- spec/fixtures/ldap_with_profile_photo.yml
|
239
216
|
- spec/fixtures/ldap_without_permission_mappings.yml
|
240
217
|
- spec/net_ldap_ext_spec.rb
|
241
218
|
- spec/spec_helper.rb
|